codehere 0.8.0 → 1.0.2

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 (119) hide show
  1. package/README.md +37 -184
  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 +329 -0
  5. package/dist/index.js +74 -1004
  6. package/dist/infrastructure/orchestration/artifacts-extractor.js +2 -265
  7. package/dist/presentation/cli/commands/check-command.js +251 -0
  8. package/dist/presentation/cli/commands/help-command.js +22 -286
  9. package/dist/ui.js +19 -438
  10. package/dist/utils/version.js +0 -12
  11. package/package.json +18 -27
  12. package/dist/application/use-cases/domain-trust.js +0 -110
  13. package/dist/application/use-cases/generate-final-report.js +0 -134
  14. package/dist/application/use-cases/generate-narration.js +0 -128
  15. package/dist/application/use-cases/generate-thread-title.js +0 -178
  16. package/dist/application/use-cases/narrator-prompt-template.js +0 -158
  17. package/dist/application/use-cases/thread-export.js +0 -155
  18. package/dist/application/use-cases/verify-claim.js +0 -274
  19. package/dist/application/use-cases/write-pass.js +0 -277
  20. package/dist/domain/entities/task.js +0 -61
  21. package/dist/domain/services/codebase-detector.js +0 -91
  22. package/dist/error-handler.js +0 -251
  23. package/dist/infrastructure/completion/bash-completion.js +0 -25
  24. package/dist/infrastructure/completion/fish-completion.js +0 -22
  25. package/dist/infrastructure/completion/zsh-completion.js +0 -30
  26. package/dist/infrastructure/config/config-manager.js +0 -173
  27. package/dist/infrastructure/config/product-context.js +0 -67
  28. package/dist/infrastructure/context/adapters/drawio-source.js +0 -157
  29. package/dist/infrastructure/context/adapters/figma-source.js +0 -163
  30. package/dist/infrastructure/context/adapters/github-issue-source.js +0 -159
  31. package/dist/infrastructure/context/adapters/linear-source.js +0 -190
  32. package/dist/infrastructure/context/context-resolver.js +0 -144
  33. package/dist/infrastructure/context/context-source.js +0 -114
  34. package/dist/infrastructure/context/oauth-flow.js +0 -207
  35. package/dist/infrastructure/context/oauth-store.js +0 -119
  36. package/dist/infrastructure/context/registry-bootstrap.js +0 -99
  37. package/dist/infrastructure/context/write-pass-resolver.js +0 -106
  38. package/dist/infrastructure/cost/budget-config.js +0 -113
  39. package/dist/infrastructure/cost/cost-router.js +0 -104
  40. package/dist/infrastructure/cost/spend-aggregator.js +0 -147
  41. package/dist/infrastructure/hooks/claude-sdk-hook.js +0 -888
  42. package/dist/infrastructure/hooks/hook-mode.js +0 -71
  43. package/dist/infrastructure/hooks/mirror-tool-call-to-audit.js +0 -43
  44. package/dist/infrastructure/hooks/pre-prompt-scan.js +0 -122
  45. package/dist/infrastructure/hooks/session-analyzer.js +0 -177
  46. package/dist/infrastructure/observability/execution-tracer.js +0 -227
  47. package/dist/infrastructure/orchestration/agent-adapter.js +0 -13
  48. package/dist/infrastructure/orchestration/agent-installer.js +0 -101
  49. package/dist/infrastructure/orchestration/agents-config-seed.js +0 -56
  50. package/dist/infrastructure/orchestration/aider-adapter.js +0 -447
  51. package/dist/infrastructure/orchestration/cassette-recorder.js +0 -120
  52. package/dist/infrastructure/orchestration/claude-code-adapter.js +0 -478
  53. package/dist/infrastructure/orchestration/codex-adapter.js +0 -538
  54. package/dist/infrastructure/orchestration/conductor-adapter.js +0 -377
  55. package/dist/infrastructure/orchestration/context-handoff.js +0 -144
  56. package/dist/infrastructure/orchestration/control/codex-control-surface.js +0 -99
  57. package/dist/infrastructure/orchestration/control/control-surface.js +0 -15
  58. package/dist/infrastructure/orchestration/failover-classifier.js +0 -151
  59. package/dist/infrastructure/orchestration/failover-config.js +0 -77
  60. package/dist/infrastructure/orchestration/failover-policy.js +0 -106
  61. package/dist/infrastructure/orchestration/gemini-adapter.js +0 -583
  62. package/dist/infrastructure/orchestration/generic-cli-adapter.js +0 -558
  63. package/dist/infrastructure/orchestration/graphify-context.js +0 -254
  64. package/dist/infrastructure/orchestration/memory-injector.js +0 -380
  65. package/dist/infrastructure/orchestration/mocks/mock-agent-repl.js +0 -233
  66. package/dist/infrastructure/orchestration/mocks/mock-codex-app-server.js +0 -73
  67. package/dist/infrastructure/orchestration/mocks/mock-synthesis.js +0 -83
  68. package/dist/infrastructure/orchestration/mocks/resolve-agent-spawn.js +0 -37
  69. package/dist/infrastructure/orchestration/opencode-adapter.js +0 -510
  70. package/dist/infrastructure/orchestration/progress-aggregator.js +0 -689
  71. package/dist/infrastructure/orchestration/readiness.js +0 -103
  72. package/dist/infrastructure/orchestration/session-manager.js +0 -1091
  73. package/dist/infrastructure/orchestration/session-persistence.js +0 -258
  74. package/dist/infrastructure/orchestration/thread-key-store.js +0 -127
  75. package/dist/infrastructure/orchestration/write-pass-store.js +0 -46
  76. package/dist/infrastructure/protocols/cloud-sync.js +0 -207
  77. package/dist/infrastructure/protocols/mcp-helpers.js +0 -25
  78. package/dist/infrastructure/protocols/mcp-server-impl.js +0 -2853
  79. package/dist/infrastructure/protocols/probe-port.js +0 -36
  80. package/dist/infrastructure/protocols/thread-phase.js +0 -105
  81. package/dist/infrastructure/protocols/ui-page-v2.js +0 -4418
  82. package/dist/infrastructure/protocols/ui-page.js +0 -2377
  83. package/dist/infrastructure/protocols/verify-page.js +0 -983
  84. package/dist/infrastructure/security/file-collection.js +0 -118
  85. package/dist/infrastructure/security/input-validator.js +0 -152
  86. package/dist/infrastructure/security/permissions-config.js +0 -234
  87. package/dist/infrastructure/security/trust-scorer.js +0 -657
  88. package/dist/infrastructure/storage/cross-tool-agents.js +0 -268
  89. package/dist/infrastructure/storage/embeddings-path.js +0 -37
  90. package/dist/infrastructure/storage/project-thread-migration.js +0 -237
  91. package/dist/infrastructure/storage/project-thread-mirror.js +0 -524
  92. package/dist/infrastructure/storage/project-thread-reader.js +0 -172
  93. package/dist/infrastructure/storage/project-thread-title-backfill.js +0 -214
  94. package/dist/infrastructure/storage/task-repository.js +0 -206
  95. package/dist/monitoring.js +0 -212
  96. package/dist/presentation/cli/commands/audit-command.js +0 -126
  97. package/dist/presentation/cli/commands/budget-command.js +0 -79
  98. package/dist/presentation/cli/commands/config-command.js +0 -125
  99. package/dist/presentation/cli/commands/context-source-command.js +0 -198
  100. package/dist/presentation/cli/commands/hook-command.js +0 -265
  101. package/dist/presentation/cli/commands/init-command.js +0 -578
  102. package/dist/presentation/cli/commands/memory-command.js +0 -1031
  103. package/dist/presentation/cli/commands/narrator-command.js +0 -101
  104. package/dist/presentation/cli/commands/permission-command.js +0 -116
  105. package/dist/presentation/cli/commands/protocols-builder.js +0 -254
  106. package/dist/presentation/cli/commands/protocols-command.js +0 -84
  107. package/dist/presentation/cli/commands/repo-map-builder.js +0 -247
  108. package/dist/presentation/cli/commands/report-command.js +0 -387
  109. package/dist/presentation/cli/commands/scan-tool-command.js +0 -94
  110. package/dist/presentation/cli/commands/setup-command.js +0 -307
  111. package/dist/presentation/cli/commands/status-command.js +0 -661
  112. package/dist/presentation/cli/commands/thread-command.js +0 -288
  113. package/dist/presentation/cli/commands/trust-command.js +0 -306
  114. package/dist/presentation/cli/commands/verify-command.js +0 -233
  115. package/dist/presentation/cli/error-display.js +0 -336
  116. package/dist/presentation/cli/repl.js +0 -797
  117. package/dist/presentation/cli/task-deliverable.js +0 -127
  118. package/dist/testing/cassette.js +0 -125
  119. package/dist/testing/replay-adapter.js +0 -166
