@markjaquith/agency 1.8.6 → 1.8.7

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.8.6",
3
+ "version": "1.8.7",
4
4
  "description": "Manages personal agents files",
5
5
  "keywords": [
6
6
  "agents",
@@ -314,6 +314,50 @@ describe("push command", () => {
314
314
  expect(await getCurrentBranch(tempDir)).toBe("agency--feature")
315
315
  })
316
316
 
317
+ test("reports pre-push hook output without suggesting --force", async () => {
318
+ await Bun.spawn(
319
+ ["git", "config", "core.hooksPath", join(tempDir, ".git", "hooks")],
320
+ {
321
+ cwd: tempDir,
322
+ stdout: "pipe",
323
+ stderr: "pipe",
324
+ },
325
+ ).exited
326
+ const hookPath = join(tempDir, ".git", "hooks", "pre-push")
327
+ await Bun.write(
328
+ hookPath,
329
+ [
330
+ "#!/bin/sh",
331
+ "printf 'pre-push hook stdout failure\\n'",
332
+ "printf 'pre-push hook stderr failure\\n' >&2",
333
+ "exit 1",
334
+ "",
335
+ ].join("\n"),
336
+ )
337
+ await Bun.spawn(["chmod", "+x", hookPath], {
338
+ cwd: tempDir,
339
+ stdout: "pipe",
340
+ stderr: "pipe",
341
+ }).exited
342
+
343
+ let error: unknown
344
+ try {
345
+ await runTestEffect(
346
+ push({ baseBranch: "main", silent: true, skipFilter: true }),
347
+ )
348
+ } catch (caught) {
349
+ error = caught
350
+ }
351
+
352
+ expect(error).toBeInstanceOf(Error)
353
+ const message = error instanceof Error ? error.message : String(error)
354
+ expect(message).toContain("pre-push hook stdout failure")
355
+ expect(message).toContain("pre-push hook stderr failure")
356
+ expect(message).not.toContain("agency push --force")
357
+
358
+ expect(await getCurrentBranch(tempDir)).toBe("agency--feature")
359
+ })
360
+
317
361
  test("does not report force push when --force is provided but not needed", async () => {
318
362
  // Capture output to check for force push message
319
363
  const originalLog = console.log
@@ -44,15 +44,21 @@ const getPushFailureStderr = (error: unknown): string => {
44
44
  return String(error).trim()
45
45
  }
46
46
 
47
+ const formatProcessOutput = (result: {
48
+ readonly stdout?: string
49
+ readonly stderr?: string
50
+ }): string => [result.stdout, result.stderr].filter(Boolean).join("\n").trim()
51
+
47
52
  const pushFailureNeedsForce = (stderr: string): boolean => {
48
53
  const normalized = stderr.toLowerCase()
49
54
 
50
- return [
51
- "non-fast-forward",
52
- "updates were rejected because the tip of your current branch is behind",
53
- "fetch first",
54
- "failed to push some refs",
55
- ].some((pattern) => normalized.includes(pattern))
55
+ return (
56
+ normalized.includes("non-fast-forward") ||
57
+ normalized.includes(
58
+ "updates were rejected because the tip of your current branch is behind",
59
+ ) ||
60
+ (normalized.includes("[rejected]") && normalized.includes("fetch first"))
61
+ )
56
62
  }
57
63
 
58
64
  const formatPushFailure = (error: unknown): Error => {
@@ -261,7 +267,7 @@ const pushBranchToRemoteEffect = (
261
267
 
262
268
  // If push failed, check if we should retry with --force
263
269
  if (pushResult.exitCode !== 0) {
264
- const stderr = pushResult.stderr
270
+ const stderr = formatProcessOutput(pushResult)
265
271
 
266
272
  // Check if this is a force-push-needed error
267
273
  const needsForce = pushFailureNeedsForce(stderr)
@@ -283,7 +289,7 @@ const pushBranchToRemoteEffect = (
283
289
  if (forceResult.exitCode !== 0) {
284
290
  return yield* Effect.fail(
285
291
  new Error(
286
- `Failed to force push branch to remote: ${forceResult.stderr}`,
292
+ `Failed to force push branch to remote: ${formatProcessOutput(forceResult)}`,
287
293
  ),
288
294
  )
289
295
  }