agent-hitch 0.1.1 → 0.2.1

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 (263) hide show
  1. package/README.md +235 -132
  2. package/README.zh-CN.md +335 -0
  3. package/dist/bin/hitch.js +9 -0
  4. package/dist/bin/hitch.js.map +1 -0
  5. package/dist/scripts/check-architecture.js +159 -0
  6. package/dist/scripts/check-architecture.js.map +1 -0
  7. package/dist/scripts/check-release.js +25 -0
  8. package/dist/scripts/check-release.js.map +1 -0
  9. package/dist/scripts/check-syntax.js +32 -0
  10. package/dist/scripts/check-syntax.js.map +1 -0
  11. package/dist/src/adapters/catalog.js +55 -0
  12. package/dist/src/adapters/catalog.js.map +1 -0
  13. package/dist/src/adapters/contract.js +2 -0
  14. package/dist/src/adapters/contract.js.map +1 -0
  15. package/dist/src/adapters/discovery.js +22 -0
  16. package/dist/src/adapters/discovery.js.map +1 -0
  17. package/dist/src/adapters/index.js +3 -0
  18. package/dist/src/adapters/index.js.map +1 -0
  19. package/dist/src/adapters/providers/claude.js +69 -0
  20. package/dist/src/adapters/providers/claude.js.map +1 -0
  21. package/dist/src/adapters/providers/codex.js +74 -0
  22. package/dist/src/adapters/providers/codex.js.map +1 -0
  23. package/dist/src/adapters/providers/deepseek.js +51 -0
  24. package/dist/src/adapters/providers/deepseek.js.map +1 -0
  25. package/dist/src/adapters/providers/opencode.js +73 -0
  26. package/dist/src/adapters/providers/opencode.js.map +1 -0
  27. package/dist/src/adapters/providers/pi.js +82 -0
  28. package/dist/src/adapters/providers/pi.js.map +1 -0
  29. package/dist/src/adapters/providers/shared.js +82 -0
  30. package/dist/src/adapters/providers/shared.js.map +1 -0
  31. package/dist/src/artifacts/index.js +3 -0
  32. package/dist/src/artifacts/index.js.map +1 -0
  33. package/dist/src/artifacts/integrity.js +188 -0
  34. package/dist/src/artifacts/integrity.js.map +1 -0
  35. package/dist/src/artifacts/preparer.js +379 -0
  36. package/dist/src/artifacts/preparer.js.map +1 -0
  37. package/dist/src/artifacts/store.js +87 -0
  38. package/dist/src/artifacts/store.js.map +1 -0
  39. package/dist/src/artifacts/types.js +2 -0
  40. package/dist/src/artifacts/types.js.map +1 -0
  41. package/dist/src/backends/contract.js +2 -0
  42. package/dist/src/backends/contract.js.map +1 -0
  43. package/dist/src/backends/harbor/backend.js +305 -0
  44. package/dist/src/backends/harbor/backend.js.map +1 -0
  45. package/dist/src/backends/harbor/index.js +4 -0
  46. package/dist/src/backends/harbor/index.js.map +1 -0
  47. package/dist/src/backends/harbor/local-git-transport.js +447 -0
  48. package/dist/src/backends/harbor/local-git-transport.js.map +1 -0
  49. package/dist/src/backends/harbor/tools.js +314 -0
  50. package/dist/src/backends/harbor/tools.js.map +1 -0
  51. package/dist/src/backends/index.js +4 -0
  52. package/dist/src/backends/index.js.map +1 -0
  53. package/dist/src/cli/arguments.js +123 -0
  54. package/dist/src/cli/arguments.js.map +1 -0
  55. package/dist/src/cli/commands/compare.js +55 -0
  56. package/dist/src/cli/commands/compare.js.map +1 -0
  57. package/dist/src/cli/commands/daemon.js +106 -0
  58. package/dist/src/cli/commands/daemon.js.map +1 -0
  59. package/dist/src/cli/commands/eval.js +126 -0
  60. package/dist/src/cli/commands/eval.js.map +1 -0
  61. package/dist/src/cli/commands/feedback.js +84 -0
  62. package/dist/src/cli/commands/feedback.js.map +1 -0
  63. package/dist/src/cli/commands/inspect.js +20 -0
  64. package/dist/src/cli/commands/inspect.js.map +1 -0
  65. package/dist/src/cli/commands/list.js +17 -0
  66. package/dist/src/cli/commands/list.js.map +1 -0
  67. package/dist/src/cli/commands/prepare.js +21 -0
  68. package/dist/src/cli/commands/prepare.js.map +1 -0
  69. package/dist/src/cli/commands/resolve.js +17 -0
  70. package/dist/src/cli/commands/resolve.js.map +1 -0
  71. package/dist/src/cli/commands/run.js +83 -0
  72. package/dist/src/cli/commands/run.js.map +1 -0
  73. package/dist/src/cli/commands/runs.js +45 -0
  74. package/dist/src/cli/commands/runs.js.map +1 -0
  75. package/dist/src/cli/commands/trajectory.js +31 -0
  76. package/dist/src/cli/commands/trajectory.js.map +1 -0
  77. package/dist/src/cli/commands/workspace.js +44 -0
  78. package/dist/src/cli/commands/workspace.js.map +1 -0
  79. package/dist/src/cli/index.js +2 -0
  80. package/dist/src/cli/index.js.map +1 -0
  81. package/dist/src/cli/main.js +48 -0
  82. package/dist/src/cli/main.js.map +1 -0
  83. package/dist/src/cli/output.js +96 -0
  84. package/dist/src/cli/output.js.map +1 -0
  85. package/dist/src/controller-runtime/hash.js +353 -0
  86. package/dist/src/controller-runtime/hash.js.map +1 -0
  87. package/dist/src/controller-runtime/index.js +3 -0
  88. package/dist/src/controller-runtime/index.js.map +1 -0
  89. package/dist/src/controller-runtime/store.js +318 -0
  90. package/dist/src/controller-runtime/store.js.map +1 -0
  91. package/dist/src/daemon/auth.js +108 -0
  92. package/dist/src/daemon/auth.js.map +1 -0
  93. package/dist/src/daemon/client.js +76 -0
  94. package/dist/src/daemon/client.js.map +1 -0
  95. package/dist/src/daemon/index.js +5 -0
  96. package/dist/src/daemon/index.js.map +1 -0
  97. package/dist/src/daemon/launcher.js +24 -0
  98. package/dist/src/daemon/launcher.js.map +1 -0
  99. package/dist/src/daemon/scheduler.js +161 -0
  100. package/dist/src/daemon/scheduler.js.map +1 -0
  101. package/dist/src/daemon/server.js +316 -0
  102. package/dist/src/daemon/server.js.map +1 -0
  103. package/dist/src/domain/artifacts.js +2 -0
  104. package/dist/src/domain/artifacts.js.map +1 -0
  105. package/dist/src/domain/controller-runtime.js +2 -0
  106. package/dist/src/domain/controller-runtime.js.map +1 -0
  107. package/dist/src/domain/eval-records.js +2 -0
  108. package/dist/src/domain/eval-records.js.map +1 -0
  109. package/dist/src/domain/evals.js +2 -0
  110. package/dist/src/domain/evals.js.map +1 -0
  111. package/dist/src/domain/feedback.js +2 -0
  112. package/dist/src/domain/feedback.js.map +1 -0
  113. package/dist/src/domain/ids.js +10 -0
  114. package/dist/src/domain/ids.js.map +1 -0
  115. package/dist/src/domain/index.js +11 -0
  116. package/dist/src/domain/index.js.map +1 -0
  117. package/dist/src/domain/revisions.js +2 -0
  118. package/dist/src/domain/revisions.js.map +1 -0
  119. package/dist/src/domain/runs.js +3 -0
  120. package/dist/src/domain/runs.js.map +1 -0
  121. package/dist/src/domain/trajectories.js +2 -0
  122. package/dist/src/domain/trajectories.js.map +1 -0
  123. package/dist/src/domain/validation.js +429 -0
  124. package/dist/src/domain/validation.js.map +1 -0
  125. package/dist/src/domain/workspaces.js +2 -0
  126. package/dist/src/domain/workspaces.js.map +1 -0
  127. package/dist/src/evals/events.js +67 -0
  128. package/dist/src/evals/events.js.map +1 -0
  129. package/dist/src/evals/index.js +5 -0
  130. package/dist/src/evals/index.js.map +1 -0
  131. package/dist/src/evals/records.js +55 -0
  132. package/dist/src/evals/records.js.map +1 -0
  133. package/dist/src/evals/request.js +109 -0
  134. package/dist/src/evals/request.js.map +1 -0
  135. package/dist/src/evals/service.js +227 -0
  136. package/dist/src/evals/service.js.map +1 -0
  137. package/dist/src/evals/trial-import.js +394 -0
  138. package/dist/src/evals/trial-import.js.map +1 -0
  139. package/dist/src/feedback/index.js +2 -0
  140. package/dist/src/feedback/index.js.map +1 -0
  141. package/dist/src/feedback/service.js +314 -0
  142. package/dist/src/feedback/service.js.map +1 -0
  143. package/dist/src/foundation/config.js +54 -0
  144. package/dist/src/foundation/config.js.map +1 -0
  145. package/dist/src/foundation/errors.js +14 -0
  146. package/dist/src/foundation/errors.js.map +1 -0
  147. package/dist/src/foundation/executable.js +135 -0
  148. package/dist/src/foundation/executable.js.map +1 -0
  149. package/dist/src/foundation/fs.js +45 -0
  150. package/dist/src/foundation/fs.js.map +1 -0
  151. package/dist/src/foundation/hash.js +24 -0
  152. package/dist/src/foundation/hash.js.map +1 -0
  153. package/dist/src/foundation/index.js +11 -0
  154. package/dist/src/foundation/index.js.map +1 -0
  155. package/dist/src/foundation/line-stream.js +20 -0
  156. package/dist/src/foundation/line-stream.js.map +1 -0
  157. package/dist/src/foundation/locks.js +114 -0
  158. package/dist/src/foundation/locks.js.map +1 -0
  159. package/dist/src/foundation/package-root.js +41 -0
  160. package/dist/src/foundation/package-root.js.map +1 -0
  161. package/dist/src/foundation/process.js +50 -0
  162. package/dist/src/foundation/process.js.map +1 -0
  163. package/dist/src/revisions/index.js +4 -0
  164. package/dist/src/revisions/index.js.map +1 -0
  165. package/dist/src/revisions/reference.js +97 -0
  166. package/dist/src/revisions/reference.js.map +1 -0
  167. package/dist/src/revisions/resolver.js +25 -0
  168. package/dist/src/revisions/resolver.js.map +1 -0
  169. package/dist/src/revisions/sources/git.js +180 -0
  170. package/dist/src/revisions/sources/git.js.map +1 -0
  171. package/dist/src/revisions/sources/installed.js +45 -0
  172. package/dist/src/revisions/sources/installed.js.map +1 -0
  173. package/dist/src/revisions/sources/npm.js +97 -0
  174. package/dist/src/revisions/sources/npm.js.map +1 -0
  175. package/dist/src/runs/compare.js +132 -0
  176. package/dist/src/runs/compare.js.map +1 -0
  177. package/dist/src/runs/events.js +79 -0
  178. package/dist/src/runs/events.js.map +1 -0
  179. package/dist/src/runs/executor.js +480 -0
  180. package/dist/src/runs/executor.js.map +1 -0
  181. package/dist/src/runs/finalizer.js +22 -0
  182. package/dist/src/runs/finalizer.js.map +1 -0
  183. package/dist/src/runs/identity.js +35 -0
  184. package/dist/src/runs/identity.js.map +1 -0
  185. package/dist/src/runs/index.js +11 -0
  186. package/dist/src/runs/index.js.map +1 -0
  187. package/dist/src/runs/manifest.js +70 -0
  188. package/dist/src/runs/manifest.js.map +1 -0
  189. package/dist/src/runs/outcome.js +49 -0
  190. package/dist/src/runs/outcome.js.map +1 -0
  191. package/dist/src/runs/query.js +104 -0
  192. package/dist/src/runs/query.js.map +1 -0
  193. package/dist/src/runs/queued.js +54 -0
  194. package/dist/src/runs/queued.js.map +1 -0
  195. package/dist/src/runs/records.js +288 -0
  196. package/dist/src/runs/records.js.map +1 -0
  197. package/dist/src/runs/request.js +169 -0
  198. package/dist/src/runs/request.js.map +1 -0
  199. package/dist/src/trajectories/contract.js +17 -0
  200. package/dist/src/trajectories/contract.js.map +1 -0
  201. package/dist/src/trajectories/format.js +127 -0
  202. package/dist/src/trajectories/format.js.map +1 -0
  203. package/dist/src/trajectories/index.js +7 -0
  204. package/dist/src/trajectories/index.js.map +1 -0
  205. package/dist/src/trajectories/projector.js +385 -0
  206. package/dist/src/trajectories/projector.js.map +1 -0
  207. package/dist/src/trajectories/provider-capture.js +133 -0
  208. package/dist/src/trajectories/provider-capture.js.map +1 -0
  209. package/dist/src/trajectories/providers/deepseek.js +179 -0
  210. package/dist/src/trajectories/providers/deepseek.js.map +1 -0
  211. package/dist/src/trajectories/store.js +421 -0
  212. package/dist/src/trajectories/store.js.map +1 -0
  213. package/dist/src/workspaces/copy.js +142 -0
  214. package/dist/src/workspaces/copy.js.map +1 -0
  215. package/dist/src/workspaces/digest.js +47 -0
  216. package/dist/src/workspaces/digest.js.map +1 -0
  217. package/dist/src/workspaces/git.js +164 -0
  218. package/dist/src/workspaces/git.js.map +1 -0
  219. package/dist/src/workspaces/index.js +6 -0
  220. package/dist/src/workspaces/index.js.map +1 -0
  221. package/dist/src/workspaces/lifecycle.js +313 -0
  222. package/dist/src/workspaces/lifecycle.js.map +1 -0
  223. package/dist/src/workspaces/planner.js +80 -0
  224. package/dist/src/workspaces/planner.js.map +1 -0
  225. package/dist/src/workspaces/store.js +25 -0
  226. package/dist/src/workspaces/store.js.map +1 -0
  227. package/dist/src/workspaces/types.js +4 -0
  228. package/dist/src/workspaces/types.js.map +1 -0
  229. package/dist/src/workspaces/utils.js +56 -0
  230. package/dist/src/workspaces/utils.js.map +1 -0
  231. package/docs/schemas/controller-runtime-manifest.schema.json +57 -0
  232. package/docs/schemas/controller-runtime-ref.schema.json +16 -0
  233. package/docs/schemas/eval-request.schema.json +2 -0
  234. package/docs/schemas/eval-result.schema.json +36 -1
  235. package/docs/schemas/local-git-transport-manifest.schema.json +34 -0
  236. package/docs/schemas/message-feedback.schema.json +37 -0
  237. package/docs/schemas/result.schema.json +9 -0
  238. package/docs/schemas/run-context.schema.json +39 -0
  239. package/docs/schemas/run-manifest.schema.json +81 -0
  240. package/docs/schemas/run-request.schema.json +16 -1
  241. package/docs/schemas/trajectory-ref.schema.json +73 -0
  242. package/integrations/harbor/hitch_harbor_agent.py +551 -5
  243. package/package.json +37 -11
  244. package/bin/hitch.js +0 -9
  245. package/src/adapters.js +0 -435
  246. package/src/artifacts.js +0 -949
  247. package/src/cli.js +0 -505
  248. package/src/config.js +0 -51
  249. package/src/daemon.js +0 -416
  250. package/src/engine.js +0 -400
  251. package/src/errors.js +0 -12
  252. package/src/eval-tools.js +0 -334
  253. package/src/evals.js +0 -276
  254. package/src/events.js +0 -69
  255. package/src/fs.js +0 -43
  256. package/src/harbor-backend.js +0 -285
  257. package/src/harness-reference.js +0 -78
  258. package/src/line-stream.js +0 -17
  259. package/src/locks.js +0 -33
  260. package/src/process.js +0 -49
  261. package/src/registry.js +0 -84
  262. package/src/scheduler.js +0 -156
  263. package/src/workspaces.js +0 -893