@@ -1,104 +0,0 @@
1
- /**
2
- * Cost Router
3
- *
4
- * Given a trust score and task complexity, recommends the cheapest model
5
- * that's safe to use. The 42x cost difference between Haiku and Opus means
6
- * routing decisions have real financial impact at scale.
7
- *
8
- * Model tiers (approximate $/M output tokens, 2026):
9
- * fast tier (e.g. claude-haiku-4-5) $1.25 — cheap, good for simple tasks
10
- * balanced tier (e.g. claude-sonnet-4-6) $15.00 — good for most tasks
11
- * max tier (e.g. claude-opus-4-6) $75.00 — strongest, use sparingly
12
- *
13
- * Routing logic:
14
- * trust >= 90, simple task → fast tier (60x cheaper than max tier)
15
- * trust >= 75, any task → balanced tier (5x cheaper than max tier)
16
- * trust < 75, or critical → balanced tier with human review flag
17
- * critical findings present → block before reaching model
18
- */
19
- const MODEL_COSTS = {
20
- haiku: 1.25,
21
- sonnet: 15.0,
22
- opus: 75.0,
23
- };
24
- const MODEL_IDS = {
25
- haiku: 'claude-haiku-4-5-20251001',
26
- sonnet: 'claude-sonnet-4-6',
27
- opus: 'claude-opus-4-6',
28
- };
29
- const TIER_LABELS = {
30
- haiku: 'fast tier',
31
- sonnet: 'balanced tier',
32
- opus: 'max tier',
33
- };
34
- function savingsLabel(chosen) {
35
- if (chosen === 'opus')
36
- return 'max tier (baseline)';
37
- const ratio = MODEL_COSTS.opus / MODEL_COSTS[chosen];
38
- return `${TIER_LABELS[chosen]} · ${Math.round(ratio)}x cheaper than max tier`;
39
- }
40
- /**
41
- * Recommend the optimal model for a given trust score and task complexity.
42
- */
43
- export function recommendModel(trustScore, complexity = 'standard', criticalFindings = 0) {
44
- // Critical findings → require human review regardless of model
45
- if (criticalFindings > 0) {
46
- return {
47
- model: 'sonnet',
48
- modelId: MODEL_IDS.sonnet,
49
- reason: `${criticalFindings} critical finding${criticalFindings !== 1 ? 's' : ''} — human review required before applying any edit`,
50
- costPer1MTokens: MODEL_COSTS.sonnet,
51
- savingsVsOpus: savingsLabel('sonnet'),
52
- humanReview: true,
53
- };
54
- }
55
- // High-trust simple tasks → Haiku
56
- if (trustScore >= 90 && complexity === 'simple') {
57
- return {
58
- model: 'haiku',
59
- modelId: MODEL_IDS.haiku,
60
- reason: `Trust ${trustScore}/100 · simple task — safe for fastest, cheapest model`,
61
- costPer1MTokens: MODEL_COSTS.haiku,
62
- savingsVsOpus: savingsLabel('haiku'),
63
- humanReview: false,
64
- };
65
- }
66
- // Good trust, standard task → Sonnet
67
- if (trustScore >= 75) {
68
- return {
69
- model: 'sonnet',
70
- modelId: MODEL_IDS.sonnet,
71
- reason: `Trust ${trustScore}/100 · ${complexity} task — Sonnet is the right balance`,
72
- costPer1MTokens: MODEL_COSTS.sonnet,
73
- savingsVsOpus: savingsLabel('sonnet'),
74
- humanReview: false,
75
- };
76
- }
77
- // Low trust → Sonnet with human review
78
- return {
79
- model: 'sonnet',
80
- modelId: MODEL_IDS.sonnet,
81
- reason: `Trust ${trustScore}/100 — lower confidence; recommend reviewing the output`,
82
- costPer1MTokens: MODEL_COSTS.sonnet,
83
- savingsVsOpus: savingsLabel('sonnet'),
84
- humanReview: true,
85
- };
86
- }
87
- /**
88
- * Estimate monthly savings from routing decisions.
89
- * @param avgTokensPerTask Average output tokens per AI task
90
- * @param tasksPerMonth Monthly task volume
91
- * @param distribution Fraction of tasks at each tier
92
- */
93
- export function estimateMonthlySavings(avgTokensPerTask = 2000, tasksPerMonth = 500, distribution = { haiku: 0.4, sonnet: 0.55, opus: 0.05 }) {
94
- const tokensMillion = avgTokensPerTask / 1_000_000;
95
- let routedCost = 0;
96
- for (const [tier, fraction] of Object.entries(distribution)) {
97
- routedCost += fraction * tasksPerMonth * tokensMillion * MODEL_COSTS[tier];
98
- }
99
- const opusCost = tasksPerMonth * tokensMillion * MODEL_COSTS.opus;
100
- const saving = opusCost - routedCost;
101
- const savingPct = (saving / opusCost) * 100;
102
- return { routedCost, opusCost, saving, savingPct };
103
- }
104
- //# sourceMappingURL=cost-router.js.map
@@ -1,147 +0,0 @@
1
- /**
2
- * v0.6 S3 slice 1 — spend-today aggregator.
3
- *
4
- * Reads ~/.codehere/sessions.jsonl (the same append-only log session-persistence
5
- * writes), filters completed records to today (local timezone), and estimates
6
- * dollar spend per agent based on token usage × per-tier output-rate ceilings.
7
- *
8
- * Why · claim_market_position v3 lists "cost-bounded execution" as one of the
9
- * few capture-strategy edges still possibly open. Demonstrating cost awareness
10
- * starts here: surface what the user has actually spent today across all spawned
11
- * agents, then (slice 2) enforce a per-day ceiling.
12
- *
13
- * Why estimates not exact · codehere doesn't see provider invoices. Adapters
14
- * report token counts via TaskArtifacts.usage; we multiply by published tier
15
- * ceilings. Per feedback_overconfidence_guard.md, copy frames this as
16
- * "estimate" and points to vendor dashboards as authoritative.
17
- *
18
- * Cost table · output-tier ceilings (input is rougher; we use a 5x ratio).
19
- * All values 2026 published rates. When a model isn't surfaced in usage,
20
- * default to the agent's typical tier.
21
- */
22
- import { existsSync, readFileSync } from 'fs';
23
- import { homedir } from 'os';
24
- import { join } from 'path';
25
- /** Resolved at call time, not module load, so test setups that swap $HOME
26
- * after import still get a fresh path on each invocation. */
27
- function sessionsFile() {
28
- return join(process.env.CODEHERE_HOME || homedir(), '.codehere', 'sessions.jsonl');
29
- }
30
- /** USD per million OUTPUT tokens at the agent's typical 2026 tier. Input is
31
- * estimated at 1/5 of output rate (Anthropic + OpenAI both publish ~5x
32
- * output:input ratios on their flagship coding tiers). Cache reads ~1/10
33
- * of input. Free-tier agents → 0.
34
- *
35
- * Conservative-ceiling philosophy: better to over-estimate spend than
36
- * under-promise and miss a real bill. */
37
- const COST_PER_M_OUTPUT_TOKENS_USD = {
38
- 'claude-code': 15.0, // Sonnet 4.6 baseline
39
- codex: 10.0, // GPT-5 / codex baseline
40
- aider: 15.0, // typically Sonnet
41
- gemini: 0, // free tier (Google AI Studio)
42
- opencode: 0, // typically free local / NIM-routed
43
- conductor: 15.0, // routes to Claude Code by default
44
- };
45
- const INPUT_RATE_RATIO = 0.2; // input ≈ 1/5 of output
46
- const CACHE_READ_RATIO = 0.1; // cache reads ≈ 1/10 of input (so 1/50 output)
47
- /**
48
- * Estimate dollar cost for one session's token usage at one agent's typical tier.
49
- * Returns 0 for free-tier agents and unknown agents (no mapping → no estimate).
50
- */
51
- export function estimateCostUsd(agent, usage) {
52
- if (!usage)
53
- return 0;
54
- const outputRate = COST_PER_M_OUTPUT_TOKENS_USD[agent];
55
- if (outputRate === undefined || outputRate === 0)
56
- return 0;
57
- const inputRate = outputRate * INPUT_RATE_RATIO;
58
- const cacheReadRate = inputRate * CACHE_READ_RATIO;
59
- // Cache CREATION is billed at input rate (Anthropic). Use same default.
60
- const tokens = {
61
- input: Math.max(0, usage.inputTokens || 0),
62
- output: Math.max(0, usage.outputTokens || 0),
63
- cacheRead: Math.max(0, usage.cacheReadTokens || 0),
64
- cacheCreate: Math.max(0, usage.cacheCreationTokens || 0),
65
- };
66
- return ((tokens.input / 1_000_000) * inputRate +
67
- (tokens.output / 1_000_000) * outputRate +
68
- (tokens.cacheRead / 1_000_000) * cacheReadRate +
69
- (tokens.cacheCreate / 1_000_000) * inputRate);
70
- }
71
- /** Return the millisecond timestamp for the start of "today" in local time. */
72
- function startOfTodayLocalMs(now = new Date()) {
73
- const d = new Date(now);
74
- d.setHours(0, 0, 0, 0);
75
- return d.getTime();
76
- }
77
- /**
78
- * Walk sessions.jsonl, sum estimated USD spend for sessions whose
79
- * `completedAt` falls within today (local). Best-effort: missing file =
80
- * empty report; parse errors per-line ignored. Pairs spawned + completed
81
- * by id so we know which agent spent what.
82
- */
83
- export function computeSpendToday(now = new Date()) {
84
- const cutoff = startOfTodayLocalMs(now);
85
- const empty = {
86
- totalUsd: 0,
87
- tokens: { input: 0, output: 0, cache: 0 },
88
- sessionCount: 0,
89
- byAgent: {},
90
- windowStartedAt: cutoff,
91
- };
92
- if (!existsSync(sessionsFile()))
93
- return empty;
94
- let content;
95
- try {
96
- content = readFileSync(sessionsFile(), 'utf-8');
97
- }
98
- catch {
99
- return empty;
100
- }
101
- // Pair spawned (carries agent) with completed (carries usage + completedAt).
102
- const spawnedAgent = new Map();
103
- const report = { ...empty, byAgent: {} };
104
- for (const line of content.split('\n')) {
105
- const trimmed = line.trim();
106
- if (!trimmed)
107
- continue;
108
- let rec;
109
- try {
110
- rec = JSON.parse(trimmed);
111
- }
112
- catch {
113
- continue;
114
- }
115
- if (rec.t === 'spawned' && rec.id && rec.agent) {
116
- spawnedAgent.set(rec.id, rec.agent);
117
- continue;
118
- }
119
- if (rec.t !== 'completed' || !rec.id)
120
- continue;
121
- if (typeof rec.completedAt !== 'number' || rec.completedAt < cutoff)
122
- continue;
123
- const agent = spawnedAgent.get(rec.id);
124
- if (!agent)
125
- continue;
126
- const usage = rec.artifacts?.usage;
127
- const usd = estimateCostUsd(agent, usage);
128
- report.sessionCount += 1;
129
- if (usage) {
130
- report.tokens.input += usage.inputTokens || 0;
131
- report.tokens.output += usage.outputTokens || 0;
132
- report.tokens.cache += (usage.cacheReadTokens || 0) + (usage.cacheCreationTokens || 0);
133
- }
134
- report.totalUsd += usd;
135
- const cur = report.byAgent[agent] || { usd: 0, sessions: 0 };
136
- cur.usd += usd;
137
- cur.sessions += 1;
138
- report.byAgent[agent] = cur;
139
- }
140
- // Round totals to 4 decimals (1/100 of a cent) — final display rounds to 2.
141
- report.totalUsd = Math.round(report.totalUsd * 10_000) / 10_000;
142
- for (const k of Object.keys(report.byAgent)) {
143
- report.byAgent[k].usd = Math.round(report.byAgent[k].usd * 10_000) / 10_000;
144
- }
145
- return report;
146
- }
147
- //# sourceMappingURL=spend-aggregator.js.map