@sortedyuan/maybecode 0.3.2 → 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.
Files changed (295) hide show
  1. package/README.md +166 -55
  2. package/README.zh-CN.md +267 -0
  3. package/dist/application.d.ts +40 -34
  4. package/dist/application.d.ts.map +1 -1
  5. package/dist/application.js +290 -170
  6. package/dist/application.js.map +1 -1
  7. package/dist/args.d.ts +2 -2
  8. package/dist/args.d.ts.map +1 -1
  9. package/dist/args.js +50 -27
  10. package/dist/args.js.map +1 -1
  11. package/dist/bin.js +82 -71
  12. package/dist/bin.js.map +4 -4
  13. package/dist/cli/chunk-3IORPKBL.js +3572 -0
  14. package/dist/cli/chunk-3IORPKBL.js.map +7 -0
  15. package/dist/cli/{chunk-LVTRXPDS.js → chunk-4B2Z6KW7.js} +1547 -1536
  16. package/dist/cli/chunk-4B2Z6KW7.js.map +7 -0
  17. package/dist/cli/{chunk-JT6VBKOM.js → chunk-4WG6JIJJ.js} +127 -33
  18. package/dist/cli/{chunk-JT6VBKOM.js.map → chunk-4WG6JIJJ.js.map} +3 -3
  19. package/dist/cli/{chunk-K5JWPNSY.js → chunk-5SLWALZK.js} +3521 -16164
  20. package/dist/cli/chunk-5SLWALZK.js.map +7 -0
  21. package/dist/cli/chunk-MNBYXL5Y.js +132 -0
  22. package/dist/cli/chunk-MNBYXL5Y.js.map +7 -0
  23. package/dist/cli/{chunk-F4XRPLUM.js → chunk-SLWLUEHQ.js} +226 -86
  24. package/dist/cli/chunk-SLWLUEHQ.js.map +7 -0
  25. package/dist/cli/chunk-UQDZ55LQ.js +199 -0
  26. package/dist/cli/chunk-UQDZ55LQ.js.map +7 -0
  27. package/dist/cli/{chunk-7ISOHFS7.js → chunk-WMSG5ZTR.js} +717 -388
  28. package/dist/cli/chunk-WMSG5ZTR.js.map +7 -0
  29. package/dist/cli/chunk-WVIRS76R.js +4057 -0
  30. package/dist/cli/chunk-WVIRS76R.js.map +7 -0
  31. package/dist/cli/{chunk-HOU5ITUK.js → chunk-XTEMRAQW.js} +1 -1
  32. package/dist/cli/chunk-XTEMRAQW.js.map +7 -0
  33. package/dist/cli/chunk-Z3BOPBVU.js +91 -0
  34. package/dist/cli/chunk-Z3BOPBVU.js.map +7 -0
  35. package/dist/cli/{configured-WHY3GGAJ.js → configured-ACNM6TRQ.js} +10 -9
  36. package/dist/cli/{file-type-R2T7TBHI.js → file-type-HLHPV7WC.js} +817 -13
  37. package/dist/cli/file-type-HLHPV7WC.js.map +7 -0
  38. package/dist/cli/mcp-auth-XD5U7WCV.js +74 -0
  39. package/dist/cli/mcp-auth-XD5U7WCV.js.map +7 -0
  40. package/dist/cli/onboarding-WQWCPYEO.js +530 -0
  41. package/dist/cli/onboarding-WQWCPYEO.js.map +7 -0
  42. package/dist/cli/onboarding-check-HRRI5OJ7.js +32 -0
  43. package/dist/cli/onboarding-check-HRRI5OJ7.js.map +7 -0
  44. package/dist/cli/{retained-tui-VJ3VX4R3.js → retained-tui-QF5VMYLC.js} +788 -332
  45. package/dist/cli/retained-tui-QF5VMYLC.js.map +7 -0
  46. package/dist/cli/{sixel-LWTCM76G.js → sixel-ISZ4FZ3U.js} +37 -37
  47. package/dist/cli/{sixel-LWTCM76G.js.map → sixel-ISZ4FZ3U.js.map} +1 -1
  48. package/dist/cli/{team-T7G7PPNN.js → team-O2I5BXHM.js} +7 -6
  49. package/dist/cli/{team-v2-JGBBQ7FR.js → team-v2-YYO2G7DJ.js} +816 -390
  50. package/dist/cli/team-v2-YYO2G7DJ.js.map +7 -0
  51. package/dist/cli/{web-server-FOMNPY7Q.js → web-server-SXMH6FGA.js} +55 -19
  52. package/dist/cli/web-server-SXMH6FGA.js.map +7 -0
  53. package/dist/cli/{web-ui-COB6PKC5.js → web-ui-UWQUFE4W.js} +7 -6
  54. package/dist/config-schema.json +337 -0
  55. package/dist/configured.d.ts +18 -11
  56. package/dist/configured.d.ts.map +1 -1
  57. package/dist/configured.js +213 -390
  58. package/dist/configured.js.map +1 -1
  59. package/dist/controller.d.ts +19 -18
  60. package/dist/controller.d.ts.map +1 -1
  61. package/dist/delegation-commands.d.ts +1 -1
  62. package/dist/delegation-commands.d.ts.map +1 -1
  63. package/dist/delegation-commands.js +8 -8
  64. package/dist/delegation-commands.js.map +1 -1
  65. package/dist/errors.d.ts +2 -1
  66. package/dist/errors.d.ts.map +1 -1
  67. package/dist/errors.js +2 -1
  68. package/dist/errors.js.map +1 -1
  69. package/dist/events.d.ts +8 -6
  70. package/dist/events.d.ts.map +1 -1
  71. package/dist/fork-picker.d.ts.map +1 -1
  72. package/dist/fork-picker.js +19 -5
  73. package/dist/fork-picker.js.map +1 -1
  74. package/dist/git-request.d.ts +6 -6
  75. package/dist/git-request.d.ts.map +1 -1
  76. package/dist/git-request.js +28 -15
  77. package/dist/git-request.js.map +1 -1
  78. package/dist/goal-commands.d.ts +1 -1
  79. package/dist/goal-commands.d.ts.map +1 -1
  80. package/dist/goal-commands.js +12 -5
  81. package/dist/goal-commands.js.map +1 -1
  82. package/dist/index.d.ts +5 -37
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +3 -36
  85. package/dist/index.js.map +1 -1
  86. package/dist/instructions.d.ts +2 -7
  87. package/dist/instructions.d.ts.map +1 -1
  88. package/dist/instructions.js +7 -15
  89. package/dist/instructions.js.map +1 -1
  90. package/dist/keymap.d.ts +2 -2
  91. package/dist/keymap.d.ts.map +1 -1
  92. package/dist/keymap.js +2 -2
  93. package/dist/keymap.js.map +1 -1
  94. package/dist/maybecode-config.schema.json +1765 -0
  95. package/dist/mcp-auth.d.ts +1 -1
  96. package/dist/mcp-auth.d.ts.map +1 -1
  97. package/dist/mcp-auth.js +11 -8
  98. package/dist/mcp-auth.js.map +1 -1
  99. package/dist/mcp-commands.d.ts.map +1 -1
  100. package/dist/mcp-commands.js +18 -4
  101. package/dist/mcp-commands.js.map +1 -1
  102. package/dist/mcp-interaction-ui.d.ts.map +1 -1
  103. package/dist/mcp-interaction-ui.js +11 -4
  104. package/dist/mcp-interaction-ui.js.map +1 -1
  105. package/dist/media-history.d.ts +1 -1
  106. package/dist/media-history.d.ts.map +1 -1
  107. package/dist/media-history.js +8 -2
  108. package/dist/media-history.js.map +1 -1
  109. package/dist/model-picker.d.ts.map +1 -1
  110. package/dist/model-picker.js +10 -11
  111. package/dist/model-picker.js.map +1 -1
  112. package/dist/model-transition.d.ts +11 -0
  113. package/dist/model-transition.d.ts.map +1 -0
  114. package/dist/model-transition.js +48 -0
  115. package/dist/model-transition.js.map +1 -0
  116. package/dist/model.d.ts +2 -2
  117. package/dist/model.d.ts.map +1 -1
  118. package/dist/model.js +8 -4
  119. package/dist/model.js.map +1 -1
  120. package/dist/onboarding-check.d.ts +3 -0
  121. package/dist/onboarding-check.d.ts.map +1 -0
  122. package/dist/onboarding-check.js +22 -0
  123. package/dist/onboarding-check.js.map +1 -0
  124. package/dist/onboarding.d.ts +6 -0
  125. package/dist/onboarding.d.ts.map +1 -0
  126. package/dist/onboarding.js +463 -0
  127. package/dist/onboarding.js.map +1 -0
  128. package/dist/plugins/application.d.ts +6 -4
  129. package/dist/plugins/application.d.ts.map +1 -1
  130. package/dist/plugins/application.js +106 -52
  131. package/dist/plugins/application.js.map +1 -1
  132. package/dist/plugins/instructions.d.ts +1 -1
  133. package/dist/plugins/instructions.d.ts.map +1 -1
  134. package/dist/plugins/instructions.js +24 -11
  135. package/dist/plugins/instructions.js.map +1 -1
  136. package/dist/plugins/resources.d.ts +2 -2
  137. package/dist/plugins/resources.d.ts.map +1 -1
  138. package/dist/plugins/resources.js +22 -12
  139. package/dist/plugins/resources.js.map +1 -1
  140. package/dist/policy.d.ts +1 -1
  141. package/dist/policy.d.ts.map +1 -1
  142. package/dist/policy.js +59 -11
  143. package/dist/policy.js.map +1 -1
  144. package/dist/run.d.ts +2 -0
  145. package/dist/run.d.ts.map +1 -1
  146. package/dist/run.js +38 -33
  147. package/dist/run.js.map +1 -1
  148. package/dist/runtime-instructions.d.ts +1 -1
  149. package/dist/runtime-instructions.d.ts.map +1 -1
  150. package/dist/runtime-instructions.js +15 -7
  151. package/dist/runtime-instructions.js.map +1 -1
  152. package/dist/session-navigation.d.ts +6 -0
  153. package/dist/session-navigation.d.ts.map +1 -0
  154. package/dist/session-navigation.js +64 -0
  155. package/dist/session-navigation.js.map +1 -0
  156. package/dist/session-picker.d.ts +1 -1
  157. package/dist/session-picker.d.ts.map +1 -1
  158. package/dist/session-picker.js +23 -32
  159. package/dist/session-picker.js.map +1 -1
  160. package/dist/settings.d.ts +718 -0
  161. package/dist/settings.d.ts.map +1 -0
  162. package/dist/settings.js +14 -0
  163. package/dist/settings.js.map +1 -0
  164. package/dist/skills.d.ts +1 -1
  165. package/dist/skills.d.ts.map +1 -1
  166. package/dist/skills.js +10 -12
  167. package/dist/skills.js.map +1 -1
  168. package/dist/slash-commands.d.ts +2 -2
  169. package/dist/slash-commands.d.ts.map +1 -1
  170. package/dist/slash-commands.js +149 -67
  171. package/dist/slash-commands.js.map +1 -1
  172. package/dist/team-execution.d.ts +10 -0
  173. package/dist/team-execution.d.ts.map +1 -0
  174. package/dist/team-execution.js +29 -0
  175. package/dist/team-execution.js.map +1 -0
  176. package/dist/team-patches.d.ts.map +1 -1
  177. package/dist/team-patches.js +149 -52
  178. package/dist/team-patches.js.map +1 -1
  179. package/dist/team-plan.d.ts +2 -2
  180. package/dist/team-plan.d.ts.map +1 -1
  181. package/dist/team-plan.js +115 -34
  182. package/dist/team-plan.js.map +1 -1
  183. package/dist/team-recovery.d.ts +1 -1
  184. package/dist/team-recovery.d.ts.map +1 -1
  185. package/dist/team-recovery.js +40 -10
  186. package/dist/team-recovery.js.map +1 -1
  187. package/dist/team-v2.d.ts.map +1 -1
  188. package/dist/team-v2.js +335 -104
  189. package/dist/team-v2.js.map +1 -1
  190. package/dist/team-verification.d.ts +4 -2
  191. package/dist/team-verification.d.ts.map +1 -1
  192. package/dist/team-verification.js +300 -97
  193. package/dist/team-verification.js.map +1 -1
  194. package/dist/team.d.ts +2 -2
  195. package/dist/team.d.ts.map +1 -1
  196. package/dist/team.js +172 -62
  197. package/dist/team.js.map +1 -1
  198. package/dist/terminal-web.d.ts +1 -0
  199. package/dist/terminal-web.d.ts.map +1 -1
  200. package/dist/terminal-web.js +28 -10
  201. package/dist/terminal-web.js.map +1 -1
  202. package/dist/ui/actions.d.ts.map +1 -1
  203. package/dist/ui/actions.js.map +1 -1
  204. package/dist/ui/retained-tui.d.ts.map +1 -1
  205. package/dist/ui/retained-tui.js +231 -173
  206. package/dist/ui/retained-tui.js.map +1 -1
  207. package/dist/ui/{prototype-view.d.ts → terminal-view.d.ts} +7 -7
  208. package/dist/ui/terminal-view.d.ts.map +1 -0
  209. package/dist/ui/{prototype-view.js → terminal-view.js} +185 -98
  210. package/dist/ui/terminal-view.js.map +1 -0
  211. package/dist/web-commands.d.ts.map +1 -1
  212. package/dist/web-commands.js +160 -57
  213. package/dist/web-commands.js.map +1 -1
  214. package/dist/web-extension.d.ts.map +1 -1
  215. package/dist/web-extension.js +14 -4
  216. package/dist/web-extension.js.map +1 -1
  217. package/dist/web-server.d.ts.map +1 -1
  218. package/dist/web-server.js +2 -1
  219. package/dist/web-server.js.map +1 -1
  220. package/dist/web-ui.d.ts.map +1 -1
  221. package/dist/web-ui.js +167 -40
  222. package/dist/web-ui.js.map +1 -1
  223. package/dist/workspace-configuration.d.ts +7 -0
  224. package/dist/workspace-configuration.d.ts.map +1 -0
  225. package/dist/workspace-configuration.js +134 -0
  226. package/dist/workspace-configuration.js.map +1 -0
  227. package/dist/workspace-state.d.ts +20 -0
  228. package/dist/workspace-state.d.ts.map +1 -0
  229. package/dist/workspace-state.js +2 -0
  230. package/dist/workspace-state.js.map +1 -0
  231. package/dist/workspace.d.ts +26 -43
  232. package/dist/workspace.d.ts.map +1 -1
  233. package/dist/workspace.js +261 -323
  234. package/dist/workspace.js.map +1 -1
  235. package/package.json +21 -31
  236. package/dist/cli/chunk-7ISOHFS7.js.map +0 -7
  237. package/dist/cli/chunk-F4XRPLUM.js.map +0 -7
  238. package/dist/cli/chunk-H7SNBFO4.js +0 -5522
  239. package/dist/cli/chunk-H7SNBFO4.js.map +0 -7
  240. package/dist/cli/chunk-HOU5ITUK.js.map +0 -7
  241. package/dist/cli/chunk-K5JWPNSY.js.map +0 -7
  242. package/dist/cli/chunk-LVTRXPDS.js.map +0 -7
  243. package/dist/cli/chunk-VAZMCNBB.js +0 -686
  244. package/dist/cli/chunk-VAZMCNBB.js.map +0 -7
  245. package/dist/cli/chunk-WOFEI42C.js +0 -7820
  246. package/dist/cli/chunk-WOFEI42C.js.map +0 -7
  247. package/dist/cli/file-type-R2T7TBHI.js.map +0 -7
  248. package/dist/cli/mcp-auth-UNRHSIKJ.js +0 -63
  249. package/dist/cli/mcp-auth-UNRHSIKJ.js.map +0 -7
  250. package/dist/cli/retained-tui-VJ3VX4R3.js.map +0 -7
  251. package/dist/cli/team-v2-JGBBQ7FR.js.map +0 -7
  252. package/dist/cli/tui-SA74DKMA.js +0 -1705
  253. package/dist/cli/tui-SA74DKMA.js.map +0 -7
  254. package/dist/cli/web-server-FOMNPY7Q.js.map +0 -7
  255. package/dist/delegation.d.ts +0 -2
  256. package/dist/delegation.d.ts.map +0 -1
  257. package/dist/delegation.js +0 -2
  258. package/dist/delegation.js.map +0 -1
  259. package/dist/history-memory.d.ts +0 -2
  260. package/dist/history-memory.d.ts.map +0 -1
  261. package/dist/history-memory.js +0 -2
  262. package/dist/history-memory.js.map +0 -1
  263. package/dist/subagent-budget.d.ts +0 -2
  264. package/dist/subagent-budget.d.ts.map +0 -1
  265. package/dist/subagent-budget.js +0 -2
  266. package/dist/subagent-budget.js.map +0 -1
  267. package/dist/subagent-files.d.ts +0 -2
  268. package/dist/subagent-files.d.ts.map +0 -1
  269. package/dist/subagent-files.js +0 -2
  270. package/dist/subagent-files.js.map +0 -1
  271. package/dist/subagent-host.d.ts +0 -2
  272. package/dist/subagent-host.d.ts.map +0 -1
  273. package/dist/subagent-host.js +0 -2
  274. package/dist/subagent-host.js.map +0 -1
  275. package/dist/subagent-instructions.d.ts +0 -2
  276. package/dist/subagent-instructions.d.ts.map +0 -1
  277. package/dist/subagent-instructions.js +0 -2
  278. package/dist/subagent-instructions.js.map +0 -1
  279. package/dist/subagents.d.ts +0 -2
  280. package/dist/subagents.d.ts.map +0 -1
  281. package/dist/subagents.js +0 -2
  282. package/dist/subagents.js.map +0 -1
  283. package/dist/summarizer.d.ts +0 -2
  284. package/dist/summarizer.d.ts.map +0 -1
  285. package/dist/summarizer.js +0 -2
  286. package/dist/summarizer.js.map +0 -1
  287. package/dist/tui.d.ts +0 -7
  288. package/dist/tui.d.ts.map +0 -1
  289. package/dist/tui.js +0 -1109
  290. package/dist/tui.js.map +0 -1
  291. package/dist/ui/prototype-view.d.ts.map +0 -1
  292. package/dist/ui/prototype-view.js.map +0 -1
  293. /package/dist/cli/{configured-WHY3GGAJ.js.map → configured-ACNM6TRQ.js.map} +0 -0
  294. /package/dist/cli/{team-T7G7PPNN.js.map → team-O2I5BXHM.js.map} +0 -0
  295. /package/dist/cli/{web-ui-COB6PKC5.js.map → web-ui-UWQUFE4W.js.map} +0 -0
