@markjaquith/agency 1.9.2 → 1.9.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markjaquith/agency",
3
- "version": "1.9.2",
3
+ "version": "1.9.4",
4
4
  "description": "Manages personal agents files",
5
5
  "keywords": [
6
6
  "agents",
@@ -125,6 +125,50 @@ describe("emit command", () => {
125
125
  expect(currentBranch).toBe("agency--feature")
126
126
  })
127
127
 
128
+ test("sets emit branch upstream when remote branch exists", async () => {
129
+ await checkoutBranch(tempDir, "main")
130
+ await createBranch(tempDir, "agency--feature")
131
+ await Bun.write(
132
+ join(tempDir, "agency.json"),
133
+ JSON.stringify({
134
+ version: 1,
135
+ injectedFiles: ["AGENTS.md"],
136
+ template: "test",
137
+ createdAt: new Date().toISOString(),
138
+ }),
139
+ )
140
+ await addAndCommit(tempDir, "agency.json", "Feature commit")
141
+
142
+ await getGitOutput(tempDir, [
143
+ "update-ref",
144
+ "refs/remotes/origin/feature",
145
+ "HEAD",
146
+ ])
147
+
148
+ await runTestEffect(emit({ silent: true, skipFilter: true }))
149
+
150
+ const remote = await getGitOutput(tempDir, [
151
+ "config",
152
+ "--get",
153
+ "branch.feature.remote",
154
+ ])
155
+ const merge = await getGitOutput(tempDir, [
156
+ "config",
157
+ "--get",
158
+ "branch.feature.merge",
159
+ ])
160
+ expect(remote.trim()).toBe("origin")
161
+ expect(merge.trim()).toBe("refs/heads/feature")
162
+
163
+ await checkoutBranch(tempDir, "feature")
164
+ const pushRef = await getGitOutput(tempDir, [
165
+ "rev-parse",
166
+ "--abbrev-ref",
167
+ "@{push}",
168
+ ])
169
+ expect(pushRef.trim()).toBe("origin/feature")
170
+ })
171
+
128
172
  test("creates emit branch with custom name", async () => {
129
173
  await createBranch(tempDir, "agency--feature")
130
174
  await createCommit(tempDir, "Feature commit")
@@ -158,9 +158,7 @@ export const emitCore = (gitRoot: string, options: EmitOptions) =>
158
158
  )
159
159
  branchExisted = existed
160
160
 
161
- // Unset any remote tracking branch for the emit branch
162
- yield* git.unsetGitConfig(`branch.${emitBranchName}.remote`, gitRoot)
163
- yield* git.unsetGitConfig(`branch.${emitBranchName}.merge`, gitRoot)
161
+ yield* configureEmitBranchTracking(gitRoot, emitBranchName, verboseLog)
164
162
  })
165
163
 
166
164
  yield* withSpinner(createBranch, {
@@ -435,6 +433,48 @@ const getFilterRepoStateDir = (gitRoot: string) =>
435
433
  return resolveGitInternalPath(gitRoot, gitPath)
436
434
  })
437
435
 
