@markjaquith/agency 1.6.3 → 1.7.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/cli.ts +23 -2
- package/package.json +1 -1
- package/src/commands/clean.test.ts +2 -2
- package/src/commands/clean.ts +3 -20
- package/src/commands/emit.integration.test.ts +17 -17
- package/src/commands/emit.test.ts +22 -22
- package/src/commands/emit.ts +8 -7
- package/src/commands/emitted.test.ts +8 -8
- package/src/commands/emitted.ts +1 -1
- package/src/commands/merge.integration.test.ts +5 -5
- package/src/commands/merge.test.ts +7 -7
- package/src/commands/pull.test.ts +15 -15
- package/src/commands/push.test.ts +30 -30
- package/src/commands/rebase.test.ts +19 -19
- package/src/commands/rebase.ts +5 -8
- package/src/commands/source.test.ts +13 -13
- package/src/commands/status.test.ts +8 -8
- package/src/commands/status.ts +4 -26
- package/src/commands/switch.test.ts +18 -18
- package/src/commands/switch.ts +3 -3
- package/src/commands/task-branching.test.ts +19 -19
- package/src/commands/task-continue.test.ts +3 -3
- package/src/commands/task-main.test.ts +7 -7
- package/src/commands/task.ts +14 -7
- package/src/constants.ts +10 -0
- package/src/schemas.ts +1 -1
- package/src/services/AgencyMetadataService.ts +217 -242
- package/src/services/ConfigService.ts +1 -1
- package/src/services/FormatterService.test.ts +432 -0
- package/src/services/FormatterService.ts +219 -0
- package/src/services/TemplateService.ts +9 -3
- package/src/test-utils.ts +3 -0
- package/src/types.ts +6 -9
- package/src/utils/pr-branch.test.ts +36 -32
- package/src/utils/pr-branch.ts +12 -15
package/src/commands/status.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Effect, DateTime } from "effect"
|
|
2
2
|
import { join } from "node:path"
|
|
3
|
-
import { Schema } from "@effect/schema"
|
|
4
3
|
import type { BaseCommandOptions } from "../utils/command"
|
|
5
4
|
import { GitService } from "../services/GitService"
|
|
6
5
|
import { ConfigService } from "../services/ConfigService"
|
|
7
6
|
import { FileSystemService } from "../services/FileSystemService"
|
|
7
|
+
import {
|
|
8
|
+
AgencyMetadataService,
|
|
9
|
+
parseAgencyMetadata,
|
|
10
|
+
} from "../services/AgencyMetadataService"
|
|
8
11
|
import { resolveBranchPairWithAgencyJson } from "../utils/pr-branch"
|
|
9
|
-
import { AgencyMetadata } from "../schemas"
|
|
10
12
|
import highlight, { plural } from "../utils/colors"
|
|
11
13
|
import { createLoggers, ensureGitRepo, getTemplateName } from "../utils/effect"
|
|
12
14
|
|
|
@@ -74,30 +76,6 @@ const readAgencyMetadataFromBranch = (gitRoot: string, branch: string) =>
|
|
|
74
76
|
return yield* parseAgencyMetadata(content)
|
|
75
77
|
}).pipe(Effect.catchAll(() => Effect.succeed(null)))
|
|
76
78
|
|
|
77
|
-
/**
|
|
78
|
-
* Parse and validate agency.json content.
|
|
79
|
-
*/
|
|
80
|
-
const parseAgencyMetadata = (content: string) =>
|
|
81
|
-
Effect.gen(function* () {
|
|
82
|
-
const data = yield* Effect.try({
|
|
83
|
-
try: () => JSON.parse(content),
|
|
84
|
-
catch: () => new Error("Failed to parse agency.json"),
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
// Validate version
|
|
88
|
-
if (typeof data.version !== "number" || data.version !== 1) {
|
|
89
|
-
return null
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Parse and validate using Effect schema
|
|
93
|
-
const metadata = yield* Effect.try({
|
|
94
|
-
try: () => Schema.decodeUnknownSync(AgencyMetadata)(data),
|
|
95
|
-
catch: () => new Error("Invalid agency.json format"),
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
return metadata
|
|
99
|
-
}).pipe(Effect.catchAll(() => Effect.succeed(null)))
|
|
100
|
-
|
|
101
79
|
export const status = (options: StatusOptions = {}) =>
|
|
102
80
|
Effect.gen(function* () {
|
|
103
81
|
const { json = false } = options
|
|
@@ -55,8 +55,8 @@ describe("switch command", () => {
|
|
|
55
55
|
|
|
56
56
|
describe("basic functionality", () => {
|
|
57
57
|
test("switches from emit branch to source branch", async () => {
|
|
58
|
-
// Create source and emit branches (source=agency
|
|
59
|
-
await createBranch(tempDir, "agency
|
|
58
|
+
// Create source and emit branches (source=agency--main, emit=main)
|
|
59
|
+
await createBranch(tempDir, "agency--main")
|
|
60
60
|
await createCommit(tempDir, "Work on source")
|
|
61
61
|
// Emit branch is just "main" (already exists from setup)
|
|
62
62
|
await checkoutBranch(tempDir, "main")
|
|
@@ -66,15 +66,15 @@ describe("switch command", () => {
|
|
|
66
66
|
|
|
67
67
|
// Should be on source branch now
|
|
68
68
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
69
|
-
expect(currentBranch).toBe("agency
|
|
69
|
+
expect(currentBranch).toBe("agency--main")
|
|
70
70
|
})
|
|
71
71
|
|
|
72
72
|
test("switches from source branch to emit branch", async () => {
|
|
73
73
|
// Create source branch (main becomes the emit branch)
|
|
74
|
-
await createBranch(tempDir, "agency
|
|
74
|
+
await createBranch(tempDir, "agency--main")
|
|
75
75
|
await createCommit(tempDir, "Work on source")
|
|
76
76
|
|
|
77
|
-
// We're on agency
|
|
77
|
+
// We're on agency--main (source), switch to main (emit)
|
|
78
78
|
// Run switch command
|
|
79
79
|
await runTestEffect(switchBranch({ silent: true }))
|
|
80
80
|
|
|
@@ -85,13 +85,13 @@ describe("switch command", () => {
|
|
|
85
85
|
|
|
86
86
|
test("toggles back and forth", async () => {
|
|
87
87
|
// Create source and emit branches
|
|
88
|
-
await createBranch(tempDir, "agency
|
|
88
|
+
await createBranch(tempDir, "agency--main")
|
|
89
89
|
await createCommit(tempDir, "Work on source")
|
|
90
90
|
await checkoutBranch(tempDir, "main") // Go to emit
|
|
91
91
|
|
|
92
92
|
// Switch to source
|
|
93
93
|
await runTestEffect(switchBranch({ silent: true }))
|
|
94
|
-
expect(await getCurrentBranch(tempDir)).toBe("agency
|
|
94
|
+
expect(await getCurrentBranch(tempDir)).toBe("agency--main")
|
|
95
95
|
|
|
96
96
|
// Switch back to emit
|
|
97
97
|
await runTestEffect(switchBranch({ silent: true }))
|
|
@@ -99,7 +99,7 @@ describe("switch command", () => {
|
|
|
99
99
|
|
|
100
100
|
// And back to source
|
|
101
101
|
await runTestEffect(switchBranch({ silent: true }))
|
|
102
|
-
expect(await getCurrentBranch(tempDir)).toBe("agency
|
|
102
|
+
expect(await getCurrentBranch(tempDir)).toBe("agency--main")
|
|
103
103
|
})
|
|
104
104
|
|
|
105
105
|
test("works with custom emit branch pattern", async () => {
|
|
@@ -108,24 +108,24 @@ describe("switch command", () => {
|
|
|
108
108
|
await Bun.write(
|
|
109
109
|
configPath,
|
|
110
110
|
JSON.stringify({
|
|
111
|
-
sourceBranchPattern: "agency
|
|
112
|
-
emitBranch: "PR
|
|
111
|
+
sourceBranchPattern: "agency--%branch%",
|
|
112
|
+
emitBranch: "PR--%branch%",
|
|
113
113
|
}),
|
|
114
114
|
)
|
|
115
115
|
process.env.AGENCY_CONFIG_PATH = configPath
|
|
116
116
|
|
|
117
117
|
// Create source branch and its emit branch
|
|
118
|
-
await createBranch(tempDir, "agency
|
|
118
|
+
await createBranch(tempDir, "agency--feature")
|
|
119
119
|
await createCommit(tempDir, "Feature work")
|
|
120
|
-
await createBranch(tempDir, "PR
|
|
120
|
+
await createBranch(tempDir, "PR--feature")
|
|
121
121
|
|
|
122
122
|
// Switch to source
|
|
123
123
|
await runTestEffect(switchBranch({ silent: true }))
|
|
124
|
-
expect(await getCurrentBranch(tempDir)).toBe("agency
|
|
124
|
+
expect(await getCurrentBranch(tempDir)).toBe("agency--feature")
|
|
125
125
|
|
|
126
126
|
// Switch back to emit
|
|
127
127
|
await runTestEffect(switchBranch({ silent: true }))
|
|
128
|
-
expect(await getCurrentBranch(tempDir)).toBe("PR
|
|
128
|
+
expect(await getCurrentBranch(tempDir)).toBe("PR--feature")
|
|
129
129
|
})
|
|
130
130
|
})
|
|
131
131
|
|
|
@@ -136,14 +136,14 @@ describe("switch command", () => {
|
|
|
136
136
|
await Bun.write(
|
|
137
137
|
configPath,
|
|
138
138
|
JSON.stringify({
|
|
139
|
-
sourceBranchPattern: "agency
|
|
139
|
+
sourceBranchPattern: "agency--%branch%",
|
|
140
140
|
emitBranch: "%branch%--PR",
|
|
141
141
|
}),
|
|
142
142
|
)
|
|
143
143
|
process.env.AGENCY_CONFIG_PATH = configPath
|
|
144
144
|
|
|
145
145
|
// Create source branch, but not the emit branch
|
|
146
|
-
await createBranch(tempDir, "agency
|
|
146
|
+
await createBranch(tempDir, "agency--feature")
|
|
147
147
|
// feature--PR doesn't exist
|
|
148
148
|
|
|
149
149
|
await expect(
|
|
@@ -153,7 +153,7 @@ describe("switch command", () => {
|
|
|
153
153
|
|
|
154
154
|
test("throws error when emit branch doesn't exist", async () => {
|
|
155
155
|
// Create source branch but no emit branch
|
|
156
|
-
await createBranch(tempDir, "agency
|
|
156
|
+
await createBranch(tempDir, "agency--feature")
|
|
157
157
|
// We never created 'feature' (emit), so it doesn't exist
|
|
158
158
|
|
|
159
159
|
await expect(
|
|
@@ -175,7 +175,7 @@ describe("switch command", () => {
|
|
|
175
175
|
|
|
176
176
|
describe("silent mode", () => {
|
|
177
177
|
test("silent flag suppresses output", async () => {
|
|
178
|
-
await createBranch(tempDir, "agency
|
|
178
|
+
await createBranch(tempDir, "agency--main")
|
|
179
179
|
await checkoutBranch(tempDir, "main")
|
|
180
180
|
|
|
181
181
|
// Capture output
|
package/src/commands/switch.ts
CHANGED
|
@@ -66,13 +66,13 @@ Usage: agency switch [options]
|
|
|
66
66
|
Toggle between source branch and emit branch.
|
|
67
67
|
|
|
68
68
|
Source and Emit Branches:
|
|
69
|
-
- Source branches: Your working branches with agency-specific files (e.g., agency
|
|
69
|
+
- Source branches: Your working branches with agency-specific files (e.g., agency--main)
|
|
70
70
|
- Emit branches: Clean branches suitable for PRs without agency files (e.g., main)
|
|
71
71
|
|
|
72
72
|
This command intelligently switches between your source branch and its
|
|
73
73
|
corresponding emit branch:
|
|
74
|
-
- If on an emit branch (e.g., main), switches to source (agency
|
|
75
|
-
- If on a source branch (e.g., agency
|
|
74
|
+
- If on an emit branch (e.g., main), switches to source (agency--main)
|
|
75
|
+
- If on a source branch (e.g., agency--main), switches to emit branch (main)
|
|
76
76
|
|
|
77
77
|
Example:
|
|
78
78
|
agency switch # Toggle between branches
|
|
@@ -42,7 +42,7 @@ describe("task command - branching functionality", () => {
|
|
|
42
42
|
})
|
|
43
43
|
|
|
44
44
|
describe("--from flag", () => {
|
|
45
|
-
test("creates new agency
|
|
45
|
+
test("creates new agency--some-branch when using --from some-branch with explicit name", async () => {
|
|
46
46
|
await initGitRepo(tempDir)
|
|
47
47
|
process.chdir(tempDir)
|
|
48
48
|
await initAgency(tempDir, "test")
|
|
@@ -54,7 +54,7 @@ describe("task command - branching functionality", () => {
|
|
|
54
54
|
await runGitCommand(tempDir, ["git", "commit", "-m", "Add feature"])
|
|
55
55
|
|
|
56
56
|
// Run agency task my-feature --from some-branch
|
|
57
|
-
// This should create a NEW branch called agency
|
|
57
|
+
// This should create a NEW branch called agency--my-feature
|
|
58
58
|
await runTestEffect(
|
|
59
59
|
task({
|
|
60
60
|
silent: true,
|
|
@@ -64,7 +64,7 @@ describe("task command - branching functionality", () => {
|
|
|
64
64
|
)
|
|
65
65
|
|
|
66
66
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
67
|
-
expect(currentBranch).toBe("agency
|
|
67
|
+
expect(currentBranch).toBe("agency--my-feature")
|
|
68
68
|
|
|
69
69
|
// Verify feature.txt exists (came from some-branch)
|
|
70
70
|
const featureFile = await Bun.file(join(tempDir, "feature.txt")).text()
|
|
@@ -75,7 +75,7 @@ describe("task command - branching functionality", () => {
|
|
|
75
75
|
expect(taskMdExists).toBe(true)
|
|
76
76
|
})
|
|
77
77
|
|
|
78
|
-
test("throws error when agency
|
|
78
|
+
test("throws error when agency--some-branch already exists", async () => {
|
|
79
79
|
await initGitRepo(tempDir)
|
|
80
80
|
process.chdir(tempDir)
|
|
81
81
|
await initAgency(tempDir, "test")
|
|
@@ -86,7 +86,7 @@ describe("task command - branching functionality", () => {
|
|
|
86
86
|
await runGitCommand(tempDir, ["git", "add", "."])
|
|
87
87
|
await runGitCommand(tempDir, ["git", "commit", "-m", "Add feature"])
|
|
88
88
|
|
|
89
|
-
// Create agency
|
|
89
|
+
// Create agency--my-feature first
|
|
90
90
|
await runTestEffect(
|
|
91
91
|
task({
|
|
92
92
|
silent: true,
|
|
@@ -134,7 +134,7 @@ describe("task command - branching functionality", () => {
|
|
|
134
134
|
)
|
|
135
135
|
|
|
136
136
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
137
|
-
expect(currentBranch).toBe("agency
|
|
137
|
+
expect(currentBranch).toBe("agency--my-task")
|
|
138
138
|
|
|
139
139
|
// Verify feature.txt exists (came from feature-base)
|
|
140
140
|
const featureFile = await Bun.file(join(tempDir, "feature.txt")).text()
|
|
@@ -191,12 +191,12 @@ describe("task command - branching functionality", () => {
|
|
|
191
191
|
task({
|
|
192
192
|
silent: true,
|
|
193
193
|
emit: "second-task",
|
|
194
|
-
from: "agency
|
|
194
|
+
from: "agency--first-task",
|
|
195
195
|
}),
|
|
196
196
|
)
|
|
197
197
|
|
|
198
198
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
199
|
-
expect(currentBranch).toBe("agency
|
|
199
|
+
expect(currentBranch).toBe("agency--second-task")
|
|
200
200
|
|
|
201
201
|
// Verify first-task.txt exists (came from emit branch)
|
|
202
202
|
const firstTaskFile = await Bun.file(
|
|
@@ -234,7 +234,7 @@ describe("task command - branching functionality", () => {
|
|
|
234
234
|
task({
|
|
235
235
|
silent: true,
|
|
236
236
|
emit: "second-task",
|
|
237
|
-
from: "agency
|
|
237
|
+
from: "agency--unemitted-task",
|
|
238
238
|
}),
|
|
239
239
|
),
|
|
240
240
|
).rejects.toThrow("emit branch")
|
|
@@ -266,7 +266,7 @@ describe("task command - branching functionality", () => {
|
|
|
266
266
|
)
|
|
267
267
|
|
|
268
268
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
269
|
-
expect(currentBranch).toBe("agency
|
|
269
|
+
expect(currentBranch).toBe("agency--my-task")
|
|
270
270
|
|
|
271
271
|
// Verify current.txt exists
|
|
272
272
|
const currentFile = await Bun.file(join(tempDir, "current.txt")).text()
|
|
@@ -301,12 +301,12 @@ describe("task command - branching functionality", () => {
|
|
|
301
301
|
task({
|
|
302
302
|
silent: true,
|
|
303
303
|
emit: "second-task",
|
|
304
|
-
from: "agency
|
|
304
|
+
from: "agency--first-task",
|
|
305
305
|
}),
|
|
306
306
|
)
|
|
307
307
|
|
|
308
308
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
309
|
-
expect(currentBranch).toBe("agency
|
|
309
|
+
expect(currentBranch).toBe("agency--second-task")
|
|
310
310
|
|
|
311
311
|
// Verify first.txt exists
|
|
312
312
|
const firstFile = await Bun.file(join(tempDir, "first.txt")).text()
|
|
@@ -335,7 +335,7 @@ describe("task command - branching functionality", () => {
|
|
|
335
335
|
task({
|
|
336
336
|
silent: true,
|
|
337
337
|
emit: "second-task",
|
|
338
|
-
from: "agency
|
|
338
|
+
from: "agency--unemitted-task",
|
|
339
339
|
}),
|
|
340
340
|
),
|
|
341
341
|
).rejects.toThrow("emit branch")
|
|
@@ -380,7 +380,7 @@ describe("task command - branching functionality", () => {
|
|
|
380
380
|
).rejects.toThrow("Branch name")
|
|
381
381
|
})
|
|
382
382
|
|
|
383
|
-
test("agency task out --from foo creates agency
|
|
383
|
+
test("agency task out --from foo creates agency--out emitting to out", async () => {
|
|
384
384
|
await initGitRepo(tempDir)
|
|
385
385
|
process.chdir(tempDir)
|
|
386
386
|
await initAgency(tempDir, "test")
|
|
@@ -397,7 +397,7 @@ describe("task command - branching functionality", () => {
|
|
|
397
397
|
)
|
|
398
398
|
|
|
399
399
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
400
|
-
expect(currentBranch).toBe("agency
|
|
400
|
+
expect(currentBranch).toBe("agency--out")
|
|
401
401
|
|
|
402
402
|
const agencyJson = JSON.parse(
|
|
403
403
|
await Bun.file(join(tempDir, "agency.json")).text(),
|
|
@@ -435,7 +435,7 @@ describe("task command - branching functionality", () => {
|
|
|
435
435
|
)
|
|
436
436
|
|
|
437
437
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
438
|
-
expect(currentBranch).toBe("agency
|
|
438
|
+
expect(currentBranch).toBe("agency--my-task")
|
|
439
439
|
|
|
440
440
|
// Verify main.txt exists but other.txt does not
|
|
441
441
|
const mainExists = await Bun.file(join(tempDir, "main.txt")).exists()
|
|
@@ -532,7 +532,7 @@ describe("task command - branching functionality", () => {
|
|
|
532
532
|
)
|
|
533
533
|
|
|
534
534
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
535
|
-
expect(currentBranch).toBe("agency
|
|
535
|
+
expect(currentBranch).toBe("agency--my-task")
|
|
536
536
|
|
|
537
537
|
// The new branch should have remote-only.txt (from origin/main)
|
|
538
538
|
const remoteFileExists = await Bun.file(
|
|
@@ -585,7 +585,7 @@ describe("task command - branching functionality", () => {
|
|
|
585
585
|
)
|
|
586
586
|
|
|
587
587
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
588
|
-
expect(currentBranch).toBe("agency
|
|
588
|
+
expect(currentBranch).toBe("agency--my-task")
|
|
589
589
|
|
|
590
590
|
// The new branch should have local.txt
|
|
591
591
|
const localFileExists = await Bun.file(
|
|
@@ -627,7 +627,7 @@ describe("task command - branching functionality", () => {
|
|
|
627
627
|
)
|
|
628
628
|
|
|
629
629
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
630
|
-
expect(currentBranch).toBe("agency
|
|
630
|
+
expect(currentBranch).toBe("agency--my-task")
|
|
631
631
|
})
|
|
632
632
|
})
|
|
633
633
|
})
|
|
@@ -82,7 +82,7 @@ describe("task --continue", () => {
|
|
|
82
82
|
|
|
83
83
|
// Verify we're on the source branch
|
|
84
84
|
const originalBranch = await getCurrentBranch(tempDir)
|
|
85
|
-
expect(originalBranch).toBe("agency
|
|
85
|
+
expect(originalBranch).toBe("agency--original-feature")
|
|
86
86
|
|
|
87
87
|
// Read the original TASK.md
|
|
88
88
|
const originalTaskContent = await readFile(join(tempDir, "TASK.md"))
|
|
@@ -99,7 +99,7 @@ describe("task --continue", () => {
|
|
|
99
99
|
|
|
100
100
|
// Verify we're on the new branch
|
|
101
101
|
const newBranch = await getCurrentBranch(tempDir)
|
|
102
|
-
expect(newBranch).toBe("agency
|
|
102
|
+
expect(newBranch).toBe("agency--continued-feature")
|
|
103
103
|
|
|
104
104
|
// Verify agency files were copied
|
|
105
105
|
expect(await fileExists(join(tempDir, "agency.json"))).toBe(true)
|
|
@@ -148,7 +148,7 @@ describe("task --continue", () => {
|
|
|
148
148
|
await runTestEffect(task({ silent: true, emit: "feature-v1" }))
|
|
149
149
|
|
|
150
150
|
// Create another branch that would conflict
|
|
151
|
-
await Bun.spawn(["git", "branch", "agency
|
|
151
|
+
await Bun.spawn(["git", "branch", "agency--feature-v2"], {
|
|
152
152
|
cwd: tempDir,
|
|
153
153
|
stdout: "pipe",
|
|
154
154
|
stderr: "pipe",
|
|
@@ -705,7 +705,7 @@ describe("task command", () => {
|
|
|
705
705
|
})
|
|
706
706
|
await proc.exited
|
|
707
707
|
const currentBranch = await new Response(proc.stdout).text()
|
|
708
|
-
expect(currentBranch.trim()).toBe("agency
|
|
708
|
+
expect(currentBranch.trim()).toBe("agency--my-feature")
|
|
709
709
|
|
|
710
710
|
// Verify files were created
|
|
711
711
|
expect(await fileExists(join(tempDir, "AGENTS.md"))).toBe(true)
|
|
@@ -716,7 +716,7 @@ describe("task command", () => {
|
|
|
716
716
|
process.chdir(tempDir)
|
|
717
717
|
|
|
718
718
|
// Create a feature branch first (using source pattern)
|
|
719
|
-
await Bun.spawn(["git", "checkout", "-b", "agency
|
|
719
|
+
await Bun.spawn(["git", "checkout", "-b", "agency--existing-branch"], {
|
|
720
720
|
cwd: tempDir,
|
|
721
721
|
stdout: "pipe",
|
|
722
722
|
stderr: "pipe",
|
|
@@ -774,7 +774,7 @@ describe("task command", () => {
|
|
|
774
774
|
|
|
775
775
|
// Verify we're on the source branch with agency.json
|
|
776
776
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
777
|
-
expect(currentBranch).toBe("agency
|
|
777
|
+
expect(currentBranch).toBe("agency--original-feature")
|
|
778
778
|
expect(await fileExists(join(tempDir, "agency.json"))).toBe(true)
|
|
779
779
|
|
|
780
780
|
// Try to run agency task again without providing a branch name
|
|
@@ -795,7 +795,7 @@ describe("task command", () => {
|
|
|
795
795
|
|
|
796
796
|
// Verify we're on the source branch with agency.json
|
|
797
797
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
798
|
-
expect(currentBranch).toBe("agency
|
|
798
|
+
expect(currentBranch).toBe("agency--original-feature")
|
|
799
799
|
expect(await fileExists(join(tempDir, "agency.json"))).toBe(true)
|
|
800
800
|
|
|
801
801
|
// With a branch name provided, it should work
|
|
@@ -803,7 +803,7 @@ describe("task command", () => {
|
|
|
803
803
|
|
|
804
804
|
// Verify we're now on the new branch
|
|
805
805
|
const newBranch = await getCurrentBranch(tempDir)
|
|
806
|
-
expect(newBranch).toBe("agency
|
|
806
|
+
expect(newBranch).toBe("agency--new-feature")
|
|
807
807
|
})
|
|
808
808
|
})
|
|
809
809
|
|
|
@@ -931,9 +931,9 @@ describe("task command", () => {
|
|
|
931
931
|
}),
|
|
932
932
|
)
|
|
933
933
|
|
|
934
|
-
// Should have created the branch with agency
|
|
934
|
+
// Should have created the branch with agency-- prefix
|
|
935
935
|
const currentBranch = await getCurrentBranch(tempDir)
|
|
936
|
-
expect(currentBranch).toBe("agency
|
|
936
|
+
expect(currentBranch).toBe("agency--backward-compat-test")
|
|
937
937
|
|
|
938
938
|
// Should have correct emitBranch in agency.json
|
|
939
939
|
const metadata = JSON.parse(await readFile(join(tempDir, "agency.json")))
|
package/src/commands/task.ts
CHANGED
|
@@ -8,10 +8,8 @@ import { PromptService } from "../services/PromptService"
|
|
|
8
8
|
import { TemplateService } from "../services/TemplateService"
|
|
9
9
|
import { OpencodeService } from "../services/OpencodeService"
|
|
10
10
|
import { ClaudeService } from "../services/ClaudeService"
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
AgencyMetadataServiceLive,
|
|
14
|
-
} from "../services/AgencyMetadataService"
|
|
11
|
+
import { AgencyMetadataService } from "../services/AgencyMetadataService"
|
|
12
|
+
import { FormatterService } from "../services/FormatterService"
|
|
15
13
|
import { initializeManagedFiles, writeAgencyMetadata } from "../types"
|
|
16
14
|
import { RepositoryNotInitializedError } from "../errors"
|
|
17
15
|
import highlight, { done, info, plural } from "../utils/colors"
|
|
@@ -22,6 +20,7 @@ import {
|
|
|
22
20
|
makeSourceBranchName,
|
|
23
21
|
} from "../utils/pr-branch"
|
|
24
22
|
import { getTopLevelDir, dirToGlobPattern } from "../utils/glob"
|
|
23
|
+
import { AGENCY_REMOVE_COMMIT } from "../constants"
|
|
25
24
|
|
|
26
25
|
interface TaskOptions extends BaseCommandOptions {
|
|
27
26
|
path?: string
|
|
@@ -103,7 +102,7 @@ const taskContinue = (options: TaskOptions) =>
|
|
|
103
102
|
const existingMetadata = yield* Effect.gen(function* () {
|
|
104
103
|
const service = yield* AgencyMetadataService
|
|
105
104
|
return yield* service.readFromDisk(targetPath)
|
|
106
|
-
}).pipe(Effect.provide(
|
|
105
|
+
}).pipe(Effect.provide(AgencyMetadataService.Default))
|
|
107
106
|
|
|
108
107
|
if (!existingMetadata) {
|
|
109
108
|
return yield* Effect.fail(
|
|
@@ -279,6 +278,10 @@ const taskContinue = (options: TaskOptions) =>
|
|
|
279
278
|
log(done(`Created ${highlight.file(file)}`))
|
|
280
279
|
}
|
|
281
280
|
|
|
281
|
+
// Format created files using project's formatter (prettier/oxfmt)
|
|
282
|
+
const formatterService = yield* FormatterService
|
|
283
|
+
yield* formatterService.formatFiles(targetPath, createdFiles, verboseLog)
|
|
284
|
+
|
|
282
285
|
// Git add and commit the created files
|
|
283
286
|
if (createdFiles.length > 0) {
|
|
284
287
|
yield* Effect.gen(function* () {
|
|
@@ -819,6 +822,10 @@ export const task = (options: TaskOptions = {}) =>
|
|
|
819
822
|
}
|
|
820
823
|
verboseLog(`Tracked backpack file${plural(injectedFiles.length)}`)
|
|
821
824
|
|
|
825
|
+
// Format created files using project's formatter (prettier/oxfmt)
|
|
826
|
+
const formatterService = yield* FormatterService
|
|
827
|
+
yield* formatterService.formatFiles(targetPath, createdFiles, verboseLog)
|
|
828
|
+
|
|
822
829
|
// Git add and commit the created files
|
|
823
830
|
if (createdFiles.length > 0) {
|
|
824
831
|
yield* Effect.gen(function* () {
|
|
@@ -873,7 +880,7 @@ export const task = (options: TaskOptions = {}) =>
|
|
|
873
880
|
|
|
874
881
|
yield* git.gitAdd(filesToAdd, targetPath)
|
|
875
882
|
// The AGENCY_REMOVE_COMMIT marker in the commit body tells emit to drop this commit entirely
|
|
876
|
-
const commitMessage = `chore: agency edit CLAUDE.md\n\
|
|
883
|
+
const commitMessage = `chore: agency edit CLAUDE.md\n\n${AGENCY_REMOVE_COMMIT}`
|
|
877
884
|
yield* git.gitCommit(commitMessage, targetPath, {
|
|
878
885
|
noVerify: true,
|
|
879
886
|
})
|
|
@@ -1117,7 +1124,7 @@ Base Branch Selection:
|
|
|
1117
1124
|
- --from <branch>: Branch from a specific branch
|
|
1118
1125
|
- --from-current: Initialize on your current branch (no new branch created)
|
|
1119
1126
|
|
|
1120
|
-
If the base branch is an agency source branch (e.g., agency
|
|
1127
|
+
If the base branch is an agency source branch (e.g., agency--branch-A), the command
|
|
1121
1128
|
will automatically use its emit branch instead. This allows you to layer work on top
|
|
1122
1129
|
of other feature branches while maintaining clean branch history.
|
|
1123
1130
|
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared constants for the agency CLI tool.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Marker used in commit messages to indicate commits that should be
|
|
7
|
+
* dropped entirely during the emit process. When this marker is found
|
|
8
|
+
* in a commit message, emit will remove that commit from history.
|
|
9
|
+
*/
|
|
10
|
+
export const AGENCY_REMOVE_COMMIT = "AGENCY_REMOVE_COMMIT"
|
package/src/schemas.ts
CHANGED
|
@@ -27,7 +27,7 @@ export class AgencyMetadata extends Schema.Class<AgencyMetadata>(
|
|
|
27
27
|
*/
|
|
28
28
|
export class AgencyConfig extends Schema.Class<AgencyConfig>("AgencyConfig")({
|
|
29
29
|
sourceBranchPattern: Schema.String.pipe(
|
|
30
|
-
Schema.annotations({ default: "agency
|
|
30
|
+
Schema.annotations({ default: "agency--%branch%" }),
|
|
31
31
|
),
|
|
32
32
|
emitBranch: Schema.String.pipe(Schema.annotations({ default: "%branch%" })),
|
|
33
33
|
}) {}
|