@@ -0,0 +1,314 @@
1
+ import { constants } from "node:fs";
2
+ import { access, mkdir, rm } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { spawn } from "node:child_process";
5
+ import { HitchError, SCHEMA_VERSION, atomicWriteJSON, detectVersion, ensureDir, invalidInput, readJSON, resolveExecutable, statePaths, terminateProcess } from "../../foundation/index.js";
6
+ export const DEFAULT_HARBOR_VERSION = "0.21.0";
7
+ export const HARBOR_CREDENTIAL_ENV = [
8
+ "DEEPSEEK_API_KEY",
9
+ "DEEPSEEK_BASE_URL",
10
+ "OPENAI_API_KEY",
11
+ "OPENAI_BASE_URL",
12
+ "OPENAI_ORG_ID",
13
+ "OPENAI_ORGANIZATION",
14
+ "ANTHROPIC_API_KEY",
15
+ "ANTHROPIC_AUTH_TOKEN",
16
+ "ANTHROPIC_BASE_URL",
17
+ "CLAUDE_CODE_OAUTH_TOKEN",
18
+ "GOOGLE_API_KEY",
19
+ "GEMINI_API_KEY",
20
+ "AZURE_OPENAI_API_KEY",
21
+ "AZURE_OPENAI_ENDPOINT",
22
+ "AZURE_OPENAI_API_VERSION",
23
+ "AWS_ACCESS_KEY_ID",
24
+ "AWS_SECRET_ACCESS_KEY",
25
+ "AWS_SESSION_TOKEN",
26
+ "AWS_REGION",
27
+ "AWS_DEFAULT_REGION",
28
+ "GITHUB_TOKEN",
29
+ "GH_TOKEN",
30
+ ];
31
+ const PROVIDER_CREDENTIAL_ENV = [
32
+ "DEEPSEEK_API_KEY",
33
+ "OPENAI_API_KEY",
34
+ "ANTHROPIC_API_KEY",
35
+ "ANTHROPIC_AUTH_TOKEN",
36
+ "CLAUDE_CODE_OAUTH_TOKEN",
37
+ "GOOGLE_API_KEY",
38
+ "GEMINI_API_KEY",
39
+ "AZURE_OPENAI_API_KEY",
40
+ "AWS_ACCESS_KEY_ID",
41
+ ];
42
+ export async function setupHarbor({ root, version = DEFAULT_HARBOR_VERSION, python, force = false, env = process.env, onProgress = () => { }, }) {
43
+ if (!root)
44
+ throw invalidInput("a Hitch state root is required for Harbor setup");
45
+ if (!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(version)) {
46
+ throw invalidInput("Harbor version must be an exact semantic version");
47
+ }
48
+ const pythonInfo = await findPython({ explicit: python, env });
49
+ if (!pythonInfo.executable) {
50
+ throw new HitchError("Python 3.12 or newer was not found; install it or pass --python <path>", {
51
+ code: "python_unavailable",
52
+ exitCode: 3,
53
+ });
54
+ }
55
+ if (!pythonInfo.supported) {
56
+ throw new HitchError(`Harbor requires Python 3.12 or newer; found ${pythonInfo.version || "an unknown version"}`, {
57
+ code: "python_unsupported",
58
+ exitCode: 3,
59
+ });
60
+ }
61
+ const toolsDirectory = statePaths(root).tools;
62
+ const installDirectory = path.join(toolsDirectory, `harbor-${version}`);
63
+ const harborExecutable = venvExecutable(installDirectory, "harbor");
64
+ const currentPath = path.join(toolsDirectory, "harbor.json");
65
+ const installedVersion = await installedHarborVersion(harborExecutable);
66
+ if (installedVersion === version && !force) {
67
+ const manifest = await writeHarborSelection(currentPath, {
68
+ version,
69
+ pythonInfo,
70
+ installDirectory,
71
+ harborExecutable,
72
+ cacheHit: true,
73
+ });
74
+ return manifest;
75
+ }
76
+ if (installedVersion && !force) {
77
+ throw new HitchError(`managed Harbor at ${installDirectory} reports ${installedVersion}; rerun with --force to replace it`, {
78
+ code: "harbor_setup_conflict",
79
+ exitCode: 3,
80
+ });
81
+ }
82
+ await ensureDir(toolsDirectory);
83
+ if (force)
84
+ await rm(installDirectory, { recursive: true, force: true });
85
+ try {
86
+ await mkdir(installDirectory);
87
+ }
88
+ catch (error) {
89
+ if (error?.code === "EEXIST") {
90
+ throw new HitchError(`incomplete Harbor installation already exists at ${installDirectory}; rerun with --force`, {
91
+ code: "harbor_setup_incomplete",
92
+ exitCode: 3,
93
+ });
94
+ }
95
+ throw error;
96
+ }
97
+ try {
98
+ onProgress(`Creating an isolated Python environment with ${pythonInfo.version}`);
99
+ await requireCommand(pythonInfo.executable, ["-m", "venv", installDirectory], {
100
+ env,
101
+ code: "harbor_setup_failed",
102
+ timeoutMs: 5 * 60_000,
103
+ });
104
+ const environmentPython = venvExecutable(installDirectory, "python");
105
+ onProgress(`Installing harbor==${version}`);
106
+ await requireCommand(environmentPython, [
107
+ "-m", "pip", "install", "--disable-pip-version-check", "--no-input", `harbor==${version}`,
108
+ ], {
109
+ env,
110
+ code: "harbor_setup_failed",
111
+ timeoutMs: 20 * 60_000,
112
+ });
113
+ const observedVersion = await installedHarborVersion(harborExecutable);
114
+ if (observedVersion !== version) {
115
+ throw new HitchError(`installed Harbor reported ${observedVersion || "no version"}; expected ${version}`, {
116
+ code: "harbor_setup_failed",
117
+ exitCode: 13,
118
+ });
119
+ }
120
+ return await writeHarborSelection(currentPath, {
121
+ version,
122
+ pythonInfo,
123
+ installDirectory,
124
+ harborExecutable,
125
+ cacheHit: false,
126
+ });
127
+ }
128
+ catch (error) {
129
+ await rm(installDirectory, { recursive: true, force: true });
130
+ throw error;
131
+ }
132
+ }
133
+ export async function doctorHarbor({ root, python, harbor, docker, env = process.env }) {
134
+ if (!root)
135
+ throw invalidInput("a Hitch state root is required for eval doctor");
136
+ const pythonInfo = await findPython({ explicit: python, env });
137
+ const harborInfo = await locateHarbor({ root, explicit: harbor, env });
138
+ const dockerConfigured = docker || env.HITCH_DOCKER_PATH || "docker";
139
+ const dockerExecutable = await resolveExecutable(dockerConfigured, env.PATH || "");
140
+ let dockerVersion = "";
141
+ let dockerDiagnostic = "";
142
+ if (dockerExecutable) {
143
+ const result = await captureCommand(dockerExecutable, ["version", "--format", "{{.Server.Version}}"], {
144
+ env,
145
+ timeoutMs: 10_000,
146
+ });
147
+ dockerVersion = result.code === 0 ? result.stdout.trim() : "";
148
+ dockerDiagnostic = result.code === 0 ? "" : (result.stderr.trim() || result.stdout.trim() || "Docker daemon is unavailable");
149
+ }
150
+ const credentials = PROVIDER_CREDENTIAL_ENV.filter((name) => typeof env[name] === "string" && env[name].trim());
151
+ const checks = {
152
+ python: pythonInfo.executable && pythonInfo.supported
153
+ ? { status: "ok", executable: pythonInfo.executable, version: pythonInfo.version, required: ">=3.12" }
154
+ : { status: "error", executable: pythonInfo.executable || null, version: pythonInfo.version || null, required: ">=3.12", message: "Python 3.12 or newer is required to install Harbor" },
155
+ harbor: harborInfo.executable
156
+ ? { status: "ok", executable: harborInfo.executable, version: harborInfo.version || null, source: harborInfo.source }
157
+ : { status: "error", executable: null, version: null, source: harborInfo.source, message: `Harbor executable not found: ${harborInfo.requested}` },
158
+ docker: dockerExecutable && dockerVersion
159
+ ? { status: "ok", executable: dockerExecutable, version: dockerVersion, daemon: "running" }
160
+ : { status: "error", executable: dockerExecutable || null, version: null, daemon: dockerExecutable ? "unavailable" : "not_checked", message: dockerExecutable ? dockerDiagnostic : `Docker executable not found: ${dockerConfigured}` },
161
+ credentials: credentials.length > 0
162
+ ? { status: "ok", present: credentials }
163
+ : { status: "warning", present: [], message: "No common provider credential is set; pass credentials before running a hosted-model eval" },
164
+ };
165
+ const ready = [checks.python, checks.harbor, checks.docker].every((check) => check?.status === "ok");
166
+ return {
167
+ schema_version: SCHEMA_VERSION,
168
+ backend: "harbor",
169
+ status: ready ? (checks.credentials?.status === "ok" ? "ready" : "ready_with_warnings") : "action_required",
170
+ ready,
171
+ checks,
172
+ };
173
+ }
174
+ export async function locateHarbor({ root, explicit, env = process.env } = {}) {
175
+ const configured = explicit || env.HITCH_HARBOR_PATH;
176
+ if (configured) {
177
+ const executable = await resolveExecutable(configured, env.PATH || "");
178
+ return {
179
+ executable,
180
+ version: executable ? await installedHarborVersion(executable) : "",
181
+ source: explicit ? "option" : "environment",
182
+ requested: configured,
183
+ };
184
+ }
185
+ const managed = root ? await managedHarborExecutable(root) : null;
186
+ if (managed) {
187
+ return {
188
+ executable: managed,
189
+ version: await installedHarborVersion(managed),
190
+ source: "managed",
191
+ requested: managed,
192
+ };
193
+ }
194
+ const executable = await resolveExecutable("harbor", env.PATH || "");
195
+ return {
196
+ executable,
197
+ version: executable ? await installedHarborVersion(executable) : "",
198
+ source: "path",
199
+ requested: "harbor",
200
+ };
201
+ }
202
+ export async function managedHarborExecutable(root) {
203
+ const toolsDirectory = statePaths(root).tools;
204
+ const current = await readJSON(path.join(toolsDirectory, "harbor.json"), null).catch(() => null);
205
+ if (!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(current?.version || ""))
206
+ return null;
207
+ const version = current?.version;
208
+ const executable = venvExecutable(path.join(toolsDirectory, `harbor-${version}`), "harbor");
209
+ try {
210
+ await access(executable, constants.X_OK);
211
+ return executable;
212
+ }
213
+ catch {
214
+ return null;
215
+ }
216
+ }
217
+ async function findPython({ explicit, env }) {
218
+ const requested = explicit || env.HITCH_PYTHON_PATH;
219
+ const candidates = requested ? [requested] : ["python3.13", "python3.12", "python3"];
220
+ let firstFound = null;
221
+ for (const candidate of candidates) {
222
+ const executable = await resolveExecutable(candidate, env.PATH || "");
223
+ if (!executable)
224
+ continue;
225
+ const result = await captureCommand(executable, ["-c", "import sys; print('.'.join(map(str, sys.version_info[:3])))"], {
226
+ env,
227
+ timeoutMs: 5_000,
228
+ });
229
+ const version = result.code === 0 ? result.stdout.trim().split(/\s+/)[0] || "" : "";
230
+ const supported = pythonVersionSupported(version);
231
+ const info = { executable, version, supported };
232
+ firstFound ||= info;
233
+ if (supported || requested)
234
+ return info;
235
+ }
236
+ return firstFound || { executable: null, version: "", supported: false };
237
+ }
238
+ function pythonVersionSupported(version) {
239
+ const match = String(version).match(/^(\d+)\.(\d+)(?:\.\d+)?$/);
240
+ if (!match)
241
+ return false;
242
+ const major = Number(match[1]);
243
+ const minor = Number(match[2]);
244
+ return major > 3 || (major === 3 && minor >= 12);
245
+ }
246
+ async function installedHarborVersion(executable) {
247
+ try {
248
+ await access(executable, constants.X_OK);
249
+ }
250
+ catch {
251
+ return "";
252
+ }
253
+ const value = await detectVersion(executable, ["--version"]);
254
+ return value.match(/\b\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?\b/)?.[0] || "";
255
+ }
256
+ async function writeHarborSelection(currentPath, { version, pythonInfo, installDirectory, harborExecutable, cacheHit, }) {
257
+ const manifest = {
258
+ schema_version: SCHEMA_VERSION,
259
+ tool: "harbor",
260
+ version,
261
+ executable: harborExecutable,
262
+ install_directory: installDirectory,
263
+ python: { executable: pythonInfo.executable || "", version: pythonInfo.version },
264
+ cache_hit: cacheHit,
265
+ selected_at: new Date().toISOString(),
266
+ };
267
+ await atomicWriteJSON(currentPath, manifest);
268
+ return manifest;
269
+ }
270
+ function venvExecutable(directory, name) {
271
+ return process.platform === "win32"
272
+ ? path.join(directory, "Scripts", `${name}.exe`)
273
+ : path.join(directory, "bin", name);
274
+ }
275
+ async function requireCommand(executable, args, { env, code, timeoutMs }) {
276
+ const result = await captureCommand(executable, args, { env, timeoutMs });
277
+ if (result.code === 0)
278
+ return result;
279
+ const detail = result.stderr.trim() || result.stdout.trim();
280
+ throw new HitchError(`${path.basename(executable)} exited with code ${result.code ?? "null"}${detail ? `: ${detail}` : ""}`, {
281
+ code,
282
+ exitCode: 13,
283
+ });
284
+ }
285
+ function captureCommand(executable, args, { env = process.env, timeoutMs = 10_000 } = {}) {
286
+ return new Promise((resolve, reject) => {
287
+ const child = spawn(executable, args, {
288
+ env,
289
+ stdio: ["ignore", "pipe", "pipe"],
290
+ detached: process.platform !== "win32",
291
+ windowsHide: true,
292
+ });
293
+ let stdout = "";
294
+ let stderr = "";
295
+ let timedOut = false;
296
+ const append = (current, chunk) => `${current}${chunk}`.slice(-1_000_000);
297
+ child.stdout.on("data", (chunk) => { stdout = append(stdout, chunk); });
298
+ child.stderr.on("data", (chunk) => { stderr = append(stderr, chunk); });
299
+ const timer = setTimeout(() => {
300
+ timedOut = true;
301
+ terminateProcess(child).catch(() => { });
302
+ }, timeoutMs);
303
+ timer.unref?.();
304
+ child.once("error", (error) => {
305
+ clearTimeout(timer);
306
+ reject(error);
307
+ });
308
+ child.once("close", (code, signal) => {
309
+ clearTimeout(timer);
310
+ resolve({ code, signal, stdout, stderr, timed_out: timedOut });
311
+ });
312
+ });
313
+ }
314
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../../src/backends/harbor/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { buildHarborJobConfig, lockedHarnessRef, normalizeHarborResult, runHarborBackend } from "./harbor/index.js";
2
+ export { DEFAULT_LOCAL_GIT_TRANSPORT_LIMITS, LOCAL_GIT_TRANSPORT_MANIFEST, LOCAL_GIT_TRANSPORT_PAYLOAD, LOCAL_GIT_TRANSPORT_SCHEMA_VERSION, buildLocalGitTransport, localGitTransportLimitsFromEnv, validateLocalGitTransportManifest, verifyLocalGitTransport, verifyMaterializedLocalGitSource } from "./harbor/index.js";
3
+ export { DEFAULT_HARBOR_VERSION, HARBOR_CREDENTIAL_ENV, doctorHarbor, locateHarbor, managedHarborExecutable, setupHarbor } from "./harbor/index.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/backends/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEpH,OAAO,EAAE,kCAAkC,EAAE,4BAA4B,EAAE,2BAA2B,EAAE,kCAAkC,EAAE,sBAAsB,EAAE,8BAA8B,EAAE,iCAAiC,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,MAAM,mBAAmB,CAAC;AAE5T,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,YAAY,EAAE,YAAY,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,123 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { DEFAULT_MAX_CONCURRENT, invalidInput, parseDuration, positiveInteger } from "../foundation/index.js";
5
+ import { WORKSPACE_MODES } from "../workspaces/index.js";
6
+ export async function parseRunRequest(args) {
7
+ const harness = takeOption(args, "--harness");
8
+ const agent = takeOption(args, "--agent");
9
+ const model = takeOption(args, "--model") || "";
10
+ const cwd = takeOption(args, "--cwd") || process.cwd();
11
+ const workspaceMode = takeOption(args, "--workspace-mode") || "shared";
12
+ const promptValue = takeOption(args, "--prompt");
13
+ const promptFile = takeOption(args, "--prompt-file");
14
+ const timeout = parseDuration(takeOption(args, "--timeout") || "0");
15
+ const agentArgs = takeRepeatedOption(args, "--agent-arg");
16
+ const contextFile = takeOption(args, "--context-file");
17
+ const parentFile = takeOption(args, "--parent-file");
18
+ const modelIdentityFile = takeOption(args, "--model-identity-file");
19
+ const protocolIdentityFile = takeOption(args, "--protocol-identity-file");
20
+ if (harness && agent)
21
+ throw invalidInput("use only one of --harness and the legacy --agent option");
22
+ if (!harness && !agent)
23
+ throw invalidInput("--harness is required");
24
+ if (!WORKSPACE_MODES.has(workspaceMode))
25
+ throw invalidInput(`--workspace-mode must be one of: ${[...WORKSPACE_MODES].join(", ")}`);
26
+ if (agent?.includes("@"))
27
+ throw invalidInput("--agent accepts only a harness name; use --harness for revision selection");
28
+ if (promptValue !== undefined && promptFile)
29
+ throw invalidInput("use only one of --prompt and --prompt-file");
30
+ let prompt = promptValue;
31
+ if (promptFile)
32
+ prompt = await readFile(path.resolve(promptFile), "utf8");
33
+ if (prompt === undefined && !process.stdin.isTTY)
34
+ prompt = readFileSync(0, "utf8");
35
+ if (!prompt)
36
+ throw invalidInput("provide --prompt, --prompt-file, or stdin");
37
+ const loadInputFile = async (file, label) => {
38
+ if (!file)
39
+ return undefined;
40
+ try {
41
+ return JSON.parse(await readFile(path.resolve(file), "utf8"));
42
+ }
43
+ catch (error) {
44
+ throw invalidInput(`${label} is not readable JSON: ${error.message}`, { cause: error });
45
+ }
46
+ };
47
+ const context = await loadInputFile(contextFile, "--context-file");
48
+ const parent = await loadInputFile(parentFile, "--parent-file");
49
+ const modelIdentity = await loadInputFile(modelIdentityFile, "--model-identity-file");
50
+ const protocolIdentity = await loadInputFile(protocolIdentityFile, "--protocol-identity-file");
51
+ return {
52
+ harness_ref: harness || `${agent}@installed`,
53
+ model,
54
+ cwd,
55
+ workspace_mode: workspaceMode,
56
+ prompt,
57
+ timeout_ms: timeout,
58
+ agent_args: agentArgs,
59
+ ...(context !== undefined ? { context } : {}),
60
+ ...(parent !== undefined ? { parent } : {}),
61
+ ...(modelIdentity !== undefined ? { model_identity: modelIdentity } : {}),
62
+ ...(protocolIdentity !== undefined ? { protocol_identity: protocolIdentity } : {}),
63
+ };
64
+ }
65
+ export function parseEvalRequest(args) {
66
+ const backend = takeOption(args, "--backend") || "harbor";
67
+ const dataset = takeOption(args, "--dataset");
68
+ const harness = takeOption(args, "--harness");
69
+ const model = takeOption(args, "--model") || "";
70
+ const attempts = positiveInteger(takeOption(args, "--attempts") || 1, "--attempts");
71
+ const maxConcurrent = positiveInteger(takeOption(args, "--max-concurrent") || DEFAULT_MAX_CONCURRENT, "--max-concurrent");
72
+ const timeoutValue = takeOption(args, "--timeout");
73
+ const setupTimeoutValue = takeOption(args, "--setup-timeout");
74
+ const agentArgs = takeRepeatedOption(args, "--agent-arg");
75
+ const passEnv = takeRepeatedOption(args, "--pass-env");
76
+ if (!dataset)
77
+ throw invalidInput("--dataset is required");
78
+ if (!harness)
79
+ throw invalidInput("--harness is required");
80
+ return {
81
+ backend,
82
+ dataset,
83
+ harness_ref: harness,
84
+ model,
85
+ attempts,
86
+ max_concurrent: maxConcurrent,
87
+ timeout_ms: timeoutValue === undefined ? undefined : parseDuration(timeoutValue),
88
+ setup_timeout_ms: setupTimeoutValue === undefined ? undefined : parseDuration(setupTimeoutValue),
89
+ agent_args: agentArgs,
90
+ pass_env: passEnv,
91
+ };
92
+ }
93
+ export function takeOption(args, name) {
94
+ const index = args.indexOf(name);
95
+ if (index < 0)
96
+ return undefined;
97
+ if (index === args.length - 1)
98
+ throw invalidInput(`${name} requires a value`);
99
+ const [value] = args.splice(index + 1, 1);
100
+ args.splice(index, 1);
101
+ return value;
102
+ }
103
+ export function takeRepeatedOption(args, name) {
104
+ const values = [];
105
+ for (;;) {
106
+ const value = takeOption(args, name);
107
+ if (value === undefined)
108
+ return values;
109
+ values.push(value);
110
+ }
111
+ }
112
+ export function takeFlag(args, name) {
113
+ const index = args.indexOf(name);
114
+ if (index < 0)
115
+ return false;
116
+ args.splice(index, 1);
117
+ return true;
118
+ }
119
+ export function assertNoArgs(args) {
120
+ if (args.length > 0)
121
+ throw invalidInput(`unexpected argument: ${args[0]}`);
122
+ }
123
+ //# sourceMappingURL=arguments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arguments.js","sourceRoot":"","sources":["../../../src/cli/arguments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9G,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAc;IAClD,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACvD,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,EAAE,kBAAkB,CAAC,IAAI,QAAQ,CAAC;IACvE,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,GAAG,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAC1D,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACrD,MAAM,iBAAiB,GAAG,UAAU,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;IACpE,MAAM,oBAAoB,GAAG,UAAU,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC;IAC1E,IAAI,OAAO,IAAI,KAAK;QAAE,MAAM,YAAY,CAAC,yDAAyD,CAAC,CAAC;IACpG,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK;QAAE,MAAM,YAAY,CAAC,uBAAuB,CAAC,CAAC;IACpE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,aAAa,CAAC;QAAE,MAAM,YAAY,CAAC,oCAAoC,CAAC,GAAG,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnI,IAAI,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC;QAAE,MAAM,YAAY,CAAC,2EAA2E,CAAC,CAAC;IAC1H,IAAI,WAAW,KAAK,SAAS,IAAI,UAAU;QAAE,MAAM,YAAY,CAAC,4CAA4C,CAAC,CAAC;IAC9G,IAAI,MAAM,GAAG,WAAW,CAAC;IACzB,IAAI,UAAU;QAAE,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC;IAC1E,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK;QAAE,MAAM,GAAG,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACnF,IAAI,CAAC,MAAM;QAAE,MAAM,YAAY,CAAC,2CAA2C,CAAC,CAAC;IAC7E,MAAM,aAAa,GAAG,KAAK,EAAE,IAAwB,EAAE,KAAa,EAAgC,EAAE;QACpG,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QAC5B,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAY,CAAC;QAC3E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,CAAC,GAAG,KAAK,0BAA2B,KAAe,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACrG,CAAC;IACH,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IACnE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IAChE,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;IACtF,MAAM,gBAAgB,GAAG,MAAM,aAAa,CAAC,oBAAoB,EAAE,0BAA0B,CAAC,CAAC;IAC/F,OAAO;QACL,WAAW,EAAE,OAAO,IAAI,GAAG,KAAK,YAAY;QAC5C,KAAK;QACL,GAAG;QACH,cAAc,EAAE,aAAa;QAC7B,MAAM;QACN,UAAU,EAAE,OAAO;QACnB,UAAU,EAAE,SAAS;QACrB,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,QAAQ,CAAC;IAC1D,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;IACpF,MAAM,aAAa,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,kBAAkB,CAAC,IAAI,sBAAsB,EAAE,kBAAkB,CAAC,CAAC;IAC1H,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACnD,MAAM,iBAAiB,GAAG,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACvD,IAAI,CAAC,OAAO;QAAE,MAAM,YAAY,CAAC,uBAAuB,CAAC,CAAC;IAC1D,IAAI,CAAC,OAAO;QAAE,MAAM,YAAY,CAAC,uBAAuB,CAAC,CAAC;IAC1D,OAAO;QACL,OAAO;QACP,OAAO;QACP,WAAW,EAAE,OAAO;QACpB,KAAK;QACL,QAAQ;QACR,cAAc,EAAE,aAAa;QAC7B,UAAU,EAAE,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC;QAChF,gBAAgB,EAAE,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,iBAAiB,CAAC;QAChG,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,OAAO;KAClB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAc,EAAE,IAAY;IACrD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAChC,IAAI,KAAK,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,YAAY,CAAC,GAAG,IAAI,mBAAmB,CAAC,CAAC;IAC9E,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACtB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAc,EAAE,IAAY;IAC7D,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,SAAS,CAAC;QACR,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAc,EAAE,IAAY;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACtB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,YAAY,CAAC,wBAAwB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,55 @@
1
+ export async function compareCommand(args, root) {
2
+ const dimension = args.shift();
3
+ if (dimension !== "model" && dimension !== "harness")
4
+ throw invalidInput("compare requires model or harness");
5
+ const json = takeFlag(args, "--json");
6
+ const referenceRunId = takeOption(args, "--reference-run");
7
+ const query = takeRunQuery(args);
8
+ assertNoArgs(args);
9
+ const comparison = await compareRuns({
10
+ root,
11
+ dimension: dimension,
12
+ query,
13
+ ...(referenceRunId ? { referenceRunId } : {}),
14
+ });
15
+ if (json) {
16
+ process.stdout.write(`${JSON.stringify(comparison, null, 2)}\n`);
17
+ return;
18
+ }
19
+ process.stdout.write(`Strict ${dimension} comparison: ${comparison.strict ? "yes" : "no"}\n`);
20
+ for (const group of comparison.groups) {
21
+ process.stdout.write(` ${JSON.stringify(group.identity)} valid=${group.valid_observations} mean=${group.rewards.mean ?? "-"} failures=${group.agent_failures}\n`);
22
+ }
23
+ if (comparison.excluded.length)
24
+ process.stdout.write(` excluded: ${comparison.excluded.length}\n`);
25
+ }
26
+ export function takeRunQuery(args) {
27
+ const query = {};
28
+ const assign = (field, option) => {
29
+ const value = takeOption(args, option);
30
+ if (value !== undefined)
31
+ query[field] = value;
32
+ };
33
+ assign("context_kind", "--context-kind");
34
+ assign("benchmark_id", "--benchmark");
35
+ assign("benchmark_revision", "--benchmark-revision");
36
+ assign("task_id", "--task");
37
+ assign("task_digest", "--task-digest");
38
+ assign("seed_task_id", "--seed-task");
39
+ assign("seed_task_digest", "--seed-digest");
40
+ assign("iteration_id", "--iteration");
41
+ assign("harness_id", "--harness");
42
+ assign("revision_identity", "--harness-revision");
43
+ assign("model_provider", "--provider");
44
+ assign("requested_model", "--requested-model");
45
+ assign("effective_model", "--effective-model");
46
+ assign("eval_id", "--eval");
47
+ assign("status", "--status");
48
+ assign("created_from", "--from");
49
+ assign("created_to", "--to");
50
+ return query;
51
+ }
52
+ import { compareRuns } from "../../runs/index.js";
53
+ import { invalidInput } from "../../foundation/index.js";
54
+ import { assertNoArgs, takeFlag, takeOption } from "../arguments.js";
55
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../../../../src/cli/commands/compare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { DaemonServer, daemonClient, probeDaemonHealth, readDaemonLogs, startDetachedDaemon } from "../../daemon/index.js";
3
+ import { discoverAgents } from "../../adapters/index.js";
4
+ import { DEFAULT_MAX_CONCURRENT, DEFAULT_PORT, HitchError, SCHEMA_VERSION, delay, invalidInput, positiveInteger } from "../../foundation/index.js";
5
+ import { assertNoArgs, parseRunRequest, takeFlag, takeOption } from "../arguments.js";
6
+ import { waitForDaemonRun } from "../output.js";
7
+ const executable = fileURLToPath(new URL("../../../bin/hitch.js", import.meta.url));
8
+ export async function daemonCommand(args, root) {
9
+ const action = args.shift();
10
+ switch (action) {
11
+ case "serve": return daemonServe(args, root);
12
+ case "start": return daemonStart(args, root);
13
+ case "stop": return daemonStop(args, root);
14
+ case "status": return daemonStatus(args, root);
15
+ case "submit": return daemonSubmit(args, root);
16
+ case "cancel": return daemonCancel(args, root);
17
+ case "logs": return daemonLogs(args, root);
18
+ default: throw invalidInput("daemon requires start, serve, stop, status, submit, cancel, or logs");
19
+ }
20
+ }
21
+ async function daemonServe(args, root) {
22
+ const port = Number(takeOption(args, "--port") || DEFAULT_PORT);
23
+ const maxConcurrent = positiveInteger(takeOption(args, "--max-concurrent") || DEFAULT_MAX_CONCURRENT, "--max-concurrent");
24
+ assertNoArgs(args);
25
+ if (!Number.isInteger(port) || port < 0 || port > 65535)
26
+ throw invalidInput("--port must be between 0 and 65535");
27
+ const server = new DaemonServer({ root, port, maxConcurrent, discoverHarnesses: discoverAgents });
28
+ await server.start();
29
+ const shutdown = () => server.close().catch((error) => process.stderr.write(`shutdown error: ${error.message}\n`));
30
+ process.once("SIGINT", shutdown);
31
+ process.once("SIGTERM", shutdown);
32
+ await server.closed;
33
+ }
34
+ async function daemonStart(args, root) {
35
+ const foreground = takeFlag(args, "--foreground");
36
+ const port = Number(takeOption(args, "--port") || DEFAULT_PORT);
37
+ const maxConcurrent = positiveInteger(takeOption(args, "--max-concurrent") || DEFAULT_MAX_CONCURRENT, "--max-concurrent");
38
+ assertNoArgs(args);
39
+ const health = await probeDaemonHealth(root);
40
+ if (health?.status === "running")
41
+ throw new HitchError(`daemon is already running (pid ${health.pid})`, { code: "already_running", exitCode: 2 });
42
+ if (foreground)
43
+ return daemonServe(["--port", String(port), "--max-concurrent", String(maxConcurrent)], root);
44
+ const child = await startDetachedDaemon({ root, executable, port, maxConcurrent });
45
+ for (let attempt = 0; attempt < 50; attempt += 1) {
46
+ await delay(100);
47
+ const current = await probeDaemonHealth(root);
48
+ if (current?.status === "running" && current.pid === child.pid) {
49
+ process.stdout.write(`Hitch daemon started (pid ${current.pid}, port ${current.port})\n`);
50
+ return;
51
+ }
52
+ }
53
+ throw new HitchError(`daemon did not become ready; see ${child.errorLog}`, { code: "daemon_start_failed", exitCode: 12 });
54
+ }
55
+ async function daemonStop(args, root) {
56
+ assertNoArgs(args);
57
+ const client = await daemonClient(root);
58
+ const response = await client.request("/shutdown", { method: "POST" });
59
+ process.stdout.write(`${response.status}\n`);
60
+ }
61
+ async function daemonStatus(args, root) {
62
+ const json = takeFlag(args, "--json");
63
+ assertNoArgs(args);
64
+ const health = await probeDaemonHealth(root);
65
+ if (!health) {
66
+ if (json)
67
+ process.stdout.write(`${JSON.stringify({ schema_version: SCHEMA_VERSION, status: "stopped" })}\n`);
68
+ else
69
+ process.stdout.write("Hitch daemon is stopped\n");
70
+ process.exitCode = 3;
71
+ return;
72
+ }
73
+ if (json)
74
+ process.stdout.write(`${JSON.stringify(health, null, 2)}\n`);
75
+ else
76
+ process.stdout.write(`Hitch daemon is ${health.status} (pid ${health.pid}, port ${health.port}, ${health.scheduler?.running} running, ${health.scheduler?.queued} queued)\n`);
77
+ }
78
+ async function daemonSubmit(args, root) {
79
+ const wait = takeFlag(args, "--wait");
80
+ const output = takeOption(args, "--output") || "json";
81
+ const request = await parseRunRequest(args);
82
+ assertNoArgs(args);
83
+ const client = await daemonClient(root);
84
+ const accepted = await client.request("/v1/runs", { method: "POST", body: JSON.stringify(request) });
85
+ if (!wait) {
86
+ process.stdout.write(`${JSON.stringify(accepted, null, 2)}\n`);
87
+ return;
88
+ }
89
+ const result = await waitForDaemonRun(client, accepted.run_id, output);
90
+ process.exitCode = result.exit_code;
91
+ }
92
+ async function daemonCancel(args, root) {
93
+ const runId = args.shift();
94
+ if (!runId)
95
+ throw invalidInput("daemon cancel requires a run ID");
96
+ assertNoArgs(args);
97
+ const client = await daemonClient(root);
98
+ const response = await client.request(`/v1/runs/${runId}/cancel`, { method: "POST" });
99
+ process.stdout.write(`${JSON.stringify(response, null, 2)}\n`);
100
+ }
101
+ async function daemonLogs(args, root) {
102
+ const lines = positiveInteger(takeOption(args, "-n") || 50, "-n");
103
+ assertNoArgs(args);
104
+ process.stdout.write(`${await readDaemonLogs(root, lines)}\n`);
105
+ }
106
+ //# sourceMappingURL=daemon.js.map