@@ -1,18 +1,18 @@
1
- import { acquireFileLock, releaseFileLock } from "@sortedyuan/session/file-store";
1
+ import { acquireFileLock, hasErrorCode } from "@sortedyuan/may/storage";
2
2
  import { createHash } from "node:crypto";
3
- import { spawn } from "node:child_process";
4
3
  import { constants } from "node:fs";
5
4
  import { lstat, mkdir, open, readdir, realpath } from "node:fs/promises";
6
5
  import { isAbsolute, join, relative, resolve, sep } from "node:path";
7
6
  import { isDeepStrictEqual } from "node:util";
8
- import { AsyncStateSerializer } from "@sortedyuan/application";
7
+ import { AsyncStateSerializer } from "@sortedyuan/may/core";
8
+ import { openCodingExecutionEnvironment } from "@sortedyuan/coding-tools";
9
9
  const maxJournalBytes = 16_777_216;
10
10
  /** Host evidence and deterministic checks; a model report can never grant acceptance. */
11
11
  export class TeamVerificationStore {
12
12
  file;
13
13
  lock;
14
- lockPath;
15
14
  checks;
15
+ executionFor;
16
16
  serial = new AsyncStateSerializer();
17
17
  reports = [];
18
18
  results = new Map();
@@ -21,11 +21,11 @@ export class TeamVerificationStore {
21
21
  failed = false;
22
22
  closing;
23
23
  active = new Set();
24
- constructor(file, lock, lockPath, checks) {
24
+ constructor(file, lock, checks, executionFor) {
25
25
  this.file = file;
26
26
  this.lock = lock;
27
- this.lockPath = lockPath;
28
27
  this.checks = checks;
28
+ this.executionFor = executionFor;
29
29
  }
30
30
  static async open(options) {
31
31
  const checks = parseTeamChecks(options.checks ?? []);
@@ -33,12 +33,9 @@ export class TeamVerificationStore {
33
33
  if ((await lstat(options.directory)).isSymbolicLink())
34
34
  throw new Error("Verification directory must not be a symbolic link");
35
35
  const path = join(await realpath(options.directory), "verification.jsonl");
36
- const lockPath = `${path}.lock`;
37
- const lock = await acquireFileLock(lockPath);
36
+ const lock = await acquireFileLock(`${path}.lock`);
38
37
  let file;
39
38
  try {
40
- await lock.writeFile(JSON.stringify({ pid: process.pid }));
41
- await lock.sync();
42
39
  await rejectLinkIfPresent(path);
43
40
  file = await open(path, constants.O_CREAT | constants.O_APPEND | constants.O_RDWR | noFollow(), 0o600);
44
41
  const { entries, committed, size } = await readJournal(file);
@@ -53,26 +50,38 @@ export class TeamVerificationStore {
53
50
  await repair.close();
54
51
  }
55
52
  }
56
- const store = new TeamVerificationStore(file, lock, lockPath, checks);
53
+ const store = new TeamVerificationStore(file, lock, checks, options.executionFor);
57
54
  store.size = committed;
58
55
  for (const entry of entries) {
59
56
  store.apply(entry.event);
60
57
  store.sequence = entry.sequence;
61
58
  }
62
- if (entries.length && !isDeepStrictEqual(entries[0].event.checks, checks))
59
+ if (entries.length &&
60
+ !isDeepStrictEqual(entries[0].event.checks, checks))
63
61
  throw new Error("Verification checks changed on resume");
64
62
  if (!entries.length)
65
63
  await store.append({ type: "config", checks });
66
64
  // No command, test, or other effect is replayed during recovery.
67
65
  for (const result of store.results.values())
68
66
  if (result.status === "pending") {
69
- await store.append({ type: "check", result: { ...result, status: "unknown", detail: "Interrupted check; inspect effects and reconcile before a new command." } });
67
+ await store.append({
68
+ type: "check",
69
+ result: {
70
+ ...result,
71
+ status: "unknown",
72
+ detail: "Interrupted check; inspect effects and reconcile before a new command.",
73
+ },
74
+ });
70
75
  }
71
76
  return store;
72
77
  }
73
78
  catch (error) {
74
- await file?.close().catch(() => undefined);
75
- await releaseFileLock(lock, lockPath);
79
+ try {
80
+ await file?.close();
81
+ }
82
+ finally {
83
+ await lock.release();
84
+ }
76
85
  throw error;
77
86
  }
78
87
  }
@@ -85,7 +94,7 @@ export class TeamVerificationStore {
85
94
  file = await open(path, constants.O_RDONLY | noFollow());
86
95
  }
87
96
  catch (error) {
88
- if (isMissing(error))
97
+ if (hasErrorCode(error, "ENOENT"))
89
98
  return { reports: [], checks: [] };
90
99
  throw error;
91
100
  }
@@ -105,7 +114,12 @@ export class TeamVerificationStore {
105
114
  await file.close();
106
115
  }
107
116
  }
108
- snapshot() { return this.serial.run(() => { this.assertOpen(); return structuredClone({ reports: this.reports, checks: [...this.results.values()] }); }); }
117
+ snapshot() {
118
+ return this.serial.run(() => {
119
+ this.assertOpen();
120
+ return structuredClone({ reports: this.reports, checks: [...this.results.values()] });
121
+ });
122
+ }
109
123
  forTask(execution, workspace, options = {}) {
110
124
  const identity = taskIdentity(execution);
111
125
  const submit = (commandId, report) => this.submit(identity, commandId, report, workspace);
@@ -115,23 +129,75 @@ export class TeamVerificationStore {
115
129
  throw new Error("Check is not configured for this task");
116
130
  return this.runCheck(commandId, spec, workspace, { ...options, ...extra, execution });
117
131
  };
118
- const tools = () => [{
119
- name: "submit_report", permissionVersion: "team-verification-v1",
132
+ const tools = () => [
133
+ {
134
+ name: "submit_report",
135
+ permissionVersion: "team-verification-v1",
120
136
  description: "Store a structured report and file/line evidence. The host validates evidence bytes, not claim correctness. This never grants acceptance.",
121
- inputSchema: { type: "object", additionalProperties: false, required: ["summary", "claims"], properties: {
122
- summary: { type: "string" }, claims: { type: "array", items: { type: "object", additionalProperties: false, required: ["text", "kind"], properties: {
123
- text: { type: "string" }, kind: { type: "string", enum: ["finding", "proposal"] }, evidence: { type: "array", items: { type: "object", additionalProperties: false, required: ["path", "startLine", "endLine"], properties: { path: { type: "string" }, startLine: { type: "integer" }, endLine: { type: "integer" }, quote: { type: "string" } } } },
124
- } } },
125
- } },
137
+ inputSchema: {
138
+ type: "object",
139
+ additionalProperties: false,
140
+ required: ["summary", "claims"],
141
+ properties: {
142
+ summary: { type: "string" },
143
+ claims: {
144
+ type: "array",
145
+ items: {
146
+ type: "object",
147
+ additionalProperties: false,
148
+ required: ["text", "kind"],
149
+ properties: {
150
+ text: { type: "string" },
151
+ kind: { type: "string", enum: ["finding", "proposal"] },
152
+ evidence: {
153
+ type: "array",
154
+ items: {
155
+ type: "object",
156
+ additionalProperties: false,
157
+ required: ["path", "startLine", "endLine"],
158
+ properties: {
159
+ path: { type: "string" },
160
+ startLine: { type: "integer" },
161
+ endLine: { type: "integer" },
162
+ quote: { type: "string" },
163
+ },
164
+ },
165
+ },
166
+ },
167
+ },
168
+ },
169
+ },
170
+ },
126
171
  parse: parseTeamReport,
127
- async execute(input, call) { call.signal.throwIfAborted(); return submit(hash(call.idempotencyKey), input); },
128
- }, {
129
- name: "run_check", permissionVersion: "team-verification-v1",
130
- description: `Run one exact host-configured check by id; no model-supplied commands or arguments. Available: ${this.checks.filter((entry) => entry.taskId === identity.taskId).map((entry) => entry.id).join(", ") || "none"}. Command checks require explicit host authorization and are not sandboxed.`,
131
- inputSchema: { type: "object", additionalProperties: false, required: ["id"], properties: { id: { type: "string" } } },
132
- parse(value) { const input = fields(value, ["id"]); identifier(input.id, "check id"); return { id: input.id }; },
133
- async execute(input, call) { call.signal.throwIfAborted(); return runCheck(hash(call.idempotencyKey), input.id, { signal: call.signal }); },
134
- }];
172
+ async execute(input, call) {
173
+ call.signal.throwIfAborted();
174
+ return submit(hash(call.idempotencyKey), input);
175
+ },
176
+ },
177
+ {
178
+ name: "run_check",
179
+ permissionVersion: "team-verification-v1",
180
+ description: `Run one exact host-configured check by id; no model-supplied commands or arguments. Available: ${this.checks
181
+ .filter((entry) => entry.taskId === identity.taskId)
182
+ .map((entry) => entry.id)
183
+ .join(", ") || "none"}. Command checks require explicit host authorization and are not sandboxed.`,
184
+ inputSchema: {
185
+ type: "object",
186
+ additionalProperties: false,
187
+ required: ["id"],
188
+ properties: { id: { type: "string" } },
189
+ },
190
+ parse(value) {
191
+ const input = fields(value, ["id"]);
192
+ identifier(input.id, "check id");
193
+ return { id: input.id };
194
+ },
195
+ async execute(input, call) {
196
+ call.signal.throwIfAborted();
197
+ return runCheck(hash(call.idempotencyKey), input.id, { signal: call.signal });
198
+ },
199
+ },
200
+ ];
135
201
  return { submit, runCheck, tools };
136
202
  }
137
203
  runCheck(commandId, input, workspace, options = {}) {
@@ -166,34 +232,56 @@ export class TeamVerificationStore {
166
232
  const fingerprint = await workspaceFingerprint(workspace);
167
233
  const state = await this.snapshot();
168
234
  const identity = execution ? taskIdentity(execution) : undefined;
169
- const report = state.reports.filter((entry) => entry.taskId === taskId && (!identity || sameIdentity(entry, identity))).at(-1);
170
- const checks = this.checks.filter((spec) => spec.taskId === taskId).map((spec) => {
171
- const result = state.checks.filter((entry) => entry.spec.id === spec.id && (!identity || entry.dispatchId === undefined || sameIdentity(entry, identity))).at(-1);
235
+ const report = state.reports
236
+ .filter((entry) => entry.taskId === taskId && (!identity || sameIdentity(entry, identity)))
237
+ .at(-1);
238
+ const checks = this.checks
239
+ .filter((spec) => spec.taskId === taskId)
240
+ .map((spec) => {
241
+ const result = state.checks
242
+ .filter((entry) => entry.spec.id === spec.id &&
243
+ (!identity || entry.dispatchId === undefined || sameIdentity(entry, identity)))
244
+ .at(-1);
172
245
  if (!result)
173
246
  return { id: spec.id, status: "missing" };
174
247
  const stale = result.workspaceFingerprint !== fingerprint || result.afterFingerprint !== fingerprint;
175
- return { id: spec.id, status: stale && !["pending", "unknown"].includes(result.status) ? "stale" : result.status, commandId: result.commandId, ...(result.detail ? { detail: result.detail } : {}) };
248
+ return {
249
+ id: spec.id,
250
+ status: stale && !["pending", "unknown"].includes(result.status) ? "stale" : result.status,
251
+ commandId: result.commandId,
252
+ ...(result.detail ? { detail: result.detail } : {}),
253
+ };
176
254
  });
177
255
  const currentReport = report?.workspaceFingerprint === fingerprint;
178
256
  const badEvidence = currentReport && report.evidence.some((item) => !item.valid);
179
- const status = badEvidence || checks.some((item) => item.status === "failed" || item.status === "cancelled") ? "failed"
180
- : currentReport && checks.length > 0 && checks.every((item) => item.status === "passed") ? "passed" : "unverified";
181
- return { status, workspaceFingerprint: fingerprint, checks, ...(report ? { report } : {}),
182
- detail: status === "passed" ? "Configured checks passed for these exact workspace bytes. Evidence locations are valid; claim logic and untested behavior remain unverified."
183
- : status === "failed" ? "A configured check or submitted evidence failed. Execution completion does not imply acceptance."
184
- : "A current structured report and all configured checks are required. Missing, stale, interrupted, or absent checks cannot grant acceptance." };
257
+ const status = badEvidence || checks.some((item) => item.status === "failed" || item.status === "cancelled")
258
+ ? "failed"
259
+ : currentReport && checks.length > 0 && checks.every((item) => item.status === "passed")
260
+ ? "passed"
261
+ : "unverified";
262
+ return {
263
+ status,
264
+ workspaceFingerprint: fingerprint,
265
+ checks,
266
+ ...(report ? { report } : {}),
267
+ detail: status === "passed"
268
+ ? "Configured checks passed for these exact workspace bytes. Evidence locations are valid; claim logic and untested behavior remain unverified."
269
+ : status === "failed"
270
+ ? "A configured check or submitted evidence failed. Execution completion does not imply acceptance."
271
+ : "A current structured report and all configured checks are required. Missing, stale, interrupted, or absent checks cannot grant acceptance.",
272
+ };
185
273
  }
186
274
  close() {
187
- return this.closing ??= (async () => {
275
+ return (this.closing ??= (async () => {
188
276
  await Promise.allSettled([...this.active]);
189
277
  await this.serial.close();
190
278
  try {
191
279
  await this.file.close();
192
280
  }
193
281
  finally {
194
- await releaseFileLock(this.lock, this.lockPath);
282
+ await this.lock.release();
195
283
  }
196
- })();
284
+ })());
197
285
  }
198
286
  async submit(identity, commandId, input, workspace) {
199
287
  identifier(commandId, "report command id");
@@ -218,15 +306,28 @@ export class TeamVerificationStore {
218
306
  if (lines.at(-1) === "")
219
307
  lines.pop();
220
308
  const excerpt = lines.slice(item.startLine - 1, item.endLine).join("\n");
221
- const valid = item.endLine <= lines.length && (item.quote === undefined || excerpt.includes(item.quote.replace(/\r\n/gu, "\n")));
222
- evidence.push({ path: item.path, startLine: item.startLine, endLine: item.endLine, sha256: hash(bytes), valid,
223
- ...(!valid ? { detail: "Line range or quote does not match the file" } : {}) });
309
+ const valid = item.endLine <= lines.length &&
310
+ (item.quote === undefined || excerpt.includes(item.quote.replace(/\r\n/gu, "\n")));
311
+ evidence.push({
312
+ path: item.path,
313
+ startLine: item.startLine,
314
+ endLine: item.endLine,
315
+ sha256: hash(bytes),
316
+ valid,
317
+ ...(!valid ? { detail: "Line range or quote does not match the file" } : {}),
318
+ });
224
319
  }
225
320
  catch (error) {
226
- evidence.push({ path: item.path, startLine: item.startLine, endLine: item.endLine, valid: false, detail: message(error) });
321
+ evidence.push({
322
+ path: item.path,
323
+ startLine: item.startLine,
324
+ endLine: item.endLine,
325
+ valid: false,
326
+ detail: message(error),
327
+ });
227
328
  }
228
329
  }
229
- if (await workspaceFingerprint(workspace) !== fingerprint)
330
+ if ((await workspaceFingerprint(workspace)) !== fingerprint)
230
331
  throw new Error("Workspace changed while validating report evidence");
231
332
  const stored = { ...identity, commandId, report, workspaceFingerprint: fingerprint, evidence };
232
333
  await this.write({ type: "report", report: stored });
@@ -258,7 +359,13 @@ export class TeamVerificationStore {
258
359
  if (spec.type === "command" && options.allowCommands !== true)
259
360
  throw new Error("Command checks require explicit --allow-checks authorization");
260
361
  options.signal?.throwIfAborted();
261
- const result = { ...identity, commandId, spec, workspaceFingerprint: await workspaceFingerprint(workspace), status: "pending" };
362
+ const result = {
363
+ ...identity,
364
+ commandId,
365
+ spec,
366
+ workspaceFingerprint: await workspaceFingerprint(workspace),
367
+ status: "pending",
368
+ };
262
369
  await this.write({ type: "check", result });
263
370
  fresh = true;
264
371
  return result;
@@ -268,12 +375,15 @@ export class TeamVerificationStore {
268
375
  let outcome;
269
376
  try {
270
377
  if (spec.type === "command")
271
- outcome = await runCommand(spec, workspace, options.signal);
378
+ outcome = await runCommand(spec, workspace, options.signal, this.executionFor);
272
379
  else {
273
380
  options.signal?.throwIfAborted();
274
381
  const bytes = await readWorkspaceFile(workspace, spec.path);
275
382
  const passed = spec.type === "file-sha256" ? hash(bytes) === spec.sha256 : bytes.toString("utf8").includes(spec.text);
276
- outcome = { status: passed ? "passed" : "failed", detail: passed ? "Exact configured file check passed" : "Configured file predicate did not match" };
383
+ outcome = {
384
+ status: passed ? "passed" : "failed",
385
+ detail: passed ? "Exact configured file check passed" : "Configured file predicate did not match",
386
+ };
277
387
  }
278
388
  }
279
389
  catch (error) {
@@ -284,13 +394,19 @@ export class TeamVerificationStore {
284
394
  afterFingerprint = await workspaceFingerprint(workspace);
285
395
  }
286
396
  catch (error) {
287
- outcome = { ...outcome, status: spec.type === "command" ? "unknown" : "failed", detail: `Cannot inspect workspace after check: ${message(error)}` };
397
+ outcome = {
398
+ ...outcome,
399
+ status: spec.type === "command" ? "unknown" : "failed",
400
+ detail: `Cannot inspect workspace after check: ${message(error)}`,
401
+ };
288
402
  }
289
403
  const result = { ...pending, ...outcome, ...(afterFingerprint ? { afterFingerprint } : {}) };
290
404
  await this.append({ type: "check", result });
291
405
  return structuredClone(result);
292
406
  }
293
- append(event) { return this.serial.run(() => this.write(event)); }
407
+ append(event) {
408
+ return this.serial.run(() => this.write(event));
409
+ }
294
410
  async write(event) {
295
411
  this.assertOpen();
296
412
  const line = `${JSON.stringify({ sequence: this.sequence + 1, event })}\n`;
@@ -315,11 +431,24 @@ export class TeamVerificationStore {
315
431
  if (event.type === "check")
316
432
  this.results.set(event.result.commandId, event.result);
317
433
  }
318
- assertOpen() { if (this.failed)
319
- throw new Error("Verification write outcome unknown; close and inspect before continuing"); }
434
+ assertOpen() {
435
+ if (this.failed)
436
+ throw new Error("Verification write outcome unknown; close and inspect before continuing");
437
+ }
320
438
  }
321
439
  export function parseTeamCheck(value) {
322
- const raw = fields(value, ["id", "taskId", "type", "path", "text", "sha256", "command", "args", "timeoutMs", "maxOutputBytes"]);
440
+ const raw = fields(value, [
441
+ "id",
442
+ "taskId",
443
+ "type",
444
+ "path",
445
+ "text",
446
+ "sha256",
447
+ "command",
448
+ "args",
449
+ "timeoutMs",
450
+ "maxOutputBytes",
451
+ ]);
323
452
  identifier(raw.id, "check id");
324
453
  identifier(raw.taskId, "check taskId");
325
454
  if (raw.type === "file-contains") {
@@ -336,7 +465,10 @@ export function parseTeamCheck(value) {
336
465
  else if (raw.type === "command") {
337
466
  fields(raw, ["id", "taskId", "type", "command", "args", "timeoutMs", "maxOutputBytes"]);
338
467
  boundedString(raw.command, "check command", 4096);
339
- if (/[\u0000\r\n]/u.test(raw.command) || !Array.isArray(raw.args) || raw.args.length > 64 || raw.args.some((arg) => typeof arg !== "string" || arg.length > 8192 || arg.includes("\0")))
468
+ if (/[\u0000\r\n]/u.test(raw.command) ||
469
+ !Array.isArray(raw.args) ||
470
+ raw.args.length > 64 ||
471
+ raw.args.some((arg) => typeof arg !== "string" || arg.length > 8192 || arg.includes("\0")))
340
472
  throw new Error("Invalid check command arguments");
341
473
  if (raw.timeoutMs !== undefined)
342
474
  integer(raw.timeoutMs, 1, 120000, "check timeoutMs");
@@ -455,39 +587,78 @@ async function readWorkspaceFile(directory, path) {
455
587
  await file.close();
456
588
  }
457
589
  }
458
- async function runCommand(spec, workspace, signal) {
590
+ async function runCommand(spec, workspace, signal, executionFor) {
591
+ const environment = executionFor
592
+ ? await executionFor(workspace)
593
+ : await openCodingExecutionEnvironment({ workspace, isolation: { mode: "host" } });
594
+ try {
595
+ return await runEnvironmentCommand(spec, workspace, environment, signal);
596
+ }
597
+ finally {
598
+ if (!executionFor)
599
+ await environment.close();
600
+ }
601
+ }
602
+ async function runEnvironmentCommand(spec, workspace, environment, signal) {
459
603
  signal?.throwIfAborted();
460
604
  if (process.platform === "win32" && /\.(?:cmd|bat)$/iu.test(spec.command))
461
- return { status: "failed", detail: "Command checks execute native programs directly. Use node.exe with the package manager JavaScript entry point, not .cmd/.bat." };
605
+ return {
606
+ status: "failed",
607
+ detail: "Command checks execute native programs directly. Use node.exe with the package manager JavaScript entry point, not .cmd/.bat.",
608
+ };
462
609
  const cwd = await realpath(workspace);
463
610
  const env = {};
464
611
  // No inherited API keys, proxy tokens, NODE_OPTIONS, package hooks, or user home config.
465
- for (const key of ["PATH", "Path", "PATHEXT", "SystemRoot", "WINDIR", "COMSPEC", "TEMP", "TMP", "TMPDIR", "LANG", "LC_ALL"])
466
- if (process.env[key] !== undefined)
612
+ for (const key of [
613
+ "PATH",
614
+ "Path",
615
+ "PATHEXT",
616
+ "SystemRoot",
617
+ "WINDIR",
618
+ "COMSPEC",
619
+ "TEMP",
620
+ "TMP",
621
+ "TMPDIR",
622
+ "LANG",
623
+ "LC_ALL",
624
+ ])
625
+ if (environment.isolation.mode === "host" && process.env[key] !== undefined)
467
626
  env[key] = process.env[key];
468
627
  env.CI = "1";
469
- return new Promise((resolveResult) => {
628
+ return new Promise((resolveResult, rejectResult) => {
629
+ const cancellation = new AbortController();
470
630
  let output = Buffer.alloc(0);
471
631
  let reason;
472
632
  let settled = false;
473
- const child = spawn(spec.command, [...spec.args], { cwd, env, shell: false, windowsHide: true, stdio: ["ignore", "pipe", "pipe"] });
633
+ const child = environment.spawn(spec.command, spec.args, {
634
+ cwd,
635
+ env,
636
+ signal: cancellation.signal,
637
+ });
638
+ const stdout = child.stdout;
639
+ const stderr = child.stderr;
640
+ if (!stdout || !stderr) {
641
+ rejectResult(new Error("Execution environment must provide command output pipes"));
642
+ return;
643
+ }
474
644
  const finish = (status, exitCode, detail) => {
475
645
  if (settled)
476
646
  return;
477
647
  settled = true;
478
648
  clearTimeout(timer);
479
- clearTimeout(killWait);
480
649
  signal?.removeEventListener("abort", abort);
481
- resolveResult({ status, ...(exitCode !== undefined ? { exitCode } : {}), ...(detail ? { detail } : {}), output: boundedOutput(output, spec.maxOutputBytes ?? 65536) });
650
+ resolveResult({
651
+ status,
652
+ ...(exitCode !== undefined ? { exitCode } : {}),
653
+ ...(detail ? { detail } : {}),
654
+ output: boundedOutput(output, spec.maxOutputBytes ?? 65536),
655
+ });
482
656
  };
483
- let killWait;
484
657
  const stop = (detail) => {
485
658
  if (reason)
486
659
  return;
487
660
  reason = detail;
488
- child.kill("SIGKILL");
489
- // A descendant may retain inherited pipes. No process-tree or OS isolation guarantee.
490
- killWait = setTimeout(() => { child.stdout.destroy(); child.stderr.destroy(); finish("unknown", undefined, `${detail}; child effects require inspection`); }, 1000);
661
+ cancellation.abort();
491
662
  };
492
663
  const abort = () => stop("Check interrupted");
493
664
  const timer = setTimeout(() => stop("Check timed out"), spec.timeoutMs ?? 30000);
@@ -500,8 +671,8 @@ async function runCommand(spec, workspace, signal) {
500
671
  else
501
672
  output = Buffer.concat([output, chunk]);
502
673
  };
503
- child.stdout.on("data", collect);
504
- child.stderr.on("data", collect);
674
+ stdout.on("data", collect);
675
+ stderr.on("data", collect);
505
676
  child.on("error", (error) => finish(child.pid === undefined ? "failed" : "unknown", undefined, message(error)));
506
677
  child.on("close", (code, terminationSignal) => {
507
678
  if (reason || terminationSignal || code === null)
@@ -561,7 +732,8 @@ async function readJournal(file) {
561
732
  const result = event.result;
562
733
  parseTeamCheck(result.spec);
563
734
  validateStored(result);
564
- if (!isDeepStrictEqual(specs.find((entry) => entry.id === result.spec.id), result.spec) || result.taskId !== result.spec.taskId ||
735
+ if (!isDeepStrictEqual(specs.find((entry) => entry.id === result.spec.id), result.spec) ||
736
+ result.taskId !== result.spec.taskId ||
565
737
  !["pending", "passed", "failed", "unknown", "cancelled"].includes(result.status) ||
566
738
  (result.afterFingerprint !== undefined && !/^[a-f0-9]{64}$/u.test(result.afterFingerprint)))
567
739
  throw new Error("Invalid check record");
@@ -571,8 +743,11 @@ async function readJournal(file) {
571
743
  throw new Error("Check result has no pending intent");
572
744
  }
573
745
  else {
574
- if (!sameIdentity(old, result) || !isDeepStrictEqual(old.spec, result.spec) || old.workspaceFingerprint !== result.workspaceFingerprint ||
575
- (old.status !== "pending" && old.status !== "unknown") || result.status === "pending" ||
746
+ if (!sameIdentity(old, result) ||
747
+ !isDeepStrictEqual(old.spec, result.spec) ||
748
+ old.workspaceFingerprint !== result.workspaceFingerprint ||
749
+ (old.status !== "pending" && old.status !== "unknown") ||
750
+ result.status === "pending" ||
576
751
  (old.status === "unknown" && (!["failed", "cancelled"].includes(result.status) || !result.reconciliation)))
577
752
  throw new Error("Invalid check history transition");
578
753
  }
@@ -591,37 +766,65 @@ function validateStored(value) {
591
766
  throw new Error("Invalid stored workspace fingerprint");
592
767
  }
593
768
  function taskIdentity(execution) {
594
- return { taskId: execution.task.id, coordinationId: execution.coordinationId, dispatchId: execution.task.dispatchId, turn: execution.task.turn ?? 0 };
769
+ return {
770
+ taskId: execution.task.id,
771
+ coordinationId: execution.coordinationId,
772
+ dispatchId: execution.task.dispatchId,
773
+ turn: execution.task.turn ?? 0,
774
+ };
775
+ }
776
+ function sameIdentity(a, b) {
777
+ return (a.taskId === b.taskId && a.coordinationId === b.coordinationId && a.dispatchId === b.dispatchId && a.turn === b.turn);
595
778
  }
596
- function sameIdentity(a, b) { return a.taskId === b.taskId && a.coordinationId === b.coordinationId && a.dispatchId === b.dispatchId && a.turn === b.turn; }
597
779
  function fields(value, allowed) {
598
- if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).some((key) => !allowed.includes(key)))
780
+ if (!value ||
781
+ typeof value !== "object" ||
782
+ Array.isArray(value) ||
783
+ Object.keys(value).some((key) => !allowed.includes(key)))
599
784
  throw new Error("Invalid verification fields");
600
785
  return value;
601
786
  }
602
- function identifier(value, label) { if (typeof value !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,255}$/u.test(value))
603
- throw new Error(`Invalid ${label}`); }
604
- function boundedString(value, label, max) { if (typeof value !== "string" || value.length < 1 || Buffer.byteLength(value) > max || value.includes("\0"))
605
- throw new Error(`Invalid ${label}`); }
606
- function integer(value, min, max, label) { if (!Number.isSafeInteger(value) || value < min || value > max)
607
- throw new Error(`Invalid ${label}`); }
787
+ function identifier(value, label) {
788
+ if (typeof value !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,255}$/u.test(value))
789
+ throw new Error(`Invalid ${label}`);
790
+ }
791
+ function boundedString(value, label, max) {
792
+ if (typeof value !== "string" || value.length < 1 || Buffer.byteLength(value) > max || value.includes("\0"))
793
+ throw new Error(`Invalid ${label}`);
794
+ }
795
+ function integer(value, min, max, label) {
796
+ if (!Number.isSafeInteger(value) || value < min || value > max)
797
+ throw new Error(`Invalid ${label}`);
798
+ }
608
799
  function safeRelative(value) {
609
800
  boundedString(value, "workspace relative path", 2048);
610
- if (isAbsolute(value) || /[:\u0000-\u001f]/u.test(value) || value.replace(/\\/gu, "/").split("/").some((part) => !part || part === "." || part === ".."))
801
+ if (isAbsolute(value) ||
802
+ /[:\u0000-\u001f]/u.test(value) ||
803
+ value
804
+ .replace(/\\/gu, "/")
805
+ .split("/")
806
+ .some((part) => !part || part === "." || part === ".."))
611
807
  throw new Error("Unsafe workspace relative path");
612
808
  }
613
- async function rejectLinkIfPresent(path) { try {
614
- if ((await lstat(path)).isSymbolicLink())
615
- throw new Error("Verification file must not be a symbolic link");
809
+ async function rejectLinkIfPresent(path) {
810
+ try {
811
+ if ((await lstat(path)).isSymbolicLink())
812
+ throw new Error("Verification file must not be a symbolic link");
813
+ }
814
+ catch (error) {
815
+ if (!hasErrorCode(error, "ENOENT"))
816
+ throw error;
817
+ }
818
+ }
819
+ function noFollow() {
820
+ return process.platform === "win32" ? 0 : constants.O_NOFOLLOW;
821
+ }
822
+ function hash(value) {
823
+ return createHash("sha256").update(value).digest("hex");
824
+ }
825
+ function message(error) {
826
+ return (error instanceof Error ? error.message : String(error)).slice(0, 2048);
616
827
  }
617
- catch (error) {
618
- if (!isMissing(error))
619
- throw error;
620
- } }
621
- function isMissing(error) { return error instanceof Error && "code" in error && error.code === "ENOENT"; }
622
- function noFollow() { return process.platform === "win32" ? 0 : constants.O_NOFOLLOW; }
623
- function hash(value) { return createHash("sha256").update(value).digest("hex"); }
624
- function message(error) { return (error instanceof Error ? error.message : String(error)).slice(0, 2048); }
625
828
  function boundedOutput(bytes, limit) {
626
829
  const text = bytes.toString("utf8");
627
830
  if (Buffer.byteLength(text) <= limit)