@donna-orchestrator/bridge 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.
- package/README.md +45 -0
- package/dist/cli.js +301 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +98 -0
- package/dist/config.js.map +1 -0
- package/dist/executor.js +150 -0
- package/dist/executor.js.map +1 -0
- package/dist/index.js +248 -0
- package/dist/index.js.map +1 -0
- package/dist/install.js +194 -0
- package/dist/install.js.map +1 -0
- package/dist/launchd.js +146 -0
- package/dist/launchd.js.map +1 -0
- package/dist/lifecycle.js +228 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/pair.js +88 -0
- package/dist/pair.js.map +1 -0
- package/dist/preflight.js +117 -0
- package/dist/preflight.js.map +1 -0
- package/dist/scope-guard.js +25 -0
- package/dist/scope-guard.js.map +1 -0
- package/dist/stream-parser.js +116 -0
- package/dist/stream-parser.js.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/dist/uninstall.js +172 -0
- package/dist/uninstall.js.map +1 -0
- package/dist/workspace.js +362 -0
- package/dist/workspace.js.map +1 -0
- package/dist/xcode-probe.js +272 -0
- package/dist/xcode-probe.js.map +1 -0
- package/package.json +26 -0
- package/templates/launchagent-bridge.plist.template +28 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `donna-bridge uninstall` (#295).
|
|
3
|
+
*
|
|
4
|
+
* Reverses install in dependency order:
|
|
5
|
+
* 1. Bootout LaunchAgent (if loaded)
|
|
6
|
+
* 2. Remove plist
|
|
7
|
+
* 3. Delete `~/.donna-bridge/config.json` (token + xcode_path)
|
|
8
|
+
* 4. If `--purge`: also remove `~/donna-projects/` and the dedicated
|
|
9
|
+
* CoreSimulator device set.
|
|
10
|
+
*
|
|
11
|
+
* Idempotent: re-running after success exits 0 with every step reporting
|
|
12
|
+
* "skip". Soft-fails inside individual steps so a partial environment still
|
|
13
|
+
* finishes the rest of the cleanup.
|
|
14
|
+
*
|
|
15
|
+
* Never touches the orchestrator DB; never modifies the user's primary
|
|
16
|
+
* `xcode-select` pointer (the bridge maintains its own pointer in config.json).
|
|
17
|
+
*/
|
|
18
|
+
import fs from 'node:fs';
|
|
19
|
+
import os from 'node:os';
|
|
20
|
+
import readline from 'node:readline';
|
|
21
|
+
import { execFile } from 'node:child_process';
|
|
22
|
+
import { deleteConfig, getConfigPath, getDefaults, loadConfig, getToolReportPath, } from './config.js';
|
|
23
|
+
import { unloadAgent } from './launchd.js';
|
|
24
|
+
function defaultIO() {
|
|
25
|
+
return {
|
|
26
|
+
stdout: (m) => process.stdout.write(m),
|
|
27
|
+
stderr: (m) => process.stderr.write(m),
|
|
28
|
+
prompt: (q) => new Promise((resolve) => {
|
|
29
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
30
|
+
rl.question(q, (a) => {
|
|
31
|
+
rl.close();
|
|
32
|
+
resolve(a);
|
|
33
|
+
});
|
|
34
|
+
}),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function execFileP(bin, args, timeoutMs = 15_000) {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
execFile(bin, args, { timeout: timeoutMs, encoding: 'utf-8' }, (err, stdout, stderr) => {
|
|
40
|
+
if (err) {
|
|
41
|
+
reject(err);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
resolve({ stdout: stdout ?? '', stderr: stderr ?? '' });
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async function softStep(io, label, fn, errors) {
|
|
49
|
+
io.stdout(` [..] ${label}\n`);
|
|
50
|
+
try {
|
|
51
|
+
const result = await fn();
|
|
52
|
+
io.stdout(` [ok] ${label}\n`);
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
const message = err.message;
|
|
57
|
+
io.stderr(` [fail] ${label}: ${message}\n`);
|
|
58
|
+
errors.push(`${label}: ${message}`);
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export async function runUninstall(opts = {}) {
|
|
63
|
+
const io = opts.io ?? defaultIO();
|
|
64
|
+
const removed = [];
|
|
65
|
+
const kept = [];
|
|
66
|
+
const errors = [];
|
|
67
|
+
const defaults = getDefaults();
|
|
68
|
+
const config = loadConfig();
|
|
69
|
+
io.stdout(`\ndonna-bridge uninstall${opts.purge ? ' --purge' : ''}\n`);
|
|
70
|
+
if (opts.purge && !opts.yes) {
|
|
71
|
+
io.stdout(`\n --purge will DELETE ${defaults.projectsDir} (all worktrees + clones)\n` +
|
|
72
|
+
` and ${config?.simulatorDeviceSetPath ?? defaults.deviceSetPath} (simulator device set).\n\n`);
|
|
73
|
+
const answer = (await io.prompt(` Type "DELETE" to confirm: `)).trim();
|
|
74
|
+
if (answer !== 'DELETE') {
|
|
75
|
+
io.stdout(` aborted\n`);
|
|
76
|
+
return { removed, kept, errors: ['user aborted'] };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// 1. Bootout LaunchAgent (best-effort, even if plist is missing)
|
|
80
|
+
if (fs.existsSync(defaults.plistPath)) {
|
|
81
|
+
await softStep(io, `Unload LaunchAgent (gui/${os.userInfo().uid}/${defaults.label})`, async () => {
|
|
82
|
+
await unloadAgent(defaults.plistPath, os.userInfo().uid);
|
|
83
|
+
removed.push(`LaunchAgent loaded state`);
|
|
84
|
+
}, errors);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
io.stdout(` [skip] LaunchAgent plist absent\n`);
|
|
88
|
+
}
|
|
89
|
+
// 2. Remove the plist file
|
|
90
|
+
if (fs.existsSync(defaults.plistPath)) {
|
|
91
|
+
await softStep(io, `Remove plist ${defaults.plistPath}`, async () => {
|
|
92
|
+
fs.rmSync(defaults.plistPath, { force: true });
|
|
93
|
+
removed.push(defaults.plistPath);
|
|
94
|
+
}, errors);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
io.stdout(` [skip] plist already absent\n`);
|
|
98
|
+
}
|
|
99
|
+
// 3. Remove the token / config + tool report
|
|
100
|
+
if (fs.existsSync(getConfigPath())) {
|
|
101
|
+
await softStep(io, `Remove config ${getConfigPath()}`, async () => {
|
|
102
|
+
deleteConfig();
|
|
103
|
+
removed.push(getConfigPath());
|
|
104
|
+
}, errors);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
io.stdout(` [skip] config already absent\n`);
|
|
108
|
+
}
|
|
109
|
+
if (fs.existsSync(getToolReportPath())) {
|
|
110
|
+
await softStep(io, `Remove tool report ${getToolReportPath()}`, async () => {
|
|
111
|
+
fs.rmSync(getToolReportPath(), { force: true });
|
|
112
|
+
removed.push(getToolReportPath());
|
|
113
|
+
}, errors);
|
|
114
|
+
}
|
|
115
|
+
// 4. --purge: remove projects dir + simulator device set
|
|
116
|
+
if (opts.purge) {
|
|
117
|
+
const projectsDir = defaults.projectsDir;
|
|
118
|
+
if (fs.existsSync(projectsDir)) {
|
|
119
|
+
await softStep(io, `Remove projects dir ${projectsDir}`, async () => {
|
|
120
|
+
fs.rmSync(projectsDir, { recursive: true, force: true });
|
|
121
|
+
removed.push(projectsDir);
|
|
122
|
+
}, errors);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
io.stdout(` [skip] projects dir ${projectsDir} already absent\n`);
|
|
126
|
+
}
|
|
127
|
+
const deviceSet = config?.simulatorDeviceSetPath ?? defaults.deviceSetPath;
|
|
128
|
+
if (fs.existsSync(deviceSet)) {
|
|
129
|
+
await softStep(io, `Remove simulator device set ${deviceSet}`, async () => {
|
|
130
|
+
// Try `simctl --set <path> delete all` first to release booted
|
|
131
|
+
// simulators; fall through to rm if simctl is unavailable.
|
|
132
|
+
try {
|
|
133
|
+
await execFileP('xcrun', ['simctl', '--set', deviceSet, 'delete', 'all']);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
/* best-effort */
|
|
137
|
+
}
|
|
138
|
+
fs.rmSync(deviceSet, { recursive: true, force: true });
|
|
139
|
+
removed.push(deviceSet);
|
|
140
|
+
}, errors);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
io.stdout(` [skip] simulator device set ${deviceSet} already absent\n`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
if (fs.existsSync(defaults.projectsDir))
|
|
148
|
+
kept.push(defaults.projectsDir);
|
|
149
|
+
const deviceSet = config?.simulatorDeviceSetPath ?? defaults.deviceSetPath;
|
|
150
|
+
if (fs.existsSync(deviceSet))
|
|
151
|
+
kept.push(deviceSet);
|
|
152
|
+
}
|
|
153
|
+
io.stdout(`\nUninstall complete.\n`);
|
|
154
|
+
if (removed.length > 0) {
|
|
155
|
+
io.stdout(` Removed:\n`);
|
|
156
|
+
for (const item of removed)
|
|
157
|
+
io.stdout(` - ${item}\n`);
|
|
158
|
+
}
|
|
159
|
+
if (kept.length > 0) {
|
|
160
|
+
io.stdout(` Kept (pass --purge to remove):\n`);
|
|
161
|
+
for (const item of kept)
|
|
162
|
+
io.stdout(` - ${item}\n`);
|
|
163
|
+
}
|
|
164
|
+
if (errors.length > 0) {
|
|
165
|
+
io.stdout(` Errors (best-effort, not fatal):\n`);
|
|
166
|
+
for (const e of errors)
|
|
167
|
+
io.stdout(` - ${e}\n`);
|
|
168
|
+
}
|
|
169
|
+
io.stdout(`\n`);
|
|
170
|
+
return { removed, kept, errors };
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=uninstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../uninstall.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge workspace management (#295).
|
|
3
|
+
*
|
|
4
|
+
* Implements the `WorkspaceHandler` interface from `bridge/types.ts`. Each
|
|
5
|
+
* project clones once to `~/donna-projects/<project>/`; each card materializes
|
|
6
|
+
* a worktree at `~/donna-projects/<project>-worktrees/<cardId>/`.
|
|
7
|
+
*
|
|
8
|
+
* Mirrors `runner/native/workspace.ts` patterns (validated workspace root,
|
|
9
|
+
* per-project mutex, safe-ref / safe-url gates) but kept here so the bridge
|
|
10
|
+
* remains a standalone module without `runner/` imports.
|
|
11
|
+
*/
|
|
12
|
+
import { execFile } from 'node:child_process';
|
|
13
|
+
import { createHash } from 'node:crypto';
|
|
14
|
+
import fs from 'node:fs';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
const DEFAULT_GIT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
17
|
+
function runGit(args, opts = {}) {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
execFile('git', args, {
|
|
20
|
+
cwd: opts.cwd,
|
|
21
|
+
env: { ...process.env, ...(opts.env ?? {}) },
|
|
22
|
+
encoding: 'utf-8',
|
|
23
|
+
timeout: opts.timeoutMs ?? DEFAULT_GIT_TIMEOUT_MS,
|
|
24
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
25
|
+
}, (err, stdout, stderr) => {
|
|
26
|
+
const so = String(stdout ?? '');
|
|
27
|
+
const se = String(stderr ?? '');
|
|
28
|
+
if (err) {
|
|
29
|
+
if (err.code === 'ENOENT') {
|
|
30
|
+
reject(new Error('git binary not found'));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const exitCode = typeof err.code === 'number'
|
|
34
|
+
? err.code
|
|
35
|
+
: -1;
|
|
36
|
+
resolve({ code: exitCode, stdout: so, stderr: se });
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
resolve({ code: 0, stdout: so, stderr: se });
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Reject git option-injection payloads in `repoUrl`. Same shape-rules as
|
|
45
|
+
* `runner/native/workspace.ts` — duplicated to keep the bridge import-free.
|
|
46
|
+
*/
|
|
47
|
+
export function isSafeRepoUrl(url) {
|
|
48
|
+
if (typeof url !== 'string' || url.length === 0)
|
|
49
|
+
return false;
|
|
50
|
+
if (url.length > 2048)
|
|
51
|
+
return false;
|
|
52
|
+
if (url.startsWith('-'))
|
|
53
|
+
return false;
|
|
54
|
+
if (/[\s\x00-\x1f]/.test(url))
|
|
55
|
+
return false;
|
|
56
|
+
if (/--upload-pack=/i.test(url))
|
|
57
|
+
return false;
|
|
58
|
+
if (/--receive-pack=/i.test(url))
|
|
59
|
+
return false;
|
|
60
|
+
if (/--config=/i.test(url))
|
|
61
|
+
return false;
|
|
62
|
+
if (url.startsWith('/'))
|
|
63
|
+
return true;
|
|
64
|
+
if (/^[A-Za-z0-9_.+-]+@[A-Za-z0-9_.+-]+:[^\s]+$/.test(url))
|
|
65
|
+
return true;
|
|
66
|
+
return /^(https?|git|ssh|file):\/\//i.test(url);
|
|
67
|
+
}
|
|
68
|
+
export function isSafeRef(ref) {
|
|
69
|
+
if (typeof ref !== 'string' || ref.length === 0)
|
|
70
|
+
return false;
|
|
71
|
+
if (ref.length > 256)
|
|
72
|
+
return false;
|
|
73
|
+
if (ref.startsWith('-'))
|
|
74
|
+
return false;
|
|
75
|
+
if (/[\s\x00-\x1f]/.test(ref))
|
|
76
|
+
return false;
|
|
77
|
+
if (ref.includes('..'))
|
|
78
|
+
return false;
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
/** Stable per-repo slug — last path segment + 12-char sha hash. */
|
|
82
|
+
export function projectSlugFromRepoUrl(repoUrl) {
|
|
83
|
+
const hash = createHash('sha256').update(repoUrl).digest('hex').slice(0, 12);
|
|
84
|
+
const lastSeg = repoUrl
|
|
85
|
+
.replace(/\.git$/i, '')
|
|
86
|
+
.split(/[\/:]/)
|
|
87
|
+
.filter(Boolean)
|
|
88
|
+
.pop() ?? 'repo';
|
|
89
|
+
const safe = lastSeg.replace(/[^A-Za-z0-9_-]/g, '_').slice(0, 32) || 'repo';
|
|
90
|
+
return `${safe}-${hash}`;
|
|
91
|
+
}
|
|
92
|
+
// ── Per-project mutex ──
|
|
93
|
+
//
|
|
94
|
+
// `git fetch` against a single main clone is NOT safe to run concurrently
|
|
95
|
+
// with itself (refs race). We serialize "fetch + worktree add" per project
|
|
96
|
+
// via a promise-chain mutex keyed by project slug. Different projects run
|
|
97
|
+
// in parallel — only same-project setups queue.
|
|
98
|
+
const projectMutexes = new Map();
|
|
99
|
+
export function withProjectMutex(projectKey, fn) {
|
|
100
|
+
const prev = projectMutexes.get(projectKey) ?? Promise.resolve();
|
|
101
|
+
const next = prev.then(fn, fn);
|
|
102
|
+
projectMutexes.set(projectKey, next.catch(() => {
|
|
103
|
+
/* swallow — only used for ordering */
|
|
104
|
+
}));
|
|
105
|
+
return next;
|
|
106
|
+
}
|
|
107
|
+
/** For tests — reset the mutex map. */
|
|
108
|
+
export function _resetMutexesForTests() {
|
|
109
|
+
projectMutexes.clear();
|
|
110
|
+
}
|
|
111
|
+
function truncate(s, n) {
|
|
112
|
+
if (typeof s !== 'string')
|
|
113
|
+
return '';
|
|
114
|
+
return s.length > n ? `${s.slice(0, n)}...` : s;
|
|
115
|
+
}
|
|
116
|
+
function classifyCloneError(stderr) {
|
|
117
|
+
const lower = stderr.toLowerCase();
|
|
118
|
+
if (lower.includes('authentication failed') ||
|
|
119
|
+
lower.includes('could not read username') ||
|
|
120
|
+
lower.includes('permission denied (publickey)') ||
|
|
121
|
+
lower.includes('access denied')) {
|
|
122
|
+
return 'auth_failed';
|
|
123
|
+
}
|
|
124
|
+
if (lower.includes('no space left on device') || lower.includes('disk full')) {
|
|
125
|
+
return 'disk_full';
|
|
126
|
+
}
|
|
127
|
+
return 'clone_failed';
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Build a `WorkspaceHandler` implementation for the bridge. The handler
|
|
131
|
+
* stores its clones under `projectsDir` and computes worktree paths as
|
|
132
|
+
* `<projectsDir>/<project>-worktrees/<cardId>/`.
|
|
133
|
+
*
|
|
134
|
+
* The orchestrator may also send a `workDir` it computed itself; we honour
|
|
135
|
+
* it when it lives under our projects root, and fall back to the computed
|
|
136
|
+
* path otherwise (defense against a routing bug that hands us an absolute
|
|
137
|
+
* path outside our writable tree).
|
|
138
|
+
*/
|
|
139
|
+
export function createWorkspaceHandler(opts) {
|
|
140
|
+
const projectsDir = path.resolve(opts.projectsDir);
|
|
141
|
+
return {
|
|
142
|
+
async setup(req) {
|
|
143
|
+
if (!isSafeRepoUrl(req.repoUrl)) {
|
|
144
|
+
return {
|
|
145
|
+
ok: false,
|
|
146
|
+
errorClass: 'clone_failed',
|
|
147
|
+
error: `unsafe repoUrl rejected: ${truncate(req.repoUrl, 80)}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
if (!isSafeRef(req.branch)) {
|
|
151
|
+
return {
|
|
152
|
+
ok: false,
|
|
153
|
+
errorClass: 'clone_failed',
|
|
154
|
+
error: `unsafe branch rejected: ${truncate(req.branch, 80)}`,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
if (req.commit !== undefined && !isSafeRef(req.commit)) {
|
|
158
|
+
return {
|
|
159
|
+
ok: false,
|
|
160
|
+
errorClass: 'clone_failed',
|
|
161
|
+
error: `unsafe commit rejected: ${truncate(req.commit, 80)}`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (req.gitCredentials) {
|
|
165
|
+
// The bridge is a developer Mac — the user's SSH agent / git credential
|
|
166
|
+
// helper is expected to handle auth. We refuse explicit in-band
|
|
167
|
+
// credentials so we never write secrets to disk or env. The CLI's
|
|
168
|
+
// install summary documents this; #296 may revisit for non-loopback
|
|
169
|
+
// installs.
|
|
170
|
+
return {
|
|
171
|
+
ok: false,
|
|
172
|
+
errorClass: 'auth_failed',
|
|
173
|
+
error: 'donna-bridge does not accept in-band git credentials; use the host SSH agent',
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
const projectKey = projectSlugFromRepoUrl(req.repoUrl);
|
|
177
|
+
const mainClone = path.join(projectsDir, projectKey);
|
|
178
|
+
const worktreesDir = path.join(projectsDir, `${projectKey}-worktrees`);
|
|
179
|
+
const workDir = resolveCardWorkDir(projectsDir, worktreesDir, req.cardId, req.workDir);
|
|
180
|
+
return withProjectMutex(projectKey, async () => {
|
|
181
|
+
try {
|
|
182
|
+
await ensureMainClone(mainClone, req.repoUrl);
|
|
183
|
+
await fetchOrigin(mainClone);
|
|
184
|
+
await ensureWorktree(mainClone, workDir, req.branch);
|
|
185
|
+
if (req.commit) {
|
|
186
|
+
await checkoutCommit(workDir, req.commit);
|
|
187
|
+
}
|
|
188
|
+
const commit = await readHead(workDir);
|
|
189
|
+
return { ok: true, workDir, commit };
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
if (err instanceof WorkspaceError) {
|
|
193
|
+
await safeRemoveWorktree(mainClone, workDir).catch(() => { });
|
|
194
|
+
return { ok: false, errorClass: err.errorClass, error: err.message };
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
ok: false,
|
|
198
|
+
errorClass: 'unknown',
|
|
199
|
+
error: err.message,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
},
|
|
204
|
+
async cleanup(req) {
|
|
205
|
+
if (req.keepWorktree) {
|
|
206
|
+
return { ok: true };
|
|
207
|
+
}
|
|
208
|
+
const workDir = path.resolve(req.workDir);
|
|
209
|
+
// Refuse to delete anything outside our projects root.
|
|
210
|
+
const rel = path.relative(projectsDir, workDir);
|
|
211
|
+
if (rel === '' || rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
212
|
+
return {
|
|
213
|
+
ok: false,
|
|
214
|
+
errorClass: 'unknown',
|
|
215
|
+
error: `workDir ${req.workDir} is not under projectsDir ${projectsDir}`,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
const owner = await findOwningMainClone(workDir);
|
|
219
|
+
if (!owner) {
|
|
220
|
+
try {
|
|
221
|
+
await fs.promises.rm(workDir, { recursive: true, force: true });
|
|
222
|
+
return { ok: true };
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
return {
|
|
226
|
+
ok: false,
|
|
227
|
+
errorClass: 'unknown',
|
|
228
|
+
error: `cleanup failed: ${err.message}`,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const remove = await runGit(['worktree', 'remove', '--force', '--', workDir], { cwd: owner });
|
|
233
|
+
if (remove.code !== 0) {
|
|
234
|
+
try {
|
|
235
|
+
await fs.promises.rm(workDir, { recursive: true, force: true });
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
return {
|
|
239
|
+
ok: false,
|
|
240
|
+
errorClass: 'unknown',
|
|
241
|
+
error: `worktree remove failed (${remove.stderr.trim() || remove.stdout.trim()}); rm fallback also failed: ${err.message}`,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
await runGit(['worktree', 'prune'], { cwd: owner }).catch(() => { });
|
|
246
|
+
return { ok: true };
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
class WorkspaceError extends Error {
|
|
251
|
+
errorClass;
|
|
252
|
+
constructor(errorClass, message) {
|
|
253
|
+
super(message);
|
|
254
|
+
this.errorClass = errorClass;
|
|
255
|
+
this.name = 'WorkspaceError';
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Pick a safe workDir for the card. Prefers the orchestrator's suggestion
|
|
260
|
+
* when it lives under `projectsDir`; otherwise falls back to
|
|
261
|
+
* `<worktreesDir>/<cardId>`. Reject `..` traversal in `cardId`.
|
|
262
|
+
*/
|
|
263
|
+
export function resolveCardWorkDir(projectsDir, worktreesDir, cardId, suggestedWorkDir) {
|
|
264
|
+
const projectsRoot = path.resolve(projectsDir);
|
|
265
|
+
const safeCardId = String(cardId ?? '').replace(/[^A-Za-z0-9_-]/g, '_');
|
|
266
|
+
if (!safeCardId) {
|
|
267
|
+
throw new WorkspaceError('clone_failed', 'cardId is empty after sanitization');
|
|
268
|
+
}
|
|
269
|
+
if (suggestedWorkDir) {
|
|
270
|
+
const abs = path.resolve(suggestedWorkDir);
|
|
271
|
+
const rel = path.relative(projectsRoot, abs);
|
|
272
|
+
if (rel !== '' && !rel.startsWith('..') && !path.isAbsolute(rel)) {
|
|
273
|
+
return abs;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return path.join(worktreesDir, safeCardId);
|
|
277
|
+
}
|
|
278
|
+
async function ensureMainClone(mainClone, repoUrl) {
|
|
279
|
+
if (fs.existsSync(path.join(mainClone, '.git')))
|
|
280
|
+
return;
|
|
281
|
+
await fs.promises.mkdir(path.dirname(mainClone), { recursive: true });
|
|
282
|
+
const out = await runGit(['clone', '--', repoUrl, mainClone]);
|
|
283
|
+
if (out.code !== 0) {
|
|
284
|
+
const stderr = out.stderr.trim();
|
|
285
|
+
throw new WorkspaceError(classifyCloneError(stderr), `git clone failed: ${stderr || out.stdout.trim()}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async function fetchOrigin(mainClone) {
|
|
289
|
+
const out = await runGit(['fetch', '--prune', 'origin'], { cwd: mainClone });
|
|
290
|
+
if (out.code !== 0) {
|
|
291
|
+
const stderr = out.stderr.trim();
|
|
292
|
+
throw new WorkspaceError(classifyCloneError(stderr), `git fetch failed: ${stderr || out.stdout.trim()}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
async function ensureWorktree(mainClone, workDir, branch) {
|
|
296
|
+
await fs.promises.mkdir(path.dirname(workDir), { recursive: true });
|
|
297
|
+
const localCheck = await runGit(['rev-parse', '--verify', '--quiet', `refs/heads/${branch}`], { cwd: mainClone });
|
|
298
|
+
const remoteCheck = await runGit(['rev-parse', '--verify', '--quiet', `refs/remotes/origin/${branch}`], { cwd: mainClone });
|
|
299
|
+
const branchExistsLocal = localCheck.code === 0;
|
|
300
|
+
const branchExistsRemote = remoteCheck.code === 0;
|
|
301
|
+
let args;
|
|
302
|
+
if (branchExistsLocal) {
|
|
303
|
+
args = ['worktree', 'add', '--', workDir, branch];
|
|
304
|
+
}
|
|
305
|
+
else if (branchExistsRemote) {
|
|
306
|
+
args = ['worktree', 'add', '-B', branch, '--', workDir, `origin/${branch}`];
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
args = ['worktree', 'add', '-b', branch, '--', workDir];
|
|
310
|
+
}
|
|
311
|
+
const out = await runGit(args, { cwd: mainClone });
|
|
312
|
+
if (out.code !== 0) {
|
|
313
|
+
throw new WorkspaceError('checkout_failed', `git worktree add failed: ${out.stderr.trim() || out.stdout.trim()}`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
async function checkoutCommit(workDir, commit) {
|
|
317
|
+
const out = await runGit(['checkout', '--detach', commit], { cwd: workDir });
|
|
318
|
+
if (out.code !== 0) {
|
|
319
|
+
throw new WorkspaceError('checkout_failed', `git checkout ${commit} failed: ${out.stderr.trim() || out.stdout.trim()}`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
async function readHead(workDir) {
|
|
323
|
+
const out = await runGit(['rev-parse', 'HEAD'], { cwd: workDir });
|
|
324
|
+
if (out.code !== 0) {
|
|
325
|
+
throw new WorkspaceError('checkout_failed', `git rev-parse HEAD failed: ${out.stderr.trim() || out.stdout.trim()}`);
|
|
326
|
+
}
|
|
327
|
+
return out.stdout.trim();
|
|
328
|
+
}
|
|
329
|
+
async function safeRemoveWorktree(mainClone, workDir) {
|
|
330
|
+
if (!fs.existsSync(workDir))
|
|
331
|
+
return;
|
|
332
|
+
await runGit(['worktree', 'remove', '--force', '--', workDir], { cwd: mainClone }).catch(() => { });
|
|
333
|
+
await runGit(['worktree', 'prune'], { cwd: mainClone }).catch(() => { });
|
|
334
|
+
await fs.promises.rm(workDir, { recursive: true, force: true }).catch(() => { });
|
|
335
|
+
}
|
|
336
|
+
async function findOwningMainClone(workDir) {
|
|
337
|
+
const dotGit = path.join(workDir, '.git');
|
|
338
|
+
let stat;
|
|
339
|
+
try {
|
|
340
|
+
stat = await fs.promises.stat(dotGit);
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
if (stat.isDirectory())
|
|
346
|
+
return null;
|
|
347
|
+
let contents;
|
|
348
|
+
try {
|
|
349
|
+
contents = await fs.promises.readFile(dotGit, 'utf-8');
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
const match = /^gitdir:\s*(.+)\s*$/m.exec(contents);
|
|
355
|
+
if (!match)
|
|
356
|
+
return null;
|
|
357
|
+
const gitdir = match[1].trim();
|
|
358
|
+
const worktreesDir = path.dirname(gitdir);
|
|
359
|
+
const dotGitDir = path.dirname(worktreesDir);
|
|
360
|
+
return path.dirname(dotGitDir);
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../workspace.ts"],"names":[],"mappings":"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"}
|