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.
Files changed (163) hide show
  1. package/README.md +35 -193
  2. package/dist/application/use-cases/check-claimed-tests.js +81 -0
  3. package/dist/application/use-cases/detect-test-weakening.js +237 -0
  4. package/dist/application/use-cases/rerun-tests.js +110 -7
  5. package/dist/index.js +38 -1212
  6. package/dist/infrastructure/orchestration/artifacts-extractor.js +2 -323
  7. package/dist/presentation/cli/commands/check-command.js +178 -23
  8. package/dist/presentation/cli/commands/help-command.js +21 -285
  9. package/dist/ui.js +5 -236
  10. package/dist/utils/version.js +0 -6
  11. package/package.json +9 -38
  12. package/dist/application/services/verdict-service.js +0 -154
  13. package/dist/application/use-cases/assess-cross-vendor.js +0 -126
  14. package/dist/application/use-cases/build-cross-vendor-verdict.js +0 -118
  15. package/dist/application/use-cases/domain-trust.js +0 -110
  16. package/dist/application/use-cases/export-aat.js +0 -107
  17. package/dist/application/use-cases/generate-acceptance-criteria.js +0 -223
  18. package/dist/application/use-cases/generate-final-report.js +0 -259
  19. package/dist/application/use-cases/generate-narration.js +0 -130
  20. package/dist/application/use-cases/generate-thread-title.js +0 -181
  21. package/dist/application/use-cases/narrator-prompt-template.js +0 -158
  22. package/dist/application/use-cases/plan-auto-review.js +0 -57
  23. package/dist/application/use-cases/reconcile-audit.js +0 -100
  24. package/dist/application/use-cases/search-sessions.js +0 -70
  25. package/dist/application/use-cases/should-auto-review.js +0 -71
  26. package/dist/application/use-cases/thread-export.js +0 -245
  27. package/dist/application/use-cases/verify-claim.js +0 -456
  28. package/dist/application/use-cases/write-pass.js +0 -277
  29. package/dist/domain/audit.js +0 -11
  30. package/dist/domain/services/codebase-detector.js +0 -85
  31. package/dist/domain/task.js +0 -91
  32. package/dist/error-handler.js +0 -139
  33. package/dist/infrastructure/completion/bash-completion.js +0 -29
  34. package/dist/infrastructure/completion/fish-completion.js +0 -17
  35. package/dist/infrastructure/completion/zsh-completion.js +0 -25
  36. package/dist/infrastructure/config/config-manager.js +0 -174
  37. package/dist/infrastructure/config/product-context.js +0 -49
  38. package/dist/infrastructure/context/adapters/drawio-source.js +0 -157
  39. package/dist/infrastructure/context/adapters/figma-source.js +0 -198
  40. package/dist/infrastructure/context/adapters/github-issue-source.js +0 -160
  41. package/dist/infrastructure/context/adapters/linear-source.js +0 -190
  42. package/dist/infrastructure/context/context-resolver.js +0 -144
  43. package/dist/infrastructure/context/context-source.js +0 -114
  44. package/dist/infrastructure/context/github-api.js +0 -110
  45. package/dist/infrastructure/context/github-device-flow.js +0 -65
  46. package/dist/infrastructure/context/oauth-flow.js +0 -207
  47. package/dist/infrastructure/context/oauth-store.js +0 -122
  48. package/dist/infrastructure/context/registry-bootstrap.js +0 -95
  49. package/dist/infrastructure/context/write-pass-resolver.js +0 -106
  50. package/dist/infrastructure/cost/budget-config.js +0 -114
  51. package/dist/infrastructure/cost/cost-router.js +0 -97
  52. package/dist/infrastructure/cost/spend-aggregator.js +0 -222
  53. package/dist/infrastructure/cost/team-ledger.js +0 -355
  54. package/dist/infrastructure/discovery/discovery-log.js +0 -85
  55. package/dist/infrastructure/hooks/audit-tip-signature.js +0 -336
  56. package/dist/infrastructure/hooks/claude-sdk-hook.js +0 -1018
  57. package/dist/infrastructure/hooks/hook-mode.js +0 -87
  58. package/dist/infrastructure/hooks/mirror-tool-call-to-audit.js +0 -49
  59. package/dist/infrastructure/hooks/pre-prompt-scan.js +0 -122
  60. package/dist/infrastructure/hooks/session-analyzer.js +0 -177
  61. package/dist/infrastructure/observability/execution-tracer.js +0 -227
  62. package/dist/infrastructure/orchestration/agent-adapter.js +0 -13
  63. package/dist/infrastructure/orchestration/agent-installer.js +0 -101
  64. package/dist/infrastructure/orchestration/agents-config-seed.js +0 -68
  65. package/dist/infrastructure/orchestration/aider-adapter.js +0 -611
  66. package/dist/infrastructure/orchestration/cassette-recorder.js +0 -120
  67. package/dist/infrastructure/orchestration/claude-code-adapter.js +0 -592
  68. package/dist/infrastructure/orchestration/codex-adapter.js +0 -574
  69. package/dist/infrastructure/orchestration/conductor-adapter.js +0 -416
  70. package/dist/infrastructure/orchestration/context-handoff.js +0 -162
  71. package/dist/infrastructure/orchestration/control/codex-control-surface.js +0 -99
  72. package/dist/infrastructure/orchestration/control/control-surface.js +0 -15
  73. package/dist/infrastructure/orchestration/detect-ollama.js +0 -75
  74. package/dist/infrastructure/orchestration/failover-classifier.js +0 -151
  75. package/dist/infrastructure/orchestration/failover-config.js +0 -67
  76. package/dist/infrastructure/orchestration/failover-policy.js +0 -106
  77. package/dist/infrastructure/orchestration/gemini-adapter.js +0 -663
  78. package/dist/infrastructure/orchestration/generic-cli-adapter.js +0 -689
  79. package/dist/infrastructure/orchestration/graphify-context.js +0 -209
  80. package/dist/infrastructure/orchestration/memory-injector.js +0 -380
  81. package/dist/infrastructure/orchestration/mocks/mock-agent-repl.js +0 -388
  82. package/dist/infrastructure/orchestration/mocks/mock-codex-app-server.js +0 -73
  83. package/dist/infrastructure/orchestration/mocks/mock-synthesis.js +0 -83
  84. package/dist/infrastructure/orchestration/mocks/resolve-agent-spawn.js +0 -37
  85. package/dist/infrastructure/orchestration/opencode-adapter.js +0 -580
  86. package/dist/infrastructure/orchestration/progress-aggregator.js +0 -906
  87. package/dist/infrastructure/orchestration/readiness.js +0 -103
  88. package/dist/infrastructure/orchestration/session-manager.js +0 -1590
  89. package/dist/infrastructure/orchestration/session-persistence.js +0 -394
  90. package/dist/infrastructure/orchestration/thread-key-store.js +0 -127
  91. package/dist/infrastructure/orchestration/write-pass-store.js +0 -38
  92. package/dist/infrastructure/protocols/cloud-sync.js +0 -207
  93. package/dist/infrastructure/protocols/mcp-helpers.js +0 -25
  94. package/dist/infrastructure/protocols/mcp-server-impl.js +0 -3935
  95. package/dist/infrastructure/protocols/mcp-tools.js +0 -401
  96. package/dist/infrastructure/protocols/probe-port.js +0 -36
  97. package/dist/infrastructure/protocols/thread-phase.js +0 -105
  98. package/dist/infrastructure/protocols/ui/app-script-artifacts.js +0 -121
  99. package/dist/infrastructure/protocols/ui/app-script-audit-footer.js +0 -44
  100. package/dist/infrastructure/protocols/ui/app-script-audit-verify.js +0 -56
  101. package/dist/infrastructure/protocols/ui/app-script-composer-cost.js +0 -588
  102. package/dist/infrastructure/protocols/ui/app-script-context-sources.js +0 -168
  103. package/dist/infrastructure/protocols/ui/app-script-conversation.js +0 -67
  104. package/dist/infrastructure/protocols/ui/app-script-drawer.js +0 -115
  105. package/dist/infrastructure/protocols/ui/app-script-failover.js +0 -133
  106. package/dist/infrastructure/protocols/ui/app-script-github.js +0 -113
  107. package/dist/infrastructure/protocols/ui/app-script-observer.js +0 -104
  108. package/dist/infrastructure/protocols/ui/app-script-onboarding.js +0 -80
  109. package/dist/infrastructure/protocols/ui/app-script-overlay.js +0 -203
  110. package/dist/infrastructure/protocols/ui/app-script-recovery.js +0 -136
  111. package/dist/infrastructure/protocols/ui/app-script-render.js +0 -166
  112. package/dist/infrastructure/protocols/ui/app-script-share.js +0 -78
  113. package/dist/infrastructure/protocols/ui/app-script-sidebar.js +0 -194
  114. package/dist/infrastructure/protocols/ui/app-script-tour.js +0 -78
  115. package/dist/infrastructure/protocols/ui/app-script-wpass.js +0 -312
  116. package/dist/infrastructure/protocols/ui/app-script.js +0 -2998
  117. package/dist/infrastructure/protocols/ui/font-faces.js +0 -7
  118. package/dist/infrastructure/protocols/ui/styles.js +0 -2147
  119. package/dist/infrastructure/protocols/ui/tokens.js +0 -96
  120. package/dist/infrastructure/protocols/ui-page-v2.js +0 -320
  121. package/dist/infrastructure/protocols/verify-page.js +0 -1677
  122. package/dist/infrastructure/security/file-collection.js +0 -118
  123. package/dist/infrastructure/security/fix-code.js +0 -144
  124. package/dist/infrastructure/security/fix-secret.js +0 -89
  125. package/dist/infrastructure/security/permissions-config.js +0 -235
  126. package/dist/infrastructure/security/scan-types.js +0 -10
  127. package/dist/infrastructure/security/ship-scan.js +0 -195
  128. package/dist/infrastructure/security/trust-scorer.js +0 -724
  129. package/dist/infrastructure/security/vibe-checks.js +0 -99
  130. package/dist/infrastructure/storage/atomic-write.js +0 -86
  131. package/dist/infrastructure/storage/cross-tool-agents.js +0 -268
  132. package/dist/infrastructure/storage/project-thread-migration.js +0 -237
  133. package/dist/infrastructure/storage/project-thread-mirror.js +0 -671
  134. package/dist/infrastructure/storage/project-thread-reader.js +0 -409
  135. package/dist/infrastructure/storage/project-thread-title-backfill.js +0 -214
  136. package/dist/monitoring.js +0 -212
  137. package/dist/presentation/cli/commands/audit-command.js +0 -201
  138. package/dist/presentation/cli/commands/budget-command.js +0 -79
  139. package/dist/presentation/cli/commands/config-command.js +0 -125
  140. package/dist/presentation/cli/commands/context-source-command.js +0 -217
  141. package/dist/presentation/cli/commands/hook-command.js +0 -265
  142. package/dist/presentation/cli/commands/init-command.js +0 -590
  143. package/dist/presentation/cli/commands/memory-command.js +0 -1031
  144. package/dist/presentation/cli/commands/narrator-command.js +0 -101
  145. package/dist/presentation/cli/commands/permission-command.js +0 -105
  146. package/dist/presentation/cli/commands/protocols-builder.js +0 -254
  147. package/dist/presentation/cli/commands/protocols-command.js +0 -84
  148. package/dist/presentation/cli/commands/repo-map-builder.js +0 -247
  149. package/dist/presentation/cli/commands/report-command.js +0 -403
  150. package/dist/presentation/cli/commands/scan-command.js +0 -52
  151. package/dist/presentation/cli/commands/scan-tool-command.js +0 -110
  152. package/dist/presentation/cli/commands/search-command.js +0 -51
  153. package/dist/presentation/cli/commands/setup-command.js +0 -330
  154. package/dist/presentation/cli/commands/status-command.js +0 -614
  155. package/dist/presentation/cli/commands/team-command.js +0 -256
  156. package/dist/presentation/cli/commands/thread-command.js +0 -370
  157. package/dist/presentation/cli/commands/trust-command.js +0 -328
  158. package/dist/presentation/cli/commands/verify-command.js +0 -298
  159. package/dist/presentation/cli/error-display.js +0 -328
  160. package/dist/presentation/cli/repl.js +0 -805
  161. package/dist/presentation/cli/task-deliverable.js +0 -153
  162. package/dist/testing/cassette.js +0 -125
  163. 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 DEFAULT_TIMEOUT_MS = Number(process.env.CODEHERE_RERUN_TIMEOUT_MS ?? 120_000);
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({ ran: false, skippedReason: `could not spawn test command: ${String(e).slice(0, 80)}` });
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({ ran: false, skippedReason: `test re-run timed out after ${Math.round(DEFAULT_TIMEOUT_MS / 1000)}s` });
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({ ran: false, skippedReason: `test command errored: ${String(e.message).slice(0, 80)}` });
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: code ?? -1,
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
  });