codehere 0.2.2 → 0.3.0-rc.1
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 +88 -68
- package/dist/domain/entities/task.js +4 -4
- package/dist/error-handler.js +4 -9
- package/dist/index.js +253 -1219
- package/dist/infrastructure/config/product-context.js +7 -6
- package/dist/infrastructure/hooks/claude-sdk-hook.js +335 -63
- package/dist/infrastructure/observability/execution-tracer.js +11 -6
- package/dist/infrastructure/orchestration/agent-adapter.js +13 -0
- package/dist/infrastructure/orchestration/agent-installer.js +101 -0
- package/dist/infrastructure/orchestration/agents-config-seed.js +56 -0
- package/dist/infrastructure/orchestration/aider-adapter.js +319 -0
- package/dist/infrastructure/orchestration/artifacts-extractor.js +175 -0
- package/dist/infrastructure/orchestration/claude-code-adapter.js +352 -0
- package/dist/infrastructure/orchestration/codex-adapter.js +310 -0
- package/dist/infrastructure/orchestration/generic-cli-adapter.js +553 -0
- package/dist/infrastructure/orchestration/opencode-adapter.js +275 -0
- package/dist/infrastructure/orchestration/progress-aggregator.js +189 -0
- package/dist/infrastructure/orchestration/readiness.js +106 -0
- package/dist/infrastructure/orchestration/session-manager.js +272 -0
- package/dist/infrastructure/orchestration/session-persistence.js +109 -0
- package/dist/infrastructure/protocols/mcp-helpers.js +10 -30
- package/dist/infrastructure/protocols/mcp-server-impl.js +359 -21
- package/dist/infrastructure/protocols/ui-page.js +1827 -0
- package/dist/infrastructure/security/file-collection.js +115 -0
- package/dist/infrastructure/security/trust-scorer.js +301 -56
- package/dist/infrastructure/storage/task-repository.js +8 -7
- package/dist/monitoring.js +9 -38
- package/dist/presentation/cli/commands/help-command.js +96 -139
- package/dist/presentation/cli/commands/hook-command.js +17 -24
- package/dist/presentation/cli/commands/report-command.js +59 -72
- package/dist/presentation/cli/commands/setup-command.js +4 -4
- package/dist/presentation/cli/commands/status-command.js +321 -30
- package/dist/presentation/cli/commands/trust-command.js +84 -72
- package/dist/presentation/cli/error-display.js +17 -21
- package/dist/ui.js +11 -11
- package/package.json +24 -62
- package/dist/agents/base.js +0 -101
- package/dist/agents/orchestrator-model-driven.js +0 -141
- package/dist/agents/react-orchestrator-agent.js +0 -54
- package/dist/application/agents/execution-agent.js +0 -508
- package/dist/application/agents/multi-agent-orchestrator.js +0 -295
- package/dist/application/agents/planning-agent.js +0 -433
- package/dist/application/agents/validation-agent.js +0 -317
- package/dist/application/architectures/plan-and-act.js +0 -242
- package/dist/application/index.js +0 -12
- package/dist/application/services/agent-factory.js +0 -28
- package/dist/application/services/dependency-container.js +0 -596
- package/dist/application/services/git-context-service.js +0 -83
- package/dist/application/services/intelligent-router.js +0 -934
- package/dist/application/services/tool-executor-service.js +0 -94
- package/dist/application/use-cases/ask-question-use-case.js +0 -338
- package/dist/application/use-cases/edit-file-use-case.js +0 -830
- package/dist/application/use-cases/explain-file-use-case.js +0 -50
- package/dist/application/use-cases/index-codebase-use-case.js +0 -113
- package/dist/application/use-cases/planning-use-case.js +0 -276
- package/dist/application/use-cases/react-orchestration-use-case.js +0 -329
- package/dist/application/use-cases/reflexion-use-case.js +0 -30
- package/dist/application/workflows/deterministic-workflows.js +0 -189
- package/dist/ast-parser.js +0 -331
- package/dist/cache.js +0 -180
- package/dist/chat.js +0 -251
- package/dist/code-analysis.js +0 -327
- package/dist/context.js +0 -187
- package/dist/docs.js +0 -146
- package/dist/domain/entities/code-chunk.js +0 -6
- package/dist/domain/entities/decision.js +0 -9
- package/dist/domain/entities/edit.js +0 -6
- package/dist/domain/entities/knowledge-node.js +0 -9
- package/dist/domain/entities/knowledge-preservation.js +0 -10
- package/dist/domain/entities/memory.js +0 -6
- package/dist/domain/entities/pattern.js +0 -7
- package/dist/domain/entities/plan.js +0 -6
- package/dist/domain/entities/query.js +0 -6
- package/dist/domain/errors/embeddings-not-found-error.js +0 -13
- package/dist/domain/index.js +0 -19
- package/dist/domain/interfaces/ai-service.interface.js +0 -6
- package/dist/domain/interfaces/code-analyzer.interface.js +0 -6
- package/dist/domain/interfaces/decision-repository.interface.js +0 -9
- package/dist/domain/interfaces/embedding-repository.interface.js +0 -6
- package/dist/domain/interfaces/knowledge-graph-repository.interface.js +0 -9
- package/dist/domain/interfaces/knowledge-preservation-repository.interface.js +0 -8
- package/dist/domain/interfaces/memory-repository.interface.js +0 -6
- package/dist/domain/interfaces/pattern-repository.interface.js +0 -6
- package/dist/domain/interfaces/verification-service.interface.js +0 -6
- package/dist/domain/services/cross-team-pattern-sharing.js +0 -125
- package/dist/domain/services/decision-recorder.js +0 -223
- package/dist/domain/services/decision-retriever.js +0 -133
- package/dist/domain/services/environment-mode-manager.js +0 -22
- package/dist/domain/services/graded-memory-activation.js +0 -69
- package/dist/domain/services/knowledge-access.js +0 -132
- package/dist/domain/services/knowledge-extractor.js +0 -247
- package/dist/domain/services/knowledge-graph-builder.js +0 -268
- package/dist/domain/services/knowledge-graph-query.js +0 -187
- package/dist/domain/services/memory-retriever.js +0 -82
- package/dist/domain/services/memory-synthesizer.js +0 -91
- package/dist/domain/services/pattern-extractor.js +0 -442
- package/dist/domain/services/query-intent-classifier.js +0 -140
- package/dist/domain/services/react-loop.js +0 -186
- package/dist/domain/services/risk-tier-detector.js +0 -78
- package/dist/edit.js +0 -319
- package/dist/embed.js +0 -459
- package/dist/formatter.js +0 -168
- package/dist/git.js +0 -198
- package/dist/infrastructure/ai/cohere-ai-service.js +0 -607
- package/dist/infrastructure/ai/command-r-evaluation.js +0 -206
- package/dist/infrastructure/ai/model-config.js +0 -84
- package/dist/infrastructure/ai/provider-ai-service.js +0 -477
- package/dist/infrastructure/cache/embedding-cache.js +0 -175
- package/dist/infrastructure/cache/query-result-cache.js +0 -66
- package/dist/infrastructure/cache/response-cache.js +0 -48
- package/dist/infrastructure/cache/security-scan-cache.js +0 -47
- package/dist/infrastructure/chunking/ast-code-chunker.js +0 -19
- package/dist/infrastructure/chunking/code-aware-chunker.js +0 -397
- package/dist/infrastructure/context/context-compressor.js +0 -329
- package/dist/infrastructure/context/conversation-context.js +0 -128
- package/dist/infrastructure/context/session-manager.js +0 -94
- package/dist/infrastructure/cost/cost-tracker.js +0 -360
- package/dist/infrastructure/file-scanner/file-scanner.js +0 -106
- package/dist/infrastructure/governance/nist-ai-rmf.js +0 -292
- package/dist/infrastructure/governance/policy-as-code.js +0 -258
- package/dist/infrastructure/governance/prompt-to-code-lineage.js +0 -239
- package/dist/infrastructure/index.js +0 -7
- package/dist/infrastructure/observability/prompt-versioner.js +0 -145
- package/dist/infrastructure/protocols/a2a-metadata.js +0 -137
- package/dist/infrastructure/protocols/a2a-protocol.js +0 -314
- package/dist/infrastructure/protocols/mcp-oauth.js +0 -184
- package/dist/infrastructure/protocols/mcp-server.js +0 -333
- package/dist/infrastructure/protocols/streaming-handler.js +0 -103
- package/dist/infrastructure/providers/cohere-provider.js +0 -444
- package/dist/infrastructure/providers/fake-provider.js +0 -130
- package/dist/infrastructure/providers/local-llm-provider.js +0 -330
- package/dist/infrastructure/providers/model-config.types.js +0 -9
- package/dist/infrastructure/providers/model-provider.interface.js +0 -8
- package/dist/infrastructure/providers/openai-provider.js +0 -413
- package/dist/infrastructure/providers/openrouter-provider.js +0 -399
- package/dist/infrastructure/providers/operation-provider-resolver.js +0 -105
- package/dist/infrastructure/providers/provider-config-loader.js +0 -120
- package/dist/infrastructure/providers/provider-registry.js +0 -88
- package/dist/infrastructure/safety/pattern-detector.js +0 -133
- package/dist/infrastructure/security/ai-sast-scanner.js +0 -290
- package/dist/infrastructure/security/docker-sandbox.js +0 -178
- package/dist/infrastructure/security/enhanced-security-gate.js +0 -151
- package/dist/infrastructure/security/license-scanner.js +0 -167
- package/dist/infrastructure/security/provider-bias-detector.js +0 -164
- package/dist/infrastructure/security/sandbox-executor.js +0 -64
- package/dist/infrastructure/serialization/toon-serializer.js +0 -119
- package/dist/infrastructure/storage/memory-stream-service.js +0 -204
- package/dist/infrastructure/storage/plan-repository.js +0 -96
- package/dist/infrastructure/storage/sqlite-decision-repository.js +0 -232
- package/dist/infrastructure/storage/sqlite-embedding-repository.js +0 -311
- package/dist/infrastructure/storage/sqlite-knowledge-graph-repository.js +0 -417
- package/dist/infrastructure/storage/sqlite-knowledge-preservation-repository.js +0 -230
- package/dist/infrastructure/storage/sqlite-memory-repository.js +0 -229
- package/dist/infrastructure/storage/sqlite-pattern-repository.js +0 -249
- package/dist/infrastructure/storage/task-helpers.js +0 -197
- package/dist/infrastructure/telemetry/telemetry-service.js +0 -167
- package/dist/infrastructure/ux/appropriate-friction.js +0 -213
- package/dist/infrastructure/ux/bi-directional-learning.js +0 -337
- package/dist/infrastructure/ux/capability-boundaries.js +0 -42
- package/dist/infrastructure/ux/comprehensive-formatter.js +0 -117
- package/dist/infrastructure/ux/contextual-feature-discovery.js +0 -10
- package/dist/infrastructure/ux/expectation-management.js +0 -327
- package/dist/infrastructure/ux/feature-discovery.js +0 -14
- package/dist/infrastructure/ux/feedback-prompt.js +0 -45
- package/dist/infrastructure/ux/hitl-validation.js +0 -297
- package/dist/infrastructure/ux/progress-indicator.js +0 -116
- package/dist/infrastructure/ux/progressive-disclosure.js +0 -236
- package/dist/infrastructure/ux/review-checkpoint.js +0 -72
- package/dist/infrastructure/ux/staged-feature-intro.js +0 -24
- package/dist/infrastructure/ux/stream-markdown.js +0 -151
- package/dist/infrastructure/ux/syntax-highlighter.js +0 -91
- package/dist/infrastructure/ux/team-standards.js +0 -196
- package/dist/infrastructure/ux/transparency.js +0 -71
- package/dist/infrastructure/validation/agent-feedback.js +0 -55
- package/dist/infrastructure/validation/agent-validation-helper.js +0 -137
- package/dist/infrastructure/validation/review-handler.js +0 -40
- package/dist/infrastructure/validation/summary-aggregator.js +0 -70
- package/dist/infrastructure/validation/summary-extractor.js +0 -45
- package/dist/infrastructure/validation/trace-summary.js +0 -52
- package/dist/infrastructure/verification/verification-service.js +0 -47
- package/dist/infrastructure/xai/attention-visualizer.js +0 -172
- package/dist/infrastructure/xai/cot-visualizer.js +0 -283
- package/dist/infrastructure/xai/decision-tree-log.js +0 -212
- package/dist/infrastructure/xai/interactive-xai.js +0 -260
- package/dist/infrastructure/xai/uncertainty-quantifier.js +0 -198
- package/dist/intelligent-retrieval.js +0 -272
- package/dist/intent/classifier.js +0 -2
- package/dist/intent/context.js +0 -2
- package/dist/iterative-refinement.js +0 -189
- package/dist/learning.js +0 -232
- package/dist/log.js +0 -31
- package/dist/migrate.js +0 -133
- package/dist/parallel-processor.js +0 -534
- package/dist/planner.js +0 -198
- package/dist/policy.js +0 -26
- package/dist/presentation/cli/commands/ask-command.js +0 -314
- package/dist/presentation/cli/commands/cost-command.js +0 -191
- package/dist/presentation/cli/commands/decision-command.js +0 -207
- package/dist/presentation/cli/commands/docs-command.js +0 -25
- package/dist/presentation/cli/commands/fix-command.js +0 -53
- package/dist/presentation/cli/commands/knowledge-command.js +0 -129
- package/dist/presentation/cli/commands/learning-dashboard-command.js +0 -183
- package/dist/presentation/cli/commands/models-command.js +0 -194
- package/dist/presentation/cli/commands/orchestrate-command.js +0 -207
- package/dist/presentation/cli/commands/plan-command.js +0 -246
- package/dist/presentation/cli/commands/product-command.js +0 -199
- package/dist/presentation/cli/commands/react-command.js +0 -181
- package/dist/presentation/cli/commands/review-command.js +0 -154
- package/dist/presentation/cli/commands/run-command.js +0 -188
- package/dist/presentation/cli/commands/smart-command.js +0 -395
- package/dist/presentation/cli/commands/suggest-command.js +0 -138
- package/dist/presentation/cli/commands/trace-command.js +0 -129
- package/dist/presentation/cli/commands/undo-command.js +0 -150
- package/dist/query-optimizer.js +0 -205
- package/dist/refactor.js +0 -116
- package/dist/review.js +0 -206
- package/dist/search.js +0 -163
- package/dist/session.js +0 -704
- package/dist/task-verification.js +0 -336
- package/dist/testgen.js +0 -166
- package/dist/token-optimizer.js +0 -277
- package/dist/tools/bash.js +0 -213
- package/dist/tools/edit.js +0 -235
- package/dist/tools/executor.js +0 -153
- package/dist/tools/git-tool.js +0 -292
- package/dist/tools/parser.js +0 -158
- package/dist/tools/registry.js +0 -302
- package/dist/tools/search.js +0 -100
- package/dist/types.js +0 -2
- package/dist/utils/check-api-status.js +0 -100
- package/dist/utils/diff-parser.js +0 -162
- package/dist/verification/backup.js +0 -259
- package/dist/verification/compiler.js +0 -264
- package/dist/verification/index.js +0 -273
- package/dist/verification/test-runner.js +0 -379
package/dist/monitoring.js
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
* Enterprise Monitoring & Health Check System
|
|
3
3
|
* Ensures 24/7 operation visibility
|
|
4
4
|
*/
|
|
5
|
-
import { existsSync,
|
|
5
|
+
import { existsSync, mkdirSync } from 'fs';
|
|
6
6
|
import { join, dirname } from 'path';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
import { cohereCircuitBreaker } from './error-handler.js';
|
|
9
|
-
import { getEmbeddingsDbPath } from './infrastructure/storage/embeddings-path.js';
|
|
10
9
|
class MetricsCollector {
|
|
11
10
|
operations = {
|
|
12
11
|
total: 0,
|
|
@@ -89,32 +88,6 @@ class MetricsCollector {
|
|
|
89
88
|
}
|
|
90
89
|
}
|
|
91
90
|
export const metricsCollector = new MetricsCollector();
|
|
92
|
-
/**
|
|
93
|
-
* Check database health
|
|
94
|
-
*/
|
|
95
|
-
function checkDatabase() {
|
|
96
|
-
try {
|
|
97
|
-
// Use per-repo embeddings database path
|
|
98
|
-
const pathInfo = getEmbeddingsDbPath(process.cwd());
|
|
99
|
-
const dbPath = pathInfo.dbPath;
|
|
100
|
-
if (!existsSync(dbPath)) {
|
|
101
|
-
return { status: 'warning', message: 'No embeddings database found (run "codehere index" to create one)' };
|
|
102
|
-
}
|
|
103
|
-
// Try to read database
|
|
104
|
-
const buffer = readFileSync(dbPath);
|
|
105
|
-
if (buffer.length === 0) {
|
|
106
|
-
return { status: 'warning', message: 'Database file is empty' };
|
|
107
|
-
}
|
|
108
|
-
return { status: 'ok', message: 'Database accessible' };
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
// If check fails, treat as warning (not critical - database is optional)
|
|
112
|
-
return {
|
|
113
|
-
status: 'warning',
|
|
114
|
-
message: `Database check: ${error instanceof Error ? error.message : String(error)}`,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
91
|
/**
|
|
119
92
|
* Check API health
|
|
120
93
|
*/
|
|
@@ -127,7 +100,10 @@ function checkApi() {
|
|
|
127
100
|
return { status: 'error', message: 'API circuit breaker is HALF_OPEN - recovering' };
|
|
128
101
|
}
|
|
129
102
|
// Check if any API key is configured
|
|
130
|
-
const hasKey = !!(process.env.ANTHROPIC_API_KEY ||
|
|
103
|
+
const hasKey = !!(process.env.ANTHROPIC_API_KEY ||
|
|
104
|
+
process.env.OPENAI_API_KEY ||
|
|
105
|
+
process.env.COHERE_API_KEY ||
|
|
106
|
+
process.env.OPENROUTER_API_KEY);
|
|
131
107
|
if (!hasKey) {
|
|
132
108
|
return { status: 'error', message: 'No API key configured' };
|
|
133
109
|
}
|
|
@@ -194,24 +170,19 @@ function checkMemory() {
|
|
|
194
170
|
* Perform health check
|
|
195
171
|
*/
|
|
196
172
|
export function performHealthCheck() {
|
|
197
|
-
const dbCheck = checkDatabase();
|
|
198
173
|
const apiCheck = checkApi();
|
|
199
174
|
const fsCheck = checkFilesystem();
|
|
200
175
|
const memCheck = checkMemory();
|
|
201
176
|
const checks = {
|
|
202
|
-
database: dbCheck,
|
|
203
177
|
api: apiCheck,
|
|
204
178
|
filesystem: fsCheck,
|
|
205
179
|
memory: memCheck,
|
|
206
180
|
};
|
|
207
|
-
// Determine overall status
|
|
208
|
-
// Database warnings are non-fatal (embeddings are optional)
|
|
209
181
|
let status = 'healthy';
|
|
210
|
-
if (
|
|
182
|
+
if (apiCheck.status === 'circuit_open' || fsCheck.status === 'error') {
|
|
211
183
|
status = 'unhealthy';
|
|
212
184
|
}
|
|
213
|
-
else if (apiCheck.status === 'error' || memCheck.status === 'warning'
|
|
214
|
-
// Database warning alone doesn't degrade status, but combined with other issues it does
|
|
185
|
+
else if (apiCheck.status === 'error' || memCheck.status === 'warning') {
|
|
215
186
|
status = 'degraded';
|
|
216
187
|
}
|
|
217
188
|
return {
|
|
@@ -230,10 +201,10 @@ export function getMetrics() {
|
|
|
230
201
|
* Format health status for display
|
|
231
202
|
*/
|
|
232
203
|
export function formatHealthStatus(health) {
|
|
233
|
-
const statusIcon = health.status === 'healthy' ? '✓' : health.status === 'degraded' ? '
|
|
204
|
+
const statusIcon = health.status === 'healthy' ? '✓' : health.status === 'degraded' ? '⚠' : '✗';
|
|
234
205
|
let output = ` ${statusIcon} ${health.status.toUpperCase()}\n\n`;
|
|
235
206
|
for (const [component, check] of Object.entries(health.checks)) {
|
|
236
|
-
const icon = check.status === 'ok' ? '✓' : check.status === 'warning' ? '
|
|
207
|
+
const icon = check.status === 'ok' ? '✓' : check.status === 'warning' ? '⚠' : '✗';
|
|
237
208
|
output += ` ${icon} ${component.padEnd(12)} ${check.message}\n`;
|
|
238
209
|
}
|
|
239
210
|
return output;
|
|
@@ -2,22 +2,50 @@
|
|
|
2
2
|
* Help Command
|
|
3
3
|
* Provides contextual help for Codehere commands
|
|
4
4
|
*/
|
|
5
|
-
import { colors, newline
|
|
5
|
+
import { colors, newline } from '../../../ui.js';
|
|
6
6
|
const COMMAND_INFO = {
|
|
7
|
-
// ===
|
|
8
|
-
|
|
9
|
-
name: '
|
|
10
|
-
description: '
|
|
11
|
-
usage: 'codehere
|
|
7
|
+
// === Delegate (the v0.3 PM surface) ===
|
|
8
|
+
start: {
|
|
9
|
+
name: 'start',
|
|
10
|
+
description: 'Open the task intake web UI at http://127.0.0.1:3773',
|
|
11
|
+
usage: 'codehere start [options]',
|
|
12
|
+
examples: ['codehere start', 'codehere start --port 3773', 'codehere start --no-open'],
|
|
13
|
+
options: [
|
|
14
|
+
{ flag: '--port <n>', description: 'Port for the local UI (default: 3773)' },
|
|
15
|
+
{ flag: '--no-open', description: "Don't auto-open the browser" },
|
|
16
|
+
],
|
|
17
|
+
related: ['task', 'kill', 'status'],
|
|
18
|
+
},
|
|
19
|
+
task: {
|
|
20
|
+
name: 'task',
|
|
21
|
+
description: 'Spawn a task from the CLI (requires `codehere start` running)',
|
|
22
|
+
usage: 'codehere task <prompt> [options]',
|
|
12
23
|
examples: [
|
|
13
|
-
'codehere
|
|
14
|
-
'codehere
|
|
15
|
-
|
|
16
|
-
|
|
24
|
+
'codehere task "review src/auth.ts for SQL injection"',
|
|
25
|
+
'codehere task "add JSDoc to all exports" --agent codex',
|
|
26
|
+
],
|
|
27
|
+
options: [
|
|
28
|
+
{ flag: '--agent <id>', description: 'Agent ID: claude-code | codex | aider | opencode' },
|
|
29
|
+
{ flag: '--cwd <path>', description: 'Absolute working directory for the agent' },
|
|
17
30
|
],
|
|
31
|
+
related: ['start', 'kill'],
|
|
32
|
+
},
|
|
33
|
+
kill: {
|
|
34
|
+
name: 'kill',
|
|
35
|
+
description: 'Terminate a running task session',
|
|
36
|
+
usage: 'codehere kill <sessionId>',
|
|
37
|
+
examples: ['codehere kill abc123de-...'],
|
|
38
|
+
related: ['task', 'status'],
|
|
39
|
+
},
|
|
40
|
+
// === Safety & Trust (no API key, no agents needed) ===
|
|
41
|
+
hook: {
|
|
42
|
+
name: 'hook',
|
|
43
|
+
description: 'Install, manage, and monitor the safety hook for Claude Code',
|
|
44
|
+
usage: 'codehere hook <action>',
|
|
45
|
+
examples: ['codehere hook install', 'codehere hook status', 'codehere hook log', 'codehere hook uninstall'],
|
|
18
46
|
related: ['trust', 'status'],
|
|
19
47
|
},
|
|
20
|
-
|
|
48
|
+
trust: {
|
|
21
49
|
name: 'trust',
|
|
22
50
|
description: 'Scan your project for security issues — instant score, no API key needed',
|
|
23
51
|
usage: 'codehere trust [path] [options]',
|
|
@@ -35,9 +63,9 @@ const COMMAND_INFO = {
|
|
|
35
63
|
],
|
|
36
64
|
related: ['report', 'hook'],
|
|
37
65
|
},
|
|
38
|
-
|
|
66
|
+
report: {
|
|
39
67
|
name: 'report',
|
|
40
|
-
description: 'Generate a shareable
|
|
68
|
+
description: 'Generate a shareable markdown audit report',
|
|
41
69
|
usage: 'codehere report [options]',
|
|
42
70
|
examples: [
|
|
43
71
|
'codehere report',
|
|
@@ -52,137 +80,64 @@ const COMMAND_INFO = {
|
|
|
52
80
|
],
|
|
53
81
|
related: ['trust', 'status'],
|
|
54
82
|
},
|
|
55
|
-
|
|
83
|
+
status: {
|
|
56
84
|
name: 'status',
|
|
57
|
-
description: 'Dashboard —
|
|
85
|
+
description: 'Dashboard — sessions, blocked calls, audit trends',
|
|
58
86
|
usage: 'codehere status [options]',
|
|
59
|
-
examples: [
|
|
60
|
-
'codehere status',
|
|
61
|
-
'codehere status --sessions',
|
|
62
|
-
'codehere status --json',
|
|
63
|
-
],
|
|
87
|
+
examples: ['codehere status', 'codehere status --sessions', 'codehere status --weekly', 'codehere status --json'],
|
|
64
88
|
options: [
|
|
65
89
|
{ flag: '--sessions', description: 'Show session breakdown with risk levels' },
|
|
90
|
+
{ flag: '--weekly', description: '7-day shareable agent-activity recap' },
|
|
66
91
|
{ flag: '--json', description: 'Output as JSON' },
|
|
92
|
+
{ flag: '--export <fmt>', description: 'Export raw audit feed (jsonl, json, csv, md)' },
|
|
67
93
|
],
|
|
68
94
|
related: ['hook', 'trust'],
|
|
69
95
|
},
|
|
70
|
-
|
|
96
|
+
serve: {
|
|
71
97
|
name: 'serve',
|
|
72
|
-
description: 'Start
|
|
98
|
+
description: 'Start codehere as an MCP server (Claude Desktop, Cursor, Zed, etc.)',
|
|
73
99
|
usage: 'codehere serve [options]',
|
|
74
|
-
examples: [
|
|
75
|
-
'codehere serve',
|
|
76
|
-
'codehere serve --show-config',
|
|
77
|
-
],
|
|
100
|
+
examples: ['codehere serve', 'codehere serve --show-config', 'codehere serve --port 8080'],
|
|
78
101
|
options: [
|
|
79
102
|
{ flag: '--show-config', description: 'Print MCP config for Claude Desktop or Cursor' },
|
|
103
|
+
{ flag: '--port <n>', description: 'Port (default: 3773)' },
|
|
80
104
|
],
|
|
81
105
|
related: ['hook'],
|
|
82
106
|
},
|
|
83
|
-
// ===
|
|
84
|
-
|
|
85
|
-
name: 'ask',
|
|
86
|
-
description: 'Ask questions about your codebase using natural language',
|
|
87
|
-
usage: 'codehere ask "<question>"',
|
|
88
|
-
examples: [
|
|
89
|
-
'codehere ask "How does authentication work?"',
|
|
90
|
-
'codehere ask "What design patterns are used?"',
|
|
91
|
-
],
|
|
92
|
-
related: ['explain', 'smart'],
|
|
93
|
-
},
|
|
94
|
-
'fix': {
|
|
95
|
-
name: 'fix',
|
|
96
|
-
description: 'Apply AI-powered fixes to your code with safety pipeline',
|
|
97
|
-
usage: 'codehere fix <file> "<instruction>"',
|
|
98
|
-
examples: [
|
|
99
|
-
'codehere fix src/api.ts "add input validation"',
|
|
100
|
-
'codehere fix src/auth.ts "switch to bcrypt hashing"',
|
|
101
|
-
],
|
|
102
|
-
related: ['plan', 'trust'],
|
|
103
|
-
},
|
|
104
|
-
'explain': {
|
|
105
|
-
name: 'explain',
|
|
106
|
-
description: 'Get detailed explanations of code files or functions',
|
|
107
|
-
usage: 'codehere explain <filepath>',
|
|
108
|
-
examples: [
|
|
109
|
-
'codehere explain src/utils.ts',
|
|
110
|
-
'codehere explain src/services/auth.ts',
|
|
111
|
-
],
|
|
112
|
-
related: ['ask', 'smart'],
|
|
113
|
-
},
|
|
114
|
-
'plan': {
|
|
115
|
-
name: 'plan',
|
|
116
|
-
description: 'Generate a step-by-step plan for complex tasks',
|
|
117
|
-
usage: 'codehere plan "<goal>" [options]',
|
|
118
|
-
examples: [
|
|
119
|
-
'codehere plan "implement user authentication"',
|
|
120
|
-
'codehere plan "refactor to dependency injection" --execute',
|
|
121
|
-
],
|
|
122
|
-
options: [
|
|
123
|
-
{ flag: '--execute', description: 'Execute the plan after generation' },
|
|
124
|
-
],
|
|
125
|
-
related: ['orchestrate', 'fix'],
|
|
126
|
-
},
|
|
127
|
-
'orchestrate': {
|
|
128
|
-
name: 'orchestrate',
|
|
129
|
-
description: 'Orchestrate multi-agent workflows — plan, execute, validate',
|
|
130
|
-
usage: 'codehere orchestrate "<goal>" [options]',
|
|
131
|
-
examples: [
|
|
132
|
-
'codehere orchestrate "implement auth system"',
|
|
133
|
-
'codehere orchestrate "add logging across services" --mode full',
|
|
134
|
-
],
|
|
135
|
-
options: [
|
|
136
|
-
{ flag: '--mode <mode>', description: 'Mode: plan, execute, full (default: full)' },
|
|
137
|
-
],
|
|
138
|
-
related: ['plan', 'smart'],
|
|
139
|
-
},
|
|
140
|
-
'index': {
|
|
141
|
-
name: 'index',
|
|
142
|
-
description: 'Build semantic index of your codebase for AI queries',
|
|
143
|
-
usage: 'codehere index [options]',
|
|
144
|
-
examples: [
|
|
145
|
-
'codehere index',
|
|
146
|
-
'codehere index --repo ./my-project',
|
|
147
|
-
],
|
|
148
|
-
options: [
|
|
149
|
-
{ flag: '--repo <path>, -r <path>', description: 'Repository path (default: current directory)' },
|
|
150
|
-
],
|
|
151
|
-
related: ['ask'],
|
|
152
|
-
},
|
|
153
|
-
'setup': {
|
|
107
|
+
// === Configuration ===
|
|
108
|
+
setup: {
|
|
154
109
|
name: 'setup',
|
|
155
|
-
description: 'Interactive setup wizard',
|
|
110
|
+
description: 'Interactive first-run setup wizard',
|
|
156
111
|
usage: 'codehere setup [options]',
|
|
157
|
-
examples: [
|
|
158
|
-
|
|
159
|
-
'codehere setup --force',
|
|
160
|
-
],
|
|
161
|
-
options: [
|
|
162
|
-
{ flag: '--force, -f', description: 'Force reconfiguration' },
|
|
163
|
-
],
|
|
112
|
+
examples: ['codehere setup', 'codehere setup --force'],
|
|
113
|
+
options: [{ flag: '--force, -f', description: 'Force reconfiguration' }],
|
|
164
114
|
related: ['config', 'hook'],
|
|
165
115
|
},
|
|
166
|
-
|
|
116
|
+
config: {
|
|
167
117
|
name: 'config',
|
|
168
118
|
description: 'Manage configuration and preferences',
|
|
169
119
|
usage: 'codehere config [action] [key] [value]',
|
|
170
|
-
examples: [
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
120
|
+
examples: ['codehere config', 'codehere config set temperature 0.5'],
|
|
121
|
+
related: ['setup'],
|
|
122
|
+
},
|
|
123
|
+
health: {
|
|
124
|
+
name: 'health',
|
|
125
|
+
description: 'System health check — filesystem, memory, audit log accessible',
|
|
126
|
+
usage: 'codehere health [options]',
|
|
127
|
+
examples: ['codehere health', 'codehere health --json'],
|
|
128
|
+
options: [{ flag: '--json', description: 'Output as JSON' }],
|
|
129
|
+
related: ['status'],
|
|
175
130
|
},
|
|
176
|
-
|
|
177
|
-
name: '
|
|
178
|
-
description: '
|
|
179
|
-
usage: 'codehere
|
|
131
|
+
completion: {
|
|
132
|
+
name: 'completion',
|
|
133
|
+
description: 'Generate bash, zsh, or fish completion script',
|
|
134
|
+
usage: 'codehere completion <shell>',
|
|
180
135
|
examples: [
|
|
181
|
-
'codehere
|
|
182
|
-
'codehere
|
|
183
|
-
'codehere
|
|
136
|
+
'codehere completion bash >> ~/.bashrc',
|
|
137
|
+
'codehere completion zsh > /usr/local/share/zsh/site-functions/_codehere',
|
|
138
|
+
'codehere completion fish > ~/.config/fish/completions/codehere.fish',
|
|
184
139
|
],
|
|
185
|
-
related: [
|
|
140
|
+
related: [],
|
|
186
141
|
},
|
|
187
142
|
};
|
|
188
143
|
const ALL_COMMANDS = Object.keys(COMMAND_INFO);
|
|
@@ -196,7 +151,7 @@ function findSimilarCommands(input, maxResults = 3) {
|
|
|
196
151
|
return [lowerInput];
|
|
197
152
|
}
|
|
198
153
|
// Calculate similarity scores
|
|
199
|
-
const scores = ALL_COMMANDS.map(cmd => {
|
|
154
|
+
const scores = ALL_COMMANDS.map((cmd) => {
|
|
200
155
|
const lowerCmd = cmd.toLowerCase();
|
|
201
156
|
// Exact substring match
|
|
202
157
|
if (lowerCmd.includes(lowerInput) || lowerInput.includes(lowerCmd)) {
|
|
@@ -210,10 +165,10 @@ function findSimilarCommands(input, maxResults = 3) {
|
|
|
210
165
|
});
|
|
211
166
|
// Sort by score and return top matches
|
|
212
167
|
return scores
|
|
213
|
-
.filter(s => s.score > 0.3)
|
|
168
|
+
.filter((s) => s.score > 0.3)
|
|
214
169
|
.sort((a, b) => b.score - a.score)
|
|
215
170
|
.slice(0, maxResults)
|
|
216
|
-
.map(s => s.cmd);
|
|
171
|
+
.map((s) => s.cmd);
|
|
217
172
|
}
|
|
218
173
|
/**
|
|
219
174
|
* Simple Levenshtein distance calculation
|
|
@@ -221,7 +176,9 @@ function findSimilarCommands(input, maxResults = 3) {
|
|
|
221
176
|
function levenshteinDistance(str1, str2) {
|
|
222
177
|
const m = str1.length;
|
|
223
178
|
const n = str2.length;
|
|
224
|
-
const dp = Array(m + 1)
|
|
179
|
+
const dp = Array(m + 1)
|
|
180
|
+
.fill(null)
|
|
181
|
+
.map(() => Array(n + 1).fill(0));
|
|
225
182
|
for (let i = 0; i <= m; i++)
|
|
226
183
|
dp[i][0] = i;
|
|
227
184
|
for (let j = 0; j <= n; j++)
|
|
@@ -234,8 +191,7 @@ function levenshteinDistance(str1, str2) {
|
|
|
234
191
|
else {
|
|
235
192
|
dp[i][j] = Math.min(dp[i - 1][j] + 1, // deletion
|
|
236
193
|
dp[i][j - 1] + 1, // insertion
|
|
237
|
-
dp[i - 1][j - 1] + 1
|
|
238
|
-
);
|
|
194
|
+
dp[i - 1][j - 1] + 1);
|
|
239
195
|
}
|
|
240
196
|
}
|
|
241
197
|
}
|
|
@@ -253,7 +209,7 @@ function displayCommandHelp(commandName) {
|
|
|
253
209
|
if (suggestions.length > 0) {
|
|
254
210
|
newline();
|
|
255
211
|
console.log(colors.bold('Did you mean:'));
|
|
256
|
-
suggestions.forEach(cmd => {
|
|
212
|
+
suggestions.forEach((cmd) => {
|
|
257
213
|
console.log(` ${colors.cyan(`codehere help ${cmd}`)}`);
|
|
258
214
|
});
|
|
259
215
|
newline();
|
|
@@ -269,20 +225,20 @@ function displayCommandHelp(commandName) {
|
|
|
269
225
|
console.log(' ' + colors.cyan(command.usage));
|
|
270
226
|
newline();
|
|
271
227
|
console.log(colors.bold('Examples'));
|
|
272
|
-
command.examples.forEach(example => {
|
|
228
|
+
command.examples.forEach((example) => {
|
|
273
229
|
console.log(colors.dim(' $ ') + colors.cyan(example));
|
|
274
230
|
});
|
|
275
231
|
newline();
|
|
276
232
|
if (command.options && command.options.length > 0) {
|
|
277
233
|
console.log(colors.bold('Options'));
|
|
278
|
-
command.options.forEach(opt => {
|
|
234
|
+
command.options.forEach((opt) => {
|
|
279
235
|
console.log(' ' + colors.cyan(opt.flag.padEnd(24)) + colors.dim(opt.description));
|
|
280
236
|
});
|
|
281
237
|
newline();
|
|
282
238
|
}
|
|
283
239
|
if (command.related && command.related.length > 0) {
|
|
284
240
|
console.log(colors.bold('Related'));
|
|
285
|
-
command.related.forEach(related => {
|
|
241
|
+
command.related.forEach((related) => {
|
|
286
242
|
console.log(' ' + colors.cyan(`codehere help ${related}`));
|
|
287
243
|
});
|
|
288
244
|
newline();
|
|
@@ -296,28 +252,29 @@ function printCmd(name, desc) {
|
|
|
296
252
|
}
|
|
297
253
|
function displayGeneralHelp() {
|
|
298
254
|
newline();
|
|
299
|
-
console.log(colors.bold('codehere') + colors.dim(' —
|
|
255
|
+
console.log(colors.bold('codehere') + colors.dim(' — A PM for your AI coding agents'));
|
|
300
256
|
newline();
|
|
301
|
-
console.log(colors.bold('
|
|
302
|
-
for (const cmd of ['
|
|
257
|
+
console.log(colors.bold('Delegate'));
|
|
258
|
+
for (const cmd of ['start', 'task', 'kill']) {
|
|
303
259
|
printCmd(cmd, COMMAND_INFO[cmd].description);
|
|
304
260
|
}
|
|
305
261
|
newline();
|
|
306
|
-
console.log(colors.bold('
|
|
307
|
-
for (const cmd of ['
|
|
262
|
+
console.log(colors.bold('Safety & Trust') + colors.dim(' (no API key, no agents needed)'));
|
|
263
|
+
for (const cmd of ['hook', 'trust', 'report', 'status', 'serve']) {
|
|
308
264
|
printCmd(cmd, COMMAND_INFO[cmd].description);
|
|
309
265
|
}
|
|
310
266
|
newline();
|
|
311
267
|
console.log(colors.bold('Configuration'));
|
|
312
|
-
|
|
268
|
+
for (const cmd of ['setup', 'config', 'health', 'completion']) {
|
|
269
|
+
printCmd(cmd, COMMAND_INFO[cmd].description);
|
|
270
|
+
}
|
|
313
271
|
newline();
|
|
314
272
|
console.log(colors.bold('Getting Started'));
|
|
315
|
-
console.log(colors.dim(' 1. ') + colors.cyan('codehere
|
|
316
|
-
console.log(colors.dim(' 2. ') + colors.cyan('codehere
|
|
317
|
-
console.log(colors.dim(' 3. ') + colors.cyan('codehere
|
|
273
|
+
console.log(colors.dim(' 1. ') + colors.cyan('codehere start') + colors.dim(' Open the task intake at :3773'));
|
|
274
|
+
console.log(colors.dim(' 2. ') + colors.cyan('codehere hook install') + colors.dim(' Audit every Claude Code action'));
|
|
275
|
+
console.log(colors.dim(' 3. ') + colors.cyan('codehere trust .') + colors.dim(' Scan your project (no API key)'));
|
|
318
276
|
newline();
|
|
319
277
|
console.log(colors.dim('Run ') + colors.cyan('codehere help <command>') + colors.dim(' for details on any command.'));
|
|
320
|
-
console.log(colors.dim('Run ') + colors.cyan('codehere help --all') + colors.dim(' to see all commands.'));
|
|
321
278
|
newline();
|
|
322
279
|
}
|
|
323
280
|
/**
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* codehere hook log # Show recent audit log
|
|
12
12
|
* codehere hook log --tail 50 # Last 50 events
|
|
13
13
|
*/
|
|
14
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, copyFileSync, unlinkSync, rmdirSync } from 'fs';
|
|
14
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, copyFileSync, unlinkSync, rmdirSync, } from 'fs';
|
|
15
15
|
import { join, dirname } from 'path';
|
|
16
16
|
import { homedir } from 'os';
|
|
17
17
|
import { fileURLToPath } from 'url';
|
|
@@ -33,7 +33,7 @@ function installSkills() {
|
|
|
33
33
|
if (!existsSync(SKILLS_TARGET_DIR)) {
|
|
34
34
|
mkdirSync(SKILLS_TARGET_DIR, { recursive: true });
|
|
35
35
|
}
|
|
36
|
-
const files = readdirSync(sourceDir).filter(f => f.endsWith('.md'));
|
|
36
|
+
const files = readdirSync(sourceDir).filter((f) => f.endsWith('.md'));
|
|
37
37
|
for (const file of files) {
|
|
38
38
|
copyFileSync(join(sourceDir, file), join(SKILLS_TARGET_DIR, file));
|
|
39
39
|
}
|
|
@@ -48,11 +48,12 @@ function uninstallSkills() {
|
|
|
48
48
|
}
|
|
49
49
|
rmdirSync(SKILLS_TARGET_DIR);
|
|
50
50
|
}
|
|
51
|
-
catch {
|
|
51
|
+
catch {
|
|
52
|
+
/* ignore */
|
|
53
|
+
}
|
|
52
54
|
}
|
|
53
55
|
function skillsInstalled() {
|
|
54
|
-
return existsSync(SKILLS_TARGET_DIR) &&
|
|
55
|
-
readdirSync(SKILLS_TARGET_DIR).some(f => f.endsWith('.md'));
|
|
56
|
+
return existsSync(SKILLS_TARGET_DIR) && readdirSync(SKILLS_TARGET_DIR).some((f) => f.endsWith('.md'));
|
|
56
57
|
}
|
|
57
58
|
const SETTINGS_PATH = join(homedir(), '.claude', 'settings.json');
|
|
58
59
|
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
@@ -75,7 +76,7 @@ function writeSettings(settings) {
|
|
|
75
76
|
function isInstalled(settings) {
|
|
76
77
|
const hooks = (settings.hooks ?? {});
|
|
77
78
|
const preToolUse = (hooks.PreToolUse ?? []);
|
|
78
|
-
return preToolUse.some(entry => entry.hooks?.some(h => h.command?.includes('codehere scan-tool')));
|
|
79
|
+
return preToolUse.some((entry) => entry.hooks?.some((h) => h.command?.includes('codehere scan-tool')));
|
|
79
80
|
}
|
|
80
81
|
// ── command ───────────────────────────────────────────────────────────────────
|
|
81
82
|
export async function executeHookCommand(subcommand, options = {}) {
|
|
@@ -191,23 +192,22 @@ export async function executeHookCommand(subcommand, options = {}) {
|
|
|
191
192
|
newline();
|
|
192
193
|
// Show recent audit stats
|
|
193
194
|
if (existsSync(AUDIT_FILE)) {
|
|
194
|
-
const lines = readFileSync(AUDIT_FILE, 'utf-8')
|
|
195
|
-
.split('\n')
|
|
196
|
-
.filter(Boolean)
|
|
197
|
-
.slice(-1000); // last 1000 events
|
|
195
|
+
const lines = readFileSync(AUDIT_FILE, 'utf-8').split('\n').filter(Boolean).slice(-1000); // last 1000 events
|
|
198
196
|
if (lines.length > 0) {
|
|
199
|
-
const entries = lines
|
|
197
|
+
const entries = lines
|
|
198
|
+
.map((l) => {
|
|
200
199
|
try {
|
|
201
200
|
return JSON.parse(l);
|
|
202
201
|
}
|
|
203
202
|
catch {
|
|
204
203
|
return null;
|
|
205
204
|
}
|
|
206
|
-
})
|
|
205
|
+
})
|
|
206
|
+
.filter(Boolean);
|
|
207
207
|
const total = entries.length;
|
|
208
208
|
const blocked = entries.filter((e) => e.blocked).length;
|
|
209
209
|
const critical = entries.filter((e) => (e.criticalFindings ?? 0) > 0).length;
|
|
210
|
-
console.log(colors.bold(
|
|
210
|
+
console.log(colors.bold("What it's seen") + colors.dim(' (last 1000 events):'));
|
|
211
211
|
console.log(` ${colors.cyan(String(total))} tool calls scanned`);
|
|
212
212
|
console.log(` ${blocked > 0 ? colors.red(String(blocked)) : colors.green('none')} blocked`);
|
|
213
213
|
console.log(` ${critical > 0 ? colors.red(String(critical)) : colors.green('none')} with critical findings`);
|
|
@@ -219,7 +219,7 @@ export async function executeHookCommand(subcommand, options = {}) {
|
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
else {
|
|
222
|
-
console.log(colors.dim(
|
|
222
|
+
console.log(colors.dim(" No events logged yet — run Claude Code and it'll start tracking."));
|
|
223
223
|
newline();
|
|
224
224
|
}
|
|
225
225
|
break;
|
|
@@ -231,10 +231,7 @@ export async function executeHookCommand(subcommand, options = {}) {
|
|
|
231
231
|
console.log(colors.dim(' Run `codehere hook install` first'));
|
|
232
232
|
return;
|
|
233
233
|
}
|
|
234
|
-
const lines = readFileSync(AUDIT_FILE, 'utf-8')
|
|
235
|
-
.split('\n')
|
|
236
|
-
.filter(Boolean)
|
|
237
|
-
.slice(-tail);
|
|
234
|
+
const lines = readFileSync(AUDIT_FILE, 'utf-8').split('\n').filter(Boolean).slice(-tail);
|
|
238
235
|
if (lines.length === 0) {
|
|
239
236
|
console.log(info('Audit log is empty'));
|
|
240
237
|
return;
|
|
@@ -245,12 +242,8 @@ export async function executeHookCommand(subcommand, options = {}) {
|
|
|
245
242
|
try {
|
|
246
243
|
const entry = JSON.parse(line);
|
|
247
244
|
const ts = new Date(entry.timestamp).toLocaleTimeString();
|
|
248
|
-
const status = entry.blocked
|
|
249
|
-
|
|
250
|
-
: colors.green('[ALLOW] ');
|
|
251
|
-
const risk = entry.riskScore > 0
|
|
252
|
-
? colors.yellow(` risk:${entry.riskScore}`)
|
|
253
|
-
: '';
|
|
245
|
+
const status = entry.blocked ? colors.red('[BLOCKED]') : colors.green('[ALLOW] ');
|
|
246
|
+
const risk = entry.riskScore > 0 ? colors.yellow(` risk:${entry.riskScore}`) : '';
|
|
254
247
|
const tool = colors.cyan(entry.toolName.padEnd(10));
|
|
255
248
|
const preview = entry.toolInput.substring(0, 60).replace(/\n/g, ' ');
|
|
256
249
|
console.log(` ${ts} ${status} ${tool}${risk} ${colors.dim(preview)}`);
|