gsd-pi 2.41.0-dev.97349b1 → 2.41.0-dev.b832948
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +1 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +118 -100
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/captures.test.ts +1 -12
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +105 -195
- /package/dist/web/standalone/.next/static/{ZrI3HOoXD7Fh84fAHZVxb → 43Aw72Fdw8k1aAHQOYOXr}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{ZrI3HOoXD7Fh84fAHZVxb → 43Aw72Fdw8k1aAHQOYOXr}/_ssgManifest.js +0 -0
|
@@ -119,23 +119,12 @@ test("captures: loadPendingCaptures filters resolved entries", () => {
|
|
|
119
119
|
const id1 = appendCapture(tmp, "pending one");
|
|
120
120
|
appendCapture(tmp, "pending two");
|
|
121
121
|
|
|
122
|
+
// Resolve the first one
|
|
122
123
|
markCaptureResolved(tmp, id1, "note", "acknowledged", "just a note");
|
|
123
124
|
|
|
124
125
|
const pending = loadPendingCaptures(tmp);
|
|
125
126
|
assert.strictEqual(pending.length, 1, "should have 1 pending");
|
|
126
127
|
assert.strictEqual(pending[0].text, "pending two");
|
|
127
|
-
} finally {
|
|
128
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
test("captures: loadAllCaptures preserves resolved entries", () => {
|
|
133
|
-
const tmp = makeTempDir("cap-all-resolved");
|
|
134
|
-
try {
|
|
135
|
-
const id1 = appendCapture(tmp, "pending one");
|
|
136
|
-
appendCapture(tmp, "pending two");
|
|
137
|
-
|
|
138
|
-
markCaptureResolved(tmp, id1, "note", "acknowledged", "just a note");
|
|
139
128
|
|
|
140
129
|
const all = loadAllCaptures(tmp);
|
|
141
130
|
assert.strictEqual(all.length, 2, "all should still have 2");
|
|
@@ -72,17 +72,18 @@ describe("continue-here", () => {
|
|
|
72
72
|
const budget = computeBudgets(128_000);
|
|
73
73
|
const threshold = budget.continueThresholdPercent;
|
|
74
74
|
|
|
75
|
-
// Simulate repeated polls with percent above threshold
|
|
76
|
-
|
|
75
|
+
// Simulate repeated polls with percent above threshold
|
|
76
|
+
let fired = false;
|
|
77
|
+
let fireCount = 0;
|
|
77
78
|
const usagePercents = [75, 80, 85, 90, 95];
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
|
|
80
|
+
for (const percent of usagePercents) {
|
|
81
|
+
if (fired) continue; // one-shot guard
|
|
82
|
+
if (percent >= threshold) {
|
|
83
|
+
fired = true;
|
|
84
|
+
fireCount++;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
86
87
|
|
|
87
88
|
assert.equal(fireCount, 1, "must fire exactly once");
|
|
88
89
|
assert.equal(fired, true);
|
|
@@ -96,17 +97,16 @@ describe("continue-here", () => {
|
|
|
96
97
|
{ name: "1M", contextWindow: 1_000_000 },
|
|
97
98
|
];
|
|
98
99
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
["200K", 200_000],
|
|
102
|
-
["1M", 1_000_000],
|
|
103
|
-
];
|
|
104
|
-
for (const [name, contextWindow] of thresholdCases) {
|
|
105
|
-
it(`${name} model produces continueThresholdPercent of 70`, () => {
|
|
100
|
+
it("all model sizes produce continueThresholdPercent of 70", () => {
|
|
101
|
+
for (const { name, contextWindow } of modelSizes) {
|
|
106
102
|
const budget = computeBudgets(contextWindow);
|
|
107
|
-
assert.equal(
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
assert.equal(
|
|
104
|
+
budget.continueThresholdPercent,
|
|
105
|
+
70,
|
|
106
|
+
`${name} model should have 70% threshold`,
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
110
|
|
|
111
111
|
it("larger models produce larger verificationBudgetChars", () => {
|
|
112
112
|
const budgets = modelSizes.map(({ contextWindow }) => computeBudgets(contextWindow));
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import assert from "node:assert/strict";
|
|
3
|
-
import { mkdtempSync, mkdirSync, rmSync, writeFileSync, existsSync } from "node:fs";
|
|
1
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync, existsSync, readFileSync } from "node:fs";
|
|
4
2
|
import { join } from "node:path";
|
|
5
3
|
import { tmpdir } from "node:os";
|
|
6
4
|
import { execSync } from "node:child_process";
|
|
@@ -15,42 +13,82 @@ import {
|
|
|
15
13
|
worktreeBranchName,
|
|
16
14
|
worktreePath,
|
|
17
15
|
} from "../worktree-manager.ts";
|
|
16
|
+
import { createTestContext } from './test-helpers.ts';
|
|
18
17
|
|
|
18
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
19
19
|
function run(command: string, cwd: string): string {
|
|
20
20
|
return execSync(command, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
23
|
+
// Set up a test repo
|
|
24
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-worktree-mgr-test-"));
|
|
25
|
+
run("git init -b main", base);
|
|
26
|
+
run('git config user.name "Pi Test"', base);
|
|
27
|
+
run('git config user.email "pi@example.com"', base);
|
|
28
|
+
|
|
29
|
+
// Create initial project structure
|
|
30
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
31
|
+
writeFileSync(join(base, "README.md"), "# Test Project\n", "utf-8");
|
|
32
|
+
writeFileSync(
|
|
33
|
+
join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"),
|
|
34
|
+
"# M001: Demo\n\n## Slices\n- [ ] **S01: First** `risk:low` `depends:[]`\n > After this: it works\n",
|
|
35
|
+
"utf-8",
|
|
36
|
+
);
|
|
37
|
+
run("git add .", base);
|
|
38
|
+
run('git commit -m "chore: init"', base);
|
|
39
|
+
|
|
40
|
+
async function main(): Promise<void> {
|
|
41
|
+
console.log("\n=== worktreeBranchName ===");
|
|
42
|
+
assertEq(worktreeBranchName("feature-x"), "worktree/feature-x", "branch name format");
|
|
43
|
+
|
|
44
|
+
console.log("\n=== createWorktree ===");
|
|
45
|
+
const info = createWorktree(base, "feature-x");
|
|
46
|
+
assertTrue(info.name === "feature-x", "name matches");
|
|
47
|
+
assertTrue(info.branch === "worktree/feature-x", "branch matches");
|
|
48
|
+
assertTrue(info.exists, "worktree exists");
|
|
49
|
+
assertTrue(existsSync(info.path), "worktree path exists on disk");
|
|
50
|
+
assertTrue(existsSync(join(info.path, "README.md")), "README.md copied to worktree");
|
|
51
|
+
assertTrue(existsSync(join(info.path, ".gsd", "milestones", "M001", "M001-ROADMAP.md")), ".gsd files copied");
|
|
52
|
+
|
|
53
|
+
// Branch was created
|
|
54
|
+
const branches = run("git branch", base);
|
|
55
|
+
assertTrue(branches.includes("worktree/feature-x"), "branch was created");
|
|
56
|
+
|
|
57
|
+
console.log("\n=== createWorktree — duplicate ===");
|
|
58
|
+
let duplicateError = "";
|
|
59
|
+
try {
|
|
60
|
+
createWorktree(base, "feature-x");
|
|
61
|
+
} catch (e) {
|
|
62
|
+
duplicateError = (e as Error).message;
|
|
63
|
+
}
|
|
64
|
+
assertTrue(duplicateError.includes("already exists"), "duplicate creation fails");
|
|
45
65
|
|
|
46
|
-
|
|
47
|
-
|
|
66
|
+
console.log("\n=== createWorktree — invalid name ===");
|
|
67
|
+
let invalidError = "";
|
|
68
|
+
try {
|
|
69
|
+
createWorktree(base, "bad name!");
|
|
70
|
+
} catch (e) {
|
|
71
|
+
invalidError = (e as Error).message;
|
|
72
|
+
}
|
|
73
|
+
assertTrue(invalidError.includes("Invalid worktree name"), "invalid name rejected");
|
|
74
|
+
|
|
75
|
+
console.log("\n=== listWorktrees ===");
|
|
76
|
+
const list = listWorktrees(base);
|
|
77
|
+
assertEq(list.length, 1, "one worktree listed");
|
|
78
|
+
assertEq(list[0]!.name, "feature-x", "correct name");
|
|
79
|
+
assertEq(list[0]!.branch, "worktree/feature-x", "correct branch");
|
|
80
|
+
assertTrue(list[0]!.exists, "exists flag is true");
|
|
81
|
+
|
|
82
|
+
console.log("\n=== make changes in worktree ===");
|
|
83
|
+
const wtPath = worktreePath(base, "feature-x");
|
|
84
|
+
// Add a new GSD artifact in the worktree
|
|
48
85
|
mkdirSync(join(wtPath, ".gsd", "milestones", "M002"), { recursive: true });
|
|
49
86
|
writeFileSync(
|
|
50
87
|
join(wtPath, ".gsd", "milestones", "M002", "M002-ROADMAP.md"),
|
|
51
88
|
"# M002: New Feature\n\n## Slices\n- [ ] **S01: Setup** `risk:low` `depends:[]`\n > After this: new feature ready\n",
|
|
52
89
|
"utf-8",
|
|
53
90
|
);
|
|
91
|
+
// Modify an existing artifact
|
|
54
92
|
writeFileSync(
|
|
55
93
|
join(wtPath, ".gsd", "milestones", "M001", "M001-ROADMAP.md"),
|
|
56
94
|
"# M001: Demo (updated)\n\n## Slices\n- [x] **S01: First** `risk:low` `depends:[]`\n > Done\n",
|
|
@@ -58,174 +96,46 @@ function makeRepoWithChanges(worktreeName: string): { base: string; wtPath: stri
|
|
|
58
96
|
);
|
|
59
97
|
run("git add .", wtPath);
|
|
60
98
|
run('git commit -m "feat: add M002 and update M001"', wtPath);
|
|
61
|
-
return { base, wtPath };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// ─── worktreeBranchName ───────────────────────────────────────────────────────
|
|
65
|
-
|
|
66
|
-
test("worktreeBranchName formats branch name", () => {
|
|
67
|
-
assert.strictEqual(
|
|
68
|
-
worktreeBranchName("feature-x"),
|
|
69
|
-
"worktree/feature-x",
|
|
70
|
-
"should prefix with worktree/",
|
|
71
|
-
);
|
|
72
|
-
});
|
|
73
99
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
rmSync(base, { recursive: true, force: true });
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
test("createWorktree rejects invalid name", () => {
|
|
116
|
-
const base = makeBaseRepo();
|
|
117
|
-
try {
|
|
118
|
-
assert.throws(
|
|
119
|
-
() => createWorktree(base, "bad name!"),
|
|
120
|
-
(err: Error) => {
|
|
121
|
-
assert.ok(
|
|
122
|
-
err.message.includes("Invalid worktree name"),
|
|
123
|
-
`expected "Invalid worktree name" in error, got: ${err.message}`,
|
|
124
|
-
);
|
|
125
|
-
return true;
|
|
126
|
-
},
|
|
127
|
-
"should throw on invalid worktree name",
|
|
128
|
-
);
|
|
129
|
-
} finally {
|
|
130
|
-
rmSync(base, { recursive: true, force: true });
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
// ─── listWorktrees ────────────────────────────────────────────────────────────
|
|
135
|
-
|
|
136
|
-
test("listWorktrees returns active worktrees", () => {
|
|
137
|
-
const { base } = makeRepoWithWorktree("feature-x");
|
|
138
|
-
try {
|
|
139
|
-
const list = listWorktrees(base);
|
|
140
|
-
assert.strictEqual(list.length, 1, "should list exactly one worktree");
|
|
141
|
-
assert.strictEqual(list[0]!.name, "feature-x", "name should match");
|
|
142
|
-
assert.strictEqual(list[0]!.branch, "worktree/feature-x", "branch should match");
|
|
143
|
-
assert.ok(list[0]!.exists, "exists flag should be true");
|
|
144
|
-
} finally {
|
|
145
|
-
rmSync(base, { recursive: true, force: true });
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
test("listWorktrees returns empty after removal", () => {
|
|
150
|
-
const { base } = makeRepoWithWorktree("feature-x");
|
|
151
|
-
try {
|
|
152
|
-
removeWorktree(base, "feature-x");
|
|
153
|
-
const list = listWorktrees(base);
|
|
154
|
-
assert.strictEqual(list.length, 0, "should have no worktrees after removal");
|
|
155
|
-
} finally {
|
|
156
|
-
rmSync(base, { recursive: true, force: true });
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// ─── diffWorktreeGSD ─────────────────────────────────────────────────────────
|
|
161
|
-
|
|
162
|
-
test("diffWorktreeGSD detects added and modified GSD files", () => {
|
|
163
|
-
const { base } = makeRepoWithChanges("feature-x");
|
|
164
|
-
try {
|
|
165
|
-
const diff = diffWorktreeGSD(base, "feature-x");
|
|
166
|
-
assert.ok(diff.added.length > 0, "should have added files");
|
|
167
|
-
assert.ok(
|
|
168
|
-
diff.added.some((f) => f.includes("M002")),
|
|
169
|
-
"M002 roadmap should be in added files",
|
|
170
|
-
);
|
|
171
|
-
assert.ok(diff.modified.length > 0, "should have modified files");
|
|
172
|
-
assert.ok(
|
|
173
|
-
diff.modified.some((f) => f.includes("M001")),
|
|
174
|
-
"M001 roadmap should be in modified files",
|
|
175
|
-
);
|
|
176
|
-
assert.strictEqual(diff.removed.length, 0, "should have no removed files");
|
|
177
|
-
} finally {
|
|
178
|
-
rmSync(base, { recursive: true, force: true });
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
// ─── getWorktreeGSDDiff ───────────────────────────────────────────────────────
|
|
183
|
-
|
|
184
|
-
test("getWorktreeGSDDiff returns patch content", () => {
|
|
185
|
-
const { base } = makeRepoWithChanges("feature-x");
|
|
186
|
-
try {
|
|
187
|
-
const fullDiff = getWorktreeGSDDiff(base, "feature-x");
|
|
188
|
-
assert.ok(fullDiff.includes("M002"), "diff should mention M002");
|
|
189
|
-
assert.ok(fullDiff.includes("updated"), "diff should mention the update");
|
|
190
|
-
} finally {
|
|
191
|
-
rmSync(base, { recursive: true, force: true });
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
// ─── getWorktreeLog ───────────────────────────────────────────────────────────
|
|
196
|
-
|
|
197
|
-
test("getWorktreeLog shows commits", () => {
|
|
198
|
-
const { base } = makeRepoWithChanges("feature-x");
|
|
199
|
-
try {
|
|
200
|
-
const log = getWorktreeLog(base, "feature-x");
|
|
201
|
-
assert.ok(log.includes("add M002"), "log should include the commit message");
|
|
202
|
-
} finally {
|
|
203
|
-
rmSync(base, { recursive: true, force: true });
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
// ─── removeWorktree ───────────────────────────────────────────────────────────
|
|
208
|
-
|
|
209
|
-
test("removeWorktree removes directory and branch", () => {
|
|
210
|
-
const { base, wtPath } = makeRepoWithWorktree("feature-x");
|
|
211
|
-
try {
|
|
212
|
-
removeWorktree(base, "feature-x", { deleteBranch: true });
|
|
213
|
-
assert.ok(!existsSync(wtPath), "worktree directory should be gone");
|
|
214
|
-
const branches = run("git branch", base);
|
|
215
|
-
assert.ok(!branches.includes("worktree/feature-x"), "branch should be deleted");
|
|
216
|
-
} finally {
|
|
217
|
-
rmSync(base, { recursive: true, force: true });
|
|
218
|
-
}
|
|
219
|
-
});
|
|
100
|
+
console.log("\n=== diffWorktreeGSD ===");
|
|
101
|
+
const diff = diffWorktreeGSD(base, "feature-x");
|
|
102
|
+
assertTrue(diff.added.length > 0, "has added files");
|
|
103
|
+
assertTrue(diff.added.some(f => f.includes("M002")), "M002 roadmap is in added");
|
|
104
|
+
assertTrue(diff.modified.length > 0, "has modified files");
|
|
105
|
+
assertTrue(diff.modified.some(f => f.includes("M001")), "M001 roadmap is in modified");
|
|
106
|
+
assertEq(diff.removed.length, 0, "no removed files");
|
|
107
|
+
|
|
108
|
+
console.log("\n=== getWorktreeGSDDiff ===");
|
|
109
|
+
const fullDiff = getWorktreeGSDDiff(base, "feature-x");
|
|
110
|
+
assertTrue(fullDiff.includes("M002"), "full diff mentions M002");
|
|
111
|
+
assertTrue(fullDiff.includes("updated"), "full diff mentions update");
|
|
112
|
+
|
|
113
|
+
console.log("\n=== getWorktreeLog ===");
|
|
114
|
+
const log = getWorktreeLog(base, "feature-x");
|
|
115
|
+
assertTrue(log.includes("add M002"), "log shows commit message");
|
|
116
|
+
|
|
117
|
+
console.log("\n=== removeWorktree ===");
|
|
118
|
+
removeWorktree(base, "feature-x", { deleteBranch: true });
|
|
119
|
+
assertTrue(!existsSync(wtPath), "worktree directory removed");
|
|
120
|
+
const branchesAfter = run("git branch", base);
|
|
121
|
+
assertTrue(!branchesAfter.includes("worktree/feature-x"), "branch deleted");
|
|
122
|
+
|
|
123
|
+
console.log("\n=== listWorktrees after removal ===");
|
|
124
|
+
const listAfter = listWorktrees(base);
|
|
125
|
+
assertEq(listAfter.length, 0, "no worktrees after removal");
|
|
126
|
+
|
|
127
|
+
console.log("\n=== removeWorktree — already gone ===");
|
|
128
|
+
// Should not throw
|
|
129
|
+
removeWorktree(base, "feature-x", { deleteBranch: true });
|
|
130
|
+
assertTrue(true, "removeWorktree on missing worktree does not throw");
|
|
131
|
+
|
|
132
|
+
// Cleanup
|
|
133
|
+
rmSync(base, { recursive: true, force: true });
|
|
134
|
+
|
|
135
|
+
report();
|
|
136
|
+
}
|
|
220
137
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
assert.doesNotThrow(
|
|
225
|
-
() => removeWorktree(base, "nonexistent"),
|
|
226
|
-
"should not throw when worktree does not exist",
|
|
227
|
-
);
|
|
228
|
-
} finally {
|
|
229
|
-
rmSync(base, { recursive: true, force: true });
|
|
230
|
-
}
|
|
138
|
+
main().catch((error) => {
|
|
139
|
+
console.error(error);
|
|
140
|
+
process.exit(1);
|
|
231
141
|
});
|
|
File without changes
|
|
File without changes
|