@markjaquith/agency 1.11.1 → 2.0.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.
- package/README.md +302 -113
- package/cli.ts +123 -420
- package/index.ts +1 -1
- package/package.json +12 -17
- package/skills/agency/SKILL.md +258 -0
- package/src/cli.test.ts +290 -0
- package/src/commands/description.test.ts +103 -0
- package/src/commands/epic.test.ts +103 -0
- package/src/commands/epic.ts +101 -0
- package/src/commands/init.test.ts +42 -290
- package/src/commands/init.ts +15 -123
- package/src/commands/phase.ts +120 -0
- package/src/commands/pr.test.ts +19 -170
- package/src/commands/pr.ts +23 -179
- package/src/commands/repo.test.ts +80 -0
- package/src/commands/repo.ts +83 -0
- package/src/commands/status.test.ts +35 -477
- package/src/commands/status.ts +24 -213
- package/src/commands/task-phase.test.ts +206 -0
- package/src/commands/task.ts +83 -1285
- package/src/commands/validate.test.ts +91 -0
- package/src/commands/validate.ts +50 -0
- package/src/commands/work.test.ts +172 -419
- package/src/commands/work.ts +47 -166
- package/src/services/EpicService.test.ts +71 -0
- package/src/services/EpicService.ts +135 -0
- package/src/services/FileSystemService.ts +61 -92
- package/src/services/PhaseService.ts +323 -0
- package/src/services/PullRequestService.test.ts +386 -0
- package/src/services/PullRequestService.ts +143 -0
- package/src/services/RepositoryService.test.ts +106 -0
- package/src/services/RepositoryService.ts +159 -0
- package/src/services/TaskPhaseService.test.ts +217 -0
- package/src/services/TaskService.ts +192 -0
- package/src/services/WorkbaseService.test.ts +446 -0
- package/src/services/WorkbaseService.ts +493 -0
- package/src/services/WorktreeService.test.ts +599 -0
- package/src/services/WorktreeService.ts +357 -0
- package/src/test-utils.ts +41 -438
- package/src/types.ts +1 -215
- package/src/utils/command.ts +1 -5
- package/src/utils/effect.test.ts +24 -0
- package/src/utils/effect.ts +3 -273
- package/src/utils/process.test.ts +0 -15
- package/src/utils/process.ts +1 -60
- package/src/workbase/frontmatter.test.ts +50 -0
- package/src/workbase/frontmatter.ts +77 -0
- package/src/workbase/repository-reference.test.ts +25 -0
- package/src/workbase/repository-reference.ts +18 -0
- package/src/workbase/schemas.test.ts +146 -0
- package/src/workbase/schemas.ts +78 -0
- package/src/workbase/worktree-command.test.ts +61 -0
- package/src/workbase/worktree-command.ts +52 -0
- package/src/commands/base.test.ts +0 -198
- package/src/commands/base.ts +0 -198
- package/src/commands/clean.test.ts +0 -299
- package/src/commands/clean.ts +0 -274
- package/src/commands/completions.test.ts +0 -51
- package/src/commands/completions.ts +0 -308
- package/src/commands/emit.integration.test.ts +0 -549
- package/src/commands/emit.test.ts +0 -576
- package/src/commands/emit.ts +0 -700
- package/src/commands/emitted.test.ts +0 -226
- package/src/commands/emitted.ts +0 -57
- package/src/commands/loop.test.ts +0 -621
- package/src/commands/loop.ts +0 -406
- package/src/commands/merge.integration.test.ts +0 -195
- package/src/commands/merge.test.ts +0 -246
- package/src/commands/merge.ts +0 -244
- package/src/commands/pull.test.ts +0 -395
- package/src/commands/pull.ts +0 -205
- package/src/commands/push.test.ts +0 -641
- package/src/commands/push.ts +0 -482
- package/src/commands/rebase.test.ts +0 -521
- package/src/commands/rebase.ts +0 -232
- package/src/commands/save.test.ts +0 -247
- package/src/commands/save.ts +0 -162
- package/src/commands/source.test.ts +0 -195
- package/src/commands/source.ts +0 -72
- package/src/commands/switch.test.ts +0 -194
- package/src/commands/switch.ts +0 -84
- package/src/commands/task-branching.test.ts +0 -633
- package/src/commands/task-continue.test.ts +0 -311
- package/src/commands/task-edit.test.ts +0 -235
- package/src/commands/task-main.test.ts +0 -1066
- package/src/commands/task-squash.test.ts +0 -266
- package/src/commands/tasks.test.ts +0 -391
- package/src/commands/tasks.ts +0 -161
- package/src/commands/template-delete.test.ts +0 -178
- package/src/commands/template-delete.ts +0 -98
- package/src/commands/template-list.test.ts +0 -135
- package/src/commands/template-list.ts +0 -87
- package/src/commands/template-view.test.ts +0 -158
- package/src/commands/template-view.ts +0 -86
- package/src/commands/template.test.ts +0 -32
- package/src/commands/template.ts +0 -96
- package/src/commands/use.test.ts +0 -87
- package/src/commands/use.ts +0 -97
- package/src/constants.ts +0 -10
- package/src/errors.ts +0 -17
- package/src/schemas.ts +0 -33
- package/src/services/AgencyMetadataService.ts +0 -311
- package/src/services/ClaudeService.test.ts +0 -184
- package/src/services/ClaudeService.ts +0 -91
- package/src/services/ConfigService.ts +0 -115
- package/src/services/FilterRepoService.ts +0 -164
- package/src/services/FormatterService.test.ts +0 -432
- package/src/services/FormatterService.ts +0 -219
- package/src/services/GitService.ts +0 -1187
- package/src/services/MockFilterRepoService.ts +0 -140
- package/src/services/OpencodeService.ts +0 -263
- package/src/services/PromptService.ts +0 -183
- package/src/services/TemplateService.ts +0 -81
- package/src/types/native-exec.d.ts +0 -8
- package/src/utils/colors.ts +0 -178
- package/src/utils/git-path.ts +0 -6
- package/src/utils/glob.test.ts +0 -161
- package/src/utils/glob.ts +0 -78
- package/src/utils/paths.ts +0 -51
- package/src/utils/pr-branch.test.ts +0 -376
- package/src/utils/pr-branch.ts +0 -508
- package/src/utils/spinner.test.ts +0 -45
- package/src/utils/spinner.ts +0 -96
- package/src/utils/task-parser.test.ts +0 -172
- package/src/utils/task-parser.ts +0 -93
- package/templates/AGENCY.md +0 -22
- package/templates/AGENTS.md +0 -11
- package/templates/CLAUDE.md +0 -3
- package/templates/TASK.md +0 -5
- package/templates/opencode.json +0 -4
|
@@ -1,549 +0,0 @@
|
|
|
1
|
-
import { test, expect, describe, beforeEach, afterEach } from "bun:test"
|
|
2
|
-
import { join } from "path"
|
|
3
|
-
import { emit } from "../commands/emit"
|
|
4
|
-
import { task } from "../commands/task"
|
|
5
|
-
import {
|
|
6
|
-
createTempDir,
|
|
7
|
-
cleanupTempDir,
|
|
8
|
-
initGitRepo,
|
|
9
|
-
initAgency,
|
|
10
|
-
getGitOutput,
|
|
11
|
-
getCurrentBranch,
|
|
12
|
-
createCommit,
|
|
13
|
-
checkoutBranch,
|
|
14
|
-
createBranch,
|
|
15
|
-
addAndCommit,
|
|
16
|
-
setupRemote,
|
|
17
|
-
runTestEffect,
|
|
18
|
-
} from "../test-utils"
|
|
19
|
-
|
|
20
|
-
// Cache the git-filter-repo availability check (it doesn't change during test run)
|
|
21
|
-
let hasGitFilterRepoCache: boolean | null = null
|
|
22
|
-
async function checkGitFilterRepo(): Promise<boolean> {
|
|
23
|
-
if (hasGitFilterRepoCache === null) {
|
|
24
|
-
const proc = Bun.spawn(["which", "git-filter-repo"], {
|
|
25
|
-
stdout: "pipe",
|
|
26
|
-
stderr: "pipe",
|
|
27
|
-
})
|
|
28
|
-
await proc.exited
|
|
29
|
-
hasGitFilterRepoCache = proc.exitCode === 0
|
|
30
|
-
}
|
|
31
|
-
return hasGitFilterRepoCache
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
describe("emit command - integration tests (requires git-filter-repo)", () => {
|
|
35
|
-
let tempDir: string
|
|
36
|
-
let originalCwd: string
|
|
37
|
-
let hasGitFilterRepo: boolean
|
|
38
|
-
|
|
39
|
-
beforeEach(async () => {
|
|
40
|
-
tempDir = await createTempDir()
|
|
41
|
-
originalCwd = process.cwd()
|
|
42
|
-
process.chdir(tempDir)
|
|
43
|
-
|
|
44
|
-
// Set config path to non-existent file to use defaults
|
|
45
|
-
process.env.AGENCY_CONFIG_PATH = join(tempDir, "non-existent-config.json")
|
|
46
|
-
// Set config dir to temp dir to avoid picking up user's config files
|
|
47
|
-
process.env.AGENCY_CONFIG_DIR = await createTempDir()
|
|
48
|
-
|
|
49
|
-
// Check if git-filter-repo is available (cached)
|
|
50
|
-
hasGitFilterRepo = await checkGitFilterRepo()
|
|
51
|
-
|
|
52
|
-
// Initialize git repo with main branch (already includes initial commit)
|
|
53
|
-
await initGitRepo(tempDir)
|
|
54
|
-
|
|
55
|
-
// Create a source branch (with agency-- prefix)
|
|
56
|
-
await createBranch(tempDir, "agency--test-feature")
|
|
57
|
-
|
|
58
|
-
// Initialize AGENTS.md and commit in one go
|
|
59
|
-
await initAgency(tempDir, "test")
|
|
60
|
-
|
|
61
|
-
await runTestEffect(task({ silent: true, fromCurrent: true }))
|
|
62
|
-
await addAndCommit(tempDir, "AGENTS.md", "Add AGENTS.md")
|
|
63
|
-
|
|
64
|
-
// Set up origin/main for git-filter-repo
|
|
65
|
-
await setupRemote(tempDir, "origin", tempDir)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
afterEach(async () => {
|
|
69
|
-
process.chdir(originalCwd)
|
|
70
|
-
delete process.env.AGENCY_CONFIG_PATH
|
|
71
|
-
if (process.env.AGENCY_CONFIG_DIR) {
|
|
72
|
-
await cleanupTempDir(process.env.AGENCY_CONFIG_DIR)
|
|
73
|
-
delete process.env.AGENCY_CONFIG_DIR
|
|
74
|
-
}
|
|
75
|
-
await cleanupTempDir(tempDir)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
test("filters AGENTS.md from emit branch", async () => {
|
|
79
|
-
if (!hasGitFilterRepo) {
|
|
80
|
-
console.log("Skipping test: git-filter-repo not installed")
|
|
81
|
-
return
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Go back to main and create a fresh source branch
|
|
85
|
-
await checkoutBranch(tempDir, "main")
|
|
86
|
-
await createBranch(tempDir, "agency--feature")
|
|
87
|
-
// Create agency.json with AGENTS.md as managed file
|
|
88
|
-
await Bun.write(
|
|
89
|
-
join(tempDir, "agency.json"),
|
|
90
|
-
JSON.stringify({
|
|
91
|
-
version: 1,
|
|
92
|
-
injectedFiles: ["AGENTS.md"],
|
|
93
|
-
template: "test",
|
|
94
|
-
createdAt: new Date().toISOString(),
|
|
95
|
-
}),
|
|
96
|
-
)
|
|
97
|
-
await Bun.write(join(tempDir, "AGENTS.md"), "# Test AGENTS\n")
|
|
98
|
-
await addAndCommit(tempDir, "agency.json AGENTS.md", "Add agency files")
|
|
99
|
-
// Also create a test.txt file via createCommit
|
|
100
|
-
await createCommit(tempDir, "Feature commit")
|
|
101
|
-
|
|
102
|
-
// Create emit branch (this runs git-filter-repo)
|
|
103
|
-
await runTestEffect(emit({ silent: true }))
|
|
104
|
-
|
|
105
|
-
// Should still be on feature branch
|
|
106
|
-
const currentBranch = await getCurrentBranch(tempDir)
|
|
107
|
-
expect(currentBranch).toBe("agency--feature")
|
|
108
|
-
|
|
109
|
-
// Switch to emit branch to verify files
|
|
110
|
-
await checkoutBranch(tempDir, "feature")
|
|
111
|
-
|
|
112
|
-
// AGENTS.md should be filtered out
|
|
113
|
-
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
114
|
-
expect(files).not.toContain("AGENTS.md")
|
|
115
|
-
expect(files).not.toContain("AGENCY.md")
|
|
116
|
-
|
|
117
|
-
// But test.txt should still exist
|
|
118
|
-
expect(files).toContain("test.txt")
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
test("handles emit branch recreation after source branch rebase", async () => {
|
|
122
|
-
if (!hasGitFilterRepo) {
|
|
123
|
-
console.log("Skipping test: git-filter-repo not installed")
|
|
124
|
-
return
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// We're on test-feature which has AGENTS.md
|
|
128
|
-
// Add a feature-specific file to avoid conflicts
|
|
129
|
-
await Bun.write(join(tempDir, "feature.txt"), "feature content\n")
|
|
130
|
-
await addAndCommit(tempDir, "feature.txt", "Add feature file")
|
|
131
|
-
|
|
132
|
-
// Store merge-base before advancing main
|
|
133
|
-
const initialMergeBase = await getGitOutput(tempDir, [
|
|
134
|
-
"merge-base",
|
|
135
|
-
"agency--test-feature",
|
|
136
|
-
"main",
|
|
137
|
-
])
|
|
138
|
-
|
|
139
|
-
// Create initial emit branch
|
|
140
|
-
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
141
|
-
|
|
142
|
-
// Should still be on test-feature branch
|
|
143
|
-
let currentBranch = await getCurrentBranch(tempDir)
|
|
144
|
-
expect(currentBranch).toBe("agency--test-feature")
|
|
145
|
-
|
|
146
|
-
// Switch to emit branch to verify AGENTS.md is filtered
|
|
147
|
-
await checkoutBranch(tempDir, "test-feature")
|
|
148
|
-
|
|
149
|
-
let files = await getGitOutput(tempDir, ["ls-files"])
|
|
150
|
-
expect(files).not.toContain("AGENTS.md")
|
|
151
|
-
expect(files).toContain("feature.txt")
|
|
152
|
-
|
|
153
|
-
// Switch back to source branch
|
|
154
|
-
await checkoutBranch(tempDir, "agency--test-feature")
|
|
155
|
-
|
|
156
|
-
// Simulate advancing main branch with a different file
|
|
157
|
-
await checkoutBranch(tempDir, "main")
|
|
158
|
-
await Bun.write(join(tempDir, "main-file.txt"), "main content\n")
|
|
159
|
-
await addAndCommit(tempDir, "main-file.txt", "Main branch advancement")
|
|
160
|
-
|
|
161
|
-
// Rebase test-feature onto new main
|
|
162
|
-
await checkoutBranch(tempDir, "agency--test-feature")
|
|
163
|
-
const rebaseProc = Bun.spawn(["git", "rebase", "main"], {
|
|
164
|
-
cwd: tempDir,
|
|
165
|
-
stdout: "pipe",
|
|
166
|
-
stderr: "pipe",
|
|
167
|
-
})
|
|
168
|
-
await rebaseProc.exited
|
|
169
|
-
if (rebaseProc.exitCode !== 0) {
|
|
170
|
-
const stderr = await new Response(rebaseProc.stderr).text()
|
|
171
|
-
throw new Error(`Rebase failed: ${stderr}`)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Verify merge-base has changed after rebase
|
|
175
|
-
const newMergeBase = await getGitOutput(tempDir, [
|
|
176
|
-
"merge-base",
|
|
177
|
-
"agency--test-feature",
|
|
178
|
-
"main",
|
|
179
|
-
])
|
|
180
|
-
expect(newMergeBase.trim()).not.toBe(initialMergeBase.trim())
|
|
181
|
-
|
|
182
|
-
// Recreate emit branch after rebase (this is where the bug would manifest)
|
|
183
|
-
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
184
|
-
|
|
185
|
-
// Should still be on test-feature branch
|
|
186
|
-
currentBranch = await getCurrentBranch(tempDir)
|
|
187
|
-
expect(currentBranch).toBe("agency--test-feature")
|
|
188
|
-
|
|
189
|
-
// Switch to emit branch to verify files
|
|
190
|
-
await checkoutBranch(tempDir, "test-feature")
|
|
191
|
-
|
|
192
|
-
// Verify AGENTS.md is still filtered and no extraneous changes
|
|
193
|
-
files = await getGitOutput(tempDir, ["ls-files"])
|
|
194
|
-
expect(files).not.toContain("AGENTS.md")
|
|
195
|
-
expect(files).toContain("feature.txt")
|
|
196
|
-
expect(files).toContain("main-file.txt") // Should have main's file after rebase
|
|
197
|
-
|
|
198
|
-
// Verify that our feature commits exist but AGENTS.md commit is filtered
|
|
199
|
-
const logOutput = await getGitOutput(tempDir, [
|
|
200
|
-
"log",
|
|
201
|
-
"--oneline",
|
|
202
|
-
"main..test-feature",
|
|
203
|
-
])
|
|
204
|
-
expect(logOutput).toContain("Add feature file")
|
|
205
|
-
expect(logOutput).not.toContain("Add AGENTS.md")
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
test("filters pre-existing CLAUDE.md that gets edited by agency", async () => {
|
|
209
|
-
if (!hasGitFilterRepo) {
|
|
210
|
-
console.log("Skipping test: git-filter-repo not installed")
|
|
211
|
-
return
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Start fresh on main branch
|
|
215
|
-
await checkoutBranch(tempDir, "main")
|
|
216
|
-
|
|
217
|
-
// Create CLAUDE.md on main branch (simulating pre-existing file)
|
|
218
|
-
await Bun.write(
|
|
219
|
-
join(tempDir, "CLAUDE.md"),
|
|
220
|
-
"# Original Claude Instructions\n\nSome content here.\n",
|
|
221
|
-
)
|
|
222
|
-
await addAndCommit(tempDir, "CLAUDE.md", "Add CLAUDE.md")
|
|
223
|
-
|
|
224
|
-
// Create a new feature branch
|
|
225
|
-
await createBranch(tempDir, "agency--claude-test")
|
|
226
|
-
|
|
227
|
-
// Initialize agency on this branch - first commit has agency files (NOT including CLAUDE.md)
|
|
228
|
-
await Bun.write(
|
|
229
|
-
join(tempDir, "agency.json"),
|
|
230
|
-
JSON.stringify({
|
|
231
|
-
version: 1,
|
|
232
|
-
injectedFiles: ["AGENTS.md"],
|
|
233
|
-
template: "test",
|
|
234
|
-
createdAt: new Date().toISOString(),
|
|
235
|
-
}),
|
|
236
|
-
)
|
|
237
|
-
await Bun.write(join(tempDir, "AGENTS.md"), "# Test AGENTS\n")
|
|
238
|
-
await addAndCommit(
|
|
239
|
-
tempDir,
|
|
240
|
-
"agency.json AGENTS.md",
|
|
241
|
-
"Initialize agency files",
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
// Simulate what agency task now does - CLAUDE.md modification in a separate commit
|
|
245
|
-
// with AGENCY_REMOVE_COMMIT marker so the commit gets dropped during emit
|
|
246
|
-
const originalClaude = await Bun.file(join(tempDir, "CLAUDE.md")).text()
|
|
247
|
-
const modifiedClaude = `${originalClaude}\n# Agency References\n@AGENTS.md\n@TASK.md\n`
|
|
248
|
-
await Bun.write(join(tempDir, "CLAUDE.md"), modifiedClaude)
|
|
249
|
-
await addAndCommit(
|
|
250
|
-
tempDir,
|
|
251
|
-
"CLAUDE.md",
|
|
252
|
-
"chore: agency edit CLAUDE.md\n\nAGENCY_REMOVE_COMMIT",
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
// Add a feature file
|
|
256
|
-
await createCommit(tempDir, "Feature commit")
|
|
257
|
-
|
|
258
|
-
// Create emit branch (this should drop the CLAUDE.md modification commit)
|
|
259
|
-
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
260
|
-
|
|
261
|
-
// Should still be on source branch
|
|
262
|
-
const currentBranch = await getCurrentBranch(tempDir)
|
|
263
|
-
expect(currentBranch).toBe("agency--claude-test")
|
|
264
|
-
|
|
265
|
-
// Switch to emit branch to verify CLAUDE.md is reverted to main's version
|
|
266
|
-
await checkoutBranch(tempDir, "claude-test")
|
|
267
|
-
|
|
268
|
-
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
269
|
-
expect(files).toContain("CLAUDE.md") // File should exist (from main)
|
|
270
|
-
expect(files).not.toContain("AGENTS.md") // Should be filtered
|
|
271
|
-
expect(files).not.toContain("TASK.md") // Should be filtered
|
|
272
|
-
expect(files).toContain("test.txt") // Feature file should exist
|
|
273
|
-
|
|
274
|
-
// Verify CLAUDE.md was reverted to original (no agency references)
|
|
275
|
-
const claudeContent = await Bun.file(join(tempDir, "CLAUDE.md")).text()
|
|
276
|
-
expect(claudeContent).toBe(
|
|
277
|
-
"# Original Claude Instructions\n\nSome content here.\n",
|
|
278
|
-
)
|
|
279
|
-
expect(claudeContent).not.toContain("@AGENTS.md")
|
|
280
|
-
expect(claudeContent).not.toContain("@TASK.md")
|
|
281
|
-
})
|
|
282
|
-
|
|
283
|
-
describe("AGENCY_REMOVE_COMMIT edge cases", () => {
|
|
284
|
-
test("handles two contiguous AGENCY_REMOVE_COMMIT commits", async () => {
|
|
285
|
-
if (!hasGitFilterRepo) {
|
|
286
|
-
console.log("Skipping test: git-filter-repo not installed")
|
|
287
|
-
return
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
await checkoutBranch(tempDir, "main")
|
|
291
|
-
|
|
292
|
-
// Create two files on main that will be modified
|
|
293
|
-
await Bun.write(join(tempDir, "FILE1.md"), "Original content 1\n")
|
|
294
|
-
await Bun.write(join(tempDir, "FILE2.md"), "Original content 2\n")
|
|
295
|
-
await addAndCommit(tempDir, "FILE1.md FILE2.md", "Add files")
|
|
296
|
-
|
|
297
|
-
await createBranch(tempDir, "agency--contiguous-test")
|
|
298
|
-
|
|
299
|
-
// Create agency.json
|
|
300
|
-
await Bun.write(
|
|
301
|
-
join(tempDir, "agency.json"),
|
|
302
|
-
JSON.stringify({
|
|
303
|
-
version: 1,
|
|
304
|
-
injectedFiles: [],
|
|
305
|
-
template: "test",
|
|
306
|
-
createdAt: new Date().toISOString(),
|
|
307
|
-
}),
|
|
308
|
-
)
|
|
309
|
-
await addAndCommit(tempDir, "agency.json", "Add agency.json")
|
|
310
|
-
|
|
311
|
-
// Two contiguous AGENCY_REMOVE_COMMIT commits
|
|
312
|
-
await Bun.write(join(tempDir, "FILE1.md"), "Modified content 1\n")
|
|
313
|
-
await addAndCommit(
|
|
314
|
-
tempDir,
|
|
315
|
-
"FILE1.md",
|
|
316
|
-
"chore: edit FILE1\n\nAGENCY_REMOVE_COMMIT",
|
|
317
|
-
)
|
|
318
|
-
|
|
319
|
-
await Bun.write(join(tempDir, "FILE2.md"), "Modified content 2\n")
|
|
320
|
-
await addAndCommit(
|
|
321
|
-
tempDir,
|
|
322
|
-
"FILE2.md",
|
|
323
|
-
"chore: edit FILE2\n\nAGENCY_REMOVE_COMMIT",
|
|
324
|
-
)
|
|
325
|
-
|
|
326
|
-
// Add a feature commit after
|
|
327
|
-
await createCommit(tempDir, "Feature commit")
|
|
328
|
-
|
|
329
|
-
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
330
|
-
await checkoutBranch(tempDir, "contiguous-test")
|
|
331
|
-
|
|
332
|
-
// Both files should be reverted to original
|
|
333
|
-
const file1 = await Bun.file(join(tempDir, "FILE1.md")).text()
|
|
334
|
-
const file2 = await Bun.file(join(tempDir, "FILE2.md")).text()
|
|
335
|
-
expect(file1).toBe("Original content 1\n")
|
|
336
|
-
expect(file2).toBe("Original content 2\n")
|
|
337
|
-
|
|
338
|
-
// Feature commit should still exist
|
|
339
|
-
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
340
|
-
expect(files).toContain("test.txt")
|
|
341
|
-
})
|
|
342
|
-
|
|
343
|
-
test("handles two non-contiguous AGENCY_REMOVE_COMMIT commits", async () => {
|
|
344
|
-
if (!hasGitFilterRepo) {
|
|
345
|
-
console.log("Skipping test: git-filter-repo not installed")
|
|
346
|
-
return
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
await checkoutBranch(tempDir, "main")
|
|
350
|
-
|
|
351
|
-
await Bun.write(join(tempDir, "FILE1.md"), "Original content 1\n")
|
|
352
|
-
await Bun.write(join(tempDir, "FILE2.md"), "Original content 2\n")
|
|
353
|
-
await addAndCommit(tempDir, "FILE1.md FILE2.md", "Add files")
|
|
354
|
-
|
|
355
|
-
await createBranch(tempDir, "agency--non-contiguous-test")
|
|
356
|
-
|
|
357
|
-
await Bun.write(
|
|
358
|
-
join(tempDir, "agency.json"),
|
|
359
|
-
JSON.stringify({
|
|
360
|
-
version: 1,
|
|
361
|
-
injectedFiles: [],
|
|
362
|
-
template: "test",
|
|
363
|
-
createdAt: new Date().toISOString(),
|
|
364
|
-
}),
|
|
365
|
-
)
|
|
366
|
-
await addAndCommit(tempDir, "agency.json", "Add agency.json")
|
|
367
|
-
|
|
368
|
-
// First AGENCY_REMOVE_COMMIT
|
|
369
|
-
await Bun.write(join(tempDir, "FILE1.md"), "Modified content 1\n")
|
|
370
|
-
await addAndCommit(
|
|
371
|
-
tempDir,
|
|
372
|
-
"FILE1.md",
|
|
373
|
-
"chore: edit FILE1\n\nAGENCY_REMOVE_COMMIT",
|
|
374
|
-
)
|
|
375
|
-
|
|
376
|
-
// Regular commit in between
|
|
377
|
-
await Bun.write(join(tempDir, "feature1.txt"), "feature 1\n")
|
|
378
|
-
await addAndCommit(tempDir, "feature1.txt", "Add feature 1")
|
|
379
|
-
|
|
380
|
-
// Second AGENCY_REMOVE_COMMIT
|
|
381
|
-
await Bun.write(join(tempDir, "FILE2.md"), "Modified content 2\n")
|
|
382
|
-
await addAndCommit(
|
|
383
|
-
tempDir,
|
|
384
|
-
"FILE2.md",
|
|
385
|
-
"chore: edit FILE2\n\nAGENCY_REMOVE_COMMIT",
|
|
386
|
-
)
|
|
387
|
-
|
|
388
|
-
// Another regular commit
|
|
389
|
-
await Bun.write(join(tempDir, "feature2.txt"), "feature 2\n")
|
|
390
|
-
await addAndCommit(tempDir, "feature2.txt", "Add feature 2")
|
|
391
|
-
|
|
392
|
-
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
393
|
-
await checkoutBranch(tempDir, "non-contiguous-test")
|
|
394
|
-
|
|
395
|
-
// Both files should be reverted to original
|
|
396
|
-
const file1 = await Bun.file(join(tempDir, "FILE1.md")).text()
|
|
397
|
-
const file2 = await Bun.file(join(tempDir, "FILE2.md")).text()
|
|
398
|
-
expect(file1).toBe("Original content 1\n")
|
|
399
|
-
expect(file2).toBe("Original content 2\n")
|
|
400
|
-
|
|
401
|
-
// Feature commits should still exist
|
|
402
|
-
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
403
|
-
expect(files).toContain("feature1.txt")
|
|
404
|
-
expect(files).toContain("feature2.txt")
|
|
405
|
-
})
|
|
406
|
-
|
|
407
|
-
test("handles AGENCY_REMOVE_COMMIT as first commit after fork point", async () => {
|
|
408
|
-
if (!hasGitFilterRepo) {
|
|
409
|
-
console.log("Skipping test: git-filter-repo not installed")
|
|
410
|
-
return
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
await checkoutBranch(tempDir, "main")
|
|
414
|
-
|
|
415
|
-
await Bun.write(join(tempDir, "EXISTING.md"), "Original content\n")
|
|
416
|
-
await addAndCommit(tempDir, "EXISTING.md", "Add existing file")
|
|
417
|
-
|
|
418
|
-
await createBranch(tempDir, "agency--first-commit-test")
|
|
419
|
-
|
|
420
|
-
// First commit is AGENCY_REMOVE_COMMIT (modifying existing file)
|
|
421
|
-
await Bun.write(join(tempDir, "EXISTING.md"), "Modified content\n")
|
|
422
|
-
await addAndCommit(
|
|
423
|
-
tempDir,
|
|
424
|
-
"EXISTING.md",
|
|
425
|
-
"chore: edit EXISTING\n\nAGENCY_REMOVE_COMMIT",
|
|
426
|
-
)
|
|
427
|
-
|
|
428
|
-
// Then agency.json
|
|
429
|
-
await Bun.write(
|
|
430
|
-
join(tempDir, "agency.json"),
|
|
431
|
-
JSON.stringify({
|
|
432
|
-
version: 1,
|
|
433
|
-
injectedFiles: [],
|
|
434
|
-
template: "test",
|
|
435
|
-
createdAt: new Date().toISOString(),
|
|
436
|
-
}),
|
|
437
|
-
)
|
|
438
|
-
await addAndCommit(tempDir, "agency.json", "Add agency.json")
|
|
439
|
-
|
|
440
|
-
// Feature commit
|
|
441
|
-
await createCommit(tempDir, "Feature commit")
|
|
442
|
-
|
|
443
|
-
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
444
|
-
await checkoutBranch(tempDir, "first-commit-test")
|
|
445
|
-
|
|
446
|
-
// File should be reverted to original
|
|
447
|
-
const content = await Bun.file(join(tempDir, "EXISTING.md")).text()
|
|
448
|
-
expect(content).toBe("Original content\n")
|
|
449
|
-
|
|
450
|
-
// Feature commit should exist
|
|
451
|
-
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
452
|
-
expect(files).toContain("test.txt")
|
|
453
|
-
})
|
|
454
|
-
|
|
455
|
-
test("handles AGENCY_REMOVE_COMMIT as last commit", async () => {
|
|
456
|
-
if (!hasGitFilterRepo) {
|
|
457
|
-
console.log("Skipping test: git-filter-repo not installed")
|
|
458
|
-
return
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
await checkoutBranch(tempDir, "main")
|
|
462
|
-
|
|
463
|
-
await Bun.write(join(tempDir, "EXISTING.md"), "Original content\n")
|
|
464
|
-
await addAndCommit(tempDir, "EXISTING.md", "Add existing file")
|
|
465
|
-
|
|
466
|
-
await createBranch(tempDir, "agency--last-commit-test")
|
|
467
|
-
|
|
468
|
-
// agency.json first
|
|
469
|
-
await Bun.write(
|
|
470
|
-
join(tempDir, "agency.json"),
|
|
471
|
-
JSON.stringify({
|
|
472
|
-
version: 1,
|
|
473
|
-
injectedFiles: [],
|
|
474
|
-
template: "test",
|
|
475
|
-
createdAt: new Date().toISOString(),
|
|
476
|
-
}),
|
|
477
|
-
)
|
|
478
|
-
await addAndCommit(tempDir, "agency.json", "Add agency.json")
|
|
479
|
-
|
|
480
|
-
// Feature commit
|
|
481
|
-
await Bun.write(join(tempDir, "feature.txt"), "feature\n")
|
|
482
|
-
await addAndCommit(tempDir, "feature.txt", "Add feature")
|
|
483
|
-
|
|
484
|
-
// Last commit is AGENCY_REMOVE_COMMIT
|
|
485
|
-
await Bun.write(join(tempDir, "EXISTING.md"), "Modified content\n")
|
|
486
|
-
await addAndCommit(
|
|
487
|
-
tempDir,
|
|
488
|
-
"EXISTING.md",
|
|
489
|
-
"chore: edit EXISTING\n\nAGENCY_REMOVE_COMMIT",
|
|
490
|
-
)
|
|
491
|
-
|
|
492
|
-
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
493
|
-
await checkoutBranch(tempDir, "last-commit-test")
|
|
494
|
-
|
|
495
|
-
// File should be reverted to original
|
|
496
|
-
const content = await Bun.file(join(tempDir, "EXISTING.md")).text()
|
|
497
|
-
expect(content).toBe("Original content\n")
|
|
498
|
-
|
|
499
|
-
// Feature commit should exist
|
|
500
|
-
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
501
|
-
expect(files).toContain("feature.txt")
|
|
502
|
-
})
|
|
503
|
-
|
|
504
|
-
test("handles AGENCY_REMOVE_COMMIT as only commit (besides agency.json)", async () => {
|
|
505
|
-
if (!hasGitFilterRepo) {
|
|
506
|
-
console.log("Skipping test: git-filter-repo not installed")
|
|
507
|
-
return
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
await checkoutBranch(tempDir, "main")
|
|
511
|
-
|
|
512
|
-
await Bun.write(join(tempDir, "EXISTING.md"), "Original content\n")
|
|
513
|
-
await addAndCommit(tempDir, "EXISTING.md", "Add existing file")
|
|
514
|
-
|
|
515
|
-
await createBranch(tempDir, "agency--only-commit-test")
|
|
516
|
-
|
|
517
|
-
// agency.json
|
|
518
|
-
await Bun.write(
|
|
519
|
-
join(tempDir, "agency.json"),
|
|
520
|
-
JSON.stringify({
|
|
521
|
-
version: 1,
|
|
522
|
-
injectedFiles: [],
|
|
523
|
-
template: "test",
|
|
524
|
-
createdAt: new Date().toISOString(),
|
|
525
|
-
}),
|
|
526
|
-
)
|
|
527
|
-
await addAndCommit(tempDir, "agency.json", "Add agency.json")
|
|
528
|
-
|
|
529
|
-
// Only other commit is AGENCY_REMOVE_COMMIT
|
|
530
|
-
await Bun.write(join(tempDir, "EXISTING.md"), "Modified content\n")
|
|
531
|
-
await addAndCommit(
|
|
532
|
-
tempDir,
|
|
533
|
-
"EXISTING.md",
|
|
534
|
-
"chore: edit EXISTING\n\nAGENCY_REMOVE_COMMIT",
|
|
535
|
-
)
|
|
536
|
-
|
|
537
|
-
await runTestEffect(emit({ silent: true, baseBranch: "main" }))
|
|
538
|
-
await checkoutBranch(tempDir, "only-commit-test")
|
|
539
|
-
|
|
540
|
-
// File should be reverted to original
|
|
541
|
-
const content = await Bun.file(join(tempDir, "EXISTING.md")).text()
|
|
542
|
-
expect(content).toBe("Original content\n")
|
|
543
|
-
|
|
544
|
-
// Emit branch should exist and have the file
|
|
545
|
-
const files = await getGitOutput(tempDir, ["ls-files"])
|
|
546
|
-
expect(files).toContain("EXISTING.md")
|
|
547
|
-
})
|
|
548
|
-
})
|
|
549
|
-
})
|