@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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markjaquith/agency",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Manages personal agents files",
5
5
  "license": "MIT",
6
6
  "author": "Mark Jaquith",
@@ -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
+ `
@@ -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, best-effort switch back to source branch
157
- try {
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
- // Verify we're still on the source branch (emit() now stays on source branch)
193
- // Verify we're still on the source branch (best-effort)
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