@markjaquith/agency 2.71.21 → 2.71.23

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": "2.71.21",
3
+ "version": "2.71.23",
4
4
  "description": "Manage agentic work across repositories with durable workbases",
5
5
  "keywords": [
6
6
  "agents",
@@ -83,10 +83,12 @@
83
83
  "benchmark:graph": "bun scripts/benchmark-graph.ts",
84
84
  "benchmark:push": "bun scripts/benchmark-push.ts",
85
85
  "benchmark:archive": "bun scripts/benchmark-archive.ts",
86
+ "benchmark:vcs": "bun scripts/benchmark-vcs.ts",
86
87
  "benchmark:sync": "bun scripts/benchmark-sync.ts",
87
88
  "benchmark:task": "bun scripts/benchmark-task.ts",
88
89
  "benchmark:validate": "bun scripts/benchmark-validate.ts",
89
90
  "benchmark:worktree": "bun scripts/benchmark-worktree.ts",
91
+ "benchmark:review": "bun scripts/benchmark-review.ts",
90
92
  "test": "find src \\( -name '*.test.ts' -o -name '*.test.tsx' \\) -print0 | xargs -0 -n 1 -P 4 bun test",
91
93
  "test:opencode": "AGENCY_TEST_OPENCODE=1 bun test src/cli.test.ts --test-name-pattern 'provides effective whole-workbase OpenCode access'",
92
94
  "format": "oxfmt",
@@ -23,7 +23,10 @@ import {
23
23
  runLifecycleTransaction,
24
24
  type TransactionStep,
25
25
  } from "./LifecycleTransaction"
26
- import { RevisionConflictError } from "../workbase/document-revision"
26
+ import {
27
+ documentRevision,
28
+ RevisionConflictError,
29
+ } from "../workbase/document-revision"
27
30
  import {
28
31
  formatMarkdownDocument,
29
32
  parseFrontmatter,
@@ -359,24 +362,33 @@ export class ReviewService extends Effect.Service<ReviewService>()(
359
362
  message: `Cannot refresh review task '${taskId}'; its checkout is dirty or structurally unexpected`,
360
363
  })
361
364
  }
362
- const latest = yield* service.resolve(
365
+ const repository = yield* repositories.show(
363
366
  task.data.review.repo,
364
- task.data.review.source.kind === "pull-request"
365
- ? { pullRequest: task.data.review.source.url }
366
- : { ref: task.data.review.source.ref },
367
367
  root,
368
368
  )
369
+ if (!repository.remote || repository.states.includes("missing")) {
370
+ return yield* new ReviewError({
371
+ message: `Repository alias '${task.data.review.repo}' must be materialized with an origin remote`,
372
+ })
373
+ }
374
+ const versionControl = yield* VersionControlService
375
+ const backend = yield* versionControl.forWorkbase(root)
376
+ const latest = {
377
+ ...task.data.review,
378
+ commit: yield* fetchCommit(
379
+ repository.path,
380
+ task.data.review.source.kind === "pull-request"
381
+ ? task.data.review.source.fetchRef
382
+ : task.data.review.source.ref,
383
+ backend,
384
+ ),
385
+ refreshedAt: new Date().toISOString(),
386
+ } satisfies ReviewRecord
369
387
  const parsed = yield* parseFrontmatter(task.content, task.path)
370
388
  const content = formatMarkdownDocument(
371
389
  { ...task.data, review: latest },
372
390
  parsed.body,
373
391
  )
374
- const repository = yield* repositories.show(
375
- task.data.review.repo,
376
- root,
377
- )
378
- const versionControl = yield* VersionControlService
379
- const backend = yield* versionControl.forWorkbase(root)
380
392
  const gitEnvironment = yield* backend.gitEnvironment(
381
393
  repository.path,
382
394
  )
@@ -456,7 +468,7 @@ export class ReviewService extends Effect.Service<ReviewService>()(
456
468
  commit: latest.commit,
457
469
  changed: latest.commit !== task.data.review.commit,
458
470
  refreshedAt: latest.refreshedAt,
459
- revision: (yield* tasks.show(taskId, root)).revision,
471
+ revision: documentRevision(content),
460
472
  }
461
473
  }),
