codehere 1.0.1 → 1.0.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 +35 -193
- package/dist/application/use-cases/check-claimed-tests.js +81 -0
- package/dist/application/use-cases/detect-test-weakening.js +237 -0
- package/dist/application/use-cases/rerun-tests.js +110 -7
- package/dist/index.js +38 -1212
- package/dist/infrastructure/orchestration/artifacts-extractor.js +2 -323
- package/dist/presentation/cli/commands/check-command.js +178 -23
- package/dist/presentation/cli/commands/help-command.js +21 -285
- package/dist/ui.js +5 -236
- package/dist/utils/version.js +0 -6
- package/package.json +9 -38
- package/dist/application/services/verdict-service.js +0 -154
- package/dist/application/use-cases/assess-cross-vendor.js +0 -126
- package/dist/application/use-cases/build-cross-vendor-verdict.js +0 -118
- package/dist/application/use-cases/domain-trust.js +0 -110
- package/dist/application/use-cases/export-aat.js +0 -107
- package/dist/application/use-cases/generate-acceptance-criteria.js +0 -223
- package/dist/application/use-cases/generate-final-report.js +0 -259
- package/dist/application/use-cases/generate-narration.js +0 -130
- package/dist/application/use-cases/generate-thread-title.js +0 -181
- package/dist/application/use-cases/narrator-prompt-template.js +0 -158
- package/dist/application/use-cases/plan-auto-review.js +0 -57
- package/dist/application/use-cases/reconcile-audit.js +0 -100
- package/dist/application/use-cases/search-sessions.js +0 -70
- package/dist/application/use-cases/should-auto-review.js +0 -71
- package/dist/application/use-cases/thread-export.js +0 -245
- package/dist/application/use-cases/verify-claim.js +0 -456
- package/dist/application/use-cases/write-pass.js +0 -277
- package/dist/domain/audit.js +0 -11
- package/dist/domain/services/codebase-detector.js +0 -85
- package/dist/domain/task.js +0 -91
- package/dist/error-handler.js +0 -139
- package/dist/infrastructure/completion/bash-completion.js +0 -29
- package/dist/infrastructure/completion/fish-completion.js +0 -17
- package/dist/infrastructure/completion/zsh-completion.js +0 -25
- package/dist/infrastructure/config/config-manager.js +0 -174
- package/dist/infrastructure/config/product-context.js +0 -49
- package/dist/infrastructure/context/adapters/drawio-source.js +0 -157
- package/dist/infrastructure/context/adapters/figma-source.js +0 -198
- package/dist/infrastructure/context/adapters/github-issue-source.js +0 -160
- package/dist/infrastructure/context/adapters/linear-source.js +0 -190
- package/dist/infrastructure/context/context-resolver.js +0 -144
- package/dist/infrastructure/context/context-source.js +0 -114
- package/dist/infrastructure/context/github-api.js +0 -110
- package/dist/infrastructure/context/github-device-flow.js +0 -65
- package/dist/infrastructure/context/oauth-flow.js +0 -207
- package/dist/infrastructure/context/oauth-store.js +0 -122
- package/dist/infrastructure/context/registry-bootstrap.js +0 -95
- package/dist/infrastructure/context/write-pass-resolver.js +0 -106
- package/dist/infrastructure/cost/budget-config.js +0 -114
- package/dist/infrastructure/cost/cost-router.js +0 -97
- package/dist/infrastructure/cost/spend-aggregator.js +0 -222
- package/dist/infrastructure/cost/team-ledger.js +0 -355
- package/dist/infrastructure/discovery/discovery-log.js +0 -85
- package/dist/infrastructure/hooks/audit-tip-signature.js +0 -336
- package/dist/infrastructure/hooks/claude-sdk-hook.js +0 -1018
- package/dist/infrastructure/hooks/hook-mode.js +0 -87
- package/dist/infrastructure/hooks/mirror-tool-call-to-audit.js +0 -49
- package/dist/infrastructure/hooks/pre-prompt-scan.js +0 -122
- package/dist/infrastructure/hooks/session-analyzer.js +0 -177
- package/dist/infrastructure/observability/execution-tracer.js +0 -227
- package/dist/infrastructure/orchestration/agent-adapter.js +0 -13
- package/dist/infrastructure/orchestration/agent-installer.js +0 -101
- package/dist/infrastructure/orchestration/agents-config-seed.js +0 -68
- package/dist/infrastructure/orchestration/aider-adapter.js +0 -611
- package/dist/infrastructure/orchestration/cassette-recorder.js +0 -120
- package/dist/infrastructure/orchestration/claude-code-adapter.js +0 -592
- package/dist/infrastructure/orchestration/codex-adapter.js +0 -574
- package/dist/infrastructure/orchestration/conductor-adapter.js +0 -416
- package/dist/infrastructure/orchestration/context-handoff.js +0 -162
- package/dist/infrastructure/orchestration/control/codex-control-surface.js +0 -99
- package/dist/infrastructure/orchestration/control/control-surface.js +0 -15
- package/dist/infrastructure/orchestration/detect-ollama.js +0 -75
- package/dist/infrastructure/orchestration/failover-classifier.js +0 -151
- package/dist/infrastructure/orchestration/failover-config.js +0 -67
- package/dist/infrastructure/orchestration/failover-policy.js +0 -106
- package/dist/infrastructure/orchestration/gemini-adapter.js +0 -663
- package/dist/infrastructure/orchestration/generic-cli-adapter.js +0 -689
- package/dist/infrastructure/orchestration/graphify-context.js +0 -209
- package/dist/infrastructure/orchestration/memory-injector.js +0 -380
- package/dist/infrastructure/orchestration/mocks/mock-agent-repl.js +0 -388
- package/dist/infrastructure/orchestration/mocks/mock-codex-app-server.js +0 -73
- package/dist/infrastructure/orchestration/mocks/mock-synthesis.js +0 -83
- package/dist/infrastructure/orchestration/mocks/resolve-agent-spawn.js +0 -37
- package/dist/infrastructure/orchestration/opencode-adapter.js +0 -580
- package/dist/infrastructure/orchestration/progress-aggregator.js +0 -906
- package/dist/infrastructure/orchestration/readiness.js +0 -103
- package/dist/infrastructure/orchestration/session-manager.js +0 -1590
- package/dist/infrastructure/orchestration/session-persistence.js +0 -394
- package/dist/infrastructure/orchestration/thread-key-store.js +0 -127
- package/dist/infrastructure/orchestration/write-pass-store.js +0 -38
- package/dist/infrastructure/protocols/cloud-sync.js +0 -207
- package/dist/infrastructure/protocols/mcp-helpers.js +0 -25
- package/dist/infrastructure/protocols/mcp-server-impl.js +0 -3935
- package/dist/infrastructure/protocols/mcp-tools.js +0 -401
- package/dist/infrastructure/protocols/probe-port.js +0 -36
- package/dist/infrastructure/protocols/thread-phase.js +0 -105
- package/dist/infrastructure/protocols/ui/app-script-artifacts.js +0 -121
- package/dist/infrastructure/protocols/ui/app-script-audit-footer.js +0 -44
- package/dist/infrastructure/protocols/ui/app-script-audit-verify.js +0 -56
- package/dist/infrastructure/protocols/ui/app-script-composer-cost.js +0 -588
- package/dist/infrastructure/protocols/ui/app-script-context-sources.js +0 -168
- package/dist/infrastructure/protocols/ui/app-script-conversation.js +0 -67
- package/dist/infrastructure/protocols/ui/app-script-drawer.js +0 -115
- package/dist/infrastructure/protocols/ui/app-script-failover.js +0 -133
- package/dist/infrastructure/protocols/ui/app-script-github.js +0 -113
- package/dist/infrastructure/protocols/ui/app-script-observer.js +0 -104
- package/dist/infrastructure/protocols/ui/app-script-onboarding.js +0 -80
- package/dist/infrastructure/protocols/ui/app-script-overlay.js +0 -203
- package/dist/infrastructure/protocols/ui/app-script-recovery.js +0 -136
- package/dist/infrastructure/protocols/ui/app-script-render.js +0 -166
- package/dist/infrastructure/protocols/ui/app-script-share.js +0 -78
- package/dist/infrastructure/protocols/ui/app-script-sidebar.js +0 -194
- package/dist/infrastructure/protocols/ui/app-script-tour.js +0 -78
- package/dist/infrastructure/protocols/ui/app-script-wpass.js +0 -312
- package/dist/infrastructure/protocols/ui/app-script.js +0 -2998
- package/dist/infrastructure/protocols/ui/font-faces.js +0 -7
- package/dist/infrastructure/protocols/ui/styles.js +0 -2147
- package/dist/infrastructure/protocols/ui/tokens.js +0 -96
- package/dist/infrastructure/protocols/ui-page-v2.js +0 -320
- package/dist/infrastructure/protocols/verify-page.js +0 -1677
- package/dist/infrastructure/security/file-collection.js +0 -118
- package/dist/infrastructure/security/fix-code.js +0 -144
- package/dist/infrastructure/security/fix-secret.js +0 -89
- package/dist/infrastructure/security/permissions-config.js +0 -235
- package/dist/infrastructure/security/scan-types.js +0 -10
- package/dist/infrastructure/security/ship-scan.js +0 -195
- package/dist/infrastructure/security/trust-scorer.js +0 -724
- package/dist/infrastructure/security/vibe-checks.js +0 -99
- package/dist/infrastructure/storage/atomic-write.js +0 -86
- package/dist/infrastructure/storage/cross-tool-agents.js +0 -268
- package/dist/infrastructure/storage/project-thread-migration.js +0 -237
- package/dist/infrastructure/storage/project-thread-mirror.js +0 -671
- package/dist/infrastructure/storage/project-thread-reader.js +0 -409
- package/dist/infrastructure/storage/project-thread-title-backfill.js +0 -214
- package/dist/monitoring.js +0 -212
- package/dist/presentation/cli/commands/audit-command.js +0 -201
- package/dist/presentation/cli/commands/budget-command.js +0 -79
- package/dist/presentation/cli/commands/config-command.js +0 -125
- package/dist/presentation/cli/commands/context-source-command.js +0 -217
- package/dist/presentation/cli/commands/hook-command.js +0 -265
- package/dist/presentation/cli/commands/init-command.js +0 -590
- package/dist/presentation/cli/commands/memory-command.js +0 -1031
- package/dist/presentation/cli/commands/narrator-command.js +0 -101
- package/dist/presentation/cli/commands/permission-command.js +0 -105
- package/dist/presentation/cli/commands/protocols-builder.js +0 -254
- package/dist/presentation/cli/commands/protocols-command.js +0 -84
- package/dist/presentation/cli/commands/repo-map-builder.js +0 -247
- package/dist/presentation/cli/commands/report-command.js +0 -403
- package/dist/presentation/cli/commands/scan-command.js +0 -52
- package/dist/presentation/cli/commands/scan-tool-command.js +0 -110
- package/dist/presentation/cli/commands/search-command.js +0 -51
- package/dist/presentation/cli/commands/setup-command.js +0 -330
- package/dist/presentation/cli/commands/status-command.js +0 -614
- package/dist/presentation/cli/commands/team-command.js +0 -256
- package/dist/presentation/cli/commands/thread-command.js +0 -370
- package/dist/presentation/cli/commands/trust-command.js +0 -328
- package/dist/presentation/cli/commands/verify-command.js +0 -298
- package/dist/presentation/cli/error-display.js +0 -328
- package/dist/presentation/cli/repl.js +0 -805
- package/dist/presentation/cli/task-deliverable.js +0 -153
- package/dist/testing/cassette.js +0 -125
- package/dist/testing/replay-adapter.js +0 -147
|
@@ -24,7 +24,46 @@ import { spawn } from 'node:child_process';
|
|
|
24
24
|
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
25
25
|
import { join } from 'node:path';
|
|
26
26
|
import { parseTestSummary } from '../../infrastructure/orchestration/artifacts-extractor.js';
|
|
27
|
-
const
|
|
27
|
+
const TIMEOUT_SETTING = Number(process.env.CODEHERE_RERUN_TIMEOUT_MS);
|
|
28
|
+
/**
|
|
29
|
+
* Whole milliseconds that a timer can hold; anything else falls back to two minutes. Node fires a NaN, fractional
|
|
30
|
+
* or over-2^31 timer after 1 ms, which would time out every run.
|
|
31
|
+
*/
|
|
32
|
+
const DEFAULT_TIMEOUT_MS = Number.isInteger(TIMEOUT_SETTING) && TIMEOUT_SETTING > 0 && TIMEOUT_SETTING <= 2 ** 31 - 1
|
|
33
|
+
? TIMEOUT_SETTING
|
|
34
|
+
: 120_000;
|
|
35
|
+
/** 500 → "0.5s", 120000 → "120s". */
|
|
36
|
+
const seconds = (ms) => `${Number.isInteger(ms / 1000) ? ms / 1000 : (ms / 1000).toFixed(1)}s`;
|
|
37
|
+
/** True when node's test runner printed a summary and every summary says 0 tests, or when go test found no test files. `node --test`
|
|
38
|
+
* exits 0 for a misnamed file (`calc.tests.js`), so the exit code alone reads as a pass.
|
|
39
|
+
* pytest already exits 5 in that case. */
|
|
40
|
+
export function reportedZeroTests(out) {
|
|
41
|
+
const counts = [...out.matchAll(/^[ \t]*(?:ℹ|#)[ \t]+tests[ \t]+(\d+)[ \t]*$/gm)].map((m) => Number(m[1]));
|
|
42
|
+
if (counts.length > 0)
|
|
43
|
+
return counts.every((n) => n === 0);
|
|
44
|
+
// `go test ./...` exits 0 and prints `[no test files]` for every package when the module has no _test.go files.
|
|
45
|
+
return /^\?[ \t]+.*\[no test files\]/m.test(out) && !/^(ok|FAIL|---)[ \t]/m.test(out);
|
|
46
|
+
}
|
|
47
|
+
/** True when the runner's own summary says tests were skipped and none passed or failed: node:test (`pass 0`,
|
|
48
|
+
* `skipped N`), pytest's final line, and the jest or vitest `Tests` line. A run like that tested nothing. */
|
|
49
|
+
export function reportedOnlySkipped(out) {
|
|
50
|
+
const last = (re) => [...out.matchAll(re)].pop();
|
|
51
|
+
const node = (k) => {
|
|
52
|
+
const m = last(new RegExp(`^[ \\t]*(?:ℹ|#)[ \\t]+${k}[ \\t]+(\\d+)[ \\t]*$`, 'gm'));
|
|
53
|
+
return m ? Number(m[1]) : null;
|
|
54
|
+
};
|
|
55
|
+
const pass = node('pass');
|
|
56
|
+
const skipped = node('skipped');
|
|
57
|
+
if (pass !== null && skipped !== null)
|
|
58
|
+
return pass === 0 && (node('fail') ?? 0) === 0 && skipped > 0;
|
|
59
|
+
const py = last(/^=+ (.*) in [\d.]+s(?: \([^)]*\))? =+$/gm);
|
|
60
|
+
if (py)
|
|
61
|
+
return /\b\d+ skipped\b/.test(py[1]) && !/\b\d+ (passed|failed|errors?|xpassed)\b/.test(py[1]);
|
|
62
|
+
const js = last(/^[ \t]*Tests:?[ \t]+(.*)$/gm);
|
|
63
|
+
if (js)
|
|
64
|
+
return /\b\d+ skipped\b/.test(js[1]) && !/\b\d+ (passed|failed)\b/.test(js[1]);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
28
67
|
/** True if `file` exists in `cwd` and its text contains `needle` (case-insensitive). */
|
|
29
68
|
function fileMentions(cwd, file, needle) {
|
|
30
69
|
try {
|
|
@@ -139,6 +178,41 @@ export function detectTestCommand(cwd) {
|
|
|
139
178
|
}
|
|
140
179
|
return null;
|
|
141
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* The one command that would make the suite runnable — returned as a STRING to
|
|
183
|
+
* SHOW the user, NEVER executed. The owner's call (2026-08-17): guide, never execute —
|
|
184
|
+
* auto-installing runs arbitrary postinstall code, which is exactly the posture
|
|
185
|
+
* a trust tool must not take (the same reason detectTestCommand keeps
|
|
186
|
+
* `--no-install`). Mirrors detectTestCommand's marker-probing: pick the
|
|
187
|
+
* ecosystem, name its install. Returns undefined when there's nothing to suggest.
|
|
188
|
+
*/
|
|
189
|
+
export function detectRemedy(cwd) {
|
|
190
|
+
const has = (f) => existsSync(join(cwd, f));
|
|
191
|
+
// Node — deps missing / runner not installed → install from the lockfile.
|
|
192
|
+
if (has('package.json')) {
|
|
193
|
+
if (has('pnpm-lock.yaml'))
|
|
194
|
+
return 'pnpm install';
|
|
195
|
+
if (has('yarn.lock'))
|
|
196
|
+
return 'yarn install';
|
|
197
|
+
if (has('package-lock.json'))
|
|
198
|
+
return 'npm ci';
|
|
199
|
+
return 'npm install';
|
|
200
|
+
}
|
|
201
|
+
// Python — set up a venv and install, then re-check.
|
|
202
|
+
if (has('requirements.txt')) {
|
|
203
|
+
return 'python -m venv .venv && . .venv/bin/activate && pip install -r requirements.txt';
|
|
204
|
+
}
|
|
205
|
+
if (has('pyproject.toml') || has('setup.py') || has('setup.cfg')) {
|
|
206
|
+
return 'python -m venv .venv && . .venv/bin/activate && pip install -e .';
|
|
207
|
+
}
|
|
208
|
+
if (has('pytest.ini') || has('conftest.py'))
|
|
209
|
+
return 'pip install pytest';
|
|
210
|
+
if (has('go.mod'))
|
|
211
|
+
return 'go mod download';
|
|
212
|
+
if (has('Cargo.toml'))
|
|
213
|
+
return 'cargo fetch';
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
142
216
|
/**
|
|
143
217
|
* Re-run the project's tests on the real on-disk state. Async + timeout-bounded.
|
|
144
218
|
* Resolves with `ran:false` + a reason when there's nothing to run or it's
|
|
@@ -146,11 +220,11 @@ export function detectTestCommand(cwd) {
|
|
|
146
220
|
*/
|
|
147
221
|
export function rerunTests(cwd) {
|
|
148
222
|
if (process.env.CODEHERE_RERUN_TESTS === '0') {
|
|
149
|
-
return Promise.resolve({ ran: false, skippedReason: 'disabled (CODEHERE_RERUN_TESTS=0)' });
|
|
223
|
+
return Promise.resolve({ ran: false, kind: 'disabled', skippedReason: 'disabled (CODEHERE_RERUN_TESTS=0)' });
|
|
150
224
|
}
|
|
151
225
|
const detected = detectTestCommand(cwd);
|
|
152
226
|
if (!detected) {
|
|
153
|
-
return Promise.resolve({ ran: false, skippedReason: 'no known test command in this project' });
|
|
227
|
+
return Promise.resolve({ ran: false, kind: 'no-command', skippedReason: 'no known test command in this project' });
|
|
154
228
|
}
|
|
155
229
|
return new Promise((resolve) => {
|
|
156
230
|
const start = Date.now();
|
|
@@ -175,7 +249,13 @@ export function rerunTests(cwd) {
|
|
|
175
249
|
});
|
|
176
250
|
}
|
|
177
251
|
catch (e) {
|
|
178
|
-
done({
|
|
252
|
+
done({
|
|
253
|
+
ran: false,
|
|
254
|
+
kind: 'command-not-found',
|
|
255
|
+
command: detected.display,
|
|
256
|
+
skippedReason: `could not spawn test command: ${String(e).slice(0, 80)}`,
|
|
257
|
+
remedy: detectRemedy(cwd),
|
|
258
|
+
});
|
|
179
259
|
return;
|
|
180
260
|
}
|
|
181
261
|
const timer = setTimeout(() => {
|
|
@@ -195,7 +275,12 @@ export function rerunTests(cwd) {
|
|
|
195
275
|
/* best-effort */
|
|
196
276
|
}
|
|
197
277
|
}
|
|
198
|
-
done({
|
|
278
|
+
done({
|
|
279
|
+
ran: false,
|
|
280
|
+
kind: 'timed-out',
|
|
281
|
+
command: detected.display,
|
|
282
|
+
skippedReason: `test re-run timed out after ${seconds(DEFAULT_TIMEOUT_MS)}`,
|
|
283
|
+
});
|
|
199
284
|
}, DEFAULT_TIMEOUT_MS);
|
|
200
285
|
const cap = (chunk) => {
|
|
201
286
|
out += String(chunk);
|
|
@@ -207,18 +292,36 @@ export function rerunTests(cwd) {
|
|
|
207
292
|
child.stderr?.on('data', cap);
|
|
208
293
|
child.on('error', (e) => {
|
|
209
294
|
clearTimeout(timer);
|
|
210
|
-
done({
|
|
295
|
+
done({
|
|
296
|
+
ran: false,
|
|
297
|
+
kind: 'command-not-found',
|
|
298
|
+
command: detected.display,
|
|
299
|
+
skippedReason: `test command errored: ${String(e.message).slice(0, 80)}`,
|
|
300
|
+
remedy: detectRemedy(cwd),
|
|
301
|
+
});
|
|
211
302
|
});
|
|
212
303
|
child.on('close', (code) => {
|
|
213
304
|
clearTimeout(timer);
|
|
305
|
+
const ec = code ?? -1;
|
|
214
306
|
const parsed = parseTestSummary(out);
|
|
307
|
+
// 126/127 = the wrapper launched but the runner/deps aren't installed —
|
|
308
|
+
// nothing was tested, so this is NOT a failing suite. Classify it as
|
|
309
|
+
// runner-missing (with the one-command remedy) so no surface renders a
|
|
310
|
+
// red measured-fail for an unrunnable suite.
|
|
311
|
+
const allSkipped = ec === 0 && reportedOnlySkipped(out);
|
|
312
|
+
const noTests = ec === 0 && (reportedZeroTests(out) || allSkipped);
|
|
313
|
+
const kind = ec === 126 || ec === 127 ? 'runner-missing' : ec === 0 && !noTests ? 'passed' : 'failed';
|
|
215
314
|
done({
|
|
216
315
|
ran: true,
|
|
316
|
+
kind,
|
|
217
317
|
command: detected.display,
|
|
218
|
-
exitCode:
|
|
318
|
+
exitCode: ec,
|
|
219
319
|
passed: parsed?.passed,
|
|
220
320
|
failed: parsed?.failed,
|
|
321
|
+
...(noTests ? { noTests: true } : {}),
|
|
322
|
+
...(allSkipped ? { allSkipped: true } : {}),
|
|
221
323
|
durationMs: Date.now() - start,
|
|
324
|
+
...(kind === 'runner-missing' ? { remedy: detectRemedy(cwd) } : {}),
|
|
222
325
|
});
|
|
223
326
|
});
|
|
224
327
|
});
|