@markjaquith/agency 0.5.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/LICENSE +21 -0
- package/README.md +109 -0
- package/cli.ts +569 -0
- package/index.ts +1 -0
- package/package.json +65 -0
- package/src/commands/base.test.ts +198 -0
- package/src/commands/base.ts +198 -0
- package/src/commands/clean.test.ts +299 -0
- package/src/commands/clean.ts +320 -0
- package/src/commands/emit.test.ts +412 -0
- package/src/commands/emit.ts +521 -0
- package/src/commands/emitted.test.ts +226 -0
- package/src/commands/emitted.ts +57 -0
- package/src/commands/init.test.ts +311 -0
- package/src/commands/init.ts +140 -0
- package/src/commands/merge.test.ts +365 -0
- package/src/commands/merge.ts +253 -0
- package/src/commands/pull.test.ts +385 -0
- package/src/commands/pull.ts +205 -0
- package/src/commands/push.test.ts +394 -0
- package/src/commands/push.ts +346 -0
- package/src/commands/save.test.ts +247 -0
- package/src/commands/save.ts +162 -0
- package/src/commands/source.test.ts +195 -0
- package/src/commands/source.ts +72 -0
- package/src/commands/status.test.ts +489 -0
- package/src/commands/status.ts +258 -0
- package/src/commands/switch.test.ts +194 -0
- package/src/commands/switch.ts +84 -0
- package/src/commands/task-branching.test.ts +334 -0
- package/src/commands/task-edit.test.ts +141 -0
- package/src/commands/task-main.test.ts +872 -0
- package/src/commands/task.ts +712 -0
- package/src/commands/tasks.test.ts +335 -0
- package/src/commands/tasks.ts +155 -0
- package/src/commands/template-delete.test.ts +178 -0
- package/src/commands/template-delete.ts +98 -0
- package/src/commands/template-list.test.ts +135 -0
- package/src/commands/template-list.ts +87 -0
- package/src/commands/template-view.test.ts +158 -0
- package/src/commands/template-view.ts +86 -0
- package/src/commands/template.test.ts +32 -0
- package/src/commands/template.ts +96 -0
- package/src/commands/use.test.ts +87 -0
- package/src/commands/use.ts +97 -0
- package/src/commands/work.test.ts +462 -0
- package/src/commands/work.ts +193 -0
- package/src/errors.ts +17 -0
- package/src/schemas.ts +33 -0
- package/src/services/AgencyMetadataService.ts +287 -0
- package/src/services/ClaudeService.test.ts +184 -0
- package/src/services/ClaudeService.ts +91 -0
- package/src/services/ConfigService.ts +115 -0
- package/src/services/FileSystemService.ts +222 -0
- package/src/services/GitService.ts +751 -0
- package/src/services/OpencodeService.ts +263 -0
- package/src/services/PromptService.ts +183 -0
- package/src/services/TemplateService.ts +75 -0
- package/src/test-utils.ts +362 -0
- package/src/types/native-exec.d.ts +8 -0
- package/src/types.ts +216 -0
- package/src/utils/colors.ts +178 -0
- package/src/utils/command.ts +17 -0
- package/src/utils/effect.ts +281 -0
- package/src/utils/exec.ts +48 -0
- package/src/utils/paths.ts +51 -0
- package/src/utils/pr-branch.test.ts +372 -0
- package/src/utils/pr-branch.ts +473 -0
- package/src/utils/process.ts +110 -0
- package/src/utils/spinner.ts +82 -0
- package/templates/AGENCY.md +20 -0
- package/templates/AGENTS.md +11 -0
- package/templates/CLAUDE.md +3 -0
- package/templates/TASK.md +5 -0
- package/templates/opencode.json +4 -0
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
import { test, expect, describe, beforeEach, afterEach } from "bun:test"
|
|
2
|
+
import { join } from "path"
|
|
3
|
+
import { status } from "./status"
|
|
4
|
+
import {
|
|
5
|
+
createTempDir,
|
|
6
|
+
cleanupTempDir,
|
|
7
|
+
initGitRepo,
|
|
8
|
+
getCurrentBranch,
|
|
9
|
+
createCommit,
|
|
10
|
+
initAgency,
|
|
11
|
+
runTestEffect,
|
|
12
|
+
} from "../test-utils"
|
|
13
|
+
import { writeAgencyMetadata } from "../types"
|
|
14
|
+
|
|
15
|
+
async function createBranch(cwd: string, branchName: string): Promise<void> {
|
|
16
|
+
await Bun.spawn(["git", "checkout", "-b", branchName], {
|
|
17
|
+
cwd,
|
|
18
|
+
stdout: "pipe",
|
|
19
|
+
stderr: "pipe",
|
|
20
|
+
}).exited
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function checkoutBranch(cwd: string, branchName: string): Promise<void> {
|
|
24
|
+
await Bun.spawn(["git", "checkout", branchName], {
|
|
25
|
+
cwd,
|
|
26
|
+
stdout: "pipe",
|
|
27
|
+
stderr: "pipe",
|
|
28
|
+
}).exited
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe("status command", () => {
|
|
32
|
+
let tempDir: string
|
|
33
|
+
let originalCwd: string
|
|
34
|
+
|
|
35
|
+
beforeEach(async () => {
|
|
36
|
+
tempDir = await createTempDir()
|
|
37
|
+
originalCwd = process.cwd()
|
|
38
|
+
process.chdir(tempDir)
|
|
39
|
+
|
|
40
|
+
// Set config path to non-existent file to use defaults
|
|
41
|
+
process.env.AGENCY_CONFIG_PATH = join(tempDir, "non-existent-config.json")
|
|
42
|
+
|
|
43
|
+
// Initialize git repo
|
|
44
|
+
await initGitRepo(tempDir)
|
|
45
|
+
await createCommit(tempDir, "Initial commit")
|
|
46
|
+
|
|
47
|
+
// Rename to main if needed
|
|
48
|
+
const currentBranch = await getCurrentBranch(tempDir)
|
|
49
|
+
if (currentBranch === "master") {
|
|
50
|
+
await Bun.spawn(["git", "branch", "-m", "main"], {
|
|
51
|
+
cwd: tempDir,
|
|
52
|
+
stdout: "pipe",
|
|
53
|
+
stderr: "pipe",
|
|
54
|
+
}).exited
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
afterEach(async () => {
|
|
59
|
+
process.chdir(originalCwd)
|
|
60
|
+
delete process.env.AGENCY_CONFIG_PATH
|
|
61
|
+
await cleanupTempDir(tempDir)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
describe("basic functionality", () => {
|
|
65
|
+
test("shows not initialized when agency.json is missing", async () => {
|
|
66
|
+
let output = ""
|
|
67
|
+
const originalLog = console.log
|
|
68
|
+
console.log = (msg: string) => {
|
|
69
|
+
output += msg + "\n"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
await runTestEffect(status({}))
|
|
73
|
+
|
|
74
|
+
console.log = originalLog
|
|
75
|
+
expect(output).toContain("Not initialized")
|
|
76
|
+
expect(output).toContain("agency task")
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test("shows initialized when agency.json exists", async () => {
|
|
80
|
+
// Initialize agency
|
|
81
|
+
await initAgency(tempDir, "test-template")
|
|
82
|
+
|
|
83
|
+
// Create feature branch with agency.json
|
|
84
|
+
await createBranch(tempDir, "feature")
|
|
85
|
+
await writeAgencyMetadata(tempDir, {
|
|
86
|
+
version: 1,
|
|
87
|
+
injectedFiles: ["AGENTS.md"],
|
|
88
|
+
template: "test-template",
|
|
89
|
+
createdAt: new Date().toISOString(),
|
|
90
|
+
} as any)
|
|
91
|
+
|
|
92
|
+
let output = ""
|
|
93
|
+
const originalLog = console.log
|
|
94
|
+
console.log = (msg: string) => {
|
|
95
|
+
output += msg + "\n"
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
await runTestEffect(status({}))
|
|
99
|
+
|
|
100
|
+
console.log = originalLog
|
|
101
|
+
expect(output).toContain("Current branch:")
|
|
102
|
+
expect(output).toContain("Branch type: Source branch")
|
|
103
|
+
expect(output).toContain("Template:")
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test("shows source branch type when on source branch", async () => {
|
|
107
|
+
await initAgency(tempDir, "test-template")
|
|
108
|
+
await createBranch(tempDir, "feature")
|
|
109
|
+
await writeAgencyMetadata(tempDir, {
|
|
110
|
+
version: 1,
|
|
111
|
+
injectedFiles: [],
|
|
112
|
+
template: "test-template",
|
|
113
|
+
createdAt: new Date().toISOString(),
|
|
114
|
+
} as any)
|
|
115
|
+
|
|
116
|
+
let output = ""
|
|
117
|
+
const originalLog = console.log
|
|
118
|
+
console.log = (msg: string) => {
|
|
119
|
+
output += msg + "\n"
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
await runTestEffect(status({}))
|
|
123
|
+
|
|
124
|
+
console.log = originalLog
|
|
125
|
+
expect(output).toContain("Branch type:")
|
|
126
|
+
expect(output).toContain("Source branch")
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
test("shows emit branch type when on emit branch", async () => {
|
|
130
|
+
await initAgency(tempDir, "test-template")
|
|
131
|
+
|
|
132
|
+
// Create source branch with agency.json
|
|
133
|
+
await createBranch(tempDir, "agency/feature")
|
|
134
|
+
await writeAgencyMetadata(tempDir, {
|
|
135
|
+
version: 1,
|
|
136
|
+
injectedFiles: [],
|
|
137
|
+
template: "test-template",
|
|
138
|
+
emitBranch: "feature",
|
|
139
|
+
createdAt: new Date().toISOString(),
|
|
140
|
+
} as any)
|
|
141
|
+
// Stage and commit agency.json
|
|
142
|
+
await Bun.spawn(["git", "add", "agency.json"], {
|
|
143
|
+
cwd: tempDir,
|
|
144
|
+
stdout: "pipe",
|
|
145
|
+
stderr: "pipe",
|
|
146
|
+
}).exited
|
|
147
|
+
await createCommit(tempDir, "Feature work")
|
|
148
|
+
|
|
149
|
+
// Create and switch to emit branch
|
|
150
|
+
await createBranch(tempDir, "feature")
|
|
151
|
+
|
|
152
|
+
let output = ""
|
|
153
|
+
const originalLog = console.log
|
|
154
|
+
console.log = (msg: string) => {
|
|
155
|
+
output += msg + "\n"
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
await runTestEffect(status({}))
|
|
159
|
+
|
|
160
|
+
console.log = originalLog
|
|
161
|
+
expect(output).toContain("Branch type:")
|
|
162
|
+
expect(output).toContain("Emit branch")
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
test("shows corresponding branch when it exists", async () => {
|
|
166
|
+
await initAgency(tempDir, "test-template")
|
|
167
|
+
await createBranch(tempDir, "agency/feature")
|
|
168
|
+
await writeAgencyMetadata(tempDir, {
|
|
169
|
+
version: 1,
|
|
170
|
+
injectedFiles: [],
|
|
171
|
+
template: "test-template",
|
|
172
|
+
emitBranch: "feature",
|
|
173
|
+
createdAt: new Date().toISOString(),
|
|
174
|
+
} as any)
|
|
175
|
+
|
|
176
|
+
// Stage and commit agency.json
|
|
177
|
+
await Bun.spawn(["git", "add", "agency.json"], {
|
|
178
|
+
cwd: tempDir,
|
|
179
|
+
stdout: "pipe",
|
|
180
|
+
stderr: "pipe",
|
|
181
|
+
}).exited
|
|
182
|
+
await createCommit(tempDir, "Set up branch")
|
|
183
|
+
|
|
184
|
+
// Create emit branch
|
|
185
|
+
await createBranch(tempDir, "feature")
|
|
186
|
+
await checkoutBranch(tempDir, "agency/feature")
|
|
187
|
+
|
|
188
|
+
let output = ""
|
|
189
|
+
const originalLog = console.log
|
|
190
|
+
console.log = (msg: string) => {
|
|
191
|
+
output += msg + "\n"
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
await runTestEffect(status({}))
|
|
195
|
+
|
|
196
|
+
console.log = originalLog
|
|
197
|
+
expect(output).toContain("Emit branch: ")
|
|
198
|
+
expect(output).toContain("feature")
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
test("shows backpack files", async () => {
|
|
202
|
+
await initAgency(tempDir, "test-template")
|
|
203
|
+
await createBranch(tempDir, "feature")
|
|
204
|
+
await writeAgencyMetadata(tempDir, {
|
|
205
|
+
version: 1,
|
|
206
|
+
injectedFiles: ["AGENTS.md", "opencode.json"],
|
|
207
|
+
template: "test-template",
|
|
208
|
+
createdAt: new Date().toISOString(),
|
|
209
|
+
} as any)
|
|
210
|
+
|
|
211
|
+
let output = ""
|
|
212
|
+
const originalLog = console.log
|
|
213
|
+
console.log = (msg: string) => {
|
|
214
|
+
output += msg + "\n"
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
await runTestEffect(status({}))
|
|
218
|
+
|
|
219
|
+
console.log = originalLog
|
|
220
|
+
expect(output).toContain("Backpack:")
|
|
221
|
+
// Base backpack files (TASK.md, AGENCY.md, agency.json) + injected files (AGENTS.md, opencode.json)
|
|
222
|
+
expect(output).toContain("TASK.md")
|
|
223
|
+
expect(output).toContain("AGENCY.md")
|
|
224
|
+
expect(output).toContain("agency.json")
|
|
225
|
+
expect(output).toContain("AGENTS.md")
|
|
226
|
+
expect(output).toContain("opencode.json")
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
test("shows base branch when set", async () => {
|
|
230
|
+
await initAgency(tempDir, "test-template")
|
|
231
|
+
await createBranch(tempDir, "feature")
|
|
232
|
+
await writeAgencyMetadata(tempDir, {
|
|
233
|
+
version: 1,
|
|
234
|
+
injectedFiles: [],
|
|
235
|
+
template: "test-template",
|
|
236
|
+
baseBranch: "main",
|
|
237
|
+
createdAt: new Date().toISOString(),
|
|
238
|
+
} as any)
|
|
239
|
+
|
|
240
|
+
let output = ""
|
|
241
|
+
const originalLog = console.log
|
|
242
|
+
console.log = (msg: string) => {
|
|
243
|
+
output += msg + "\n"
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
await runTestEffect(status({}))
|
|
247
|
+
|
|
248
|
+
console.log = originalLog
|
|
249
|
+
expect(output).toContain("Base branch:")
|
|
250
|
+
expect(output).toContain("main")
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
test("shows template name", async () => {
|
|
254
|
+
await initAgency(tempDir, "my-custom-template")
|
|
255
|
+
await createBranch(tempDir, "feature")
|
|
256
|
+
await writeAgencyMetadata(tempDir, {
|
|
257
|
+
version: 1,
|
|
258
|
+
injectedFiles: [],
|
|
259
|
+
template: "my-custom-template",
|
|
260
|
+
createdAt: new Date().toISOString(),
|
|
261
|
+
} as any)
|
|
262
|
+
|
|
263
|
+
let output = ""
|
|
264
|
+
const originalLog = console.log
|
|
265
|
+
console.log = (msg: string) => {
|
|
266
|
+
output += msg + "\n"
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
await runTestEffect(status({}))
|
|
270
|
+
|
|
271
|
+
console.log = originalLog
|
|
272
|
+
expect(output).toContain("Template:")
|
|
273
|
+
expect(output).toContain("my-custom-template")
|
|
274
|
+
})
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
describe("JSON output", () => {
|
|
278
|
+
test("outputs valid JSON with --json flag", async () => {
|
|
279
|
+
await initAgency(tempDir, "test-template")
|
|
280
|
+
await createBranch(tempDir, "feature")
|
|
281
|
+
await writeAgencyMetadata(tempDir, {
|
|
282
|
+
version: 1,
|
|
283
|
+
injectedFiles: ["AGENTS.md"],
|
|
284
|
+
baseBranch: "main",
|
|
285
|
+
template: "test-template",
|
|
286
|
+
createdAt: new Date().toISOString(),
|
|
287
|
+
} as any)
|
|
288
|
+
|
|
289
|
+
let output = ""
|
|
290
|
+
const originalLog = console.log
|
|
291
|
+
console.log = (msg: string) => {
|
|
292
|
+
output += msg + "\n"
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
await runTestEffect(status({ json: true }))
|
|
296
|
+
|
|
297
|
+
console.log = originalLog
|
|
298
|
+
|
|
299
|
+
const data = JSON.parse(output.trim())
|
|
300
|
+
expect(data.initialized).toBe(true)
|
|
301
|
+
expect(data.branchType).toBe("source")
|
|
302
|
+
expect(data.currentBranch).toBe("feature")
|
|
303
|
+
expect(data.template).toBe("test-template")
|
|
304
|
+
// managedFiles includes base backpack files + injected files
|
|
305
|
+
expect(data.managedFiles).toContain("TASK.md")
|
|
306
|
+
expect(data.managedFiles).toContain("AGENCY.md")
|
|
307
|
+
expect(data.managedFiles).toContain("agency.json")
|
|
308
|
+
expect(data.managedFiles).toContain("AGENTS.md")
|
|
309
|
+
expect(data.baseBranch).toBe("main")
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
test("JSON output contains all expected fields", async () => {
|
|
313
|
+
await initAgency(tempDir, "test-template")
|
|
314
|
+
await createBranch(tempDir, "feature")
|
|
315
|
+
await writeAgencyMetadata(tempDir, {
|
|
316
|
+
version: 1,
|
|
317
|
+
injectedFiles: [],
|
|
318
|
+
template: "test-template",
|
|
319
|
+
createdAt: new Date().toISOString(),
|
|
320
|
+
} as any)
|
|
321
|
+
|
|
322
|
+
let output = ""
|
|
323
|
+
const originalLog = console.log
|
|
324
|
+
console.log = (msg: string) => {
|
|
325
|
+
output += msg + "\n"
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
await runTestEffect(status({ json: true }))
|
|
329
|
+
|
|
330
|
+
console.log = originalLog
|
|
331
|
+
|
|
332
|
+
const data = JSON.parse(output.trim())
|
|
333
|
+
expect(data).toHaveProperty("initialized")
|
|
334
|
+
expect(data).toHaveProperty("branchType")
|
|
335
|
+
expect(data).toHaveProperty("currentBranch")
|
|
336
|
+
expect(data).toHaveProperty("sourceBranch")
|
|
337
|
+
expect(data).toHaveProperty("emitBranch")
|
|
338
|
+
expect(data).toHaveProperty("correspondingBranchExists")
|
|
339
|
+
expect(data).toHaveProperty("template")
|
|
340
|
+
expect(data).toHaveProperty("managedFiles")
|
|
341
|
+
expect(data).toHaveProperty("baseBranch")
|
|
342
|
+
expect(data).toHaveProperty("createdAt")
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
test("JSON output shows not initialized state", async () => {
|
|
346
|
+
let output = ""
|
|
347
|
+
const originalLog = console.log
|
|
348
|
+
console.log = (msg: string) => {
|
|
349
|
+
output += msg + "\n"
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
await runTestEffect(status({ json: true }))
|
|
353
|
+
|
|
354
|
+
console.log = originalLog
|
|
355
|
+
|
|
356
|
+
const data = JSON.parse(output.trim())
|
|
357
|
+
expect(data.initialized).toBe(false)
|
|
358
|
+
expect(data.branchType).toBe("neither")
|
|
359
|
+
})
|
|
360
|
+
})
|
|
361
|
+
|
|
362
|
+
describe("error handling", () => {
|
|
363
|
+
test("throws error when not in a git repository", async () => {
|
|
364
|
+
const nonGitDir = await createTempDir()
|
|
365
|
+
process.chdir(nonGitDir)
|
|
366
|
+
|
|
367
|
+
await expect(runTestEffect(status({}))).rejects.toThrow(
|
|
368
|
+
"Not in a git repository",
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
await cleanupTempDir(nonGitDir)
|
|
372
|
+
})
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
describe("silent mode", () => {
|
|
376
|
+
test("silent flag suppresses output", async () => {
|
|
377
|
+
const originalLog = console.log
|
|
378
|
+
let logCalled = false
|
|
379
|
+
console.log = () => {
|
|
380
|
+
logCalled = true
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
await runTestEffect(status({ silent: true }))
|
|
384
|
+
|
|
385
|
+
console.log = originalLog
|
|
386
|
+
expect(logCalled).toBe(false)
|
|
387
|
+
})
|
|
388
|
+
})
|
|
389
|
+
|
|
390
|
+
describe("emit branch behavior", () => {
|
|
391
|
+
test("reads metadata from source branch when on emit branch without agency.json on disk", async () => {
|
|
392
|
+
await initAgency(tempDir, "test-template")
|
|
393
|
+
|
|
394
|
+
// Create source branch (agency/feature) with agency.json committed
|
|
395
|
+
await createBranch(tempDir, "agency/feature")
|
|
396
|
+
await writeAgencyMetadata(tempDir, {
|
|
397
|
+
version: 1,
|
|
398
|
+
injectedFiles: ["AGENTS.md", "opencode.json"],
|
|
399
|
+
template: "test-template",
|
|
400
|
+
baseBranch: "main",
|
|
401
|
+
emitBranch: "feature",
|
|
402
|
+
createdAt: new Date().toISOString(),
|
|
403
|
+
} as any)
|
|
404
|
+
// Stage and commit agency.json
|
|
405
|
+
await Bun.spawn(["git", "add", "agency.json"], {
|
|
406
|
+
cwd: tempDir,
|
|
407
|
+
stdout: "pipe",
|
|
408
|
+
stderr: "pipe",
|
|
409
|
+
}).exited
|
|
410
|
+
await createCommit(tempDir, "Feature work")
|
|
411
|
+
|
|
412
|
+
// Create emit branch and remove agency.json from working tree
|
|
413
|
+
await createBranch(tempDir, "feature")
|
|
414
|
+
await Bun.spawn(["rm", "agency.json"], {
|
|
415
|
+
cwd: tempDir,
|
|
416
|
+
stdout: "pipe",
|
|
417
|
+
stderr: "pipe",
|
|
418
|
+
}).exited
|
|
419
|
+
|
|
420
|
+
let output = ""
|
|
421
|
+
const originalLog = console.log
|
|
422
|
+
console.log = (msg: string) => {
|
|
423
|
+
output += msg + "\n"
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
await runTestEffect(status({ json: true }))
|
|
427
|
+
|
|
428
|
+
console.log = originalLog
|
|
429
|
+
|
|
430
|
+
const data = JSON.parse(output.trim())
|
|
431
|
+
// Verify that we're recognized as on an emit branch
|
|
432
|
+
expect(data.branchType).toBe("emit")
|
|
433
|
+
expect(data.initialized).toBe(true)
|
|
434
|
+
// Verify metadata is correctly read from source branch
|
|
435
|
+
expect(data.baseBranch).toBe("main")
|
|
436
|
+
expect(data.managedFiles).toContain("AGENTS.md")
|
|
437
|
+
expect(data.managedFiles).toContain("opencode.json")
|
|
438
|
+
expect(data.sourceBranch).toBe("agency/feature")
|
|
439
|
+
})
|
|
440
|
+
|
|
441
|
+
test("shows correct backpack when on emit branch", async () => {
|
|
442
|
+
await initAgency(tempDir, "test-template")
|
|
443
|
+
|
|
444
|
+
// Create source branch (agency/feature) with agency.json committed
|
|
445
|
+
await createBranch(tempDir, "agency/feature")
|
|
446
|
+
await writeAgencyMetadata(tempDir, {
|
|
447
|
+
version: 1,
|
|
448
|
+
injectedFiles: ["AGENTS.md"],
|
|
449
|
+
template: "test-template",
|
|
450
|
+
emitBranch: "feature",
|
|
451
|
+
createdAt: new Date().toISOString(),
|
|
452
|
+
} as any)
|
|
453
|
+
// Stage and commit agency.json
|
|
454
|
+
await Bun.spawn(["git", "add", "agency.json"], {
|
|
455
|
+
cwd: tempDir,
|
|
456
|
+
stdout: "pipe",
|
|
457
|
+
stderr: "pipe",
|
|
458
|
+
}).exited
|
|
459
|
+
await createCommit(tempDir, "Feature work")
|
|
460
|
+
|
|
461
|
+
// Create emit branch and remove agency.json from disk to simulate clean emit branch
|
|
462
|
+
await createBranch(tempDir, "feature")
|
|
463
|
+
await Bun.spawn(["rm", "agency.json"], {
|
|
464
|
+
cwd: tempDir,
|
|
465
|
+
stdout: "pipe",
|
|
466
|
+
stderr: "pipe",
|
|
467
|
+
}).exited
|
|
468
|
+
|
|
469
|
+
let output = ""
|
|
470
|
+
const originalLog = console.log
|
|
471
|
+
console.log = (msg: string) => {
|
|
472
|
+
output += msg + "\n"
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
await runTestEffect(status({ json: true }))
|
|
476
|
+
|
|
477
|
+
console.log = originalLog
|
|
478
|
+
|
|
479
|
+
const data = JSON.parse(output.trim())
|
|
480
|
+
expect(data.branchType).toBe("emit")
|
|
481
|
+
expect(data.initialized).toBe(true)
|
|
482
|
+
// Backpack should include injected files from source branch
|
|
483
|
+
expect(data.managedFiles).toContain("AGENTS.md")
|
|
484
|
+
expect(data.managedFiles).toContain("TASK.md")
|
|
485
|
+
expect(data.managedFiles).toContain("AGENCY.md")
|
|
486
|
+
expect(data.managedFiles).toContain("agency.json")
|
|
487
|
+
})
|
|
488
|
+
})
|
|
489
|
+
})
|