462
474
  )
@@ -594,12 +594,13 @@ export class TaskService extends Effect.Service<TaskService>()("TaskService", {
594
594
  }
595
595
  const content = yield* fs.readFile(path)
596
596
  const parsed = yield* parseFrontmatter(content, path)
597
+ const data: TaskData = yield* decodeTask(parsed.data)
597
598
  return {
598
599
  id: validId,
599
600
  path,
600
601
  content,
601
602
  revision: documentRevision(content),
602
- data: yield* decodeTask(parsed.data),
603
+ data,
603
604
  } satisfies TaskRecord
604
605
  }),
605
606
 
@@ -263,15 +263,24 @@ const inspectMigration = (startPath: string, requestedTarget?: VcsKind) =>
263
263
  const repositoryRecords = yield* repositories.list(root)
264
264
  const repositoryPlans: RepositoryPlan[] = []
265
265
  const repositoryStatus: MigrationState["repositories"][number][] = []
266
- for (const repository of repositoryRecords) {
267
- const initialized = yield* fs.exists(
268
- join(
269
- repository.kind === "symlink"
270
- ? yield* fs.realPath(repository.path)
271
- : repository.path,
272
- ".jj",
273
- ),
274
- )
266
+ const repositoryInspections = yield* Effect.forEach(
267
+ repositoryRecords,
268
+ (repository) =>
269
+ Effect.gen(function* () {
270
+ const targetPath =
271
+ repository.kind === "symlink"
272
+ ? yield* fs.realPath(repository.path)
273
+ : repository.path
274
+ const initialized = yield* fs.exists(join(targetPath, ".jj"))
275
+ return { repository, initialized, targetPath }
276
+ }),
277
+ { concurrency: 8 },
278
+ )
279
+ for (const {
280
+ repository,
281
+ initialized,
282
+ targetPath,
283
+ } of repositoryInspections) {
275
284
  repositoryStatus.push({
276
285
  alias: repository.alias,
277
286
  path: repository.path,
@@ -297,10 +306,6 @@ const inspectMigration = (startPath: string, requestedTarget?: VcsKind) =>
297
306
  message: `Repository '${repository.alias}' is not initialized for the configured jj backend`,
298
307
  })
299
308
  }
300
- const targetPath =
301
- repository.kind === "symlink"
302
- ? yield* fs.realPath(repository.path)
303
- : repository.path
304
309
  repositoryPlans.push({
305
310
  alias: repository.alias,
306
311
  path: repository.path,
@@ -353,6 +358,23 @@ const inspectMigration = (startPath: string, requestedTarget?: VcsKind) =>
353
358
  }
354
359
 
355
360
  const workspacePlans: WorkspacePlan[] = []
361
+ const sourceWorkspaces = new Map<
362
+ string,
363
+ Effect.Effect<
364
+ readonly import("./VersionControlService").RegisteredWorkspace[],
365
+ unknown,
366
+ any
367
+ >
368
+ >()
369
+ const listSourceWorkspaces = (repositoryPath: string) => {
370
+ const existing = sourceWorkspaces.get(repositoryPath)
371
+ if (existing) return existing
372
+ const workspaces = sourceBackend
373
+ .listWorkspaces(repositoryPath)
374
+ .pipe(Effect.cached, Effect.flatten)
375
+ sourceWorkspaces.set(repositoryPath, workspaces)
376
+ return workspaces
377
+ }
356
378
  const inspected = yield* Effect.either(
357
379
  worktrees.list(root, {
358
380
  materializedOnly: !blockers.some(
@@ -400,7 +422,7 @@ const inspectMigration = (startPath: string, requestedTarget?: VcsKind) =>
400
422
  }
401
423
  const sourceName =
402
424
  source !== target && source === "jj"
403
- ? ((yield* sourceBackend.listWorkspaces(
425
+ ? ((yield* listSourceWorkspaces(
404
426
  join(root, "repos", checkout.repo),
405
427
  )).find((item) => item.path === checkout.registeredPath)
406
428
  ?.name ?? null)