@gjermundgaraba/upup 0.4.0 → 0.5.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/dist/main.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as reason, t as openFlags } from "./io-BGJ4Yp7u.mjs";
2
+ import { n as openFlags, r as reason, t as byName } from "./io-ns6xhFdF.mjs";
3
3
  import { findPackageJSON } from "node:module";
4
4
  import { NodeRuntime, NodeServices, NodeStdio } from "@effect/platform-node";
5
5
  import { Cause, Clock, Config, Context, Data, Deferred, Duration, Effect, Equal, Exit, Fiber, FiberHandle, FiberSet, FileSystem, Layer, Option, Predicate, Queue, Ref, Result, Schedule, Schema, Semaphore, Stream, SubscriptionRef, identity } from "effect";
@@ -17,8 +17,7 @@ import { homedir, tmpdir } from "node:os";
17
17
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
18
18
  import lockfile from "proper-lockfile";
19
19
  import { BACKGROUND_CONTEXT, withAbortSignal } from "@earendil-works/chord/context";
20
- import { Type } from "@earendil-works/pi-ai";
21
- import { GenerationTask, Harness, ToolTask, createRegistry, defineDoc, defineExtension, defineTool, hook, section, watchEvents } from "@earendil-works/pi-durable";
20
+ import { GenerationTask, Harness, LiveDoc, ROOT_CONVERSATION_ID, ToolTask, createRegistry, defineDoc, defineExtension, defineTool, hook, section } from "@earendil-works/pi-durable";
22
21
  import { openNodeSqliteStorage } from "@earendil-works/pi-durable/storage/sqlite/node";
23
22
  import { ChildProcess, ChildProcessSpawner, CommandLine } from "effect/process";
24
23
  import { Worker } from "node:worker_threads";
@@ -43,7 +42,7 @@ import * as ActionMcp from "@gjermundgaraba/effect-actions/ActionMcp";
43
42
  import * as Action from "@gjermundgaraba/effect-actions/Action";
44
43
  import { setup, types } from "xstate/fsm";
45
44
  // package.json
46
- var version$1 = "0.4.0";
45
+ var version$1 = "0.5.0";
47
46
  // src/ai/Setup.ts
