@doriandev/devcc 0.1.2 → 0.3.0

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 (151) hide show
  1. package/README.md +589 -389
  2. package/bin/devcc.mjs +50 -23
  3. package/dist/devcc/agents/agents.d.ts +119 -0
  4. package/dist/devcc/agents/agents.d.ts.map +1 -0
  5. package/dist/devcc/agents/agents.js +182 -0
  6. package/dist/devcc/agents/agents.js.map +1 -0
  7. package/dist/devcc/app/App.d.ts +23 -0
  8. package/dist/devcc/app/App.d.ts.map +1 -1
  9. package/dist/devcc/app/App.js +451 -19
  10. package/dist/devcc/app/App.js.map +1 -1
  11. package/dist/devcc/app/controlPlaneCommands.d.ts +14 -0
  12. package/dist/devcc/app/controlPlaneCommands.d.ts.map +1 -0
  13. package/dist/devcc/app/controlPlaneCommands.js +204 -0
  14. package/dist/devcc/app/controlPlaneCommands.js.map +1 -0
  15. package/dist/devcc/app/keymap.d.ts.map +1 -1
  16. package/dist/devcc/app/keymap.js +25 -3
  17. package/dist/devcc/app/keymap.js.map +1 -1
  18. package/dist/devcc/automation.d.ts +52 -0
  19. package/dist/devcc/automation.d.ts.map +1 -0
  20. package/dist/devcc/automation.js +339 -0
  21. package/dist/devcc/automation.js.map +1 -0
  22. package/dist/devcc/cli.d.ts.map +1 -1
  23. package/dist/devcc/cli.js +73 -3
  24. package/dist/devcc/cli.js.map +1 -1
  25. package/dist/devcc/components/Sidebar.d.ts.map +1 -1
  26. package/dist/devcc/components/Sidebar.js +1 -0
  27. package/dist/devcc/components/Sidebar.js.map +1 -1
  28. package/dist/devcc/components/primitives.d.ts.map +1 -1
  29. package/dist/devcc/components/primitives.js +3 -0
  30. package/dist/devcc/components/primitives.js.map +1 -1
  31. package/dist/devcc/core/commands.d.ts +33 -0
  32. package/dist/devcc/core/commands.d.ts.map +1 -1
  33. package/dist/devcc/core/commands.js.map +1 -1
  34. package/dist/devcc/core/config.d.ts +71 -3
  35. package/dist/devcc/core/config.d.ts.map +1 -1
  36. package/dist/devcc/core/config.js +189 -5
  37. package/dist/devcc/core/config.js.map +1 -1
  38. package/dist/devcc/core/state.d.ts +19 -1
  39. package/dist/devcc/core/state.d.ts.map +1 -1
  40. package/dist/devcc/core/state.js +6 -0
  41. package/dist/devcc/core/state.js.map +1 -1
  42. package/dist/devcc/environment/EnvironmentService.d.ts +58 -0
  43. package/dist/devcc/environment/EnvironmentService.d.ts.map +1 -0
  44. package/dist/devcc/environment/EnvironmentService.js +159 -0
  45. package/dist/devcc/environment/EnvironmentService.js.map +1 -0
  46. package/dist/devcc/environment/integrations.d.ts +52 -0
  47. package/dist/devcc/environment/integrations.d.ts.map +1 -0
  48. package/dist/devcc/environment/integrations.js +94 -0
  49. package/dist/devcc/environment/integrations.js.map +1 -0
  50. package/dist/devcc/environment/tools.d.ts +51 -0
  51. package/dist/devcc/environment/tools.d.ts.map +1 -0
  52. package/dist/devcc/environment/tools.js +99 -0
  53. package/dist/devcc/environment/tools.js.map +1 -0
  54. package/dist/devcc/git/GitService.d.ts +26 -0
  55. package/dist/devcc/git/GitService.d.ts.map +1 -1
  56. package/dist/devcc/git/GitService.js +71 -2
  57. package/dist/devcc/git/GitService.js.map +1 -1
  58. package/dist/devcc/git/worktrees.d.ts +88 -0
  59. package/dist/devcc/git/worktrees.d.ts.map +1 -0
  60. package/dist/devcc/git/worktrees.js +226 -0
  61. package/dist/devcc/git/worktrees.js.map +1 -0
  62. package/dist/devcc/index.d.ts +15 -3
  63. package/dist/devcc/index.d.ts.map +1 -1
  64. package/dist/devcc/index.js +14 -2
  65. package/dist/devcc/index.js.map +1 -1
  66. package/dist/devcc/init/detect.d.ts +55 -0
  67. package/dist/devcc/init/detect.d.ts.map +1 -0
  68. package/dist/devcc/init/detect.js +207 -0
  69. package/dist/devcc/init/detect.js.map +1 -0
  70. package/dist/devcc/init/prompt.d.ts +25 -0
  71. package/dist/devcc/init/prompt.d.ts.map +1 -0
  72. package/dist/devcc/init/prompt.js +156 -0
  73. package/dist/devcc/init/prompt.js.map +1 -0
  74. package/dist/devcc/platform/launch.d.ts +30 -0
  75. package/dist/devcc/platform/launch.d.ts.map +1 -0
  76. package/dist/devcc/platform/launch.js +93 -0
  77. package/dist/devcc/platform/launch.js.map +1 -0
  78. package/dist/devcc/services/ServiceManager.d.ts +10 -2
  79. package/dist/devcc/services/ServiceManager.d.ts.map +1 -1
  80. package/dist/devcc/services/ServiceManager.js +18 -4
  81. package/dist/devcc/services/ServiceManager.js.map +1 -1
  82. package/dist/devcc/services/node.d.ts +11 -0
  83. package/dist/devcc/services/node.d.ts.map +1 -1
  84. package/dist/devcc/services/node.js +20 -18
  85. package/dist/devcc/services/node.js.map +1 -1
  86. package/dist/devcc/services/ollama.d.ts +64 -5
  87. package/dist/devcc/services/ollama.d.ts.map +1 -1
  88. package/dist/devcc/services/ollama.js +118 -17
  89. package/dist/devcc/services/ollama.js.map +1 -1
  90. package/dist/devcc/services/remote.d.ts +90 -0
  91. package/dist/devcc/services/remote.d.ts.map +1 -0
  92. package/dist/devcc/services/remote.js +233 -0
  93. package/dist/devcc/services/remote.js.map +1 -0
  94. package/dist/devcc/services/types.d.ts +8 -1
  95. package/dist/devcc/services/types.d.ts.map +1 -1
  96. package/dist/devcc/services/types.js.map +1 -1
  97. package/dist/devcc/utils/exec.d.ts +6 -0
  98. package/dist/devcc/utils/exec.d.ts.map +1 -1
  99. package/dist/devcc/utils/exec.js +12 -2
  100. package/dist/devcc/utils/exec.js.map +1 -1
  101. package/dist/devcc/verify/verify.d.ts +107 -0
  102. package/dist/devcc/verify/verify.d.ts.map +1 -0
  103. package/dist/devcc/verify/verify.js +203 -0
  104. package/dist/devcc/verify/verify.js.map +1 -0
  105. package/dist/devcc/views/OverviewView.d.ts.map +1 -1
  106. package/dist/devcc/views/OverviewView.js +58 -2
  107. package/dist/devcc/views/OverviewView.js.map +1 -1
  108. package/dist/devcc/views/ServicesView.d.ts +2 -0
  109. package/dist/devcc/views/ServicesView.d.ts.map +1 -1
  110. package/dist/devcc/views/ServicesView.js +15 -0
  111. package/dist/devcc/views/ServicesView.js.map +1 -1
  112. package/dist/devcc/views/SystemView.d.ts +10 -1
  113. package/dist/devcc/views/SystemView.d.ts.map +1 -1
  114. package/dist/devcc/views/SystemView.js +127 -19
  115. package/dist/devcc/views/SystemView.js.map +1 -1
  116. package/dist/devcc/views/WorktreesView.d.ts +48 -0
  117. package/dist/devcc/views/WorktreesView.d.ts.map +1 -0
  118. package/dist/devcc/views/WorktreesView.js +235 -0
  119. package/dist/devcc/views/WorktreesView.js.map +1 -0
  120. package/package.json +1 -1
  121. package/src/devcc/agents/agents.ts +292 -0
  122. package/src/devcc/app/App.ts +529 -22
  123. package/src/devcc/app/controlPlaneCommands.ts +227 -0
  124. package/src/devcc/app/keymap.ts +25 -3
  125. package/src/devcc/automation.ts +409 -0
  126. package/src/devcc/cli.ts +77 -3
  127. package/src/devcc/components/Sidebar.ts +1 -0
  128. package/src/devcc/components/primitives.ts +3 -0
  129. package/src/devcc/core/commands.ts +34 -0
  130. package/src/devcc/core/config.ts +275 -11
  131. package/src/devcc/core/state.ts +25 -0
  132. package/src/devcc/environment/EnvironmentService.ts +215 -0
  133. package/src/devcc/environment/integrations.ts +133 -0
  134. package/src/devcc/environment/tools.ts +151 -0
  135. package/src/devcc/git/GitService.ts +104 -2
  136. package/src/devcc/git/worktrees.ts +256 -0
  137. package/src/devcc/index.ts +66 -2
  138. package/src/devcc/init/detect.ts +268 -0
  139. package/src/devcc/init/prompt.ts +179 -0
  140. package/src/devcc/platform/launch.ts +125 -0
  141. package/src/devcc/services/ServiceManager.ts +15 -3
  142. package/src/devcc/services/node.ts +17 -14
  143. package/src/devcc/services/ollama.ts +162 -19
  144. package/src/devcc/services/remote.ts +306 -0
  145. package/src/devcc/services/types.ts +9 -1
  146. package/src/devcc/utils/exec.ts +26 -2
  147. package/src/devcc/verify/verify.ts +316 -0
  148. package/src/devcc/views/OverviewView.ts +84 -2
  149. package/src/devcc/views/ServicesView.ts +17 -0
  150. package/src/devcc/views/SystemView.ts +144 -22
  151. package/src/devcc/views/WorktreesView.ts +270 -0
