@hone-ai/cli 1.34.0 → 1.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/hone-mcp.js +1 -0
- package/hone-cli.js +1263 -756
- package/lib/agent-eval-pacing.js +102 -0
- package/lib/agent-eval-probes-boundary.js +0 -0
- package/lib/agent-eval-probes-stateful.js +72 -0
- package/lib/agent-eval-score.js +70 -0
- package/lib/agent-executor.js +26 -4
- package/lib/asset-fetch-list.js +72 -0
- package/lib/auto-verify.js +67 -3
- package/lib/batch-follow.js +333 -0
- package/lib/block-grammar.js +126 -0
- package/lib/bundle-context.js +43 -4
- package/lib/bundle-paths.js +698 -1
- package/lib/bundle-source-dirs.js +79 -0
- package/lib/doctor-bind-default.js +192 -18
- package/lib/doctor-local-run.js +139 -1
- package/lib/emit-pr.js +39 -6
- package/lib/git-helpers.js +19 -8
- package/lib/hard-pause-remedy.js +101 -0
- package/lib/include-paths.js +155 -0
- package/lib/learnings-parse.js +51 -6
- package/lib/materialize-diff.js +131 -73
- package/lib/pipeline-config.js +182 -0
- package/lib/private-temp.js +34 -0
- package/lib/promote-payload.js +77 -0
- package/lib/refresh-knowledge.js +15 -6
- package/lib/repo-tree.js +22 -3
- package/lib/run-context.js +698 -0
- package/lib/sandbox-lifecycle.js +357 -0
- package/lib/schedule-cron.js +1 -1
- package/lib/skill-assertions.js +61 -7
- package/lib/skill-audit-render.js +1 -1
- package/lib/story-classifier-extract.js +16 -8
- package/lib/story-classifier.js +64 -0
- package/lib/story-compose.js +69 -0
- package/lib/story-line.js +40 -0
- package/lib/story-provenance.js +267 -0
- package/lib/timeout-option.js +42 -0
- package/lib/untrusted-code-env.js +51 -0
- package/lib/verdict-env.js +31 -0
- package/lib/verify-patch.js +74 -4
- package/lib/verify-pr.js +2 -1
- package/lib/worktree-provision.js +62 -2
- package/package.json +1 -1
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
const fs = require('node:fs');
|
|
15
15
|
const path = require('node:path');
|
|
16
|
+
const { withoutHoneVars } = require('./untrusted-code-env');
|
|
16
17
|
|
|
17
18
|
const LOCKFILES = [
|
|
18
19
|
['package-lock.json', 'npm ci --no-audit --no-fund'],
|
|
@@ -104,7 +105,7 @@ function planProvision({ worktreeDir, parentDir, installCommand = null, fsMod =
|
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
/** @returns {{ok:boolean, did:'none'|'link'|'install', summary:string, command?:string}} */
|
|
107
|
-
function provisionWorktree(plan, { worktreeDir, exec, fsMod = fs }) {
|
|
108
|
+
function provisionWorktree(plan, { worktreeDir, exec, fsMod = fs, env = process.env }) {
|
|
108
109
|
if (!plan || plan.kind === 'none') return { ok: true, did: 'none', summary: `skipped (${plan ? plan.reason : 'no plan'})` };
|
|
109
110
|
// HC-GF-024: recognised-but-unautomated. ok:true keeps the fail-open contract (the
|
|
110
111
|
// test command still runs), but the summary names the manifest so a later
|
|
@@ -120,14 +121,73 @@ function provisionWorktree(plan, { worktreeDir, exec, fsMod = fs }) {
|
|
|
120
121
|
} catch (e) { return { ok: false, did: 'link', summary: `link failed (${e.message}) — tests run unprovisioned` }; }
|
|
121
122
|
}
|
|
122
123
|
try {
|
|
123
|
-
|
|
124
|
+
// HC-GF-269: the install runs the PATCHED manifest, so a `postinstall` step_4 wrote runs here —
|
|
125
|
+
// before the test command, and whether or not it passes. It keeps the operator's toolchain
|
|
126
|
+
// (proxy, registry, virtualenv: HC-GF-144) and loses only Hone's own `HONE_*` variables.
|
|
127
|
+
const run = exec(plan.command, { cwd: worktreeDir, shell: true, encoding: 'utf8', timeout: INSTALL_TIMEOUT_MS, stdio: ['ignore', 'pipe', 'pipe'], env: withoutHoneVars(env) });
|
|
124
128
|
const ok = run && run.status === 0;
|
|
125
129
|
const tail = ok ? '' : ` — ${String((run && (run.stderr || run.stdout)) || '').trim().split('\n').filter(Boolean).pop() || 'install failed'}`;
|
|
126
130
|
return { ok, did: 'install', command: plan.command, summary: `${ok ? 'ran' : 'FAILED'} \`${plan.command}\` (${plan.reason})${tail}` };
|
|
127
131
|
} catch (e) { return { ok: false, did: 'install', command: plan.command, summary: `install threw (${e.message}) — tests run unprovisioned` }; }
|
|
128
132
|
}
|
|
129
133
|
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Every directory in `dir` that owns a package manifest — HC-GF-201.
|
|
137
|
+
*
|
|
138
|
+
* `planProvision` tests exactly one directory, and this repo has three roots:
|
|
139
|
+
* `node_modules`, `cli/node_modules`, `server/node_modules`. The two it skipped are
|
|
140
|
+
* where `ci.unit` runs (`node --test cli/lib/*.test.js`), so a worktree built by
|
|
141
|
+
* `verify-patch` ran those tests against absent modules and the resulting
|
|
142
|
+
* `Cannot find module` lines were counted as the PATCH failing tests.
|
|
143
|
+
*
|
|
144
|
+
* Bounded depth on purpose: a manifest inside `node_modules` is a dependency's, not
|
|
145
|
+
* a root of the repo under test.
|
|
146
|
+
*/
|
|
147
|
+
function discoverPackageRoots(dir, { fsMod = fs, maxDepth = 3 } = {}) {
|
|
148
|
+
const SKIP = new Set(['node_modules', '.git', '.hg', 'dist', 'build', 'coverage', 'vendor']);
|
|
149
|
+
const out = [];
|
|
150
|
+
const walk = (rel, depth) => {
|
|
151
|
+
const abs = rel === '.' ? dir : path.join(dir, rel);
|
|
152
|
+
let entries = [];
|
|
153
|
+
try { entries = fsMod.readdirSync(abs, { withFileTypes: true }); } catch { return; }
|
|
154
|
+
if (entries.some((e) => e.isFile() && e.name === 'package.json')) out.push(rel);
|
|
155
|
+
if (depth >= maxDepth) return;
|
|
156
|
+
for (const e of entries) {
|
|
157
|
+
if (!e.isDirectory() || SKIP.has(e.name) || e.name.startsWith('.')) continue;
|
|
158
|
+
walk(rel === '.' ? e.name : path.join(rel, e.name), depth + 1);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
walk('.', 0);
|
|
162
|
+
return out;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Provision every discovered root, reporting the ones we MEANT to provision and could not.
|
|
167
|
+
*
|
|
168
|
+
* The distinction is load-bearing and was named in this story's step_1 plan: `kind:'none'`
|
|
169
|
+
* (no manifest) and `kind:'unsupported'` (Python/Go/Rust — deliberately not automated) mean
|
|
170
|
+
* there is nothing to do, NOT that provisioning failed. Counting them would make every
|
|
171
|
+
* non-Node adopter's every run report NOT RUN forever.
|
|
172
|
+
*/
|
|
173
|
+
function provisionAllRoots(entries, { provision = provisionWorktree } = {}) {
|
|
174
|
+
const results = [];
|
|
175
|
+
const unprovisioned = [];
|
|
176
|
+
for (const { root, plan, worktreeDir, exec } of entries) {
|
|
177
|
+
if (plan.kind === 'none' || plan.kind === 'unsupported') {
|
|
178
|
+
results.push({ root, did: plan.kind, summary: plan.reason || plan.kind });
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
const r = provision(plan, { worktreeDir, exec, root });
|
|
182
|
+
results.push({ root, did: r.did || 'failed', summary: r.summary });
|
|
183
|
+
if (!r.ok) unprovisioned.push({ root, reason: r.summary || 'provisioning failed' });
|
|
184
|
+
}
|
|
185
|
+
return { ok: unprovisioned.length === 0, results, unprovisioned };
|
|
186
|
+
}
|
|
187
|
+
|
|
130
188
|
module.exports = {
|
|
189
|
+
discoverPackageRoots,
|
|
190
|
+
provisionAllRoots,
|
|
131
191
|
planProvision, provisionWorktree,
|
|
132
192
|
LOCKFILES, RECOGNISED_MANIFESTS, ALL_MANIFEST_NAMES, INSTALL_TIMEOUT_MS,
|
|
133
193
|
};
|