xcode-build-queue 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -9,15 +9,15 @@ Running multiple Claude Code sessions on the same Xcode project requires separat
9
9
  ## How It Works
10
10
 
11
11
  ```
12
- ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
13
- │ Claude Code │ │ Claude Code │ │ Claude Code │
14
- │ (worktree A) │ │ (worktree B) │ │ (worktree C) │
15
- └──────┬───────┘ └──────┬───────┘ └──────┬───────┘
16
- │ snapshot │ snapshot │ snapshot
17
- └──────────────────┼──────────────────┘
12
+ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
13
+ │ Claude Code │ │ Claude Code │ │ Claude Code │
14
+ │ (worktree A) │ │ (worktree B) │ │ (worktree C) │
15
+ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘
16
+ │ snapshot │ snapshot │ snapshot
17
+ └──────────────────┼───────────────────┘
18
18
 
19
19
  ┌────────────────────┐
20
- xbq (serial queue) │
20
+ xbq (serial queue) │
21
21
  │ │
22
22
  │ checkout snapshot │
23
23
  │ (detached HEAD) │
@@ -27,8 +27,8 @@ Running multiple Claude Code sessions on the same Xcode project requires separat
27
27
  └────────┬───────────┘
28
28
 
29
29
  ┌───────────┐
30
- │ Main Repo │ ← single DerivedData
31
- │ (warm) │ ← SPM already resolved
30
+ │ Main Repo │ ← single DerivedData
31
+ │ (warm) │ ← SPM already resolved
32
32
  └───────────┘
33
33
  ```
34
34
 
@@ -44,7 +44,7 @@ Running multiple Claude Code sessions on the same Xcode project requires separat
44
44
  ### npm (recommended)
45
45
 
46
46
  ```bash
47
- npm install -g xbq
47
+ npm install -g xcode-build-queue
48
48
  ```
49
49
 
50
50
  ### From GitHub
package/dist/executor.js CHANGED
@@ -13,6 +13,8 @@ async function executeJob(job) {
13
13
  const config = (0, config_js_1.loadConfig)();
14
14
  const repoPath = (0, utils_js_1.expandPath)(config.main_repo);
15
15
  const workspace = config.workspace;
16
+ // 0. Pre-build safety: ensure main repo is clean and on default branch
17
+ (0, snapshot_js_1.ensureCleanMainRepo)(repoPath);
16
18
  // 1. Stash any uncommitted changes in main repo
17
19
  const stashed = stashIfDirty(repoPath);
18
20
  try {
@@ -21,3 +21,8 @@ export declare function applySnapshot(repoPath: string, sha: string): void;
21
21
  * Clean up the main repo by returning to the default branch.
22
22
  */
23
23
  export declare function cleanSnapshot(repoPath: string): void;
24
+ /**
25
+ * Pre-build safety check: ensure the main repo is on its default branch
26
+ * with no uncommitted changes or stale detached HEAD from a previous run.
27
+ */
28
+ export declare function ensureCleanMainRepo(repoPath: string): void;
package/dist/snapshot.js CHANGED
@@ -5,6 +5,7 @@ exports.isInWorktree = isInWorktree;
5
5
  exports.createSnapshot = createSnapshot;
6
6
  exports.applySnapshot = applySnapshot;
7
7
  exports.cleanSnapshot = cleanSnapshot;
8
+ exports.ensureCleanMainRepo = ensureCleanMainRepo;
8
9
  const utils_js_1 = require("./utils.js");
9
10
  /**
10
11
  * Detect the default branch (master, main, develop) for a repo.
@@ -91,9 +92,59 @@ function applySnapshot(repoPath, sha) {
91
92
  function cleanSnapshot(repoPath) {
92
93
  const defaultBranch = getDefaultBranch(repoPath);
93
94
  try {
95
+ // Discard any index/worktree changes from the snapshot before switching
96
+ (0, utils_js_1.run)("git reset --hard", { cwd: repoPath, quiet: true });
94
97
  (0, utils_js_1.run)(`git checkout ${defaultBranch}`, { cwd: repoPath, quiet: true });
95
98
  }
96
99
  catch {
97
- utils_js_1.log.warn(`Could not return to ${defaultBranch}`);
100
+ utils_js_1.log.warn(`Could not return to ${defaultBranch} — attempting force cleanup`);
101
+ try {
102
+ (0, utils_js_1.run)("git checkout --force " + defaultBranch, { cwd: repoPath, quiet: true });
103
+ }
104
+ catch {
105
+ utils_js_1.log.error(`Failed to restore ${defaultBranch}. Manual cleanup required: cd ${repoPath} && git checkout ${defaultBranch}`);
106
+ }
107
+ }
108
+ }
109
+ /**
110
+ * Pre-build safety check: ensure the main repo is on its default branch
111
+ * with no uncommitted changes or stale detached HEAD from a previous run.
112
+ */
113
+ function ensureCleanMainRepo(repoPath) {
114
+ const defaultBranch = getDefaultBranch(repoPath);
115
+ // Check if HEAD is detached
116
+ let isDetached = false;
117
+ try {
118
+ (0, utils_js_1.run)("git symbolic-ref HEAD", { cwd: repoPath, quiet: true });
119
+ }
120
+ catch {
121
+ isDetached = true;
122
+ }
123
+ if (isDetached) {
124
+ utils_js_1.log.warn("Main repo is in detached HEAD (stale snapshot?) — recovering...");
125
+ try {
126
+ (0, utils_js_1.run)("git reset --hard", { cwd: repoPath, quiet: true });
127
+ (0, utils_js_1.run)(`git checkout ${defaultBranch}`, { cwd: repoPath, quiet: true });
128
+ utils_js_1.log.ok(`Recovered to ${defaultBranch}`);
129
+ }
130
+ catch {
131
+ throw new Error(`Main repo stuck in detached HEAD and recovery failed. ` +
132
+ `Manual fix: cd ${repoPath} && git checkout ${defaultBranch}`);
133
+ }
134
+ return;
135
+ }
136
+ // Check if on the expected branch
137
+ const currentBranch = (0, utils_js_1.run)("git branch --show-current", { cwd: repoPath, quiet: true });
138
+ if (currentBranch !== defaultBranch) {
139
+ utils_js_1.log.warn(`Main repo on '${currentBranch}' instead of '${defaultBranch}' — switching...`);
140
+ try {
141
+ (0, utils_js_1.run)("git reset --hard", { cwd: repoPath, quiet: true });
142
+ (0, utils_js_1.run)(`git checkout ${defaultBranch}`, { cwd: repoPath, quiet: true });
143
+ utils_js_1.log.ok(`Switched to ${defaultBranch}`);
144
+ }
145
+ catch {
146
+ throw new Error(`Could not switch main repo to ${defaultBranch}. ` +
147
+ `Manual fix: cd ${repoPath} && git checkout ${defaultBranch}`);
148
+ }
98
149
  }
99
150
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xcode-build-queue",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Serial build queue for Xcode projects with git worktrees",
5
5
  "license": "MIT",
6
6
  "repository": {