@@ -2,17 +2,27 @@ import { TypedEmitter } from "../core/events.js";
2
2
  import { DevccError } from "../utils/errors.js";
3
3
  import type { ScopedLogger } from "../utils/logger.js";
4
4
  import { type GitCommit, type GitStatus } from "./parse.js";
5
+ import { type GitWorktree } from "./worktrees.js";
5
6
  export interface GitSnapshot {
6
7
  available: boolean;
7
8
  isRepository: boolean;
8
9
  status: GitStatus;
9
10
  commits: GitCommit[];
11
+ /** Every worktree of the repository, current one flagged. Empty outside a repo. */
12
+ worktrees: GitWorktree[];
10
13
  version: string | null;
11
14
  lastRefreshedAt: Date | null;
12
15
  /** Set when the last refresh failed; the previous snapshot is kept. */
13
16
  error: string | null;
14
17
  }
15
18
  export declare const EMPTY_GIT_SNAPSHOT: GitSnapshot;
19
+ export interface CreateWorktreeInput {
20
+ branch: string;
21
+ /** Start point when the branch does not exist yet (default: HEAD). */
22
+ base?: string;
23
+ /** Absolute destination directory. */
24
+ path: string;
25
+ }
16
26
  export type GitServiceEvents = {
17
27
  "git:changed": [GitSnapshot];
18
28
  "git:error": [DevccError];
@@ -51,9 +61,25 @@ export declare class GitService extends TypedEmitter<GitServiceEvents> {
51
61
  /** Destructive: throws away worktree changes. Callers must confirm first. */
52
62
  discard(paths: readonly string[]): Promise<void>;
53
63
  commit(message: string): Promise<void>;
64
+ /** Fresh worktree list, independent of the polling snapshot. */
65
+ listWorktrees(): Promise<GitWorktree[]>;
66
+ /**
67
+ * Create a worktree. An existing local branch is checked out; otherwise the
68
+ * branch is created from `base` (default HEAD). Input is validated before git
69
+ * runs, and git's own ref check has the final word on the branch name.
70
+ */
71
+ createWorktree(input: CreateWorktreeInput): Promise<string>;
72
+ /**
73
+ * Remove a worktree without `--force`. devcc refuses the main and current
74
+ * worktrees and ones with running work (`busy`); git refuses dirty ones, and
75
+ * that refusal is surfaced verbatim rather than overridden.
76
+ */
77
+ removeWorktree(path: string, busy?: readonly string[]): Promise<void>;
54
78
  /** Read-only diff for the inspect panel. */
55
79
  diff(path: string, staged: boolean): Promise<string>;
56
80
  private mutate;
81
+ /** Real path of the project root, so git's resolved paths compare equal (macOS /var -> /private/var). */
82
+ private currentPath;
57
83
  private git;
58
84
  private publish;
59
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"GitService.d.ts","sourceRoot":"","sources":["../../../src/devcc/git/GitService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,YAAY,CAAA;AAEnB,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,OAAO,CAAA;IACrB,MAAM,EAAE,SAAS,CAAA;IACjB,OAAO,EAAE,SAAS,EAAE,CAAA;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,eAAe,EAAE,IAAI,GAAG,IAAI,CAAA;IAC5B,uEAAuE;IACvE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,eAAO,MAAM,kBAAkB,EAAE,WAQhC,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,aAAa,EAAE,CAAC,WAAW,CAAC,CAAA;IAC5B,WAAW,EAAE,CAAC,UAAU,CAAC,CAAA;CAC1B,CAAA;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,YAAY,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;GAMG;AACH,qBAAa,UAAW,SAAQ,YAAY,CAAC,gBAAgB,CAAC;IAMhD,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,OAAO,CAAC,QAAQ,CAAyC;IACzD,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAEL,OAAO,EAAE,iBAAiB;IAMvD,WAAW,IAAI,WAAW;IAI1B,qEAAqE;IAC/D,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC;YAQvB,SAAS;IA6CvB,kEAAkE;IAC5D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,KAAK,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,OAAO,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtD,6EAA6E;IACvE,OAAO,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhD,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ5C,4CAA4C;IACtC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;YAQ5C,MAAM;IAiBpB,OAAO,CAAC,GAAG;IASX,OAAO,CAAC,OAAO;CAKhB"}
1
+ {"version":3,"file":"GitService.d.ts","sourceRoot":"","sources":["../../../src/devcc/git/GitService.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,16 @@
1
1
  import { TypedEmitter } from "../core/events.js";
2
2
  import { DevccError } from "../utils/errors.js";
3
+ import { existsSync, realpathSync } from "node:fs";
4
+ import { resolve } from "node:path";
3
5
  import { exec } from "../utils/exec.js";
4
6
  import { EMPTY_GIT_STATUS, LOG_FORMAT, parseCommits, parsePorcelainV2, } from "./parse.js";
7
+ import { parseWorktreeList, removalBlocker, validateBranchName, validateRef, validateWorktreePath, worktreeAddArgs, worktreeRemoveArgs, } from "./worktrees.js";
5
8
  export const EMPTY_GIT_SNAPSHOT = {
6
9
  available: false,
7
10
  isRepository: false,
8
11
  status: EMPTY_GIT_STATUS,
9
12
  commits: [],
13
+ worktrees: [],
10
14
  version: null,
11
15
  lastRefreshedAt: null,
12
16
  error: null,
@@ -43,10 +47,11 @@ export class GitService extends TypedEmitter {
43
47
  return this.refreshing;
44
48
  }
45
49
  async doRefresh() {
46
- const [versionResult, statusResult, logResult] = await Promise.all([
50
+ const [versionResult, statusResult, logResult, worktreeResult] = await Promise.all([
47
51
  this.git(["--version"]),
48
52
  this.git(["status", "--porcelain=v2", "--branch", "--untracked-files=all"]),
49
53
  this.git(["log", `--max-count=${this.commitLimit}`, `--pretty=format:${LOG_FORMAT}`]),
54
+ this.git(["worktree", "list", "--porcelain"]),
50
55
  ]);
51
56
  const available = versionResult.spawnError === undefined;
52
57
  if (!available) {
@@ -66,6 +71,7 @@ export class GitService extends TypedEmitter {
66
71
  isRepository: false,
67
72
  status: EMPTY_GIT_STATUS,
68
73
  commits: [],
74
+ worktrees: [],
69
75
  version,
70
76
  lastRefreshedAt: new Date(),
71
77
  error: notARepo ? null : statusResult.stderr.trim() || "git status failed",
@@ -77,6 +83,7 @@ export class GitService extends TypedEmitter {
77
83
  status: parsePorcelainV2(statusResult.stdout),
78
84
  // A fresh repository with no commits fails `git log`; an empty list is correct there.
79
85
  commits: logResult.ok ? parseCommits(logResult.stdout) : [],
86
+ worktrees: worktreeResult.ok ? parseWorktreeList(worktreeResult.stdout, this.currentPath()) : [],
80
87
  version,
81
88
  lastRefreshedAt: new Date(),
82
89
  error: null,
@@ -118,6 +125,55 @@ export class GitService extends TypedEmitter {
118
125
  }
119
126
  await this.mutate(["commit", "--message", trimmed], "git commit");
120
127
  }
128
+ /** Fresh worktree list, independent of the polling snapshot. */
129
+ async listWorktrees() {
130
+ const result = await this.git(["worktree", "list", "--porcelain"]);
131
+ if (!result.ok) {
132
+ throw new DevccError({
133
+ scope: "git",
134
+ message: "git worktree list failed",
135
+ detail: result.stderr.trim() || (result.spawnError ? "git executable not found" : undefined),
136
+ });
137
+ }
138
+ return parseWorktreeList(result.stdout, this.currentPath());
139
+ }
140
+ /**
141
+ * Create a worktree. An existing local branch is checked out; otherwise the
142
+ * branch is created from `base` (default HEAD). Input is validated before git
143
+ * runs, and git's own ref check has the final word on the branch name.
144
+ */
145
+ async createWorktree(input) {
146
+ const branch = input.branch.trim();
147
+ const base = input.base?.trim() || undefined;
148
+ const path = resolve(input.path.trim());
149
+ const problem = validateBranchName(branch) ??
150
+ (base ? validateRef(base) : null) ??
151
+ validateWorktreePath(path, existsSync);
152
+ if (problem)
153
+ throw new DevccError({ scope: "git", message: problem });
154
+ const refCheck = await this.git(["check-ref-format", "--branch", branch]);
155
+ if (!refCheck.ok) {
156
+ throw new DevccError({ scope: "git", message: `"${branch}" is not a valid branch name` });
157
+ }
158
+ const existing = await this.git(["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
159
+ const createBranch = !existing.ok;
160
+ await this.mutate(worktreeAddArgs({ path, branch, base: createBranch ? base : undefined, createBranch }), "git worktree add", 60_000);
161
+ return path;
162
+ }
163
+ /**
164
+ * Remove a worktree without `--force`. devcc refuses the main and current
165
+ * worktrees and ones with running work (`busy`); git refuses dirty ones, and
166
+ * that refusal is surfaced verbatim rather than overridden.
167
+ */
168
+ async removeWorktree(path, busy = []) {
169
+ const target = (await this.listWorktrees()).find((worktree) => worktree.path === path);
170
+ if (!target)
171
+ throw new DevccError({ scope: "git", message: `${path} is not a worktree of this repository` });
172
+ const blocker = removalBlocker(target, busy);
173
+ if (blocker)
174
+ throw new DevccError({ scope: "git", message: blocker });
175
+ await this.mutate(worktreeRemoveArgs(target.path), "git worktree remove");
176
+ }
121
177
  /** Read-only diff for the inspect panel. */
122
178
  async diff(path, staged) {
123
179
  const args = ["--no-pager", "diff", "--no-color"];
@@ -132,9 +188,12 @@ export class GitService extends TypedEmitter {
132
188
  if (!result.ok) {
133
189
  const detail = [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
134
190
  this.options.logger.warn(`${label} failed`, { code: result.code, detail });
191
+ // Prefer git's fatal/error line: progress chatter ("Preparing worktree…") can come first.
192
+ const lines = detail.split("\n");
193
+ const reason = (lines.find((line) => /^(fatal|error): /u.test(line)) ?? lines[0])?.replace(/^(fatal|error): /u, "");
135
194
  const error = new DevccError({
136
195
  scope: "git",
137
- message: `${label} failed`,
196
+ message: reason ? `${label} failed: ${reason}` : `${label} failed`,
138
197
  detail: detail || (result.timedOut ? "timed out" : undefined),
139
198
  });
140
199
  this.emit("git:error", error);
@@ -143,10 +202,20 @@ export class GitService extends TypedEmitter {
143
202
  this.options.logger.info(`${label} ok`);
144
203
  await this.refresh();
145
204
  }
205
+ /** Real path of the project root, so git's resolved paths compare equal (macOS /var -> /private/var). */
206
+ currentPath() {
207
+ try {
208
+ return realpathSync(this.options.rootDir);
209
+ }
210
+ catch {
211
+ return resolve(this.options.rootDir);
212
+ }
213
+ }
146
214
  git(args, timeoutMs) {
147
215
  return exec("git", args, {
148
216
  cwd: this.options.rootDir,
149
217
  timeoutMs: timeoutMs ?? this.timeoutMs,
218
+ logger: this.options.logger,
150
219
  // Never let git open an editor or a credential prompt under the TUI.
151
220
  env: { ...process.env, GIT_TERMINAL_PROMPT: "0", GIT_OPTIONAL_LOCKS: "0", GIT_EDITOR: "true" },
152
221
  });
@@ -1 +1 @@
1
- {"version":3,"file":"GitService.js","sourceRoot":"","sources":["../../../src/devcc/git/GitService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,IAAI,EAAmB,MAAM,kBAAkB,CAAA;AAExD,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,gBAAgB,GAGjB,MAAM,YAAY,CAAA;AAanB,MAAM,CAAC,MAAM,kBAAkB,GAAgB;IAC7C,SAAS,EAAE,KAAK;IAChB,YAAY,EAAE,KAAK;IACnB,MAAM,EAAE,gBAAgB;IACxB,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,IAAI;IACrB,KAAK,EAAE,IAAI;CACZ,CAAA;AAcD;;;;;;GAMG;AACH,MAAM,OAAO,UAAW,SAAQ,YAA8B;IAM/B;IALrB,QAAQ,GAAgB,EAAE,GAAG,kBAAkB,EAAE,CAAA;IACjD,UAAU,GAAgC,IAAI,CAAA;IACrC,WAAW,CAAQ;IACnB,SAAS,CAAQ;IAElC,YAA6B,OAA0B;QACrD,KAAK,EAAE,CAAA;QADoB,YAAO,GAAP,OAAO,CAAmB;QAErD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,CAAA;QAC3C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAA;IAC7C,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC,UAAU,CAAA;QAC3C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAC9C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;QACxB,CAAC,CAAC,CAAA;QACF,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,MAAM,CAAC,aAAa,EAAE,YAAY,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACjE,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,uBAAuB,CAAC,CAAC;YAC3E,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,eAAe,IAAI,CAAC,WAAW,EAAE,EAAE,mBAAmB,UAAU,EAAE,CAAC,CAAC;SACtF,CAAC,CAAA;QAEF,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU,KAAK,SAAS,CAAA;QACxD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,OAAO,CAAC;gBAClB,GAAG,kBAAkB;gBACrB,SAAS,EAAE,KAAK;gBAChB,eAAe,EAAE,IAAI,IAAI,EAAE;gBAC3B,KAAK,EAAE,0BAA0B;aAClC,CAAC,CAAA;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAEnG,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;YACnE,OAAO,IAAI,CAAC,OAAO,CAAC;gBAClB,GAAG,IAAI,CAAC,QAAQ;gBAChB,SAAS,EAAE,IAAI;gBACf,YAAY,EAAE,KAAK;gBACnB,MAAM,EAAE,gBAAgB;gBACxB,OAAO,EAAE,EAAE;gBACX,OAAO;gBACP,eAAe,EAAE,IAAI,IAAI,EAAE;gBAC3B,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,mBAAmB;aAC3E,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CAAC;YAClB,SAAS,EAAE,IAAI;YACf,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,gBAAgB,CAAC,YAAY,CAAC,MAAM,CAAC;YAC7C,sFAAsF;YACtF,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YAC3D,OAAO;YACP,eAAe,EAAE,IAAI,IAAI,EAAE;YAC3B,KAAK,EAAE,IAAI;SACZ,CAAC,CAAA;IACJ,CAAC;IAED,kEAAkE;IAClE,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAA;IAC9D,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;IAC9D,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;IACjD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAwB;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,SAAS,CAAC,CAAA;IACvD,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,eAAe,CAAC,CAAA;IACtD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,KAAwB;QACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,sBAAsB,CAAC,CAAA;IACpF,CAAC;IAED,6EAA6E;IAC7E,KAAK,CAAC,OAAO,CAAC,KAAwB;QACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,aAAa,CAAC,CAAA;IAC7E,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAA;QAC9B,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;YACnB,MAAM,IAAI,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAA;QAC5E,CAAC;QACD,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,YAAY,CAAC,CAAA;IACnE,CAAC;IAED,4CAA4C;IAC5C,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,MAAe;QACtC,MAAM,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,CAAC,CAAA;QACjD,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACjC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC3C,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAA;IAClD,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,IAAuB,EAAE,KAAa,EAAE,SAAkB;QAC7E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QAC9C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;YAC/E,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;YAC1E,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC;gBAC3B,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,GAAG,KAAK,SAAS;gBAC1B,MAAM,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;aAC9D,CAAC,CAAA;YACF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;YAC7B,MAAM,KAAK,CAAA;QACb,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,CAAA;QACvC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;IACtB,CAAC;IAEO,GAAG,CAAC,IAAuB,EAAE,SAAkB;QACrD,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE;YACvB,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YACzB,SAAS,EAAE,SAAS,IAAI,IAAI,CAAC,SAAS;YACtC,qEAAqE;YACrE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,mBAAmB,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE;SAC/F,CAAC,CAAA;IACJ,CAAC;IAEO,OAAO,CAAC,QAAqB;QACnC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAA;QAClC,OAAO,QAAQ,CAAA;IACjB,CAAC;CACF"}
1
+ {"version":3,"file":"GitService.js","sourceRoot":"","sources":["../../../src/devcc/git/GitService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,IAAI,EAAmB,MAAM,kBAAkB,CAAA;AAExD,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,gBAAgB,GAGjB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,kBAAkB,GAEnB,MAAM,gBAAgB,CAAA;AAevB,MAAM,CAAC,MAAM,kBAAkB,GAAgB;IAC7C,SAAS,EAAE,KAAK;IAChB,YAAY,EAAE,KAAK;IACnB,MAAM,EAAE,gBAAgB;IACxB,OAAO,EAAE,EAAE;IACX,SAAS,EAAE,EAAE;IACb,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,IAAI;IACrB,KAAK,EAAE,IAAI;CACZ,CAAA;AAsBD;;;;;;GAMG;AACH,MAAM,OAAO,UAAW,SAAQ,YAA8B;IAM/B;IALrB,QAAQ,GAAgB,EAAE,GAAG,kBAAkB,EAAE,CAAA;IACjD,UAAU,GAAgC,IAAI,CAAA;IACrC,WAAW,CAAQ;IACnB,SAAS,CAAQ;IAElC,YAA6B,OAA0B;QACrD,KAAK,EAAE,CAAA;QADoB,YAAO,GAAP,OAAO,CAAmB;QAErD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,CAAA;QAC3C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAA;IAC7C,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC,UAAU,CAAA;QAC3C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAC9C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;QACxB,CAAC,CAAC,CAAA;QACF,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,MAAM,CAAC,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACjF,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,uBAAuB,CAAC,CAAC;YAC3E,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,eAAe,IAAI,CAAC,WAAW,EAAE,EAAE,mBAAmB,UAAU,EAAE,CAAC,CAAC;YACrF,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;SAC9C,CAAC,CAAA;QAEF,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU,KAAK,SAAS,CAAA;QACxD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,OAAO,CAAC;gBAClB,GAAG,kBAAkB;gBACrB,SAAS,EAAE,KAAK;gBAChB,eAAe,EAAE,IAAI,IAAI,EAAE;gBAC3B,KAAK,EAAE,0BAA0B;aAClC,CAAC,CAAA;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAEnG,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;YACnE,OAAO,IAAI,CAAC,OAAO,CAAC;gBAClB,GAAG,IAAI,CAAC,QAAQ;gBAChB,SAAS,EAAE,IAAI;gBACf,YAAY,EAAE,KAAK;gBACnB,MAAM,EAAE,gBAAgB;gBACxB,OAAO,EAAE,EAAE;gBACX,SAAS,EAAE,EAAE;gBACb,OAAO;gBACP,eAAe,EAAE,IAAI,IAAI,EAAE;gBAC3B,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,mBAAmB;aAC3E,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CAAC;YAClB,SAAS,EAAE,IAAI;YACf,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,gBAAgB,CAAC,YAAY,CAAC,MAAM,CAAC;YAC7C,sFAAsF;YACtF,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YAC3D,SAAS,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;YAChG,OAAO;YACP,eAAe,EAAE,IAAI,IAAI,EAAE;YAC3B,KAAK,EAAE,IAAI;SACZ,CAAC,CAAA;IACJ,CAAC;IAED,kEAAkE;IAClE,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAA;IAC9D,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;IAC9D,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;IACjD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAwB;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,SAAS,CAAC,CAAA;IACvD,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,eAAe,CAAC,CAAA;IACtD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,KAAwB;QACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,sBAAsB,CAAC,CAAA;IACpF,CAAC;IAED,6EAA6E;IAC7E,KAAK,CAAC,OAAO,CAAC,KAAwB;QACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,aAAa,CAAC,CAAA;IAC7E,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAA;QAC9B,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;YACnB,MAAM,IAAI,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAA;QAC5E,CAAC;QACD,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,YAAY,CAAC,CAAA;IACnE,CAAC;IAED,gEAAgE;IAChE,KAAK,CAAC,aAAa;QACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;QAClE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,UAAU,CAAC;gBACnB,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,0BAA0B;gBACnC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,SAAS,CAAC;aAC7F,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;IAC7D,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,cAAc,CAAC,KAA0B;QAC7C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;QAClC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS,CAAA;QAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QAEvC,MAAM,OAAO,GACX,kBAAkB,CAAC,MAAM,CAAC;YAC1B,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjC,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;QACxC,IAAI,OAAO;YAAE,MAAM,IAAI,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;QAErE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,kBAAkB,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAA;QACzE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,MAAM,8BAA8B,EAAE,CAAC,CAAA;QAC3F,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,MAAM,EAAE,CAAC,CAAC,CAAA;QAC5F,MAAM,YAAY,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAA;QACjC,MAAM,IAAI,CAAC,MAAM,CACf,eAAe,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,YAAY,EAAE,CAAC,EACtF,kBAAkB,EAClB,MAAM,CACP,CAAA;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,cAAc,CAAC,IAAY,EAAE,OAA0B,EAAE;QAC7D,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;QACtF,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,uCAAuC,EAAE,CAAC,CAAA;QAEjG,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAC5C,IAAI,OAAO;YAAE,MAAM,IAAI,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;QAErE,MAAM,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,qBAAqB,CAAC,CAAA;IAC3E,CAAC;IAED,4CAA4C;IAC5C,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,MAAe;QACtC,MAAM,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,CAAC,CAAA;QACjD,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACjC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC3C,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAA;IAClD,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,IAAuB,EAAE,KAAa,EAAE,SAAkB;QAC7E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QAC9C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;YAC/E,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;YAC1E,0FAA0F;YAC1F,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAChC,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CACxF,mBAAmB,EACnB,EAAE,CACH,CAAA;YACD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC;gBAC3B,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,YAAY,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,SAAS;gBAClE,MAAM,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;aAC9D,CAAC,CAAA;YACF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;YAC7B,MAAM,KAAK,CAAA;QACb,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,CAAA;QACvC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;IACtB,CAAC;IAED,yGAAyG;IACjG,WAAW;QACjB,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAEO,GAAG,CAAC,IAAuB,EAAE,SAAkB;QACrD,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE;YACvB,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YACzB,SAAS,EAAE,SAAS,IAAI,IAAI,CAAC,SAAS;YACtC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;YAC3B,qEAAqE;YACrE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,mBAAmB,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE;SAC/F,CAAC,CAAA;IACJ,CAAC;IAEO,OAAO,CAAC,QAAqB;QACnC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAA;QAClC,OAAO,QAAQ,CAAA;IACjB,CAAC;CACF"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Pure helpers for `git worktree`.
3
+ *
4
+ * Parsing, argument construction and validation live here so they can be
5
+ * tested without a repository; `GitService` only runs the commands.
6
+ */
7
+ export interface GitWorktree {
8
+ /** Absolute path of the worktree's top-level directory. */
9
+ path: string;
10
+ /** Short branch name (`feature/x`), absent when detached or bare. */
11
+ branch?: string;
12
+ /** Full commit hash of HEAD; empty for a bare repository. */
13
+ head: string;
14
+ bare: boolean;
15
+ detached: boolean;
16
+ locked: boolean;
17
+ lockedReason?: string;
18
+ prunable: boolean;
19
+ prunableReason?: string;
20
+ /** The first entry git reports: the repository's main worktree. */
21
+ isMain: boolean;
22
+ /** The worktree devcc is running in. */
23
+ isCurrent: boolean;
24
+ }
25
+ /**
26
+ * Parse `git worktree list --porcelain` (optionally with `-z`).
27
+ *
28
+ * Records are separated by a blank line (a double NUL with `-z`). Unknown keys
29
+ * are ignored and records without a `worktree` line are dropped, so output from
30
+ * a newer git with extra attributes still parses.
31
+ *
32
+ * Format reference: `man git-worktree`, "Porcelain Format".
33
+ */
34
+ export declare function parseWorktreeList(output: string, currentPath?: string): GitWorktree[];
35
+ /**
36
+ * Flag the worktree containing `currentPath`. The deepest match wins, so a
37
+ * worktree nested inside the main checkout is attributed correctly.
38
+ */
39
+ export declare function markCurrent(worktrees: GitWorktree[], currentPath: string): GitWorktree[];
40
+ /** True when `path` is `parent` or somewhere below it. */
41
+ export declare function isInside(path: string, parent: string): boolean;
42
+ /** Display label: the branch, or a short hash when detached. */
43
+ export declare function worktreeLabel(worktree: GitWorktree): string;
44
+ /**
45
+ * Validate a branch name against git's ref rules (`man git-check-ref-format`),
46
+ * plus a leading-dash check so a name can never be read as an option.
47
+ * Returns a human-readable problem, or null when the name is acceptable.
48
+ */
49
+ export declare function validateBranchName(name: string): string | null;
50
+ /** A base ref is passed straight to git, so only rule out option-like or broken input. */
51
+ export declare function validateRef(ref: string): string | null;
52
+ /**
53
+ * Validate a destination directory for a new worktree. `exists` is injected
54
+ * so the check is testable; git itself refuses a non-empty existing directory,
55
+ * but refusing early gives a clearer message.
56
+ */
57
+ export declare function validateWorktreePath(path: string, exists: (path: string) => boolean): string | null;
58
+ /** Directory-safe form of a branch name: `feature/ai-agents` -> `feature-ai-agents`. */
59
+ export declare function branchSlug(branch: string): string;
60
+ /**
61
+ * Where a new worktree goes by default: `<directory>/<repo>-<branch>`, with
62
+ * `directory` relative to the main worktree (default: its parent).
63
+ */
64
+ export declare function defaultWorktreePath(mainWorktreePath: string, branch: string, directory?: string): string;
65
+ export interface CreateWorktreeRequest {
66
+ /** Absolute destination directory. */
67
+ path: string;
68
+ branch: string;
69
+ /** Start point for a new branch. Ignored when checking out an existing branch. */
70
+ base?: string;
71
+ /** True to create `branch` (`-b`); false to check out an existing one. */
72
+ createBranch: boolean;
73
+ }
74
+ /**
75
+ * Arguments for `git worktree add`. Everything user-provided comes after `--`
76
+ * or as the value of `-b`, and each value is its own argv entry, so nothing can
77
+ * be interpreted as an option or split by a shell.
78
+ */
79
+ export declare function worktreeAddArgs(request: CreateWorktreeRequest): string[];
80
+ /** Arguments for `git worktree remove`. Never `--force`: git's safety check stands. */
81
+ export declare function worktreeRemoveArgs(path: string): string[];
82
+ /**
83
+ * Decide whether a worktree may be removed before asking git. `busy` lists
84
+ * directories where devcc is still running something (agents, processes).
85
+ * Returns the reason for refusing, or null when removal may proceed.
86
+ */
87
+ export declare function removalBlocker(worktree: GitWorktree, busy?: readonly string[]): string | null;
88
+ //# sourceMappingURL=worktrees.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktrees.d.ts","sourceRoot":"","sources":["../../../src/devcc/git/worktrees.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,mEAAmE;IACnE,MAAM,EAAE,OAAO,CAAA;IACf,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAwErF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,WAAW,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CAOxF;AAED,0DAA0D;AAC1D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAG9D;AAED,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAI3D;AASD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiB9D;AAED,0FAA0F;AAC1F,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKtD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,GAAG,IAAI,CAMnG;AAED,wFAAwF;AACxF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOjD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAO,GAAG,MAAM,CAEtG;AAMD,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,YAAY,EAAE,OAAO,CAAA;CACtB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,EAAE,CAOxE;AAED,uFAAuF;AACvF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,GAAG,IAAI,CAUjG"}
@@ -0,0 +1,226 @@
1
+ import { basename, isAbsolute, relative, resolve } from "node:path";
2
+ /**
3
+ * Parse `git worktree list --porcelain` (optionally with `-z`).
4
+ *
5
+ * Records are separated by a blank line (a double NUL with `-z`). Unknown keys
6
+ * are ignored and records without a `worktree` line are dropped, so output from
7
+ * a newer git with extra attributes still parses.
8
+ *
9
+ * Format reference: `man git-worktree`, "Porcelain Format".
10
+ */
11
+ export function parseWorktreeList(output, currentPath) {
12
+ const nulSeparated = output.includes("\0");
13
+ const lines = nulSeparated ? output.split("\0") : output.split("\n").map((line) => line.replace(/\r$/u, ""));
14
+ const worktrees = [];
15
+ let record = null;
16
+ const flush = () => {
17
+ if (record && record.path !== "")
18
+ worktrees.push(record);
19
+ record = null;
20
+ };
21
+ for (const line of lines) {
22
+ if (line === "") {
23
+ flush();
24
+ continue;
25
+ }
26
+ const space = line.indexOf(" ");
27
+ const key = space === -1 ? line : line.slice(0, space);
28
+ const value = space === -1 ? "" : line.slice(space + 1);
29
+ if (key === "worktree") {
30
+ flush();
31
+ record = {
32
+ path: value,
33
+ head: "",
34
+ bare: false,
35
+ detached: false,
36
+ locked: false,
37
+ prunable: false,
38
+ isMain: worktrees.length === 0,
39
+ isCurrent: false,
40
+ };
41
+ continue;
42
+ }
43
+ // Attributes before any `worktree` line are malformed; skip them.
44
+ const current = record;
45
+ if (!current)
46
+ continue;
47
+ switch (key) {
48
+ case "HEAD":
49
+ current.head = value;
50
+ break;
51
+ case "branch":
52
+ current.branch = value.replace(/^refs\/heads\//u, "");
53
+ break;
54
+ case "bare":
55
+ current.bare = true;
56
+ break;
57
+ case "detached":
58
+ current.detached = true;
59
+ break;
60
+ case "locked":
61
+ current.locked = true;
62
+ if (value)
63
+ current.lockedReason = value;
64
+ break;
65
+ case "prunable":
66
+ current.prunable = true;
67
+ if (value)
68
+ current.prunableReason = value;
69
+ break;
70
+ default:
71
+ break;
72
+ }
73
+ }
74
+ flush();
75
+ // The first record is the main worktree even if it followed malformed lines.
76
+ for (const [index, worktree] of worktrees.entries())
77
+ worktree.isMain = index === 0;
78
+ return currentPath ? markCurrent(worktrees, currentPath) : worktrees;
79
+ }
80
+ /**
81
+ * Flag the worktree containing `currentPath`. The deepest match wins, so a
82
+ * worktree nested inside the main checkout is attributed correctly.
83
+ */
84
+ export function markCurrent(worktrees, currentPath) {
85
+ let best;
86
+ for (const worktree of worktrees) {
87
+ if (worktree.bare || !isInside(currentPath, worktree.path))
88
+ continue;
89
+ if (!best || worktree.path.length > best.path.length)
90
+ best = worktree;
91
+ }
92
+ return worktrees.map((worktree) => ({ ...worktree, isCurrent: worktree === best }));
93
+ }
94
+ /** True when `path` is `parent` or somewhere below it. */
95
+ export function isInside(path, parent) {
96
+ const rel = relative(resolve(parent), resolve(path));
97
+ return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
98
+ }
99
+ /** Display label: the branch, or a short hash when detached. */
100
+ export function worktreeLabel(worktree) {
101
+ if (worktree.bare)
102
+ return "(bare)";
103
+ if (worktree.branch)
104
+ return worktree.branch;
105
+ return worktree.head ? `detached @ ${worktree.head.slice(0, 7)}` : "(unknown)";
106
+ }
107
+ // ---------------------------------------------------------------------------
108
+ // Validation
109
+ // ---------------------------------------------------------------------------
110
+ // eslint-disable-next-line no-control-regex
111
+ const CONTROL_CHARS = /[\u0000-\u001f\u007f]/u;
112
+ /**
113
+ * Validate a branch name against git's ref rules (`man git-check-ref-format`),
114
+ * plus a leading-dash check so a name can never be read as an option.
115
+ * Returns a human-readable problem, or null when the name is acceptable.
116
+ */
117
+ export function validateBranchName(name) {
118
+ if (name.trim() === "")
119
+ return "Branch name is empty";
120
+ if (name !== name.trim() || /\s/u.test(name))
121
+ return "Branch name cannot contain whitespace";
122
+ if (CONTROL_CHARS.test(name))
123
+ return "Branch name cannot contain control characters";
124
+ if (name.startsWith("-"))
125
+ return "Branch name cannot start with '-'";
126
+ if (name === "@")
127
+ return "Branch name cannot be '@'";
128
+ if (/[~^:?*[\\]/u.test(name))
129
+ return "Branch name cannot contain ~ ^ : ? * [ or \\";
130
+ if (name.includes(".."))
131
+ return "Branch name cannot contain '..'";
132
+ if (name.includes("@{"))
133
+ return "Branch name cannot contain '@{'";
134
+ if (name.includes("//"))
135
+ return "Branch name cannot contain '//'";
136
+ if (name.startsWith("/") || name.endsWith("/"))
137
+ return "Branch name cannot start or end with '/'";
138
+ if (name.endsWith("."))
139
+ return "Branch name cannot end with '.'";
140
+ for (const segment of name.split("/")) {
141
+ if (segment.startsWith("."))
142
+ return "Branch name segments cannot start with '.'";
143
+ if (segment.endsWith(".lock"))
144
+ return "Branch name segments cannot end with '.lock'";
145
+ }
146
+ return null;
147
+ }
148
+ /** A base ref is passed straight to git, so only rule out option-like or broken input. */
149
+ export function validateRef(ref) {
150
+ if (ref.trim() === "")
151
+ return "Base ref is empty";
152
+ if (ref.startsWith("-"))
153
+ return "Base ref cannot start with '-'";
154
+ if (/\s/u.test(ref) || CONTROL_CHARS.test(ref))
155
+ return "Base ref cannot contain whitespace";
156
+ return null;
157
+ }
158
+ /**
159
+ * Validate a destination directory for a new worktree. `exists` is injected
160
+ * so the check is testable; git itself refuses a non-empty existing directory,
161
+ * but refusing early gives a clearer message.
162
+ */
163
+ export function validateWorktreePath(path, exists) {
164
+ if (path.trim() === "")
165
+ return "Worktree path is empty";
166
+ if (CONTROL_CHARS.test(path))
167
+ return "Worktree path cannot contain control characters";
168
+ if (!isAbsolute(path))
169
+ return "Worktree path must be absolute";
170
+ if (exists(path))
171
+ return `${path} already exists`;
172
+ return null;
173
+ }
174
+ /** Directory-safe form of a branch name: `feature/ai-agents` -> `feature-ai-agents`. */
175
+ export function branchSlug(branch) {
176
+ return (branch
177
+ .replace(/[^A-Za-z0-9._-]+/gu, "-")
178
+ .replace(/-+/gu, "-")
179
+ .replace(/^[-.]+|[-.]+$/gu, "") || "worktree");
180
+ }
181
+ /**
182
+ * Where a new worktree goes by default: `<directory>/<repo>-<branch>`, with
183
+ * `directory` relative to the main worktree (default: its parent).
184
+ */
185
+ export function defaultWorktreePath(mainWorktreePath, branch, directory = "..") {
186
+ return resolve(mainWorktreePath, directory, `${basename(mainWorktreePath)}-${branchSlug(branch)}`);
187
+ }
188
+ /**
189
+ * Arguments for `git worktree add`. Everything user-provided comes after `--`
190
+ * or as the value of `-b`, and each value is its own argv entry, so nothing can
191
+ * be interpreted as an option or split by a shell.
192
+ */
193
+ export function worktreeAddArgs(request) {
194
+ if (request.createBranch) {
195
+ const args = ["worktree", "add", "-b", request.branch, "--", request.path];
196
+ if (request.base)
197
+ args.push(request.base);
198
+ return args;
199
+ }
200
+ return ["worktree", "add", "--", request.path, request.branch];
201
+ }
202
+ /** Arguments for `git worktree remove`. Never `--force`: git's safety check stands. */
203
+ export function worktreeRemoveArgs(path) {
204
+ return ["worktree", "remove", "--", path];
205
+ }
206
+ /**
207
+ * Decide whether a worktree may be removed before asking git. `busy` lists
208
+ * directories where devcc is still running something (agents, processes).
209
+ * Returns the reason for refusing, or null when removal may proceed.
210
+ */
211
+ export function removalBlocker(worktree, busy = []) {
212
+ if (worktree.isMain)
213
+ return "The main worktree cannot be removed";
214
+ if (worktree.isCurrent)
215
+ return "devcc is running in this worktree; open another project first";
216
+ if (worktree.bare)
217
+ return "A bare repository is not a removable worktree";
218
+ if (worktree.locked) {
219
+ return `Worktree is locked${worktree.lockedReason ? `: ${worktree.lockedReason}` : ""}; unlock it with git first`;
220
+ }
221
+ const running = busy.find((dir) => isInside(dir, worktree.path));
222
+ if (running)
223
+ return `Something devcc started is still running in ${worktree.path}; stop it first`;
224
+ return null;
225
+ }
226
+ //# sourceMappingURL=worktrees.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktrees.js","sourceRoot":"","sources":["../../../src/devcc/git/worktrees.ts"],"names":[],"mappings":"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"}
@@ -6,16 +6,25 @@
6
6
  * git parsing) without the UI.
7
7
  */
8
8
  export { App, type AppOptions } from "./app/App.js";
9
+ export { createControlPlaneCommands } from "./app/controlPlaneCommands.js";
10
+ export { AgentManager, BUILTIN_AGENTS, createAgentAdapters, type AgentAdapter, type AgentConfig, type AgentLaunchOptions, type AgentSession, } from "./agents/agents.js";
11
+ export { configCheckCommand, envCommand, initCommand, verifyCommand, worktreeListCommand, } from "./automation.js";
12
+ export { detectProject, renderStarterConfig, starterConfig, type ProjectFacts } from "./init/detect.js";
13
+ export { buildSetupPrompt, extractConfigFromOutput, type SetupPromptMode } from "./init/prompt.js";
9
14
  export { createBuiltinCommands, createConfigCommands, createScriptCommands } from "./app/builtinCommands.js";
10
15
  export { HELP_SECTIONS, VIEW_SHORTCUTS } from "./app/keymap.js";
11
16
  export { theme, glyphs, processStatusStyle, serviceStateStyle } from "./app/theme.js";
12
17
  export { CommandRegistry, type CommandContext, type CommandDefinition } from "./core/commands.js";
13
- export { defineConfig, loadConfig, validateConfig, findConfigFile, CONFIG_FILENAMES, DEFAULT_REFRESH, type CommandConfigEntry, type DevccConfig, type ResolvedConfig, type ServiceConfigEntry, } from "./core/config.js";
18
+ export { defineConfig, loadConfig, validateConfig, findConfigFile, loadConfigFile, CONFIG_FILENAMES, DEFAULT_REFRESH, type CommandConfigEntry, type DevccConfig, type EditorConfig, type RemoteMachineConfig, type ResolvedConfig, type ServiceConfigEntry, type TerminalConfig, type WorktreesConfig, } from "./core/config.js";
14
19
  export { TypedEmitter, Subscriptions, type Unsubscribe } from "./core/events.js";
15
20
  export { Store, VIEW_IDS, createInitialState, type AppState, type Notification, type ProjectState, type UiState, type ViewId, } from "./core/state.js";
16
21
  export { DependencyService, updateArgs, type DependencySnapshot } from "./deps/DependencyService.js";
17
22
  export { outdatedArgs, parseOutdated, severityBetween, sortOutdated, summariseOutdated, supportsOutdatedJson, type OutdatedPackage, type UpdateSeverity, } from "./deps/parse.js";
18
- export { GitService, type GitSnapshot } from "./git/GitService.js";
23
+ export { EnvironmentService, type EnvironmentSnapshot } from "./environment/EnvironmentService.js";
24
+ export { parseDirenvStatus, parseMiseLs, type DirenvStatus, type MiseStatus, type RuntimeVersion, } from "./environment/integrations.js";
25
+ export { DEFAULT_TOOLS, detectTool, findExecutable, type ToolDefinition, type ToolStatus, } from "./environment/tools.js";
26
+ export { GitService, type CreateWorktreeInput, type GitSnapshot } from "./git/GitService.js";
27
+ export { defaultWorktreePath, parseWorktreeList, removalBlocker, validateBranchName, worktreeAddArgs, worktreeRemoveArgs, type GitWorktree, } from "./git/worktrees.js";
19
28
  export { parseCommits, parsePorcelainV2, summariseStatus, summariseTracking, type GitCommit, type GitFile, type GitStatus, } from "./git/parse.js";
20
29
  export { LogBuffer, LogStore, MAX_LOG_LINES, type LogEntry, type LogSource, type LogStream, } from "./logs/LogBuffer.js";
21
30
  export { canTransition, crashBackoffDelay, shouldAutoRestart, DEFAULT_CRASH_POLICY, createManagedProcess, describeCommand, isActive, type ManagedProcess, type ProcessDefinition, type ProcessStatus, type ReadinessCheck, } from "./processes/ManagedProcess.js";
@@ -25,7 +34,9 @@ export { buildProjectList, discoverProjects, isProjectDirectory, readRecents, re
25
34
  export { ServiceManager } from "./services/ServiceManager.js";
26
35
  export { DockerService, findComposeFile, parseComposePs } from "./services/docker.js";
27
36
  export { PortService, detectNodeServices } from "./services/node.js";
28
- export { OllamaService } from "./services/ollama.js";
37
+ export { mergeOllamaModels, OllamaService, type OllamaModel } from "./services/ollama.js";
38
+ export { parseTailscaleStatus, RemoteMachineService, TailscaleService, type TailscaleStatus, } from "./services/remote.js";
39
+ export { editorCommand, launchDetached, sshCommand, terminalCommand } from "./platform/launch.js";
29
40
  export { PostgresService, parsePostgresUrl } from "./services/postgres.js";
30
41
  export { RedisService, parseRedisUrl } from "./services/redis.js";
31
42
  export type { ServiceAdapter, ServiceSnapshot, ServiceState, ServiceStatus } from "./services/types.js";
@@ -34,4 +45,5 @@ export { DevccError, errorMessage, toDevccError } from "./utils/errors.js";
34
45
  export { Logger, createLogger, type LogLevel } from "./utils/logger.js";
35
46
  export { detectPackageManager, readPackageJson, readScripts, runScriptArgs, type PackageManager, } from "./utils/packageManager.js";
36
47
  export { findProjectRoot } from "./utils/paths.js";
48
+ export { createSpawnExecutor, resolveVerifySteps, runVerification, type VerifyEntry, type VerifyReport, type VerifyStep, } from "./verify/verify.js";
37
49
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/devcc/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/devcc/index.ts"],"names":[],"mappings":"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"}