@markjaquith/agency 1.1.0 → 1.2.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 +20 -0
- package/package.json +1 -1
- package/src/commands/pr.ts +77 -0
- package/src/commands/push.ts +8 -12
package/cli.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { task, taskEdit, help as taskHelp, editHelp } from "./src/commands/task"
|
|
|
8
8
|
import { tasks, help as tasksHelp } from "./src/commands/tasks"
|
|
9
9
|
import { emit, help as emitHelp } from "./src/commands/emit"
|
|
10
10
|
import { emitted, help as emittedHelp } from "./src/commands/emitted"
|
|
11
|
+
import { pr, help as prHelp } from "./src/commands/pr"
|
|
11
12
|
import { push, help as pushHelp } from "./src/commands/push"
|
|
12
13
|
import { pull, help as pullHelp } from "./src/commands/pull"
|
|
13
14
|
import { rebase, help as rebaseHelp } from "./src/commands/rebase"
|
|
@@ -118,6 +119,24 @@ const commands: Record<string, Command> = {
|
|
|
118
119
|
},
|
|
119
120
|
help: emittedHelp,
|
|
120
121
|
},
|
|
122
|
+
pr: {
|
|
123
|
+
name: "pr",
|
|
124
|
+
description: "Run gh pr with the emitted branch name",
|
|
125
|
+
run: async (args: string[], options: Record<string, any>) => {
|
|
126
|
+
if (options.help) {
|
|
127
|
+
console.log(prHelp)
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
await runCommand(
|
|
131
|
+
pr({
|
|
132
|
+
args,
|
|
133
|
+
silent: options.silent,
|
|
134
|
+
verbose: options.verbose,
|
|
135
|
+
}),
|
|
136
|
+
)
|
|
137
|
+
},
|
|
138
|
+
help: prHelp,
|
|
139
|
+
},
|
|
121
140
|
push: {
|
|
122
141
|
name: "push",
|
|
123
142
|
description: "Emit, push to remote, return to source",
|
|
@@ -428,6 +447,7 @@ Commands:
|
|
|
428
447
|
delete <file> ... Delete files from configured template
|
|
429
448
|
emit [base-branch] Emit a branch with backpack files reverted
|
|
430
449
|
emitted Get the name of the emitted branch
|
|
450
|
+
pr <subcommand> Run gh pr with the emitted branch name
|
|
431
451
|
push [base-branch] Emit, push to remote, return to source
|
|
432
452
|
pull Pull commits from remote emit branch to source
|
|
433
453
|
rebase [base-branch] Rebase source branch onto base branch
|
package/package.json
CHANGED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Effect } from "effect"
|
|
2
|
+
import type { BaseCommandOptions } from "../utils/command"
|
|
3
|
+
import { GitService } from "../services/GitService"
|
|
4
|
+
import { ConfigService } from "../services/ConfigService"
|
|
5
|
+
import { resolveBranchPairWithAgencyJson } from "../utils/pr-branch"
|
|
6
|
+
import { ensureGitRepo } from "../utils/effect"
|
|
7
|
+
|
|
8
|
+
interface PrOptions extends BaseCommandOptions {
|
|
9
|
+
/** Arguments to pass to gh pr (subcommand and flags) */
|
|
10
|
+
args: string[]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const pr = (options: PrOptions) =>
|
|
14
|
+
Effect.gen(function* () {
|
|
15
|
+
const git = yield* GitService
|
|
16
|
+
const configService = yield* ConfigService
|
|
17
|
+
|
|
18
|
+
const gitRoot = yield* ensureGitRepo()
|
|
19
|
+
|
|
20
|
+
// Load config
|
|
21
|
+
const config = yield* configService.loadConfig()
|
|
22
|
+
|
|
23
|
+
// Get current branch and resolve the branch pair
|
|
24
|
+
const currentBranch = yield* git.getCurrentBranch(gitRoot)
|
|
25
|
+
const branches = yield* resolveBranchPairWithAgencyJson(
|
|
26
|
+
gitRoot,
|
|
27
|
+
currentBranch,
|
|
28
|
+
config.sourceBranchPattern,
|
|
29
|
+
config.emitBranch,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
// Build the gh pr command with the emit branch
|
|
33
|
+
const ghArgs = ["gh", "pr", ...options.args, branches.emitBranch]
|
|
34
|
+
|
|
35
|
+
// Run gh pr with stdio inherited so output goes directly to terminal
|
|
36
|
+
const exitCode = yield* Effect.tryPromise({
|
|
37
|
+
try: async () => {
|
|
38
|
+
const proc = Bun.spawn(ghArgs, {
|
|
39
|
+
cwd: gitRoot,
|
|
40
|
+
stdin: "inherit",
|
|
41
|
+
stdout: "inherit",
|
|
42
|
+
stderr: "inherit",
|
|
43
|
+
})
|
|
44
|
+
return proc.exited
|
|
45
|
+
},
|
|
46
|
+
catch: (error) =>
|
|
47
|
+
new Error(
|
|
48
|
+
`Failed to run gh pr: ${error instanceof Error ? error.message : String(error)}`,
|
|
49
|
+
),
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
if (exitCode !== 0) {
|
|
53
|
+
return yield* Effect.fail(
|
|
54
|
+
new Error(`gh pr command exited with code ${exitCode}`),
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
export const help = `
|
|
60
|
+
Usage: agency pr <subcommand> [flags]
|
|
61
|
+
|
|
62
|
+
Wrapper for 'gh pr' that automatically appends the emitted branch name.
|
|
63
|
+
|
|
64
|
+
This command passes all arguments to 'gh pr' with the emitted branch name
|
|
65
|
+
appended, making it easy to work with PRs for your feature branch without
|
|
66
|
+
needing to remember or type the emit branch name.
|
|
67
|
+
|
|
68
|
+
Examples:
|
|
69
|
+
agency pr view --web # gh pr view --web <emit-branch>
|
|
70
|
+
agency pr checks # gh pr checks <emit-branch>
|
|
71
|
+
agency pr status # gh pr status <emit-branch>
|
|
72
|
+
|
|
73
|
+
Notes:
|
|
74
|
+
- Requires gh CLI to be installed and authenticated
|
|
75
|
+
- Uses source and emit patterns from ~/.config/agency/agency.json
|
|
76
|
+
- Respects emitBranch field in agency.json when present
|
|
77
|
+
`
|
package/src/commands/push.ts
CHANGED
|
@@ -137,6 +137,10 @@ const pushCore = (gitRoot: string, options: PushOptions) =>
|
|
|
137
137
|
`Step 2: Pushing ${highlight.branch(emitBranchName)} to ${highlight.remote(remote)}...`,
|
|
138
138
|
)
|
|
139
139
|
|
|
140
|
+
// Switch to emit branch before pushing so that pre-push hooks run
|
|
141
|
+
// in the context of the emit branch (without backpack files)
|
|
142
|
+
yield* git.checkoutBranch(gitRoot, emitBranchName)
|
|
143
|
+
|
|
140
144
|
const pushEither = yield* Effect.either(
|
|
141
145
|
withSpinner(
|
|
142
146
|
pushBranchToRemoteEffect(gitRoot, emitBranchName, remote, {
|
|
@@ -153,10 +157,8 @@ const pushCore = (gitRoot: string, options: PushOptions) =>
|
|
|
153
157
|
)
|
|
154
158
|
if (Either.isLeft(pushEither)) {
|
|
155
159
|
const error = pushEither.left
|
|
156
|
-
// If push failed,
|
|
157
|
-
|
|
158
|
-
yield* git.checkoutBranch(gitRoot, sourceBranch)
|
|
159
|
-
} catch {}
|
|
160
|
+
// If push failed, switch back to source branch
|
|
161
|
+
yield* git.checkoutBranch(gitRoot, sourceBranch)
|
|
160
162
|
return yield* Effect.fail(error)
|
|
161
163
|
}
|
|
162
164
|
|
|
@@ -189,14 +191,8 @@ const pushCore = (gitRoot: string, options: PushOptions) =>
|
|
|
189
191
|
}
|
|
190
192
|
}
|
|
191
193
|
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
try {
|
|
195
|
-
const finalBranch = yield* git.getCurrentBranch(gitRoot)
|
|
196
|
-
if (finalBranch !== sourceBranch) {
|
|
197
|
-
yield* git.checkoutBranch(gitRoot, sourceBranch)
|
|
198
|
-
}
|
|
199
|
-
} catch {}
|
|
194
|
+
// Switch back to source branch
|
|
195
|
+
yield* git.checkoutBranch(gitRoot, sourceBranch)
|
|
200
196
|
})
|
|
201
197
|
|
|
202
198
|
// Helper: Push branch to remote with optional force and retry logic
|