dsh-harbor-evolution 0.8.2 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/lib/evolution.js +19 -0
- package/lib/process.js +27 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,8 +14,8 @@ npx --yes dsh-harbor-evolution@latest setup --project-root "$PWD"
|
|
|
14
14
|
|
|
15
15
|
The setup command installs both required runtimes:
|
|
16
16
|
|
|
17
|
-
- `harbor-dsh-evolution==0.8.
|
|
18
|
-
- `dsh-harbor-evolution@0.8.
|
|
17
|
+
- `harbor-dsh-evolution==0.8.3` in a managed Python environment.
|
|
18
|
+
- `dsh-harbor-evolution@0.8.3` in the selected DSH profile.
|
|
19
19
|
|
|
20
20
|
It then stores the absolute Harbor executable paths and a fallback `projectRoot` in the profile's `harbor-evolution` block and verifies the integration. Agent Tool calls always use the calling session's absolute working directory as their project root; the configured value remains the Web Workbench and non-Agent fallback. Existing unrelated profile entries are preserved, and rerunning setup updates the same block.
|
|
21
21
|
|
package/lib/evolution.js
CHANGED
|
@@ -154,6 +154,15 @@ async function cliJson(config, args, { allowedExitCodes = [0], input } = {}) {
|
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
export function historicalDockerBlockers(value) {
|
|
158
|
+
const findings = Array.isArray(value?.findings) ? value.findings : []
|
|
159
|
+
return findings.filter(item => (
|
|
160
|
+
item?.level === 'error'
|
|
161
|
+
&& typeof item.code === 'string'
|
|
162
|
+
&& item.code.startsWith('DOCKER_')
|
|
163
|
+
))
|
|
164
|
+
}
|
|
165
|
+
|
|
157
166
|
export async function inspectEvaluator(config, args = {}) {
|
|
158
167
|
const stack = resolveWithin(config.projectRoot, args.stackPath ?? '.harbor/evaluation-stack.yml', 'stackPath')
|
|
159
168
|
return cliJson(config, [
|
|
@@ -467,6 +476,16 @@ export async function runHistoricalEvaluation(config, args, modelRuntime) {
|
|
|
467
476
|
])
|
|
468
477
|
const dataset = resolveWithin(projectRoot, materialized.dataset_path ?? output, 'historicalDataset')
|
|
469
478
|
const stack = resolveWithin(projectRoot, materialized.stack_path, 'historicalStack')
|
|
479
|
+
// Fail fast on Docker runtime blockers (e.g. an unresolvable credential
|
|
480
|
+
// helper) before Harbor creates a Job whose Trials would all fail during
|
|
481
|
+
// environment setup and only report missing downstream artifacts.
|
|
482
|
+
const dockerCheck = await cliJson(config, ['docker-check'], { allowedExitCodes: [0, 2] })
|
|
483
|
+
const dockerBlockers = historicalDockerBlockers(dockerCheck)
|
|
484
|
+
if (dockerBlockers.length) {
|
|
485
|
+
throw new Error(
|
|
486
|
+
`HISTORICAL_DOCKER_PREFLIGHT_FAILED: Docker runtime preflight blocked the Historical Job:\n${dockerBlockers.map(item => `${item.code}: ${item.message}`).join('\n')}`,
|
|
487
|
+
)
|
|
488
|
+
}
|
|
470
489
|
const batch = JSON.parse(await readFile(batchPath, 'utf8'))
|
|
471
490
|
const jobs = resolveWithin(projectRoot, config.jobsDir, 'jobsDir')
|
|
472
491
|
const jobName = args.jobName ?? makeHistoricalJobName(batch)
|
package/lib/process.js
CHANGED
|
@@ -1,10 +1,36 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process'
|
|
2
|
+
import { existsSync } from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
|
|
5
|
+
const DOCKER_DESKTOP_BIN = '/Applications/Docker.app/Contents/Resources/bin'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* On macOS, Docker Desktop keeps `docker-credential-desktop` (and the other
|
|
9
|
+
* credential helpers) inside the app bundle, outside the default PATH that a
|
|
10
|
+
* GUI-launched Harness inherits. A missing helper makes `docker build`/`pull`
|
|
11
|
+
* fail with `exec: "docker-credential-desktop": executable file not found in
|
|
12
|
+
* $PATH` even though the CLI and daemon are reachable. Prepend that directory
|
|
13
|
+
* to PATH for every child process we spawn so Harbor inherits a resolvable
|
|
14
|
+
* helper. The change is macOS-only, existence-checked, and idempotent.
|
|
15
|
+
*/
|
|
16
|
+
export function dockerDesktopAwareEnv(env, {
|
|
17
|
+
platform = process.platform,
|
|
18
|
+
pathExists = existsSync,
|
|
19
|
+
} = {}) {
|
|
20
|
+
const base = env ?? process.env
|
|
21
|
+
if (platform !== 'darwin') return base
|
|
22
|
+
if (!pathExists(DOCKER_DESKTOP_BIN)) return base
|
|
23
|
+
const current = String(base.PATH ?? '')
|
|
24
|
+
const segments = current.split(path.delimiter).filter(Boolean)
|
|
25
|
+
if (segments.includes(DOCKER_DESKTOP_BIN)) return base
|
|
26
|
+
return { ...base, PATH: [DOCKER_DESKTOP_BIN, ...segments].join(path.delimiter) }
|
|
27
|
+
}
|
|
2
28
|
|
|
3
29
|
export function runProcess(command, args, options = {}) {
|
|
4
30
|
return new Promise((resolve, reject) => {
|
|
5
31
|
const child = spawn(command, args, {
|
|
6
32
|
cwd: options.cwd,
|
|
7
|
-
env: options.env ?? process.env,
|
|
33
|
+
env: dockerDesktopAwareEnv(options.env ?? process.env),
|
|
8
34
|
shell: false,
|
|
9
35
|
stdio: [options.input === undefined ? 'ignore' : 'pipe', 'pipe', 'pipe'],
|
|
10
36
|
})
|
package/package.json
CHANGED