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,265 +0,0 @@
1
- /**
2
- * CLI Command: hook
3
- *
4
- * Manages Claude Code SDK hook integration.
5
- * Intercepts every Claude Code tool call and runs Layer 0 security scan.
6
- *
7
- * Usage:
8
- * codehere hook install # Add hooks to ~/.claude/settings.json
9
- * codehere hook uninstall # Remove hooks
10
- * codehere hook status # Show current hook config and recent events
11
- * codehere hook log # Show recent audit log
12
- * codehere hook log --tail 50 # Last 50 events
13
- */
14
- import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, copyFileSync, unlinkSync, rmdirSync, } from 'fs';
15
- import { join, dirname } from 'path';
16
- import { homedir } from 'os';
17
- import { fileURLToPath } from 'url';
18
- import { generateHookConfig, AUDIT_FILE } from '../../../infrastructure/hooks/claude-sdk-hook.js';
19
- import { colors, success, error, warning, info, newline, sectionHeader } from '../../../ui.js';
20
- // ── Skills management ─────────────────────────────────────────────────────────
21
- const SKILLS_TARGET_DIR = join(homedir(), '.claude', 'commands', 'codehere');
22
- function getSkillsSourceDir() {
23
- // When running from dist/, the .claude/commands dir is at package root
24
- const __filename = fileURLToPath(import.meta.url);
25
- const __dirname = dirname(__filename);
26
- // dist/presentation/cli/commands → ../../../../.claude/commands
27
- return join(__dirname, '..', '..', '..', '..', '.claude', 'commands');
28
- }
29
- function installSkills() {
30
- const sourceDir = getSkillsSourceDir();
31
- if (!existsSync(sourceDir))
32
- return false;
33
- if (!existsSync(SKILLS_TARGET_DIR)) {
34
- mkdirSync(SKILLS_TARGET_DIR, { recursive: true });
35
- }
36
- const files = readdirSync(sourceDir).filter((f) => f.endsWith('.md'));
37
- for (const file of files) {
38
- copyFileSync(join(sourceDir, file), join(SKILLS_TARGET_DIR, file));
39
- }
40
- return files.length > 0;
41
- }
42
- function uninstallSkills() {
43
- if (!existsSync(SKILLS_TARGET_DIR))
44
- return;
45
- try {
46
- for (const file of readdirSync(SKILLS_TARGET_DIR)) {
47
- unlinkSync(join(SKILLS_TARGET_DIR, file));
48
- }
49
- rmdirSync(SKILLS_TARGET_DIR);
50
- }
51
- catch {
52
- /* ignore */
53
- }
54
- }
55
- function skillsInstalled() {
56
- return existsSync(SKILLS_TARGET_DIR) && readdirSync(SKILLS_TARGET_DIR).some((f) => f.endsWith('.md'));
57
- }
58
- const SETTINGS_PATH = join(homedir(), '.claude', 'settings.json');
59
- // ── helpers ──────────────────────────────────────────────────────────────────
60
- function readSettings() {
61
- if (!existsSync(SETTINGS_PATH))
62
- return {};
63
- try {
64
- return JSON.parse(readFileSync(SETTINGS_PATH, 'utf-8'));
65
- }
66
- catch {
67
- return {};
68
- }
69
- }
70
- function writeSettings(settings) {
71
- const dir = join(homedir(), '.claude');
72
- if (!existsSync(dir))
73
- mkdirSync(dir, { recursive: true });
74
- writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + '\n');
75
- }
76
- function isInstalled(settings) {
77
- const hooks = (settings.hooks ?? {});
78
- const preToolUse = (hooks.PreToolUse ?? []);
79
- return preToolUse.some((entry) => entry.hooks?.some((h) => h.command?.includes('codehere scan-tool')));
80
- }
81
- // ── command ───────────────────────────────────────────────────────────────────
82
- export async function executeHookCommand(subcommand, options = {}) {
83
- const sub = subcommand ?? 'status';
84
- switch (sub) {
85
- case 'install': {
86
- const settings = readSettings();
87
- if (isInstalled(settings)) {
88
- console.log(warning('codehere hooks already installed'));
89
- console.log(colors.dim(` Config: ${SETTINGS_PATH}`));
90
- console.log(colors.dim(' Run `codehere hook status` to see details'));
91
- newline();
92
- return;
93
- }
94
- const hookConfig = generateHookConfig({
95
- logOnly: options.logOnly,
96
- blockMode: options.blockMode,
97
- });
98
- // Merge with existing hooks config
99
- const existingHooks = settings.hooks ?? {};
100
- const mergedHooks = { ...existingHooks };
101
- for (const [eventName, handlers] of Object.entries(hookConfig)) {
102
- const existing = mergedHooks[eventName] ?? [];
103
- mergedHooks[eventName] = [...existing, ...handlers];
104
- }
105
- settings.hooks = mergedHooks;
106
- writeSettings(settings);
107
- const skillsOk = installSkills();
108
- console.log(success('codehere hooks installed'));
109
- newline();
110
- console.log(colors.bold('What happens now:'));
111
- console.log(' Every Bash, Edit, Write, and MultiEdit call your AI makes is');
112
- console.log(' scanned by codehere before it executes.');
113
- console.log(' Zero API calls. < 5ms per scan. Runs entirely on your machine.');
114
- newline();
115
- console.log(colors.bold('Scan covers:'));
116
- console.log(' • Prompt injection & jailbreak attempts');
117
- console.log(' • Credential theft (API keys, SSH keys, env vars)');
118
- console.log(' • Destructive operations (rm -rf, DB drops, force push)');
119
- console.log(' • Code injection (curl|bash, reverse shells)');
120
- console.log(' • Supply chain attacks (typosquatting packages)');
121
- console.log(' • OWASP Top 10 patterns (SQLi, XSS, hardcoded secrets)');
122
- newline();
123
- console.log(colors.bold('Audit log:'));
124
- console.log(colors.dim(` ${AUDIT_FILE}`));
125
- newline();
126
- if (options.logOnly) {
127
- console.log(warning('Mode: log-only (no blocking). Run without --log-only to enable blocking.'));
128
- newline();
129
- }
130
- console.log(colors.dim(' Config written to: ' + SETTINGS_PATH));
131
- if (skillsOk) {
132
- console.log(colors.dim(` Skills installed to: ${SKILLS_TARGET_DIR}`));
133
- newline();
134
- console.log(colors.bold('Slash commands now available in your AI assistant:'));
135
- console.log(colors.dim(' /codehere:trust — scan current project'));
136
- console.log(colors.dim(' /codehere:report — generate shareable audit report'));
137
- console.log(colors.dim(' /codehere:audit — pre-merge security check'));
138
- console.log(colors.dim(' /codehere:hook-status — check hook health'));
139
- }
140
- newline();
141
- console.log(colors.dim(' Restart your AI assistant for changes to take effect.'));
142
- newline();
143
- break;
144
- }
145
- case 'uninstall': {
146
- const settings = readSettings();
147
- if (!isInstalled(settings)) {
148
- console.log(info('codehere hooks are not installed'));
149
- return;
150
- }
151
- const hooks = settings.hooks;
152
- for (const [eventName, handlers] of Object.entries(hooks)) {
153
- if (Array.isArray(handlers)) {
154
- hooks[eventName] = handlers.filter((entry) => !entry.hooks?.some((h) => h.command?.includes('codehere scan-tool')));
155
- }
156
- }
157
- writeSettings(settings);
158
- uninstallSkills();
159
- console.log(success('codehere hooks and skills removed'));
160
- console.log(colors.dim('Restart your AI assistant for changes to take effect.'));
161
- newline();
162
- break;
163
- }
164
- case 'status': {
165
- const settings = readSettings();
166
- const installed = isInstalled(settings);
167
- sectionHeader('codehere Hook Status');
168
- newline();
169
- if (installed) {
170
- console.log(success('Running') + ' Intercepting every tool call before it executes.');
171
- }
172
- else {
173
- console.log(warning('Not installed') + ' Run `codehere hook install` to activate.');
174
- }
175
- newline();
176
- const skills = skillsInstalled();
177
- if (skills) {
178
- console.log(info('Skills') + ' /codehere:trust /codehere:report /codehere:audit /codehere:hook-status');
179
- }
180
- else {
181
- console.log(colors.dim('Skills: not installed (run `codehere hook install` to add)'));
182
- }
183
- newline();
184
- console.log(colors.dim('Config: ') + SETTINGS_PATH);
185
- console.log(colors.dim('Audit log:') + ' ' + AUDIT_FILE);
186
- newline();
187
- // Autonomous mode callout
188
- console.log(colors.bold('Autonomous mode (shift+tab)'));
189
- console.log(colors.dim(' When Claude Code runs without approval prompts, this hook is your'));
190
- console.log(colors.dim(' last line of defense. Every tool call is scanned before it executes.'));
191
- console.log(colors.dim(' After a session: `codehere status --sessions` to review what happened.'));
192
- newline();
193
- // Show recent audit stats
194
- if (existsSync(AUDIT_FILE)) {
195
- const lines = readFileSync(AUDIT_FILE, 'utf-8').split('\n').filter(Boolean).slice(-1000); // last 1000 events
196
- if (lines.length > 0) {
197
- const entries = lines
198
- .map((l) => {
199
- try {
200
- return JSON.parse(l);
201
- }
202
- catch {
203
- return null;
204
- }
205
- })
206
- .filter(Boolean);
207
- const total = entries.length;
208
- const blocked = entries.filter((e) => e.blocked).length;
209
- const critical = entries.filter((e) => (e.criticalFindings ?? 0) > 0).length;
210
- console.log(colors.bold("What it's seen") + colors.dim(' (last 1000 events):'));
211
- console.log(` ${colors.cyan(String(total))} tool calls scanned`);
212
- console.log(` ${blocked > 0 ? colors.red(String(blocked)) : colors.green('none')} blocked`);
213
- console.log(` ${critical > 0 ? colors.red(String(critical)) : colors.green('none')} with critical findings`);
214
- newline();
215
- if (blocked > 0) {
216
- console.log(colors.dim(' Run `codehere status --sessions` to see which sessions had blocks.'));
217
- newline();
218
- }
219
- }
220
- }
221
- else {
222
- console.log(colors.dim(" No events logged yet — run Claude Code and it'll start tracking."));
223
- newline();
224
- }
225
- break;
226
- }
227
- case 'log': {
228
- const tail = options.tail ?? 20;
229
- if (!existsSync(AUDIT_FILE)) {
230
- console.log(info('No audit log yet'));
231
- console.log(colors.dim(' Run `codehere hook install` first'));
232
- return;
233
- }
234
- const lines = readFileSync(AUDIT_FILE, 'utf-8').split('\n').filter(Boolean).slice(-tail);
235
- if (lines.length === 0) {
236
- console.log(info('Audit log is empty'));
237
- return;
238
- }
239
- sectionHeader(`Hook Audit Log (last ${lines.length})`);
240
- newline();
241
- for (const line of lines) {
242
- try {
243
- const entry = JSON.parse(line);
244
- const ts = new Date(entry.timestamp).toLocaleTimeString();
245
- const status = entry.blocked ? colors.red('[BLOCKED]') : colors.green('[ALLOW] ');
246
- const risk = entry.riskScore > 0 ? colors.yellow(` risk:${entry.riskScore}`) : '';
247
- const tool = colors.cyan(entry.toolName.padEnd(10));
248
- const preview = entry.toolInput.substring(0, 60).replace(/\n/g, ' ');
249
- console.log(` ${ts} ${status} ${tool}${risk} ${colors.dim(preview)}`);
250
- }
251
- catch {
252
- // skip malformed line
253
- }
254
- }
255
- newline();
256
- break;
257
- }
258
- default: {
259
- console.log(error(`Unknown subcommand: ${sub}`));
260
- console.log(colors.dim('Usage: codehere hook install|uninstall|status|log'));
261
- process.exit(1);
262
- }
263
- }
264
- }
265
- //# sourceMappingURL=hook-command.js.map