436
+ const configureEmitBranchTracking = (
437
+ gitRoot: string,
438
+ emitBranchName: string,
439
+ verboseLog: (message: string) => void,
440
+ ) =>
441
+ Effect.gen(function* () {
442
+ const git = yield* GitService
443
+ const remote = yield* git.resolveRemote(gitRoot).pipe(Effect.option)
444
+
445
+ if (remote._tag === "None") {
446
+ yield* git.unsetGitConfig(`branch.${emitBranchName}.remote`, gitRoot)
447
+ yield* git.unsetGitConfig(`branch.${emitBranchName}.merge`, gitRoot)
448
+ return
449
+ }
450
+
451
+ const remoteBranch = `${remote.value}/${emitBranchName}`
452
+ const remoteBranchExists = yield* git.branchExists(gitRoot, remoteBranch)
453
+
454
+ if (!remoteBranchExists) {
455
+ yield* git.unsetGitConfig(`branch.${emitBranchName}.remote`, gitRoot)
456
+ yield* git.unsetGitConfig(`branch.${emitBranchName}.merge`, gitRoot)
457
+ verboseLog(
458
+ `No existing remote branch ${highlight.branch(remoteBranch)}; leaving ${highlight.branch(emitBranchName)} without upstream`,
459
+ )
460
+ return
461
+ }
462
+
463
+ yield* git.setGitConfig(
464
+ `branch.${emitBranchName}.remote`,
465
+ remote.value,
466
+ gitRoot,
467
+ )
468
+ yield* git.setGitConfig(
469
+ `branch.${emitBranchName}.merge`,
470
+ `refs/heads/${emitBranchName}`,
471
+ gitRoot,
472
+ )
473
+ verboseLog(
474
+ `Set ${highlight.branch(emitBranchName)} upstream to ${highlight.branch(remoteBranch)}`,
475
+ )
476
+ })
477
+
438
478
  /**
439
479
  * Find the best fork point by checking both local and remote tracking branches.
440
480
  *
@@ -115,6 +115,39 @@ describe("push command", () => {
115
115
  expect(remoteBranches).toContain("feature")
116
116
  })
117
117
 
118
+ test("forwards verbose output from emit step", async () => {
119
+ const originalLog = console.log
120
+ const logMessages: string[] = []
121
+ console.log = (msg: string) => {
122
+ logMessages.push(msg)
123
+ }
124
+
125
+ try {
126
+ await runTestEffect(
127
+ push({
128
+ baseBranch: "main",
129
+ verbose: true,
130
+ skipFilter: true,
131
+ }),
132
+ )
133
+ } finally {
134
+ console.log = originalLog
135
+ }
136
+
137
+ expect(logMessages).toContain("Step 1: Emitting...")
138
+ expect(
139
+ logMessages.some(
140
+ (msg) => msg.includes("Using base branch:") && msg.includes("main"),
141
+ ),
142
+ ).toBe(true)
143
+ expect(
144
+ logMessages.some((msg) =>
145
+ msg.includes("Skipping git-filter-repo (skipFilter=true)"),
146
+ ),
147
+ ).toBe(true)
148
+ expect(logMessages.some((msg) => msg.includes("Emitted"))).toBe(true)
149
+ })
150
+
118
151
  test("works with custom branch name", async () => {
119
152
  await runTestEffect(
120
153
  push({
@@ -122,41 +122,36 @@ const pushCore = (gitRoot: string, options: PushOptions) =>
122
122
  verboseLog(`Starting push workflow from ${highlight.branch(sourceBranch)}`)
123
123
 
124
124
  // Step 1: Create emit branch (agency emit)
125
- let emitHadIgnorableFailure = false
126
-
127
- if (!options.skipFilter) {
128
- verboseLog("Step 1: Emitting...")
129
- // Use emit command - prefer emit option, fallback to branch for backward compatibility
130
- const prEffectWithOptions = emit({
131
- baseBranch: options.baseBranch,
132
- emit: options.emit || options.branch,
133
- silent: true, // Suppress emit command output, we'll provide our own
134
- force: options.force,
135
- verbose: options.verbose,
136
- skipFilter: options.skipFilter,
137
- })
138
-
139
- const prResult = yield* Effect.either(prEffectWithOptions)
140
- if (Either.isLeft(prResult)) {
141
- const error =
142
- prResult.left instanceof Error
143
- ? prResult.left
144
- : new Error(String(prResult.left))
145
- const message = error.message || ""
146
- const ignorable =
147
- message === "" ||
148
- message.includes("already exists") ||
149
- message.includes("check if branch exists")
150
-
151
- if (!ignorable) {
152
- return yield* Effect.fail(
153
- new Error(`Failed to create emit branch: ${message}`),
154
- )
155
- }
156
-
157
- emitHadIgnorableFailure = true
158
- verboseLog("Emit reported existing branch; continuing")
125
+ verboseLog("Step 1: Emitting...")
126
+ // Use the emit command for the entire emit step so push and emit stay in sync.
127
+ const prEffectWithOptions = emit({
128
+ baseBranch: options.baseBranch,
129
+ emit: options.emit || options.branch,
130
+ silent: options.silent,
131
+ force: options.force,
132
+ verbose: options.verbose,
133
+ skipFilter: options.skipFilter,
134
+ })
135
+
136
+ const prResult = yield* Effect.either(prEffectWithOptions)
137
+ if (Either.isLeft(prResult)) {
138
+ const error =
139
+ prResult.left instanceof Error
140
+ ? prResult.left
141
+ : new Error(String(prResult.left))
142
+ const message = error.message || ""
143
+ const ignorable =
144
+ message === "" ||
145
+ message.includes("already exists") ||
146
+ message.includes("check if branch exists")
147
+
148
+ if (!ignorable) {
149
+ return yield* Effect.fail(
150
+ new Error(`Failed to create emit branch: ${message}`),
151
+ )
159
152
  }
153
+
154
+ verboseLog("Emit reported existing branch; continuing")
160
155
  }
161
156
 
162
157
  // Compute the emit branch name (emit() command now stays on source branch)
@@ -164,15 +159,6 @@ const pushCore = (gitRoot: string, options: PushOptions) =>
164
159
  const emitBranchName =
165
160
  options.emit || options.branch || branchInfo.emitBranch
166
161
 
167
- // If skipFilter, we skipped emit() so we must create the emit branch manually
168
- if (options.skipFilter) {
169
- yield* git.createOrResetBranch(gitRoot, emitBranchName, sourceBranch)
170
- // Switch back to source branch for consistency
171
- yield* git.checkoutBranch(gitRoot, sourceBranch)
172
- }
173
-
174
- log(done(`Emitted ${highlight.branch(emitBranchName)}`))
175
-
176
162
  // Step 2: Push to remote (git push)
177
163
  const remote = yield* getRemoteName(gitRoot)
178
164
  verboseLog(