48
47
  const Thinking = Schema.Literals([
49
48
  "off",
@@ -427,12 +426,12 @@ const withTarget = (pkg, target) => ({
427
426
  target
428
427
  });
429
428
  const isUnaudited = Schema.is(UnauditedEcosystem);
430
- const isApp = Schema.is(AppEcosystem);
429
+ const isApp$1 = Schema.is(AppEcosystem);
431
430
  const isRuntime = Schema.is(RuntimeEcosystem);
432
431
  const isUnauditedUpdate = (pkg) => isUnaudited(pkg.ecosystem);
433
- const isAppUpdate = (pkg) => isApp(pkg.ecosystem);
432
+ const isAppUpdate = (pkg) => isApp$1(pkg.ecosystem);
434
433
  const unauditedKind = (pkg) => {
435
- if (isApp(pkg.ecosystem)) return "app";
434
+ if (isApp$1(pkg.ecosystem)) return "app";
436
435
  if (isRuntime(pkg.ecosystem)) return "runtime";
437
436
  if (isUnaudited(pkg.ecosystem)) return "os";
438
437
  };
@@ -753,15 +752,15 @@ const Severity = Schema.Literals([
753
752
  const Finding = Schema.Struct({
754
753
  severity: Severity,
755
754
  title: Schema.String,
756
- detail: Schema.String,
757
- paths: Schema.Array(Schema.String)
755
+ detail: Schema.String.annotate({ description: "Markdown: the evidence and why it matters." }),
756
+ paths: Schema.Array(Schema.String).annotate({ description: "Workspace paths, with line ranges where useful." })
758
757
  });
759
758
  const Report = Schema.Struct({
760
759
  verdict: Verdict,
761
- rationale: Schema.String,
762
- summary: Schema.String,
760
+ rationale: Schema.String.annotate({ description: "One concrete sentence justifying the verdict." }),
761
+ summary: Schema.String.annotate({ description: "Markdown: what the update changes that bears on the mandate, what you flagged and why you cleared or kept it." }),
763
762
  findings: Schema.Array(Finding),
764
- unverified: Schema.Array(Schema.String)
763
+ unverified: Schema.Array(Schema.String).annotate({ description: "Each thing you could not verify." })
765
764
  });
766
765
  Schema.Struct({
767
766
  mode: Mode,
@@ -844,21 +843,23 @@ const descriptions = {
844
843
  grep: "Find a JavaScript regular expression in UTF-8 regular files below a path. Each line is matched whole. Lines over 1 KiB show a bounded window around each match with its file byte offset; a file stops at a line over 16 MiB.",
845
844
  list: "List workspace entries below a directory to a bounded depth."
846
845
  };
847
- const parameters = {
848
- read: {
849
- path: "Workspace-relative file path.",
850
- offset: "Zero-based byte offset; must be >= 0.",
851
- limit: `Maximum bytes to return; must be between 1 and ${limits$1.readBytes} inclusive.`
852
- },
853
- grep: {
854
- path: "Workspace-relative file or directory path.",
855
- pattern: "JavaScript regular expression."
856
- },
857
- list: {
858
- path: "Workspace-relative directory path; use . for the root.",
859
- depth: `Maximum directory depth; must be between 1 and ${limits$1.listDepth} inclusive.`
860
- }
861
- };
846
+ const count$1 = (maximum) => Schema.Number.pipe(Schema.check(Schema.isInt(), Schema.isBetween({
847
+ minimum: 1,
848
+ maximum
849
+ })));
850
+ const ReadArgs = Schema.Struct({
851
+ path: Schema.String.annotate({ description: "Workspace-relative file path." }),
852
+ offset: Schema.Number.pipe(Schema.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(0))).annotate({ description: "Zero-based byte offset; must be >= 0." }),
853
+ limit: count$1(limits$1.readBytes).annotate({ description: `Maximum bytes to return; must be between 1 and ${limits$1.readBytes} inclusive.` })
854
+ });
855
+ const GrepArgs = Schema.Struct({
856
+ path: Schema.String.annotate({ description: "Workspace-relative file or directory path." }),
857
+ pattern: Schema.String.annotate({ description: "JavaScript regular expression." })
858
+ });
859
+ const ListArgs = Schema.Struct({
860
+ path: Schema.String.annotate({ description: "Workspace-relative directory path; use . for the root." }),
861
+ depth: count$1(limits$1.listDepth).annotate({ description: `Maximum directory depth; must be between 1 and ${limits$1.listDepth} inclusive.` })
862
+ });
862
863
  var ToolError = class extends Error {
863
864
  constructor(message) {
864
865
  super(message);
@@ -915,10 +916,6 @@ const locate$4 = async (workspace, name, context) => {
915
916
  return fail$1(`${context}: ${reason(error)}`);
916
917
  }
917
918
  };
918
- const byName = (left, right) => {
919
- if (left.name < right.name) return -1;
920
- return left.name > right.name ? 1 : 0;
921
- };
922
919
  const suffixOf = (entry) => {
923
920
  if (entry.isDirectory()) return "/";
924
921
  return entry.isSymbolicLink() ? "@" : "";
@@ -1344,17 +1341,11 @@ const runDiff = (cwd, args, from, to, input) => Effect.callback((resume) => {
1344
1341
  });
1345
1342
  return Effect.sync(() => child.kill());
1346
1343
  });
1347
- const regularFiles = async (root, relative = "") => {
1348
- const entries = await readdir(path.join(root, relative)).catch(() => []);
1349
- const found = [];
1350
- for (const name of entries.toSorted()) {
1351
- const file = relative === "" ? name : `${relative}/${name}`;
1352
- const info = await lstat(path.join(root, file));
1353
- if (info.isDirectory()) found.push(...await regularFiles(root, file));
1354
- else if (info.isFile()) found.push(file);
1355
- }
1356
- return found;
1357
- };
1344
+ const regularFiles = (root, relative = "") => Effect.promise(async () => await readdir(path.join(root, relative), { withFileTypes: true }).catch(() => [])).pipe(Effect.flatMap((entries) => Effect.forEach(entries.toSorted(byName), (entry) => {
1345
+ const file = relative === "" ? entry.name : `${relative}/${entry.name}`;
1346
+ if (entry.isDirectory()) return regularFiles(root, file);
1347
+ return Effect.succeed(entry.isFile() ? [file] : []);
1348
+ }, { concurrency: "unbounded" })), Effect.map((found) => found.flat()));
1358
1349
  const failure$1 = (from, to) => (cause) => new DiffFailed({
1359
1350
  from,
1360
1351
  to,
@@ -1372,15 +1363,25 @@ const plain$1 = (pair) => ({
1372
1363
  paired: false,
1373
1364
  rewritten: false
1374
1365
  });
1375
- const planTree = async (workspace, from, to) => {
1376
- const [before, after] = await Promise.all([regularFiles(path.join(workspace, from)), regularFiles(path.join(workspace, to))]);
1366
+ const planTree = (workspace, from, to) => Effect.gen(function* () {
1367
+ const attempt = (run) => Effect.tryPromise({
1368
+ try: run,
1369
+ catch: failure$1(from, to)
1370
+ });
1371
+ const [before, after] = yield* Effect.all([regularFiles(path.join(workspace, from)), regularFiles(path.join(workspace, to))], { concurrency: "unbounded" });
1377
1372
  const beforeSet = new Set(before);
1378
1373
  const afterSet = new Set(after);
1379
1374
  const fromOnly = before.filter((file) => !afterSet.has(file));
1380
1375
  const toOnly = after.filter((file) => !beforeSet.has(file));
1381
- const only = /* @__PURE__ */ new Map();
1382
- for (const file of fromOnly) only.set(`from\0${file}`, await readFile(path.join(workspace, from, file)));
1383
- for (const file of toOnly) only.set(`to\0${file}`, await readFile(path.join(workspace, to, file)));
1376
+ const only = new Map(yield* Effect.forEach([...fromOnly.map((file) => ({
1377
+ side: "from",
1378
+ root: from,
1379
+ file
1380
+ })), ...toOnly.map((file) => ({
1381
+ side: "to",
1382
+ root: to,
1383
+ file
1384
+ }))], ({ side, root, file }) => attempt(async () => [`${side}\0${file}`, await readFile(path.join(workspace, root, file))]), { concurrency: 8 }));
1384
1385
  const pairs = matchRenames(fromOnly, toOnly, (side, file) => only.get(`${side}\0${file}`) ?? Buffer.alloc(0));
1385
1386
  const renames = renamesOf(pairs);
1386
1387
  const pairedFrom = new Set(pairs.map((pair) => pair.from));
@@ -1391,32 +1392,36 @@ const planTree = async (workspace, from, to) => {
1391
1392
  from: file,
1392
1393
  to: file
1393
1394
  }))];
1394
- for (const pair of candidates) {
1395
+ const classify = async (pair) => {
1395
1396
  const oldPath = path.join(workspace, from, pair.from);
1396
1397
  const nextPath = path.join(workspace, to, pair.to);
1397
1398
  const paired = pair.from !== pair.to;
1398
- if (!paired && renames.size === 0) {
1399
- if (!await identical(oldPath, nextPath)) changes.push(plain$1(pair));
1400
- continue;
1401
- }
1402
- const old = only.get(`from\0${pair.from}`) ?? await readFile(oldPath);
1403
- const next = only.get(`to\0${pair.to}`) ?? await readFile(nextPath);
1404
- if (!paired && old.equals(next)) continue;
1399
+ if (!paired && renames.size === 0) return await identical(oldPath, nextPath) ? void 0 : {
1400
+ same: false,
1401
+ change: plain$1(pair)
1402
+ };
1403
+ const [old, next] = await Promise.all([only.get(`from\0${pair.from}`) ?? readFile(oldPath), only.get(`to\0${pair.to}`) ?? readFile(nextPath)]);
1404
+ if (!paired && old.equals(next)) return;
1405
1405
  const text = isText(old) ? old.toString("latin1") : void 0;
1406
1406
  const rewrittenText = text === void 0 ? void 0 : rewrite(text, renames);
1407
1407
  const rewritten = rewrittenText !== void 0 && rewrittenText !== text;
1408
- if (!paired && !rewritten) {
1409
- changes.push(plain$1(pair));
1410
- continue;
1411
- }
1408
+ if (!paired && !rewritten) return {
1409
+ same: false,
1410
+ change: plain$1(pair)
1411
+ };
1412
1412
  const expected = rewrittenText === void 0 ? old : Buffer.from(rewrittenText, "latin1");
1413
- (expected.equals(next) ? same : changes).push({
1414
- ...pair,
1415
- expected,
1416
- paired,
1417
- rewritten
1418
- });
1419
- }
1413
+ return {
1414
+ same: expected.equals(next),
1415
+ change: {
1416
+ ...pair,
1417
+ expected,
1418
+ paired,
1419
+ rewritten
1420
+ }
1421
+ };
1422
+ };
1423
+ const planned = yield* Effect.forEach(candidates, (pair) => attempt(async () => await classify(pair)), { concurrency: 8 });
1424
+ for (const entry of planned) if (entry !== void 0) (entry.same ? same : changes).push(entry.change);
1420
1425
  for (const file of fromOnly) if (!pairedFrom.has(file)) changes.push({
1421
1426
  ...plain$1({
1422
1427
  from: file,
@@ -1438,7 +1443,7 @@ const planTree = async (workspace, from, to) => {
1438
1443
  }),
1439
1444
  same
1440
1445
  };
1441
- };
1446
+ });
1442
1447
  const mebibytes = (bytes) => `${Math.round(bytes / 1024 / 1024)} MiB`;
1443
1448
  const shownOmissions = 2e3;
1444
1449
  const changeDiff = (workspace, from, to, change) => {
@@ -1470,10 +1475,7 @@ const partial = (what, omitted) => omitted === "" ? "" : `The ${what} diff is pa
1470
1475
  const DiffBudget = Context.Reference("upup/DiffBudget", { defaultValue: () => () => maxDiffBytes });
1471
1476
  const treeDiff = (workspace, from, to, limit) => Effect.gen(function* () {
1472
1477
  const budget = limit ?? (yield* DiffBudget)(from);
1473
- const { changes, same } = yield* Effect.tryPromise({
1474
- try: async () => await planTree(workspace, from, to),
1475
- catch: failure$1(from, to)
1476
- });
1478
+ const { changes, same } = yield* planTree(workspace, from, to);
1477
1479
  const parts = [];
1478
1480
  const left = [];
1479
1481
  let size = 0;
@@ -1807,12 +1809,16 @@ const majorsOf = (from, to) => {
1807
1809
  };
1808
1810
  const exists$1 = async (file) => await stat(file).then(() => true, () => false);
1809
1811
  const emptyTree = async (directory) => await readdir(directory).then((entries) => entries.length === 0, () => false);
1810
- const readMajors = (workspace) => Effect.promise(async () => majorsOf(await listed$2(workspace, files.dependencyListFrom), await listed$2(workspace, files.dependencyListTo)));
1812
+ const majorsIn = async (workspace) => {
1813
+ const [from, to] = await Promise.all([listed$2(workspace, files.dependencyListFrom), listed$2(workspace, files.dependencyListTo)]);
1814
+ return majorsOf(from, to);
1815
+ };
1816
+ const readMajors = (workspace) => Effect.promise(async () => await majorsIn(workspace));
1811
1817
  const read$1 = (workspace) => Effect.gen(function* () {
1812
1818
  const meta = yield* readMeta(workspace);
1813
1819
  return yield* Effect.tryPromise({
1814
1820
  try: async () => {
1815
- const diff = await readFile(path.join(workspace, files.diff));
1821
+ const [diff, majors] = await Promise.all([readFile(path.join(workspace, files.diff)), majorsIn(workspace)]);
1816
1822
  const trees = [];
1817
1823
  const titled = [];
1818
1824
  const targets = /* @__PURE__ */ new Map();
@@ -1851,7 +1857,7 @@ const read$1 = (workspace) => Effect.gen(function* () {
1851
1857
  trees,
1852
1858
  files: titled,
1853
1859
  sections,
1854
- majors: majorsOf(await listed$2(workspace, files.dependencyListFrom), await listed$2(workspace, files.dependencyListTo))
1860
+ majors
1855
1861
  };
1856
1862
  },
1857
1863
  catch: failed$1(workspace)
@@ -1921,28 +1927,18 @@ const BriefDoc = defineDoc({
1921
1927
  initial: () => ({ brief: null }),
1922
1928
  checkpointWhen: () => false
1923
1929
  });
1924
- const severity = Type.Union([
1925
- Type.Literal("info"),
1926
- Type.Literal("low"),
1927
- Type.Literal("medium"),
1928
- Type.Literal("high")
1929
- ]);
1930
- const ReportParameters = Type.Object({
1931
- verdict: Type.Union([
1932
- Type.Literal("ok"),
1933
- Type.Literal("caution"),
1934
- Type.Literal("danger"),
1935
- Type.Literal("no-verdict")
1936
- ]),
1937
- rationale: Type.String({ description: "One concrete sentence justifying the verdict." }),
1938
- summary: Type.String({ description: "Markdown: what the update changes that bears on the mandate, what you flagged and why you cleared or kept it." }),
1939
- findings: Type.Array(Type.Object({
1940
- severity,
1941
- title: Type.String(),
1942
- detail: Type.String({ description: "Markdown: the evidence and why it matters." }),
1943
- paths: Type.Array(Type.String(), { description: "Workspace paths, with line ranges where useful." })
1930
+ const parameters = (schema) => Schema.toJsonSchemaDocument(schema).schema;
1931
+ const decodeRead = Schema.decodeUnknownSync(ReadArgs);
1932
+ const decodeGrep = Schema.decodeUnknownSync(GrepArgs);
1933
+ const decodeList = Schema.decodeUnknownSync(ListArgs);
1934
+ const decodeSubmitted = Schema.decodeUnknownSync(Report);
1935
+ const encodeReport = (submitted) => ({
1936
+ ...submitted,
1937
+ findings: submitted.findings.map((finding) => ({
1938
+ ...finding,
1939
+ paths: [...finding.paths]
1944
1940
  })),
1945
- unverified: Type.Array(Type.String(), { description: "Each thing you could not verify." })
1941
+ unverified: [...submitted.unverified]
1946
1942
  });
1947
1943
  const ReportDoc = defineDoc({
1948
1944
  kind: "upup.report",
@@ -1968,42 +1964,33 @@ const auditExtension = (workspace) => {
1968
1964
  name: "read",
1969
1965
  description: descriptions.read,
1970
1966
  replay: "safe",
1971
- parameters: Type.Object({
1972
- path: Type.String({ description: parameters.read.path }),
1973
- offset: Type.Integer({ description: parameters.read.offset }),
1974
- limit: Type.Integer({ description: parameters.read.limit })
1975
- }),
1976
- execute: async (args, _api, invocation) => answer(await read$2(workspace, args, invocation.abortSignal))
1967
+ parameters: parameters(ReadArgs),
1968
+ execute: async (args, _api, invocation) => answer(await read$2(workspace, decodeRead(args), invocation.abortSignal))
1977
1969
  });
1978
1970
  const grep$1 = defineTool({
1979
1971
  name: "grep",
1980
1972
  description: descriptions.grep,
1981
1973
  replay: "safe",
1982
- parameters: Type.Object({
1983
- path: Type.String({ description: parameters.grep.path }),
1984
- pattern: Type.String({ description: parameters.grep.pattern })
1985
- }),
1986
- execute: async (args, _api, invocation) => answer(await grep(workspace, args, invocation.abortSignal === void 0 ? {} : { signal: invocation.abortSignal }))
1974
+ parameters: parameters(GrepArgs),
1975
+ execute: async (args, _api, invocation) => answer(await grep(workspace, decodeGrep(args), invocation.abortSignal === void 0 ? {} : { signal: invocation.abortSignal }))
1987
1976
  });
1988
1977
  const list$1 = defineTool({
1989
1978
  name: "list",
1990
1979
  description: descriptions.list,
1991
1980
  replay: "safe",
1992
- parameters: Type.Object({
1993
- path: Type.String({ description: parameters.list.path }),
1994
- depth: Type.Integer({ description: parameters.list.depth })
1995
- }),
1996
- execute: async (args, _api, invocation) => answer(await list(workspace, args, invocation.abortSignal))
1981
+ parameters: parameters(ListArgs),
1982
+ execute: async (args, _api, invocation) => answer(await list(workspace, decodeList(args), invocation.abortSignal))
1997
1983
  });
1998
1984
  const submit = defineTool({
1999
1985
  name: "submit_report",
2000
1986
  description: "Submit the audit report. Call exactly once, when the investigation is done; the audit ends.",
2001
1987
  replay: "safe",
2002
- parameters: ReportParameters,
1988
+ parameters: parameters(Report),
2003
1989
  execute: async (args, api, invocation) => {
1990
+ const encoded = encodeReport(decodeSubmitted(args));
2004
1991
  await api.commit(async (tx) => {
2005
1992
  const doc = await tx.doc(ReportDoc, api.conversationId);
2006
- doc.report = structuredClone(args);
1993
+ doc.report = encoded;
2007
1994
  }, invocation);
2008
1995
  return {
2009
1996
  ...text$2("Report submitted."),
@@ -2079,6 +2066,32 @@ const entriesOf$1 = (message) => {
2079
2066
  }
2080
2067
  return [];
2081
2068
  };
2069
+ const TextBlock = Schema.Struct({
2070
+ type: Schema.Literal("text"),
2071
+ text: Schema.String
2072
+ });
2073
+ const ThinkingBlock = Schema.Struct({
2074
+ type: Schema.Literal("thinking"),
2075
+ thinking: Schema.String
2076
+ });
2077
+ const isTextBlock = Schema.is(TextBlock);
2078
+ const isThinkingBlock = Schema.is(ThinkingBlock);
2079
+ const decodeLive = Schema.decodeUnknownOption(Schema.Struct({ generation: Schema.optional(Schema.Struct({
2080
+ attempt: Schema.Finite,
2081
+ message: Schema.optional(Schema.Struct({ content: Schema.Array(Schema.Unknown) })),
2082
+ retry: Schema.optional(Schema.Struct({ error: Schema.String }))
2083
+ })) }));
2084
+ const streamed = (block) => {
2085
+ if (isThinkingBlock(block)) return block.thinking.trim() === "" ? [] : [{
2086
+ kind: "thinking",
2087
+ text: block.thinking
2088
+ }];
2089
+ if (isTextBlock(block)) return block.text.trim() === "" ? [] : [{
2090
+ kind: "text",
2091
+ text: block.text
2092
+ }];
2093
+ return [];
2094
+ };
2082
2095
  var Transcript = class {
2083
2096
  committed = /* @__PURE__ */ new Map();
2084
2097
  live = [];
@@ -2086,41 +2099,20 @@ var Transcript = class {
2086
2099
  add(entry) {
2087
2100
  this.committed.set(entry.id, (entry.model ?? []).flatMap(entriesOf$1));
2088
2101
  }
2089
- apply(event) {
2090
- switch (event.type) {
2091
- case "snapshot":
2092
- this.committed.clear();
2093
- for (const entry of event.entries) this.add(entry);
2094
- this.live = [];
2095
- break;
2096
- case "entry_appended":
2097
- case "message_end":
2098
- this.add(event.entry);
2099
- this.live = [];
2100
- this.retry = void 0;
2101
- break;
2102
- case "message_update":
2103
- for (const change of event.changes) if (change.type === "text_delta" || change.type === "thinking_delta") {
2104
- const kind = change.type === "text_delta" ? "text" : "thinking";
2105
- const last = this.live.at(-1);
2106
- if (last?.kind === kind) this.live[this.live.length - 1] = {
2107
- kind,
2108
- text: last.text + change.delta
2109
- };
2110
- else this.live.push({
2111
- kind,
2112
- text: change.delta
2113
- });
2114
- }
2115
- break;
2116
- case "auto_retry_start":
2117
- this.retry = {
2118
- kind: "retry",
2119
- text: `retrying (attempt ${event.attempt}): ${event.errorMessage}`
2120
- };
2121
- break;
2122
- case "auto_retry_end": this.retry = void 0;
2123
- }
2102
+ view(view) {
2103
+ for (const entry of view.entries) this.add(entry);
2104
+ const generation = decodeLive(view.docs[LiveDoc.definition.kind]).pipe(Option.flatMapNullishOr((live) => live.generation));
2105
+ this.live = Option.match(generation, {
2106
+ onNone: () => [],
2107
+ onSome: ({ message }) => (message?.content ?? []).flatMap(streamed)
2108
+ });
2109
+ this.retry = Option.match(generation, {
2110
+ onNone: () => void 0,
2111
+ onSome: ({ attempt, retry }) => retry === void 0 ? void 0 : {
2112
+ kind: "retry",
2113
+ text: `retrying (attempt ${attempt}): ${retry.error}`
2114
+ }
2115
+ });
2124
2116
  }
2125
2117
  entries() {
2126
2118
  return [
@@ -2135,16 +2127,24 @@ const attempt$1 = (evaluate) => Effect.tryPromise({
2135
2127
  try: evaluate,
2136
2128
  catch: failed
2137
2129
  });
2130
+ const watched = (open, onValue) => Effect.acquireRelease(attempt$1(async () => {
2131
+ const watch = await open();
2132
+ watch.start(async (call) => {
2133
+ if (call.kind === "value") onValue(call.value);
2134
+ });
2135
+ return watch;
2136
+ }), (watch) => Effect.promise(async () => await watch.stop()).pipe(Effect.ignore));
2138
2137
  const lastAssistant = (entries) => entries.flatMap((entry) => entry.model ?? []).findLast((message) => message.role === "assistant");
2139
- const openHarness = (file, workspace, models) => Effect.acquireRelease(attempt$1(async () => {
2140
- if (workspace === "" && !existsSync(file)) throw new Error(`no audit at ${file}`);
2141
- const extension = auditExtension(workspace);
2138
+ const openHarness = (file, models, workspace) => Effect.acquireRelease(attempt$1(async () => {
2139
+ if (workspace === void 0 && !existsSync(file)) throw new Error(`no audit at ${file}`);
2140
+ const extension = auditExtension(workspace ?? "");
2142
2141
  const registry = createRegistry();
2143
2142
  registry.install(extension);
2144
2143
  return await Harness.open(await openNodeSqliteStorage(file), {
2145
2144
  models,
2146
2145
  registry,
2147
- settings: { extensions: [extension] }
2146
+ settings: { extensions: [extension] },
2147
+ readOnly: workspace === void 0
2148
2148
  }, context);
2149
2149
  }), (harness) => Effect.promise(async () => {
2150
2150
  await harness.close(context);
@@ -2157,7 +2157,7 @@ const encodeBrief = (brief) => ({
2157
2157
  artifacts: [...brief.artifacts]
2158
2158
  });
2159
2159
  const run$5 = (options) => Effect.scoped(Effect.gen(function* () {
2160
- const harness = yield* openHarness(options.file, options.brief.workspace, options.models);
2160
+ const harness = yield* openHarness(options.file, options.models, options.brief.workspace);
2161
2161
  const root = yield* attempt$1(async () => await harness.root(context, {
2162
2162
  agent: {
2163
2163
  model: {
@@ -2172,13 +2172,12 @@ const run$5 = (options) => Effect.scoped(Effect.gen(function* () {
2172
2172
  }
2173
2173
  }));
2174
2174
  const transcript = new Transcript();
2175
- const events = yield* Effect.acquireRelease(attempt$1(async () => await watchEvents(harness, root.id, context)), (stream) => Effect.promise(async () => await stream.stop()).pipe(Effect.ignore));
2176
- transcript.apply(events.snapshot);
2177
- options.onTranscript(transcript.entries());
2178
- events.start(async (batch) => {
2179
- for (const event of batch) transcript.apply(event);
2175
+ const views = yield* watched(async () => await root.watch(context), (view) => {
2176
+ transcript.view(view);
2180
2177
  options.onTranscript(transcript.entries());
2181
2178
  });
2179
+ transcript.view(views.value);
2180
+ options.onTranscript(transcript.entries());
2182
2181
  harness.resume();
2183
2182
  const settled = yield* Effect.tryPromise({
2184
2183
  try: async (signal) => {
@@ -2205,20 +2204,29 @@ const run$5 = (options) => Effect.scoped(Effect.gen(function* () {
2205
2204
  _tag: "Reported",
2206
2205
  report: decoded.value
2207
2206
  };
2208
- const final = yield* attempt$1(async () => await watchEvents(harness, root.id, context));
2209
- yield* attempt$1(async () => await final.stop());
2207
+ const final = yield* attempt$1(async () => await root.context(context));
2210
2208
  if (settled.value.status === "unanswered") return {
2211
2209
  _tag: "Failed",
2212
2210
  issue: Predicate.isString(settled.value.detail) ? settled.value.detail : settled.value.reason
2213
2211
  };
2214
2212
  return {
2215
2213
  _tag: "Failed",
2216
- issue: lastAssistant(final.snapshot.entries)?.errorMessage ?? "the model finished without submitting a report"
2214
+ issue: lastAssistant(final.entries)?.errorMessage ?? "the model finished without submitting a report"
2217
2215
  };
2218
2216
  }));
2217
+ const storedRoot = (file, models) => Effect.gen(function* () {
2218
+ const harness = yield* openHarness(file, models);
2219
+ return {
2220
+ harness,
2221
+ root: yield* attempt$1(async () => await harness.conversation(ROOT_CONVERSATION_ID, context))
2222
+ };
2223
+ });
2219
2224
  const stored = (file, models) => Effect.scoped(Effect.gen(function* () {
2220
- const harness = yield* openHarness(file, "", models);
2221
- const root = yield* attempt$1(async () => await harness.root(context));
2225
+ const { harness, root } = yield* storedRoot(file, models);
2226
+ if (root === void 0) return {
2227
+ brief: Option.none(),
2228
+ report: Option.none()
2229
+ };
2222
2230
  const brief = yield* attempt$1(async () => await harness.snapshot(BriefDoc, root.id, context));
2223
2231
  const submitted = yield* attempt$1(async () => await harness.snapshot(ReportDoc, root.id, context));
2224
2232
  return {
@@ -2227,12 +2235,12 @@ const stored = (file, models) => Effect.scoped(Effect.gen(function* () {
2227
2235
  };
2228
2236
  }));
2229
2237
  const transcript = (file, models) => Effect.scoped(Effect.gen(function* () {
2230
- const harness = yield* openHarness(file, "", models);
2231
- const root = yield* attempt$1(async () => await harness.root(context));
2232
- const events = yield* attempt$1(async () => await watchEvents(harness, root.id, context));
2233
- yield* attempt$1(async () => await events.stop());
2238
+ const { root } = yield* storedRoot(file, models);
2234
2239
  const built = new Transcript();
2235
- built.apply(events.snapshot);
2240
+ if (root !== void 0) {
2241
+ const active = yield* attempt$1(async () => await root.context(context));
2242
+ for (const entry of active.entries) built.add(entry);
2243
+ }
2236
2244
  return built.entries();
2237
2245
  }));
2238
2246
  // src/inventory/versions.ts
@@ -2339,7 +2347,7 @@ const escape = (path) => path.replaceAll(/[A-Z]/gu, (letter) => `!${letter.toLow
2339
2347
  const deprecation = (mod) => Option.fromNullishOr(/^\/\/\s*Deprecated:\s*(?<reason>.+)$/mu.exec(mod)?.groups?.["reason"]?.trim());
2340
2348
  const lookup$5 = Effect.fn("go.lookup")(function* (client, wanted) {
2341
2349
  const base = `https://proxy.golang.org/${escape(wanted.name)}/@v`;
2342
- const [latest, infos] = yield* Effect.all([getJson(client, `https://proxy.golang.org/${escape(wanted.name)}/@latest`, Info$2), Effect.forEach(wanted.versions, (version) => getJson(client, `${base}/${escape(version)}.info`, Info$2).pipe(Effect.option), { concurrency: 2 })], { concurrency: 2 });
2350
+ const [latest, infos] = yield* Effect.all([getJson(client, `https://proxy.golang.org/${escape(wanted.name)}/@latest`, Info$2), Effect.forEach(wanted.versions, (version) => getJson(client, `${base}/${escape(version)}.info`, Info$2).pipe(Effect.option), { concurrency: 2 })], { concurrency: "unbounded" });
2343
2351
  const mod = yield* getText(client, `${base}/${escape(latest.Version)}.mod`);
2344
2352
  const deprecated = deprecation(mod);
2345
2353
  const found = infos.flatMap((info) => Option.isSome(info) ? [info.value] : []);
@@ -4850,30 +4858,36 @@ const resolveFormula = Effect.fn("brew.resolveFormula")(function* (client, sourc
4850
4858
  digest: createHash("sha256").update(body).digest("hex")
4851
4859
  };
4852
4860
  });
4853
- let to;
4854
- let from;
4855
- if (source.tapGitHead !== "") {
4856
- const current = yield* Effect.option(snapshot(source.tapGitHead, "tap revision reported by brew info"));
4857
- if (current._tag === "Some" && matchesVersion(current.value.snapshot.text, toVersion) && (source.rubySourceChecksum === "" || source.rubySourceChecksum.toLowerCase() === current.value.digest)) to = current.value.snapshot;
4858
- }
4859
- let endpoint = `${githubApi}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/commits?${new URLSearchParams({
4860
- path: source.rubySourcePath,
4861
- per_page: `${historyPageSize}`
4862
- }).toString()}`;
4863
- let scanned = 0;
4864
- const complete = () => from !== void 0 && to !== void 0;
4865
- for (let page = 0; endpoint !== "" && page < maxHistoryPages && !complete(); page += 1) {
4866
- const { body, link } = yield* githubGet(client, endpoint, token).pipe(Effect.mapError(prefixed("query brew formula history")));
4867
- const commits = yield* commitsOf(body, endpoint);
4868
- for (const commit of commits) {
4869
- scanned += 1;
4870
- const { snapshot: candidate } = yield* snapshot(commit.sha, commit.message);
4871
- if (to === void 0 && matchesVersion(candidate.text, toVersion)) to = candidate;
4872
- if (from === void 0 && matchesVersion(candidate.text, fromVersion)) from = candidate;
4873
- if (complete()) break;
4861
+ const scanHistory = Effect.gen(function* () {
4862
+ let to;
4863
+ let from;
4864
+ let endpoint = `${githubApi}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/commits?${new URLSearchParams({
4865
+ path: source.rubySourcePath,
4866
+ per_page: `${historyPageSize}`
4867
+ }).toString()}`;
4868
+ let scanned = 0;
4869
+ const complete = () => from !== void 0 && to !== void 0;
4870
+ for (let page = 0; endpoint !== "" && page < maxHistoryPages && !complete(); page += 1) {
4871
+ const { body, link } = yield* githubGet(client, endpoint, token).pipe(Effect.mapError(prefixed("query brew formula history")));
4872
+ const commits = yield* commitsOf(body, endpoint);
4873
+ for (const commit of commits) {
4874
+ scanned += 1;
4875
+ const { snapshot: candidate } = yield* snapshot(commit.sha, commit.message);
4876
+ if (to === void 0 && matchesVersion(candidate.text, toVersion)) to = candidate;
4877
+ if (from === void 0 && matchesVersion(candidate.text, fromVersion)) from = candidate;
4878
+ if (complete()) break;
4879
+ }
4880
+ endpoint = complete() ? "" : nextPage(endpoint, link);
4874
4881
  }
4875
- endpoint = complete() ? "" : nextPage(endpoint, link);
4876
- }
4882
+ return {
4883
+ from,
4884
+ to,
4885
+ scanned
4886
+ };
4887
+ });
4888
+ const [current, history] = yield* Effect.all([source.tapGitHead === "" ? Effect.succeedNone : Effect.option(snapshot(source.tapGitHead, "tap revision reported by brew info")), scanHistory], { concurrency: "unbounded" });
4889
+ const { from, scanned } = history;
4890
+ const to = current._tag === "Some" && matchesVersion(current.value.snapshot.text, toVersion) && (source.rubySourceChecksum === "" || source.rubySourceChecksum.toLowerCase() === current.value.digest) ? current.value.snapshot : history.to;
4877
4891
  if (to === void 0) return yield* new EvidenceUnavailable({
4878
4892
  source: "brew",
4879
4893
  issue: `brew formula history has no snapshot for target version ${toVersion} within the newest ${scanned} commits`
@@ -5278,13 +5292,14 @@ const payloadDiff = Effect.fn("brew.payloadDiff")(function* (client, workspace,
5278
5292
  const { name } = shortName(artifact);
5279
5293
  const oldStrip = yield* strip(name, plan.old);
5280
5294
  const newStrip = yield* strip(name, plan.new);
5281
- const oldManifest = yield* payloadManifest(client, "installed", plan.old, oldStrip, path.join(workspace, files.payloadTreeFrom));
5295
+ const [oldManifest, newManifest] = yield* Effect.all([payloadManifest(client, "installed", plan.old, oldStrip, path.join(workspace, files.payloadTreeFrom)), payloadManifest(client, "target", plan.new, newStrip, path.join(workspace, files.payloadTreeTo))], { concurrency: "unbounded" });
5282
5296
  if (oldManifest === void 0) return yield* unavailablePayload(workspace, "installed Homebrew payload archive format is unsupported");
5283
- const newManifest = yield* payloadManifest(client, "target", plan.new, newStrip, path.join(workspace, files.payloadTreeTo));
5284
5297
  if (newManifest === void 0) return yield* unavailablePayload(workspace, "target Homebrew payload archive format is unsupported");
5285
- const manifests = yield* writeFileDiff(workspace, files.payloadFrom, files.payloadTo, manifestJson(oldManifest), manifestJson(newManifest));
5286
- const binaries = yield* writeFileDiff(workspace, files.binaryFrom, files.binaryTo, json(binarySummaries(oldManifest)), json(binarySummaries(newManifest)));
5287
- const trees = yield* treeDiff(workspace, files.payloadTreeFrom, files.payloadTreeTo);
5298
+ const [manifests, binaries, trees] = yield* Effect.all([
5299
+ writeFileDiff(workspace, files.payloadFrom, files.payloadTo, manifestJson(oldManifest), manifestJson(newManifest)),
5300
+ writeFileDiff(workspace, files.binaryFrom, files.binaryTo, json(binarySummaries(oldManifest)), json(binarySummaries(newManifest))),
5301
+ treeDiff(workspace, files.payloadTreeFrom, files.payloadTreeTo)
5302
+ ], { concurrency: "unbounded" });
5288
5303
  const contents = trees.diff;
5289
5304
  const contentDetail = [" Extracted payload file contents are diffed.", partial("payload", trees.omitted)].filter((sentence) => sentence !== "").join(" ");
5290
5305
  const origin = plan.old.origin === "" ? "" : ` (pinned by ${plan.old.origin})`;
@@ -5763,9 +5778,9 @@ const writeChanges = Effect.fn("git.writeChanges")(function* (from, to, destinat
5763
5778
  modes
5764
5779
  };
5765
5780
  const contents = readBatch((yield* git(["cat-file", "--batch"], objects.map((object) => `${object}\n`).join(""))).stdout, objects);
5766
- yield* Effect.tryPromise({
5781
+ yield* Effect.forEach(changes, (change) => Effect.tryPromise({
5767
5782
  try: async () => {
5768
- for (const change of changes) for (const [object, root] of [[change.fromObject, destination.from], [change.toObject, destination.to]]) {
5783
+ for (const [object, root] of [[change.fromObject, destination.from], [change.toObject, destination.to]]) {
5769
5784
  if (object === void 0) continue;
5770
5785
  const file = path.join(root, change.path);
5771
5786
  await mkdir(path.dirname(file), {
@@ -5779,6 +5794,9 @@ const writeChanges = Effect.fn("git.writeChanges")(function* (from, to, destinat
5779
5794
  repository,
5780
5795
  issue: `write source files: ${String(error)}`
5781
5796
  })
5797
+ }), {
5798
+ concurrency: 8,
5799
+ discard: true
5782
5800
  });
5783
5801
  return {
5784
5802
  files: changes.length,
@@ -5839,9 +5857,9 @@ const moduleChanges = (from, to, released) => {
5839
5857
  };
5840
5858
  };
5841
5859
  const readSummaries = (workspace, file) => Effect.tryPromise(async () => await readFile(path.join(workspace, file), "utf-8")).pipe(Effect.flatMap((text) => Schema.decodeEffect(Summaries)(text)), Effect.option);
5860
+ const readBinarySummaries = (workspace) => Effect.all([readSummaries(workspace, files.binaryFrom), readSummaries(workspace, files.binaryTo)], { concurrency: "unbounded" });
5842
5861
  const goSourceEvidence = Effect.fn("goSource.evidence")(function* (client, workspace, released) {
5843
- const from = yield* readSummaries(workspace, files.binaryFrom);
5844
- const to = yield* readSummaries(workspace, files.binaryTo);
5862
+ const [from, to] = yield* readBinarySummaries(workspace);
5845
5863
  if (from._tag === "None" || to._tag === "None") return;
5846
5864
  const { changes, reason } = moduleChanges(from.value, to.value, released);
5847
5865
  if (changes.length === 0) return {
@@ -5853,7 +5871,7 @@ const goSourceEvidence = Effect.fn("goSource.evidence")(function* (client, works
5853
5871
  const plan = yield* resolve$3(client, "go", modulePath, version);
5854
5872
  return yield* materialize$2(client, plan, path.join(workspace, tree, modulePath));
5855
5873
  });
5856
- const fetched = yield* Effect.forEach(changes, (change) => Effect.result(Effect.all([fetch(change.path, change.from, files.goSourceFrom), fetch(change.path, change.to, files.goSourceTo)], { concurrency: 2 })), { concurrency: 2 });
5874
+ const fetched = yield* Effect.forEach(changes, (change) => Effect.result(Effect.all([fetch(change.path, change.from, files.goSourceFrom), fetch(change.path, change.to, files.goSourceTo)], { concurrency: "unbounded" })), { concurrency: 2 });
5857
5875
  const failures = changes.flatMap((change, index) => {
5858
5876
  const result = fetched[index];
5859
5877
  return result?._tag === "Failure" ? [`${change.path}: ${result.failure.issue}`] : [];
@@ -5912,8 +5930,7 @@ const buildInfoSources = (from, to) => {
5912
5930
  return [...sources.values()].slice(0, 4);
5913
5931
  };
5914
5932
  const readBuildInfoSources = Effect.fn("goSource.buildInfoSources")(function* (workspace) {
5915
- const from = yield* readSummaries(workspace, files.binaryFrom);
5916
- const to = yield* readSummaries(workspace, files.binaryTo);
5933
+ const [from, to] = yield* readBinarySummaries(workspace);
5917
5934
  return from._tag === "None" || to._tag === "None" ? [] : buildInfoSources(from.value, to.value);
5918
5935
  });
5919
5936
  // src/audit/source-evidence.ts
@@ -6225,7 +6242,7 @@ const releaseAssetSources = Effect.fn("sourceLink.releaseAssets")(function* (cli
6225
6242
  } })), Effect.catch((error) => Effect.succeed(gap(error.issue))));
6226
6243
  }
6227
6244
  return Effect.succeed(gap("no release of the repository publishes this exact binary"));
6228
- });
6245
+ }, { concurrency: 4 });
6229
6246
  });
6230
6247
  // src/audit/brew.ts
6231
6248
  const caskArchiveUnavailable = "compiled cask payloads are not source archives";
@@ -6291,7 +6308,7 @@ const sourceDiff = Effect.fn("brew.sourceDiff")(function* (client, workspace, pa
6291
6308
  const [gap] = yield* Effect.all([sourceTree(client, pair.old, path.join(workspace, files.sourceFrom)).pipe(Effect.as(""), Effect.catch((error) => {
6292
6309
  const reason = historicalGap(pair.old.url, error);
6293
6310
  return reason === void 0 ? Effect.fail(labelled("download old brew source archive")(error)) : Effect.succeed(reason);
6294
- })), sourceTree(client, pair.new, path.join(workspace, files.source)).pipe(Effect.mapError(labelled("download new brew source archive")))], { concurrency: 2 });
6311
+ })), sourceTree(client, pair.new, path.join(workspace, files.source)).pipe(Effect.mapError(labelled("download new brew source archive")))], { concurrency: "unbounded" });
6295
6312
  if (gap !== "") return {
6296
6313
  diff: Buffer.alloc(0),
6297
6314
  reason: gap,
@@ -6328,9 +6345,11 @@ const sourceEvidence = Effect.fn("brew.sourceEvidence")(function* (client, works
6328
6345
  };
6329
6346
  });
6330
6347
  const materialize$1 = Effect.fn("brew.materialize")(function* (client, workspace, identity, plan, key) {
6331
- const formula = yield* materializeFormula(workspace, plan.formula);
6332
- const source = yield* sourceEvidence(client, workspace, archives(plan.formula), plan.sourceGap);
6333
- const payload = yield* materializePayload(client, workspace, identity.delta.artifact, plan.payload);
6348
+ const [formula, source, payload] = yield* Effect.all([
6349
+ materializeFormula(workspace, plan.formula),
6350
+ sourceEvidence(client, workspace, archives(plan.formula), plan.sourceGap),
6351
+ materializePayload(client, workspace, identity.delta.artifact, plan.payload)
6352
+ ], { concurrency: "unbounded" });
6334
6353
  const goSource = source.included ? void 0 : yield* goSourceEvidence(client, workspace, identity.delta);
6335
6354
  const sources = goSource?.included === true || source.included ? [] : [...plan.repository === void 0 ? [] : [plan.repository], ...yield* readBuildInfoSources(workspace)];
6336
6355
  const repository = sources.length === 0 ? void 0 : yield* materializeSources(workspace, sources);
@@ -6357,7 +6376,7 @@ const resolve$2 = Effect.fn("brew.resolve")(function* (client, identity) {
6357
6376
  const formulaGap = formula.fromGap === "" ? archiveUnavailableReason(archives(formula)) : "the installed version's formula snapshot is unavailable";
6358
6377
  const sourceGap = kind === "cask" ? caskArchiveUnavailable : formulaGap;
6359
6378
  const payload = yield* resolvePayload(info, artifact, from, to, formula.from?.text);
6360
- const released = sourceGap !== "" && payload.old.url !== "" && payload.new.url !== "" ? yield* Effect.all([releaseTagSource(payload.old.url), releaseTagSource(payload.new.url)], { concurrency: 2 }) : void 0;
6379
+ const released = sourceGap !== "" && payload.old.url !== "" && payload.new.url !== "" ? yield* Effect.all([releaseTagSource(payload.old.url), releaseTagSource(payload.new.url)], { concurrency: "unbounded" }) : void 0;
6361
6380
  const repository = released === void 0 || released.every((side) => "gap" in side) ? void 0 : {
6362
6381
  label: artifact,
6363
6382
  from: released[0],
@@ -6422,7 +6441,7 @@ const workspaceOf$1 = Effect.fn("githubActions.workspace")(function* (workspace,
6422
6441
  const githubActionPreparer = (repositoryOf, options = {}) => Effect.fn("githubActions.prepare")(function* (_client, identity) {
6423
6442
  const { artifact, from, to } = identity.delta;
6424
6443
  const repository = repositoryOf(artifact);
6425
- const [fromCommit, toCommit] = yield* Effect.all([tagCommit(repository, from, options), tagCommit(repository, to, options)], { concurrency: 2 }).pipe(Effect.mapError(unavailable$1));
6444
+ const [fromCommit, toCommit] = yield* Effect.all([tagCommit(repository, from, options), tagCommit(repository, to, options)], { concurrency: "unbounded" }).pipe(Effect.mapError(unavailable$1));
6426
6445
  const listed = identity.context["revision"];
6427
6446
  if (listed !== toCommit) return yield* new EvidenceUnavailable({
6428
6447
  source: repository,
@@ -6619,12 +6638,14 @@ const pypiWorkspace = Effect.fn("pypi.workspace")(function* (client, workspace,
6619
6638
  issue: error instanceof Error ? error.message : String(error)
6620
6639
  })
6621
6640
  });
6622
- const [from, to] = yield* Effect.all([materialize(client, plans.from, path.join(workspace, files.from), path.join(workspace, files.wheelFrom)), materialize(client, plans.to, path.join(workspace, files.to), path.join(workspace, files.wheelTo))], { concurrency: 2 });
6623
- const sources = yield* treeDiff(workspace, files.from, files.to);
6624
- const records = yield* writeFileDiff(workspace, files.pypiFrom, files.pypiTo, manifestJson(from), manifestJson(to));
6625
- const sourceBinaries = yield* writeFileDiff(workspace, files.binaryFrom, files.binaryTo, json(binarySummaries(from.publisher_sdist?.archive_manifest)), json(binarySummaries(to.publisher_sdist?.archive_manifest)));
6626
- const wheels = yield* treeDiff(workspace, files.wheelFrom, files.wheelTo);
6627
- const wheelBinaries = yield* writeFileDiff(workspace, files.binaryWheelFrom, files.binaryWheelTo, json(binarySummaries(from.compatible_universal_wheel?.archive_manifest)), json(binarySummaries(to.compatible_universal_wheel?.archive_manifest)));
6641
+ const [from, to] = yield* Effect.all([materialize(client, plans.from, path.join(workspace, files.from), path.join(workspace, files.wheelFrom)), materialize(client, plans.to, path.join(workspace, files.to), path.join(workspace, files.wheelTo))], { concurrency: "unbounded" });
6642
+ const [sources, records, sourceBinaries, wheels, wheelBinaries] = yield* Effect.all([
6643
+ treeDiff(workspace, files.from, files.to),
6644
+ writeFileDiff(workspace, files.pypiFrom, files.pypiTo, manifestJson(from), manifestJson(to)),
6645
+ writeFileDiff(workspace, files.binaryFrom, files.binaryTo, json(binarySummaries(from.publisher_sdist?.archive_manifest)), json(binarySummaries(to.publisher_sdist?.archive_manifest))),
6646
+ treeDiff(workspace, files.wheelFrom, files.wheelTo),
6647
+ writeFileDiff(workspace, files.binaryWheelFrom, files.binaryWheelTo, json(binarySummaries(from.compatible_universal_wheel?.archive_manifest)), json(binarySummaries(to.compatible_universal_wheel?.archive_manifest)))
6648
+ ], { concurrency: "unbounded" });
6628
6649
  const detail = `Checksum-verified PyPI publisher artifacts; ${pairedDetail("source distributions", from.publisher_sdist, to.publisher_sdist)}; ${pairedDetail("compatible universal wheel candidates", from.compatible_universal_wheel, to.compatible_universal_wheel)}; the installer’s exact resolver selection is not known.`;
6629
6650
  return yield* write(workspace, identity, Buffer.concat([
6630
6651
  sources.diff,
@@ -6641,7 +6662,7 @@ const pypiWorkspace = Effect.fn("pypi.workspace")(function* (client, workspace,
6641
6662
  const preparePyPI = Effect.fn("pypi.prepare")(function* (client, identity) {
6642
6663
  const { artifact, from, to } = identity.delta;
6643
6664
  const python = identity.context["python"] ?? "";
6644
- const [fromPlan, toPlan] = yield* Effect.all([resolve$1(client, artifact, from, python), resolve$1(client, artifact, to, python)], { concurrency: 2 });
6665
+ const [fromPlan, toPlan] = yield* Effect.all([resolve$1(client, artifact, from, python), resolve$1(client, artifact, to, python)], { concurrency: "unbounded" });
6645
6666
  const plans = {
6646
6667
  from: fromPlan,
6647
6668
  to: toPlan
@@ -6734,7 +6755,7 @@ const resolveDependencies = Effect.fn("npmDependencies.resolve")(function* (clie
6734
6755
  const outcomes = yield* Effect.forEach(changedNames, (dependency) => Effect.gen(function* () {
6735
6756
  if (!packageName.test(dependency)) return Result.fail("its name is not a valid registry package name");
6736
6757
  const side = (declared) => declared === void 0 ? Effect.undefined : resolveSide(client, host, dependency, declared);
6737
- const resolved = yield* Effect.result(Effect.all([side(before.get(dependency)), side(after.get(dependency))], { concurrency: 2 }));
6758
+ const resolved = yield* Effect.result(Effect.all([side(before.get(dependency)), side(after.get(dependency))], { concurrency: "unbounded" }));
6738
6759
  return Result.isFailure(resolved) ? Result.fail(resolved.failure.issue) : Result.succeed(resolved.success);
6739
6760
  }), { concurrency: 4 });
6740
6761
  for (const [index, dependency] of changedNames.entries()) {
@@ -6841,8 +6862,8 @@ const materializeDependencies = Effect.fn("npmDependencies.materialize")(functio
6841
6862
  issue: error instanceof Error ? error.message : String(error)
6842
6863
  })
6843
6864
  });
6844
- const sides = yield* Effect.forEach(dependencies.changed, (dependency) => Effect.all([fetchSide(client, dependency.from, path.join(workspace, files.dependenciesFrom, dependency.name)), fetchSide(client, dependency.to, path.join(workspace, files.dependenciesTo, dependency.name))], { concurrency: 2 }), { concurrency: 4 });
6845
- const summaries = yield* writeFileDiff(workspace, files.dependencyListFrom, files.dependencyListTo, record(dependencies, dependencies.changed.map((dependency, index) => ({
6865
+ const sides = yield* Effect.forEach(dependencies.changed, (dependency) => Effect.all([fetchSide(client, dependency.from, path.join(workspace, files.dependenciesFrom, dependency.name)), fetchSide(client, dependency.to, path.join(workspace, files.dependenciesTo, dependency.name))], { concurrency: "unbounded" }), { concurrency: 4 });
6866
+ const [summaries, trees] = yield* Effect.all([writeFileDiff(workspace, files.dependencyListFrom, files.dependencyListTo, record(dependencies, dependencies.changed.map((dependency, index) => ({
6846
6867
  name: dependency.name,
6847
6868
  ...dependency.from === void 0 ? {} : { resolved: dependency.from },
6848
6869
  ...sides[index]?.[0] === void 0 ? {} : { fetched: sides[index][0] }
@@ -6850,8 +6871,7 @@ const materializeDependencies = Effect.fn("npmDependencies.materialize")(functio
6850
6871
  name: dependency.name,
6851
6872
  ...dependency.to === void 0 ? {} : { resolved: dependency.to },
6852
6873
  ...sides[index]?.[1] === void 0 ? {} : { fetched: sides[index][1] }
6853
- }))));
6854
- const trees = yield* treeDiff(workspace, files.dependenciesFrom, files.dependenciesTo);
6874
+ })))), treeDiff(workspace, files.dependenciesFrom, files.dependenciesTo)], { concurrency: "unbounded" });
6855
6875
  const failed = dependencies.changed.filter((_, index) => (sides[index] ?? []).some((side) => side?.error !== void 0));
6856
6876
  const included = dependencies.changed.map((dependency) => `${dependency.name} ${dependency.from?.plan.version ?? "(new)"}${dependency.from?.lowest === true ? " (lowest of its range)" : ""} -> ${dependency.to?.plan.version ?? "(removed)"}${dependency.to?.bundled === true ? " (now a devDependency, so probably bundled into the package)" : ""}`);
6857
6877
  const noneIncluded = dependencies.omitted.length === 0 ? "No direct dependency's declared version changed." : "No changed direct dependency is compared.";
@@ -6884,10 +6904,12 @@ const materializeDependencies = Effect.fn("npmDependencies.materialize")(functio
6884
6904
  // src/audit/registry-evidence.ts
6885
6905
  const registryDetail = "Both published packages were downloaded and their checksums verified. File types and modes, and any native binaries, are summarised without running them.";
6886
6906
  const registryWorkspace = Effect.fn("evidence.registryWorkspace")(function* (client, workspace, identity, plans, npm, key) {
6887
- const [from, to] = yield* Effect.all([materialize$2(client, plans.from, path.join(workspace, files.from)), materialize$2(client, plans.to, path.join(workspace, files.to))], { concurrency: 2 });
6888
- const artifacts = yield* writeFileDiff(workspace, files.artifactFrom, files.artifactTo, manifestJson(from), manifestJson(to));
6889
- const trees = yield* treeDiff(workspace, files.from, files.to);
6890
- const binaries = yield* writeFileDiff(workspace, files.binaryFrom, files.binaryTo, json(binarySummaries(from)), json(binarySummaries(to)));
6907
+ const [from, to] = yield* Effect.all([materialize$2(client, plans.from, path.join(workspace, files.from)), materialize$2(client, plans.to, path.join(workspace, files.to))], { concurrency: "unbounded" });
6908
+ const [artifacts, trees, binaries] = yield* Effect.all([
6909
+ writeFileDiff(workspace, files.artifactFrom, files.artifactTo, manifestJson(from), manifestJson(to)),
6910
+ treeDiff(workspace, files.from, files.to),
6911
+ writeFileDiff(workspace, files.binaryFrom, files.binaryTo, json(binarySummaries(from)), json(binarySummaries(to)))
6912
+ ], { concurrency: "unbounded" });
6891
6913
  const treeDetail = [registryDetail, partial("artifact", trees.omitted)].filter((sentence) => sentence !== "").join(" ");
6892
6914
  if (npm === void 0) return yield* write(workspace, identity, Buffer.concat([
6893
6915
  artifacts,
@@ -6921,7 +6943,7 @@ const npmExtras = Effect.fn("evidence.npmExtras")(function* (client, name, from,
6921
6943
  cpu: process.arch
6922
6944
  });
6923
6945
  const verifier = yield* Effect.cached(sigstoreVerifier);
6924
- const [fromSource, toSource] = yield* Effect.all([npmSource(client, name, from, fromManifest, verifier), npmSource(client, name, to, toManifest, verifier)], { concurrency: 2 });
6946
+ const [fromSource, toSource] = yield* Effect.all([npmSource(client, name, from, fromManifest, verifier), npmSource(client, name, to, toManifest, verifier)], { concurrency: "unbounded" });
6925
6947
  const { directory } = npmRepository(toManifest);
6926
6948
  return {
6927
6949
  dependencies,
@@ -6938,8 +6960,8 @@ const prepareRegistry = Effect.fn("evidence.prepareRegistry")(function* (client,
6938
6960
  const manifests = ecosystem === "npm" ? yield* Effect.all({
6939
6961
  from: npmVersion(client, artifact, from),
6940
6962
  to: npmVersion(client, artifact, to)
6941
- }, { concurrency: 2 }) : void 0;
6942
- const [fromPlan, toPlan] = yield* Effect.all(manifests === void 0 ? [resolve$3(client, ecosystem, artifact, from), resolve$3(client, ecosystem, artifact, to)] : [npmPlan(artifact, from, manifests.from), npmPlan(artifact, to, manifests.to)], { concurrency: 2 });
6963
+ }, { concurrency: "unbounded" }) : void 0;
6964
+ const [fromPlan, toPlan] = yield* Effect.all(manifests === void 0 ? [resolve$3(client, ecosystem, artifact, from), resolve$3(client, ecosystem, artifact, to)] : [npmPlan(artifact, from, manifests.from), npmPlan(artifact, to, manifests.to)], { concurrency: "unbounded" });
6943
6965
  const plans = {
6944
6966
  from: fromPlan,
6945
6967
  to: toPlan
@@ -7314,10 +7336,9 @@ const layer$5 = (cacheDir) => Layer.effect(Audits, Effect.gen(function* () {
7314
7336
  }));
7315
7337
  const started = yield* Clock.currentTimeMillis;
7316
7338
  const base = path.join(root, "workspaces");
7317
- for (const name of yield* children(base)) {
7318
- if (name.endsWith(".lock")) continue;
7339
+ yield* Effect.forEach((yield* children(base)).filter((name) => !name.endsWith(".lock")), (name) => {
7319
7340
  const workspace = path.join(base, name);
7320
- yield* Effect.scoped(Effect.gen(function* () {
7341
+ return Effect.scoped(Effect.gen(function* () {
7321
7342
  if (!(yield* tryHold(workspace))) return;
7322
7343
  const prepared = yield* Effect.promise(async () => await stat(path.join(workspace, files.meta)).then((info) => info.mtimeMs, () => 0));
7323
7344
  if (started - prepared > Duration.toMillis(keptWorkspaces)) {
@@ -7325,9 +7346,15 @@ const layer$5 = (cacheDir) => Layer.effect(Audits, Effect.gen(function* () {
7325
7346
  return;
7326
7347
  }
7327
7348
  const entries = yield* Effect.promise(async () => await readdir(workspace, { withFileTypes: true }).catch(() => []));
7328
- for (const entry of entries) if (entry.isDirectory()) yield* discard(path.join(workspace, entry.name), name);
7349
+ yield* Effect.forEach(entries.filter((entry) => entry.isDirectory()), (entry) => discard(path.join(workspace, entry.name), name), {
7350
+ concurrency: "unbounded",
7351
+ discard: true
7352
+ });
7329
7353
  })).pipe(Effect.ignore);
7330
- }
7354
+ }, {
7355
+ concurrency: 8,
7356
+ discard: true
7357
+ });
7331
7358
  yield* Effect.forkScoped(Effect.promise(async () => {
7332
7359
  for (const name of await readdir(trash).catch(() => [])) await rm(path.join(trash, name), {
7333
7360
  recursive: true,
@@ -7544,12 +7571,15 @@ const workflowFiles = Effect.fn("workflowFiles")(function* (root) {
7544
7571
  for (const name of ["action.yml", "action.yaml"]) if (yield* present(path.join(dir, name))) return Option.some(path.join(dir, name));
7545
7572
  return Option.none();
7546
7573
  });
7547
- const workflows = yield* listed(path.join(".github", "workflows"), false);
7548
- const actions = yield* listed(path.join(".github", "actions"), true);
7574
+ const [workflows, actions, own] = yield* Effect.all([
7575
+ listed(path.join(".github", "workflows"), false),
7576
+ listed(path.join(".github", "actions"), true),
7577
+ actionFile("")
7578
+ ], { concurrency: "unbounded" });
7549
7579
  const pending = [
7550
7580
  ...workflows.filter((file) => /\.ya?ml$/u.test(file)),
7551
7581
  ...actions.filter((file) => /^action\.ya?ml$/u.test(path.basename(file))),
7552
- ...Option.toArray(yield* actionFile(""))
7582
+ ...Option.toArray(own)
7553
7583
  ];
7554
7584
  const seen = /* @__PURE__ */ new Set();
7555
7585
  const files = [];
@@ -7874,7 +7904,7 @@ const discover$4 = Effect.fn("GitHubActions.discover")(function* (dir) {
7874
7904
  ".github",
7875
7905
  "action.yml",
7876
7906
  "action.yaml"
7877
- ], exists)).length === 0) return [];
7907
+ ], exists, { concurrency: "unbounded" })).length === 0) return [];
7878
7908
  const origin = yield* exec.stdout({
7879
7909
  command: "git",
7880
7910
  args: [
@@ -7889,7 +7919,7 @@ const discover$4 = Effect.fn("GitHubActions.discover")(function* (dir) {
7889
7919
  });
7890
7920
  // src/process/on-path.ts
7891
7921
  const executable = (file) => Effect.promise(async () => await access(file, constants.X_OK).then(() => true, () => false));
7892
- const onPath = (command) => Effect.forEach((process.env["PATH"] ?? "").split(path.delimiter).filter((dir) => dir !== ""), (dir) => executable(path.join(dir, command))).pipe(Effect.map((found) => found.includes(true)));
7922
+ const onPath = (command) => Effect.forEach((process.env["PATH"] ?? "").split(path.delimiter).filter((dir) => dir !== ""), (dir) => executable(path.join(dir, command)), { concurrency: "unbounded" }).pipe(Effect.map((found) => found.includes(true)));
7893
7923
  // src/process/Sudo.ts
7894
7924
  var Sudo = class extends Context.Service()("upup/Sudo") {};
7895
7925
  const asRoot = (invocation) => [
@@ -8483,8 +8513,7 @@ const read = Effect.fn("bundles.read")(function* (bundle, arch) {
8483
8513
  const short = nonEmpty(info.value.CFBundleShortVersionString);
8484
8514
  const build = nonEmpty(info.value.CFBundleVersion);
8485
8515
  const executable = nonEmpty(info.value.CFBundleExecutable);
8486
- const sparkle = yield* sparkleKeysOf(bundle, info.value);
8487
- const source = yield* sourceOf(bundle, bundleId, nonEmpty(info.value.SUFeedURL), arch);
8516
+ const [sparkle, source] = yield* Effect.all([sparkleKeysOf(bundle, info.value), sourceOf(bundle, bundleId, nonEmpty(info.value.SUFeedURL), arch)], { concurrency: "unbounded" });
8488
8517
  return Option.some({
8489
8518
  path: bundle,
8490
8519
  name: path.basename(bundle, ".app"),
@@ -8497,23 +8526,25 @@ const read = Effect.fn("bundles.read")(function* (bundle, arch) {
8497
8526
  ...plist === void 0 ? {} : { plist }
8498
8527
  });
8499
8528
  });
8500
- const walk = Effect.fn("bundles.walk")(function* (roots, wanted) {
8529
+ const isApp = (entry) => entry.endsWith(".app");
8530
+ const isLeftover = (entry) => entry.endsWith(".app.upup-old");
8531
+ const wanted$1 = (entry) => isApp(entry) || isLeftover(entry);
8532
+ const walk = Effect.fn("bundles.walk")(function* (roots) {
8501
8533
  const fs = yield* FileSystem.FileSystem;
8502
8534
  const entries = (dir) => fs.readDirectory(dir).pipe(Effect.orElseSucceed(() => []), Effect.map((names) => names.toSorted((left, right) => left.localeCompare(right)).map((name) => path.join(dir, name))));
8503
8535
  const isLink = (entry) => fs.readLink(entry).pipe(Effect.isSuccess);
8504
8536
  const isDirectory = (entry) => fs.stat(entry).pipe(Effect.map((info) => info.type === "Directory"), Effect.orElseSucceed(() => false));
8505
- const found = [];
8506
- for (const root of roots) for (const entry of yield* entries(root)) {
8507
- if (yield* isLink(entry)) continue;
8508
- if (wanted(entry)) found.push(entry);
8509
- else if (!/\.(?:app|localized|upup-old|upup-new)$/u.test(entry) && (yield* isDirectory(entry))) {
8510
- for (const nested of yield* entries(entry)) if (wanted(nested) && !(yield* isLink(nested))) found.push(nested);
8511
- }
8512
- }
8513
- return found;
8537
+ const nestedIn = (folder) => entries(folder).pipe(Effect.flatMap((listed) => Effect.filter(listed.filter(wanted$1), (nested) => Effect.map(isLink(nested), (link) => !link), { concurrency: "unbounded" })));
8538
+ const walked = (yield* Effect.forEach(roots, (root) => entries(root).pipe(Effect.flatMap((listed) => Effect.forEach(listed, (entry) => Effect.gen(function* () {
8539
+ if (yield* isLink(entry)) return [];
8540
+ if (wanted$1(entry)) return [entry];
8541
+ return !/\.(?:app|localized|upup-old|upup-new)$/u.test(entry) && (yield* isDirectory(entry)) ? yield* nestedIn(entry) : [];
8542
+ }), { concurrency: "unbounded" })), Effect.map((listed) => listed.flat())), { concurrency: "unbounded" })).flat();
8543
+ return {
8544
+ apps: walked.filter(isApp),
8545
+ leftovers: walked.filter(isLeftover)
8546
+ };
8514
8547
  });
8515
- const paths = (roots) => walk(roots, (entry) => entry.endsWith(".app"));
8516
- const leftovers = (roots) => walk(roots, (entry) => entry.endsWith(".app.upup-old"));
8517
8548
  // src/apps/running.ts
8518
8549
  const command$4 = (name, args) => ({
8519
8550
  command: name,
@@ -8576,7 +8607,7 @@ const command$3 = (name, args) => ({
8576
8607
  });
8577
8608
  const host = Effect.gen(function* () {
8578
8609
  const exec = yield* Exec;
8579
- const [arm64, os] = yield* Effect.all([exec.run(command$3("sysctl", ["-n", "hw.optional.arm64"])).pipe(Effect.map((output) => output.exitCode === 0 && output.stdout.trim() === "1"), Effect.orElseSucceed(() => false)), exec.stdout(command$3("sw_vers", ["-productVersion"])).pipe(Effect.map((text) => text.trim()))], { concurrency: 2 });
8610
+ const [arm64, os] = yield* Effect.all([exec.run(command$3("sysctl", ["-n", "hw.optional.arm64"])).pipe(Effect.map((output) => output.exitCode === 0 && output.stdout.trim() === "1"), Effect.orElseSucceed(() => false)), exec.stdout(command$3("sw_vers", ["-productVersion"])).pipe(Effect.map((text) => text.trim()))], { concurrency: "unbounded" });
8580
8611
  return {
8581
8612
  arch: arm64 ? "arm64" : "x86_64",
8582
8613
  os
@@ -8654,7 +8685,7 @@ const stage = Effect.fn("install.stage")(function* (client, wanted) {
8654
8685
  const found = (yield* Effect.forEach(candidates, (candidate) => readInfo(candidate).pipe(Effect.map((info) => ({
8655
8686
  path: candidate,
8656
8687
  info
8657
- }))))).find(({ info }) => Option.isSome(info) && info.value.CFBundleIdentifier === wanted.bundleId);
8688
+ }))), { concurrency: 4 })).find(({ info }) => Option.isSome(info) && info.value.CFBundleIdentifier === wanted.bundleId);
8658
8689
  if (found === void 0 || Option.isNone(found.info)) return yield* refused(`its download holds no app with the bundle ID ${wanted.bundleId}`);
8659
8690
  const app = found.path;
8660
8691
  const info = found.info.value;
@@ -8673,7 +8704,7 @@ const stage = Effect.fn("install.stage")(function* (client, wanted) {
8673
8704
  ])).pipe(Effect.mapError((error) => refused(`codesign failed: ${error.output.trim()}`)), Effect.flatMap((output) => {
8674
8705
  const hash = /^CDHash=(?<hash>[0-9a-f]+)$/mu.exec(output.stderr)?.groups?.["hash"];
8675
8706
  return hash === void 0 ? Effect.fail(unsigned(output.stderr.trim())) : Effect.succeed(hash);
8676
- }))).pipe(Effect.map((hashes) => `${requirement(wanted.bundleId, wanted.team)} and info [CFBundleShortVersionString] = "${wanted.version.replaceAll(/["\\]/gu, "\\$&")}" and (${hashes.map((hash) => `cdhash H"${hash}"`).join(" or ")})`));
8707
+ })), { concurrency: 2 }).pipe(Effect.map((hashes) => `${requirement(wanted.bundleId, wanted.team)} and info [CFBundleShortVersionString] = "${wanted.version.replaceAll(/["\\]/gu, "\\$&")}" and (${hashes.map((hash) => `cdhash H"${hash}"`).join(" or ")})`));
8677
8708
  const signed = yield* exec.run(command$2("codesign", [
8678
8709
  "--verify",
8679
8710
  "--deep",
@@ -9156,16 +9187,27 @@ const makeWith = (options) => Effect.gen(function* () {
9156
9187
  }
9157
9188
  };
9158
9189
  });
9190
+ const leftoverNotice = (old) => {
9191
+ const app = old.slice(0, -9);
9192
+ return fs.exists(app).pipe(Effect.orElseSucceed(() => true), Effect.map((present) => ({ message: present ? `${old} is the old copy of ${path.basename(app)} that an update left behind; move it to the Trash` : `${old} is ${path.basename(app)} from before an update that did not finish; rename it back to ${path.basename(app)}` })));
9193
+ };
9194
+ const scan = Effect.gen(function* () {
9195
+ const [here, walked] = yield* Effect.all([host, walk(options.roots)], { concurrency: "unbounded" });
9196
+ const [bundles, left] = yield* Effect.all([Effect.forEach(walked.apps, (app) => read(app, here.arch), { concurrency: inFlight }), Effect.forEach(walked.leftovers, leftoverNotice, { concurrency: "unbounded" })], { concurrency: "unbounded" });
9197
+ return {
9198
+ here,
9199
+ found: bundles.flatMap((bundle) => Option.toArray(bundle)),
9200
+ left
9201
+ };
9202
+ });
9159
9203
  const list = Effect.gen(function* () {
9160
- const owners = yield* Effect.result(casks);
9204
+ const [owners, { here, found, left }] = yield* Effect.all([Effect.result(casks), scan], { concurrency: "unbounded" });
9161
9205
  if (Result.isFailure(owners)) return {
9162
9206
  packages: [],
9163
9207
  notices: [{ message: `upup lists no apps while it cannot read which apps Homebrew installed: ${describeError(owners.failure)}` }]
9164
9208
  };
9165
- const here = yield* host;
9166
9209
  const locale = yield* Effect.cached(country);
9167
9210
  const caskOf = new Map(owners.success.flatMap((cask) => caskApps(cask).map((app) => [app, cask])));
9168
- const found = (yield* Effect.forEach(yield* paths(options.roots), (app) => read(app, here.arch), { concurrency: inFlight })).flatMap((bundle) => Option.toArray(bundle));
9169
9211
  const ids = /* @__PURE__ */ new Set();
9170
9212
  const kept = found.filter((bundle) => {
9171
9213
  const cask = caskOf.get(path.basename(bundle.path));
@@ -9193,13 +9235,9 @@ const makeWith = (options) => Effect.gen(function* () {
9193
9235
  here,
9194
9236
  rows: new Map(all.map((row) => [row.pkg.id, row.listed]))
9195
9237
  });
9196
- const leftovers$1 = yield* Effect.forEach(yield* leftovers(options.roots), (old) => {
9197
- const app = old.slice(0, -9);
9198
- return fs.exists(app).pipe(Effect.orElseSucceed(() => true), Effect.map((present) => ({ message: present ? `${old} is the old copy of ${path.basename(app)} that an update left behind; move it to the Trash` : `${old} is ${path.basename(app)} from before an update that did not finish; rename it back to ${path.basename(app)}` })));
9199
- });
9200
9238
  return {
9201
9239
  packages: all.map((row) => row.pkg),
9202
- notices: [...all.flatMap((row) => row.notice), ...leftovers$1]
9240
+ notices: [...all.flatMap((row) => row.notice), ...left]
9203
9241
  };
9204
9242
  }).pipe(Effect.withSpan("Apps.list"), provide);
9205
9243
  const observe = Effect.fn("Apps.observe")(function* (pkg) {
@@ -9234,7 +9272,7 @@ const makeWith = (options) => Effect.gen(function* () {
9234
9272
  const ids = yield* Effect.forEach(paths, (app) => readInfo(app).pipe(Effect.flatMap((info) => Option.match(info, {
9235
9273
  onNone: () => Effect.fail(new Unsupported({ reason: `upup could not read ${app}` })),
9236
9274
  onSome: (found) => Effect.succeed(found.CFBundleIdentifier)
9237
- }))));
9275
+ }))), { concurrency: inFlight });
9238
9276
  const found = {
9239
9277
  paths,
9240
9278
  ids: new Set(ids)
@@ -9515,7 +9553,7 @@ const nestedDirs = Effect.fn("nestedDirs")(function* (dir, names) {
9515
9553
  args,
9516
9554
  cwd: dir
9517
9555
  }).pipe(Effect.orElseSucceed(() => ""));
9518
- const [prefix, listed] = yield* Effect.all([git("rev-parse", "--show-prefix"), git("ls-files", "-z", "--cached", "--others", "--exclude-standard", "--", ...names.map((name) => `:(glob)**/${name}`))], { concurrency: 2 });
9556
+ const [prefix, listed] = yield* Effect.all([git("rev-parse", "--show-prefix"), git("ls-files", "-z", "--cached", "--others", "--exclude-standard", "--", ...names.map((name) => `:(glob)**/${name}`))], { concurrency: "unbounded" });
9519
9557
  const files = listed.split("\0").filter((file) => {
9520
9558
  const folders = file.split("/").slice(0, -1);
9521
9559
  return folders.length > 0 && !folders.includes("node_modules") && !(path.basename(file) === "go.mod" && ignoredByGo(folders));
@@ -9542,8 +9580,7 @@ const failing = (name, error) => ({
9542
9580
  observe: () => Effect.succeedNone
9543
9581
  });
9544
9582
  const locateAll = Effect.fn("locateAll")(function* (dir, nested, manifest, locate) {
9545
- const own = yield* locate(dir);
9546
- const below = yield* Effect.forEach(nested, (from) => Effect.map(Effect.result(locate(from)), (result) => [from, result]), { concurrency: 8 });
9583
+ const [own, below] = yield* Effect.all([locate(dir), Effect.forEach(nested, (from) => Effect.map(Effect.result(locate(from)), (result) => [from, result]), { concurrency: 8 })], { concurrency: "unbounded" });
9547
9584
  const found = /* @__PURE__ */ new Map();
9548
9585
  const claimed = /* @__PURE__ */ new Map();
9549
9586
  const failed = [];
@@ -9706,7 +9743,7 @@ const make$9 = (root, place = "") => Effect.gen(function* () {
9706
9743
  const entries = (manifest) => manifestOf(manifest).pipe(Effect.map((parsed) => entriesOf(manifest, parsed)));
9707
9744
  const workspace = Effect.gen(function* () {
9708
9745
  const resolved = resolvedByMember(root, yield* metadata);
9709
- const manifests = yield* Effect.forEach(/* @__PURE__ */ new Set(["Cargo.toml", ...resolved.keys()]), (manifest) => manifestOf(manifest).pipe(Effect.map((parsed) => [manifest, parsed])));
9746
+ const manifests = yield* Effect.forEach(/* @__PURE__ */ new Set(["Cargo.toml", ...resolved.keys()]), (manifest) => manifestOf(manifest).pipe(Effect.map((parsed) => [manifest, parsed])), { concurrency: 8 });
9710
9747
  const inheritors = (key) => manifests.flatMap(([manifest, parsed]) => resolved.has(manifest) && inheritedKeys(parsed).includes(key) ? [manifest] : []);
9711
9748
  return {
9712
9749
  resolved,
@@ -10011,9 +10048,11 @@ const make$8 = Effect.gen(function* () {
10011
10048
  });
10012
10049
  const isPlainExecutable = Effect.fn("GoInstall.isPlainExecutable")(function* (dir, file) {
10013
10050
  const binary = path.join(dir, file);
10014
- const info = yield* fs.stat(binary).pipe(Effect.mapError(fileFailed("stat", binary)));
10015
- const real = yield* fs.realPath(binary).pipe(Effect.mapError(fileFailed("resolve", binary)));
10016
- const realDir = yield* fs.realPath(dir).pipe(Effect.mapError(fileFailed("resolve", dir)));
10051
+ const [info, real, realDir] = yield* Effect.all([
10052
+ fs.stat(binary).pipe(Effect.mapError(fileFailed("stat", binary))),
10053
+ fs.realPath(binary).pipe(Effect.mapError(fileFailed("resolve", binary))),
10054
+ fs.realPath(dir).pipe(Effect.mapError(fileFailed("resolve", dir)))
10055
+ ], { concurrency: "unbounded" });
10017
10056
  return info.type === "File" && (info.mode & 73) !== 0 && real === path.join(realDir, file);
10018
10057
  });
10019
10058
  const latest = Effect.fn("GoInstall.latest")(function* (modules) {
@@ -10172,8 +10211,7 @@ const make$7 = (root, moduleDir, place = "", local = /* @__PURE__ */ new Set())
10172
10211
  ]);
10173
10212
  const origin = exec.stdout(env).pipe(Effect.flatMap(decodeGoJson(GoProxyEnv, commandLine(env))), Effect.map(withGoOrigin));
10174
10213
  const list = Effect.gen(function* () {
10175
- const direct = yield* requirements;
10176
- const located = yield* origin;
10214
+ const [direct, located] = yield* Effect.all([requirements, origin], { concurrency: "unbounded" });
10177
10215
  const entries = yield* selected(direct.map((requirement) => requirement.Path), true);
10178
10216
  const notices = [];
10179
10217
  return {
@@ -10235,17 +10273,17 @@ const locate$1 = Effect.fn("GoModule.locate")(function* (dir) {
10235
10273
  const discover$2 = Effect.fn("GoModule.discover")(function* (dir, nested = []) {
10236
10274
  const exec = yield* Exec;
10237
10275
  const { found, failed } = yield* locateAll(dir, nested, "go.mod", locate$1);
10238
- const failedWorks = [];
10239
- const listed = /* @__PURE__ */ new Set();
10240
- const modules = yield* Effect.forEach(found, ({ root, work, claimed }) => Effect.gen(function* () {
10241
- if (!work) {
10242
- listed.add(root);
10243
- return [{
10276
+ const works = yield* Effect.forEach(found, ({ root, work, claimed }) => Effect.gen(function* () {
10277
+ if (!work) return {
10278
+ modules: [{
10244
10279
  root,
10245
10280
  moduleDir: root,
10246
10281
  local: /* @__PURE__ */ new Set()
10247
- }];
10248
- }
10282
+ }],
10283
+ failed: [],
10284
+ covered: [root]
10285
+ };
10286
+ const covered = [];
10249
10287
  const place = placeOf$1(dir, root);
10250
10288
  const scanned = yield* Effect.gen(function* () {
10251
10289
  const edit = {
@@ -10259,7 +10297,7 @@ const discover$2 = Effect.fn("GoModule.discover")(function* (dir, nested = []) {
10259
10297
  };
10260
10298
  const file = yield* exec.stdout(edit).pipe(Effect.flatMap(decodeGoJson(WorkFile, commandLine(edit))));
10261
10299
  const used = (file.Use ?? []).map((use) => path.resolve(root, use.DiskPath));
10262
- for (const moduleDir of used) listed.add(moduleDir);
10300
+ covered.push(...used);
10263
10301
  const paths = yield* Effect.forEach(used, (moduleDir) => Effect.gen(function* () {
10264
10302
  const mod = yield* readModFile(exec, moduleDir);
10265
10303
  if (mod.Module === void 0) return yield* new OutputMalformed({
@@ -10275,20 +10313,27 @@ const discover$2 = Effect.fn("GoModule.discover")(function* (dir, nested = []) {
10275
10313
  local
10276
10314
  })).filter(({ moduleDir }) => place === "" || placeOf$1(dir, moduleDir) !== "");
10277
10315
  }).pipe(Effect.result);
10278
- if (Result.isSuccess(scanned)) return scanned.success;
10279
- for (const moduleDir of claimed) listed.add(moduleDir);
10280
- failedWorks.push(failing(path.join(place, "go.work"), scanned.failure));
10281
- return [];
10282
- }));
10316
+ if (Result.isSuccess(scanned)) return {
10317
+ modules: scanned.success,
10318
+ failed: [],
10319
+ covered
10320
+ };
10321
+ return {
10322
+ modules: [],
10323
+ failed: [failing(path.join(place, "go.work"), scanned.failure)],
10324
+ covered: [...covered, ...claimed]
10325
+ };
10326
+ }), { concurrency: 4 });
10327
+ const listed = new Set(works.flatMap((work) => work.covered));
10283
10328
  const outside = nested.flatMap((moduleDir) => listed.has(moduleDir) ? [] : [{
10284
10329
  root: moduleDir,
10285
10330
  moduleDir,
10286
10331
  local: /* @__PURE__ */ new Set()
10287
10332
  }]);
10288
- const providers = yield* Effect.forEach([...modules.flat(), ...outside], ({ root, moduleDir, local }) => make$7(root, moduleDir, placeOf$1(dir, root), local));
10333
+ const providers = yield* Effect.forEach([...works.flatMap(({ modules }) => modules), ...outside], ({ root, moduleDir, local }) => make$7(root, moduleDir, placeOf$1(dir, root), local));
10289
10334
  return [
10290
10335
  ...failed,
10291
- ...failedWorks,
10336
+ ...works.flatMap((work) => work.failed),
10292
10337
  ...providers
10293
10338
  ];
10294
10339
  });
@@ -10296,24 +10341,23 @@ const discover$2 = Effect.fn("GoModule.discover")(function* (dir, nested = []) {
10296
10341
  var ProviderSource = class extends Context.Service()("upup/ProviderSource") {};
10297
10342
  // src/node/release-history.ts
10298
10343
  const minutesPerDay = 1440;
10299
- const firstPnpmMajorWithDefaultReleaseAge = 11;
10300
10344
  const gateSettings = {
10301
10345
  pnpm: {
10302
10346
  age: "minimumReleaseAge",
10303
10347
  exclude: "minimumReleaseAgeExclude",
10304
10348
  unit: 1,
10305
- unset: (version) => (semver.coerce(version)?.major ?? 0) >= firstPnpmMajorWithDefaultReleaseAge ? minutesPerDay : 0
10349
+ unset: minutesPerDay
10306
10350
  },
10307
10351
  npm: {
10308
10352
  age: "min-release-age",
10309
10353
  exclude: "min-release-age-exclude",
10310
10354
  unit: minutesPerDay,
10311
- unset: () => 0
10355
+ unset: 0
10312
10356
  }
10313
10357
  };
10314
- const releaseGate = (manager, version, config) => {
10358
+ const releaseGate = (manager, config) => {
10315
10359
  const settings = gateSettings[manager];
10316
- const minutes = Number(config[settings.age] ?? settings.unset(version)) * settings.unit;
10360
+ const minutes = Number(config[settings.age] ?? settings.unset) * settings.unit;
10317
10361
  return {
10318
10362
  minutes: Number.isFinite(minutes) && minutes > 0 ? minutes : 0,
10319
10363
  exclude: [config[settings.exclude] ?? []].flat().filter((pattern) => typeof pattern === "string")
@@ -10399,8 +10443,7 @@ const releaseOffers = Effect.fn("releaseOffers")(function* (pins, manager, run,
10399
10443
  const reads = yield* Effect.result(Effect.forEach(artifacts, read, { concurrency: 8 }));
10400
10444
  const histories = new Map(Result.isSuccess(reads) ? reads.success : []);
10401
10445
  const notices = Result.isFailure(reads) ? [{ message: `release histories could not be read, so upup offers nothing: ${describeError(reads.failure)}` }] : [];
10402
- const version = manager === "pnpm" && histories.size > 0 ? yield* exec.stdout(run(["--version"])) : "";
10403
- const gate = releaseGate(manager, version.trim(), config);
10446
+ const gate = releaseGate(manager, config);
10404
10447
  const offer = (pin) => {
10405
10448
  const history = histories.get(pin.artifact);
10406
10449
  if (history === void 0) return Result.succeed(void 0);
@@ -10511,7 +10554,7 @@ const makeGlobal = (spec) => Effect.gen(function* () {
10511
10554
  installed,
10512
10555
  latest,
10513
10556
  readNpmConfig(spec.config, "/").pipe(Effect.provideService(Exec, exec))
10514
- ], { concurrency: 3 });
10557
+ ], { concurrency: "unbounded" });
10515
10558
  const { offer, notices: unread } = yield* releaseOffers(packages.filter((pkg) => isPrerelease(pkg.current)), spec.config, (args) => ({
10516
10559
  command: spec.config,
10517
10560
  args,
@@ -10742,9 +10785,10 @@ const scan = Effect.fn("NodePins.scan")(function* (root, dir, nested) {
10742
10785
  const fs = yield* FileSystem.FileSystem;
10743
10786
  const read = (file) => readText(path.join(root, file));
10744
10787
  const exists = (file) => fs.exists(path.join(root, file)).pipe(Effect.mapError(fileFailed("stat", path.join(root, file))));
10745
- const steps = (yield* workflowFiles(root)).flatMap(({ file, text }) => stepPins(file, text) ?? []);
10746
- const versioned = yield* Effect.filter(yield* versionFilesOf(root, dir, nested), exists);
10747
- const files = yield* Effect.forEach(versioned.toSorted(), (file) => Effect.map(read(file), (text) => filePin(file, text)));
10788
+ const [workflows, listed] = yield* Effect.all([workflowFiles(root), versionFilesOf(root, dir, nested)], { concurrency: "unbounded" });
10789
+ const steps = workflows.flatMap(({ file, text }) => stepPins(file, text) ?? []);
10790
+ const versioned = yield* Effect.filter(listed, exists, { concurrency: "unbounded" });
10791
+ const files = yield* Effect.forEach(versioned.toSorted(), (file) => Effect.map(read(file), (text) => filePin(file, text)), { concurrency: 8 });
10748
10792
  return [...steps, ...files.flat()];
10749
10793
  });
10750
10794
  const make$6 = (root, dir = root, nested = []) => Effect.gen(function* () {
@@ -11007,26 +11051,31 @@ const make$5 = (root, manager, place = "", claimed = []) => Effect.gen(function*
11007
11051
  const unlocked = claimed.filter((dir) => !lockedDirs.has(path.normalize(dir))).toSorted((a, b) => a.localeCompare(b));
11008
11052
  if (unlocked.length > 0) notices.push({ message: `not listed: ${unlocked.join(", ")} (not in ${lockfile})` });
11009
11053
  const catalogLocked = /* @__PURE__ */ new Map();
11010
- for (const member of members.toSorted((a, b) => a.localeCompare(b))) {
11054
+ const memberManifests = yield* Effect.forEach(members.toSorted((a, b) => a.localeCompare(b)), (member) => {
11011
11055
  const memberDir = member === "." ? "" : member;
11012
11056
  const manifest = path.join(memberDir, "package.json");
11013
- const fields = yield* readJson(Manifest, path.join(root, manifest));
11014
- for (const section of sections) for (const [name, spec] of Object.entries(fields[section] ?? {})) {
11015
- const resolved = Option.match(pnpm, {
11016
- onSome: (lock) => resolvedVersion(lock.importers?.[member]?.[section]?.[name]?.version),
11017
- onNone: () => Option.match(npm, {
11018
- onSome: (lock) => lock.packages[path.join(memberDir, "node_modules", name)]?.version ?? lock.packages[path.join("node_modules", name)]?.version,
11019
- onNone: () => void 0
11020
- })
11021
- });
11022
- if (spec.startsWith("catalog:")) {
11023
- const catalog = spec.slice(8) || "default";
11024
- const locked = catalogLocked.get(catalog) ?? /* @__PURE__ */ new Map();
11025
- if (resolved !== void 0 && !locked.has(name)) catalogLocked.set(catalog, locked.set(name, resolved));
11026
- continue;
11027
- }
11028
- add(manifest, section, [section, name], name, spec, resolved);
11057
+ return Effect.map(readJson(Manifest, path.join(root, manifest)), (fields) => ({
11058
+ member,
11059
+ memberDir,
11060
+ manifest,
11061
+ fields
11062
+ }));
11063
+ }, { concurrency: 8 });
11064
+ for (const { member, memberDir, manifest, fields } of memberManifests) for (const section of sections) for (const [name, spec] of Object.entries(fields[section] ?? {})) {
11065
+ const resolved = Option.match(pnpm, {
11066
+ onSome: (lock) => resolvedVersion(lock.importers?.[member]?.[section]?.[name]?.version),
11067
+ onNone: () => Option.match(npm, {
11068
+ onSome: (lock) => lock.packages[path.join(memberDir, "node_modules", name)]?.version ?? lock.packages[path.join("node_modules", name)]?.version,
11069
+ onNone: () => void 0
11070
+ })
11071
+ });
11072
+ if (spec.startsWith("catalog:")) {
11073
+ const catalog = spec.slice(8) || "default";
11074
+ const locked = catalogLocked.get(catalog) ?? /* @__PURE__ */ new Map();
11075
+ if (resolved !== void 0 && !locked.has(name)) catalogLocked.set(catalog, locked.set(name, resolved));
11076
+ continue;
11029
11077
  }
11078
+ add(manifest, section, [section, name], name, spec, resolved);
11030
11079
  }
11031
11080
  if (Option.isSome(pnpm) && (yield* exists(path.join(root, "pnpm-workspace.yaml")))) {
11032
11081
  const workspacePath = path.join(root, "pnpm-workspace.yaml");
@@ -11096,7 +11145,7 @@ const make$5 = (root, manager, place = "", claimed = []) => Effect.gen(function*
11096
11145
  };
11097
11146
  }).pipe(Effect.provideService(FileSystem.FileSystem, fs));
11098
11147
  const list = Effect.gen(function* () {
11099
- const [{ declared, notices }, config] = yield* Effect.all([declarations, readNpmConfig(manager, root).pipe(Effect.provideService(Exec, exec))], { concurrency: 2 });
11148
+ const [{ declared, notices }, config] = yield* Effect.all([declarations, readNpmConfig(manager, root).pipe(Effect.provideService(Exec, exec))], { concurrency: "unbounded" });
11100
11149
  const origin = withNpmOrigin(npmRegistries(config));
11101
11150
  const { offer, notices: unread } = yield* releaseOffers(declared.flatMap((entry) => entry.held === true ? [] : [entry.pkg]), manager, run, config).pipe(Effect.provideService(Exec, exec));
11102
11151
  return {
@@ -11302,7 +11351,7 @@ const discover = Effect.fn("NodeProject.discover")(function* (dir, nested = [])
11302
11351
  const installed = yield* fs.exists(lockfile).pipe(Effect.mapError(fileFailed("stat", lockfile)));
11303
11352
  if (place !== "" && !installed) unlisted.push(`${place} (no ${lockfiles[manager]} yet)`);
11304
11353
  else {
11305
- const manifests = yield* Effect.filter(claimed, (from) => fs.exists(path.join(from, "package.json")).pipe(Effect.mapError(fileFailed("stat", from))));
11354
+ const manifests = yield* Effect.filter(claimed, (from) => fs.exists(path.join(from, "package.json")).pipe(Effect.mapError(fileFailed("stat", from))), { concurrency: "unbounded" });
11306
11355
  providers.push(yield* make$5(root, manager, place, manifests.map((from) => path.relative(root, from))));
11307
11356
  }
11308
11357
  }
@@ -11401,10 +11450,13 @@ const make$4 = Effect.gen(function* () {
11401
11450
  });
11402
11451
  const list = Effect.gen(function* () {
11403
11452
  const found = yield* configured;
11453
+ const offered = yield* Effect.forEach(found.packages, (pkg) => Effect.map(Effect.result(offer(pkg)), (target) => ({
11454
+ pkg,
11455
+ target
11456
+ })), { concurrency: 4 });
11404
11457
  const notices = [...found.notices];
11405
11458
  return {
11406
- packages: yield* Effect.forEach(found.packages, (pkg) => Effect.gen(function* () {
11407
- const target = yield* Effect.result(offer(pkg));
11459
+ packages: offered.map(({ pkg, target }) => {
11408
11460
  if (Result.isFailure(target)) {
11409
11461
  notices.push({
11410
11462
  rowKey: rowKey(pkg),
@@ -11413,7 +11465,7 @@ const make$4 = Effect.gen(function* () {
11413
11465
  return pkg;
11414
11466
  }
11415
11467
  return target.success === void 0 ? pkg : withTarget(pkg, target.success);
11416
- })),
11468
+ }),
11417
11469
  notices
11418
11470
  };
11419
11471
  }).pipe(Effect.withSpan("VpEnv.list"));
@@ -11545,7 +11597,7 @@ const make$2 = Effect.gen(function* () {
11545
11597
  exec.stdout(command$1("apt", ["list", "--upgradable"])).pipe(Effect.map(parseUpgradable)),
11546
11598
  exec.stdout(command$1("apt-mark", ["showhold"])).pipe(Effect.map((text) => new Set(text.split("\n").filter((line) => line !== "")))),
11547
11599
  restart
11548
- ], { concurrency: 4 });
11600
+ ], { concurrency: "unbounded" });
11549
11601
  const packages = upgradable.map((entry) => {
11550
11602
  const pkg = packageOf(entry, arch);
11551
11603
  return holds.has(entry.name) || holds.has(pkg.id) ? pkg : withTarget(pkg, entry.version);
@@ -11690,7 +11742,7 @@ const make$1 = Effect.gen(function* () {
11690
11742
  running,
11691
11743
  scan(args),
11692
11744
  Ref.get(installed)
11693
- ], { concurrency: 2 });
11745
+ ], { concurrency: "unbounded" });
11694
11746
  return {
11695
11747
  packages: packagesOf$1(version, offers.filter((offer) => !done.has(offer.label))),
11696
11748
  done
@@ -11775,7 +11827,7 @@ const make = Effect.gen(function* () {
11775
11827
  "list",
11776
11828
  "--outdated",
11777
11829
  "--show-python"
11778
- ])).pipe(Effect.map(parseTools))], { concurrency: 2 });
11830
+ ])).pipe(Effect.map(parseTools))], { concurrency: "unbounded" });
11779
11831
  const targets = new Map(outdated.flatMap((tool) => tool.fromPyPI && tool.latest !== void 0 ? [[tool.pkg.id, tool.latest]] : []));
11780
11832
  const index = privatePypiIndex();
11781
11833
  return {
@@ -11824,8 +11876,8 @@ const system$1 = [
11824
11876
  ["go", make$8],
11825
11877
  ["uv", make]
11826
11878
  ];
11827
- const available = (entries) => Effect.filter([...new Set(entries.map(([command]) => command))], onPath).pipe(Effect.map((found) => entries.filter(([command]) => found.includes(command))));
11828
- const systemProviders = available(system$1).pipe(Effect.flatMap((found) => Effect.forEach(found, ([, make]) => make)));
11879
+ const available = (entries) => Effect.filter([...new Set(entries.map(([command]) => command))], onPath, { concurrency: "unbounded" }).pipe(Effect.map((found) => entries.filter(([command]) => found.includes(command))));
11880
+ const systemProviders = available(system$1).pipe(Effect.flatMap((found) => Effect.forEach(found, ([, make]) => make, { concurrency: "unbounded" })));
11829
11881
  const project$1 = [
11830
11882
  ["go", {
11831
11883
  manifests: ["go.mod"],
@@ -11851,9 +11903,8 @@ const project$1 = [
11851
11903
  const manifests = project$1.flatMap(([, kind]) => kind.manifests);
11852
11904
  const projectProviders = (given) => Effect.gen(function* () {
11853
11905
  const dir = yield* (yield* FileSystem.FileSystem).realPath(given).pipe(Effect.orElseSucceed(() => given));
11854
- const found = yield* available(project$1);
11855
- const nested = yield* nestedDirs(dir, manifests);
11856
- return (yield* Effect.forEach(found, ([, kind]) => kind.discover(dir, [...new Set(kind.manifests.flatMap(nested))]))).flat();
11906
+ const [found, nested] = yield* Effect.all([available(project$1), nestedDirs(dir, manifests)], { concurrency: "unbounded" });
11907
+ return (yield* Effect.forEach(found, ([, kind]) => kind.discover(dir, [...new Set(kind.manifests.flatMap(nested))]), { concurrency: "unbounded" })).flat();
11857
11908
  });
11858
11909
  const layer$3 = Layer.effect(ProviderSource, Effect.gen(function* () {
11859
11910
  const context = yield* Effect.context();
@@ -11963,7 +12014,7 @@ const message = (version) => {
11963
12014
  };
11964
12015
  const lookup$1 = Effect.fn("npm.lookup")(function* (client, wanted) {
11965
12016
  const path = wanted.name.replace("/", "%2F");
11966
- const [packument, downloads] = yield* Effect.all([getJson(client, `https://registry.npmjs.org/${path}`, Packument), getJson(client, `https://api.npmjs.org/downloads/point/last-week/${wanted.name}`, Downloads).pipe(Effect.option)], { concurrency: 2 });
12017
+ const [packument, downloads] = yield* Effect.all([getJson(client, `https://registry.npmjs.org/${path}`, Packument), getJson(client, `https://api.npmjs.org/downloads/point/last-week/${wanted.name}`, Downloads).pipe(Effect.option)], { concurrency: "unbounded" });
11967
12018
  const versions = packument.versions ?? {};
11968
12019
  const latest = packument["dist-tags"]?.latest;
11969
12020
  const repository = Predicate.isString(packument.repository) ? packument.repository : packument.repository?.url;
@@ -12003,7 +12054,7 @@ const repositoryKeys = [
12003
12054
  "GitHub"
12004
12055
  ];
12005
12056
  const lookup = Effect.fn("pypi.lookup")(function* (client, wanted) {
12006
- const [project, recent] = yield* Effect.all([getJson(client, `https://pypi.org/pypi/${wanted.name}/json`, Project), getJson(client, `https://pypistats.org/api/packages/${wanted.name.toLowerCase()}/recent`, Recent).pipe(Effect.option)], { concurrency: 2 });
12057
+ const [project, recent] = yield* Effect.all([getJson(client, `https://pypi.org/pypi/${wanted.name}/json`, Project), getJson(client, `https://pypistats.org/api/packages/${wanted.name.toLowerCase()}/recent`, Recent).pipe(Effect.option)], { concurrency: "unbounded" });
12007
12058
  const urls = project.info.project_urls ?? {};
12008
12059
  const repository = repositoryKeys.map((key) => urls[key]).find((url) => url !== void 0);
12009
12060
  const homepage = urls["Homepage"] ?? project.info.home_page ?? void 0;
@@ -12597,12 +12648,10 @@ const layer$1 = (cacheDir) => Layer.succeed(UpdateLog, UpdateLog.of({
12597
12648
  const directory = path.join(cacheDir, "updates");
12598
12649
  const names = (await readdir(directory).catch(() => [])).filter((name) => name.endsWith(".jsonl")).toSorted();
12599
12650
  const found = [];
12600
- for (const name of names) {
12601
- const text = await readFile(path.join(directory, name), "utf-8").catch(() => "");
12602
- for (const line of text.split("\n")) {
12603
- const entry = Option.getOrUndefined(decodeLine(line));
12604
- if (entry?.scope === scope && Date.parse(entry.at) >= since) found.push(entry);
12605
- }
12651
+ const texts = await Promise.all(names.map(async (name) => await readFile(path.join(directory, name), "utf-8").catch(() => "")));
12652
+ for (const text of texts) for (const line of text.split("\n")) {
12653
+ const entry = Option.getOrUndefined(decodeLine(line));
12654
+ if (entry?.scope === scope && Date.parse(entry.at) >= since) found.push(entry);
12606
12655
  }
12607
12656
  return found;
12608
12657
  })
@@ -13346,8 +13395,8 @@ const layer = Layer.effect(Session, Effect.gen(function* () {
13346
13395
  };
13347
13396
  });
13348
13397
  const recallAll = Effect.gen(function* () {
13349
- const found = yield* earlier(yield* SubscriptionRef.get(state));
13350
- const logged = yield* fromLog(yield* SubscriptionRef.get(state));
13398
+ const before = yield* SubscriptionRef.get(state);
13399
+ const [found, logged] = yield* Effect.all([earlier(before), fromLog(before)], { concurrency: "unbounded" });
13351
13400
  yield* update((latest) => ({
13352
13401
  ...latest,
13353
13402
  installed: {
@@ -13366,15 +13415,14 @@ const layer = Layer.effect(Session, Effect.gen(function* () {
13366
13415
  const identity = identityOf(pkg, current.mode);
13367
13416
  if (identity !== void 0 && current.audits[jobKey(identity)]?._tag !== "Running") wanted.set(jobKey(identity), identity);
13368
13417
  }
13369
- yield* Effect.forEach(wanted.values(), audits.recall, {
13370
- concurrency: 4,
13371
- discard: true
13372
- });
13373
13418
  const offered = packagesOf(current).flatMap((pkg) => {
13374
13419
  const identity = pkg.target === void 0 ? void 0 : identityOf(pkg, current.mode);
13375
13420
  return identity === void 0 ? [] : [identity];
13376
13421
  });
13377
- const majors = yield* Effect.forEach(offered, (identity) => audits.majors(identity).pipe(Effect.map((identityMajors) => [jobKey(identity), identityMajors])), { concurrency: 4 });
13422
+ const [, majors] = yield* Effect.all([Effect.forEach(wanted.values(), audits.recall, {
13423
+ concurrency: 4,
13424
+ discard: true
13425
+ }), Effect.forEach(offered, (identity) => audits.majors(identity).pipe(Effect.map((identityMajors) => [jobKey(identity), identityMajors])), { concurrency: 4 })], { concurrency: "unbounded" });
13378
13426
  yield* update((latest) => ({
13379
13427
  ...latest,
13380
13428
  majors: {