@markjaquith/agency 2.7.1 → 2.7.3

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.
@@ -60,6 +60,11 @@ const formatCommand = (args: readonly string[]) =>
60
60
  )
61
61
  .join(" ")
62
62
 
63
+ const isCommitId = (ref: string) => /^[0-9a-f]{40,64}$/i.test(ref)
64
+
65
+ const originRef = (ref: string) =>
66
+ ref.replace(/^refs\/remotes\/origin\//, "").replace(/^origin\//, "")
67
+
63
68
  export class WorktreeService extends Effect.Service<WorktreeService>()(
64
69
  "WorktreeService",
65
70
  {
@@ -80,12 +85,10 @@ export class WorktreeService extends Effect.Service<WorktreeService>()(
80
85
  options.verbose === true && !options.silent && !options.json
81
86
  const { root, config } = yield* workbase.loadConfig(startPath)
82
87
  const report = yield* workbase.validate(root)
83
- const ownershipIssue = report.issues.find((issue) =>
84
- issue.message.startsWith("Writable branch "),
85
- )
86
- if (ownershipIssue) {
88
+ const validationIssue = report.issues[0]
89
+ if (validationIssue) {
87
90
  return yield* new WorktreeError({
88
- message: `${ownershipIssue.path}: ${ownershipIssue.message}`,
91
+ message: `${validationIssue.path}: ${validationIssue.message}`,
89
92
  })
90
93
  }
91
94
  const task = yield* tasks.show(taskId, root)
@@ -136,23 +139,32 @@ export class WorktreeService extends Effect.Service<WorktreeService>()(
136
139
  })
137
140
  }
138
141
 
139
- const fetchOrigin = Effect.gen(function* () {
140
- const remote = yield* fs.runCommand(
141
- ["git", "-C", repositoryPath, "remote", "get-url", "origin"],
142
- { captureOutput: true },
143
- )
144
- if (remote.exitCode !== 0) return
142
+ const fetchOrigin = (ref?: string) =>
143
+ Effect.gen(function* () {
144
+ const remote = yield* fs.runCommand(
145
+ ["git", "-C", repositoryPath, "remote", "get-url", "origin"],
146
+ { captureOutput: true },
147
+ )
148
+ if (remote.exitCode !== 0) return false
145
149
 
146
- const fetch = yield* fs.runCommand(
147
- ["git", "-C", repositoryPath, "fetch", "origin"],
148
- { captureOutput: true },
149
- )
150
- if (fetch.exitCode !== 0) {
151
- return yield* new WorktreeError({
152
- message: `Failed to fetch '${alias}': ${fetch.stderr}`,
153
- })
154
- }
155
- })
150
+ const fetch = yield* fs.runCommand(
151
+ [
152
+ "git",
153
+ "-C",
154
+ repositoryPath,
155
+ "fetch",
156
+ "origin",
157
+ ...(ref ? [ref] : []),
158
+ ],
159
+ { captureOutput: true },
160
+ )
161
+ if (fetch.exitCode !== 0) {
162
+ return yield* new WorktreeError({
163
+ message: `Failed to fetch '${alias}': ${fetch.stderr}`,
164
+ })
165
+ }
166
+ return true
167
+ })
156
168
 
157
169
  const listed = yield* fs.runCommand(
158
170
  [
@@ -210,7 +222,7 @@ export class WorktreeService extends Effect.Service<WorktreeService>()(
210
222
  message: `Worktree registry contains a missing checkout at ${checkoutPath}`,
211
223
  })
212
224
  }
213
- yield* fetchOrigin
225
+ yield* fetchOrigin()
214
226
 
215
227
  let args: string[]
216
228
  let env: Record<string, string> | undefined
@@ -297,6 +309,10 @@ export class WorktreeService extends Effect.Service<WorktreeService>()(
297
309
  })
298
310
  }
299
311
  } else {
312
+ const fetched = isCommitId(checkout.ref)
313
+ ? false
314
+ : yield* fetchOrigin(originRef(checkout.ref))
315
+ const resolvedRefName = fetched ? "FETCH_HEAD" : checkout.ref
300
316
  const resolvedRef = yield* fs.runCommand(
301
317
  [
302
318
  "git",
@@ -304,7 +320,7 @@ export class WorktreeService extends Effect.Service<WorktreeService>()(
304
320
  repositoryPath,
305
321
  "rev-parse",
306
322
  "--verify",
307
- `${checkout.ref}^{commit}`,
323
+ `${resolvedRefName}^{commit}`,
308
324
  ],
309
325
  { captureOutput: true },
310
326
  )
@@ -344,7 +360,6 @@ export class WorktreeService extends Effect.Service<WorktreeService>()(
344
360
  message: `Worktree registry contains a missing checkout at ${checkoutPath}`,
345
361
  })
346
362
  }
347
- yield* fetchOrigin
348
363
  const result = yield* fs.runCommand(
349
364
  [
350
365
  "git",
@@ -5,6 +5,8 @@ export interface BaseCommandOptions {
5
5
  readonly silent?: boolean
6
6
  readonly verbose?: boolean
7
7
  readonly json?: boolean
8
+ /** Whether this invocation may open prompts or selectors. */
9
+ readonly inputAllowed?: boolean
8
10
  /**
9
11
  * Working directory to use instead of process.cwd().
10
12
  * Primarily used for testing to enable concurrent test execution.
@@ -34,6 +34,7 @@ export const resolveWorkbase = (
34
34
  startPath: string,
35
35
  log: (message: string) => void,
36
36
  pick: PickWorkbase = pickWorkbase,
37
+ inputAllowed = true,
37
38
  ) =>
38
39
  Effect.gen(function* () {
39
40
  const fs = yield* FileSystemService
@@ -50,6 +51,13 @@ export const resolveWorkbase = (
50
51
  ),
51
52
  )
52
53
  }
54
+ if (!inputAllowed) {
55
+ return yield* Effect.fail(
56
+ new Error(
57
+ "Workbase selection requires interactive input; provide an explicit path or run Agency from a workbase",
58
+ ),
59
+ )
60
+ }
53
61
 
54
62
  const fzf = yield* fs.runCommand(["which", "fzf"], {
55
63
  captureOutput: true,