codehere 0.2.2 → 0.3.0-rc.10
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 +261 -1224
- package/dist/infrastructure/config/product-context.js +7 -6
- package/dist/infrastructure/hooks/claude-sdk-hook.js +348 -72
- 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/conductor-adapter.js +340 -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 +278 -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/probe-port.js +36 -0
- 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/presentation/cli/repl.js +474 -0
- 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
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Domain Service: ReAct Loop
|
|
3
|
-
* Implements Thought → Action → Observation cycle
|
|
4
|
-
*/
|
|
5
|
-
export class ReActLoop {
|
|
6
|
-
maxTurns;
|
|
7
|
-
trajectory = null;
|
|
8
|
-
consecutiveFailures = 0;
|
|
9
|
-
maxConsecutiveFailures = 3;
|
|
10
|
-
recentToolCalls = new Map(); // Track repeated tool calls
|
|
11
|
-
recentActions = []; // Track recent action types for diversity check
|
|
12
|
-
noProgressTurns = 0; // Track turns with no progress
|
|
13
|
-
maxNoProgressTurns = 5; // Max turns without progress before early termination
|
|
14
|
-
lastObservationHash = null; // Track if observations are changing
|
|
15
|
-
constructor(maxTurns = 20) {
|
|
16
|
-
this.maxTurns = maxTurns;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Execute ReAct loop with infinite loop prevention
|
|
20
|
-
*/
|
|
21
|
-
async execute(query, context, generateThought, generateAction, executeAction, isFinalAnswer) {
|
|
22
|
-
this.trajectory = {
|
|
23
|
-
query,
|
|
24
|
-
steps: [],
|
|
25
|
-
success: false,
|
|
26
|
-
};
|
|
27
|
-
this.consecutiveFailures = 0;
|
|
28
|
-
this.recentToolCalls.clear();
|
|
29
|
-
this.recentActions = [];
|
|
30
|
-
this.noProgressTurns = 0;
|
|
31
|
-
this.lastObservationHash = null;
|
|
32
|
-
for (let turn = 0; turn < this.maxTurns; turn++) {
|
|
33
|
-
// 1. Generate Thought
|
|
34
|
-
const thought = await generateThought(query, context, this.trajectory);
|
|
35
|
-
// 2. Generate Action
|
|
36
|
-
const action = await generateAction(thought, context);
|
|
37
|
-
// 3. Action Diversity Check - Don't repeat same action type consecutively
|
|
38
|
-
const actionKey = `${action.type}:${action.name}`;
|
|
39
|
-
if (this.recentActions.length > 0 && this.recentActions[this.recentActions.length - 1] === actionKey) {
|
|
40
|
-
// Same action type repeated consecutively - likely stuck
|
|
41
|
-
this.trajectory.steps.push({
|
|
42
|
-
thought,
|
|
43
|
-
action,
|
|
44
|
-
observation: {
|
|
45
|
-
result: null,
|
|
46
|
-
success: false,
|
|
47
|
-
error: `Action diversity violation: Same action "${actionKey}" repeated consecutively. Stopping to prevent infinite loop.`,
|
|
48
|
-
},
|
|
49
|
-
timestamp: new Date(),
|
|
50
|
-
});
|
|
51
|
-
this.trajectory.success = false;
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
this.recentActions.push(actionKey);
|
|
55
|
-
// Keep only last 5 actions for diversity check
|
|
56
|
-
if (this.recentActions.length > 5) {
|
|
57
|
-
this.recentActions.shift();
|
|
58
|
-
}
|
|
59
|
-
// 4. Check for repeated tool calls (infinite loop detection)
|
|
60
|
-
if (action.type === 'tool') {
|
|
61
|
-
const toolKey = `${action.name}:${JSON.stringify(action.parameters || {})}`;
|
|
62
|
-
const callCount = this.recentToolCalls.get(toolKey) || 0;
|
|
63
|
-
if (callCount >= 2) {
|
|
64
|
-
// Same tool called 3+ times with same parameters - likely stuck
|
|
65
|
-
this.trajectory.steps.push({
|
|
66
|
-
thought,
|
|
67
|
-
action,
|
|
68
|
-
observation: {
|
|
69
|
-
result: null,
|
|
70
|
-
success: false,
|
|
71
|
-
error: `Infinite loop detected: Tool "${action.name}" called ${callCount + 1} times with same parameters. Stopping to prevent infinite loop.`,
|
|
72
|
-
},
|
|
73
|
-
timestamp: new Date(),
|
|
74
|
-
});
|
|
75
|
-
this.trajectory.success = false;
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
78
|
-
this.recentToolCalls.set(toolKey, callCount + 1);
|
|
79
|
-
// Clean old entries (keep only last 10 unique tool calls)
|
|
80
|
-
if (this.recentToolCalls.size > 10) {
|
|
81
|
-
const entries = Array.from(this.recentToolCalls.entries());
|
|
82
|
-
this.recentToolCalls.clear();
|
|
83
|
-
entries.slice(-10).forEach(([key, value]) => {
|
|
84
|
-
this.recentToolCalls.set(key, value);
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
// 5. Execute Action
|
|
89
|
-
const observation = await executeAction(action);
|
|
90
|
-
// 6. Track consecutive failures
|
|
91
|
-
if (!observation.success) {
|
|
92
|
-
this.consecutiveFailures++;
|
|
93
|
-
if (this.consecutiveFailures >= this.maxConsecutiveFailures) {
|
|
94
|
-
// Too many consecutive failures - stop to prevent infinite loop
|
|
95
|
-
this.trajectory.steps.push({
|
|
96
|
-
thought,
|
|
97
|
-
action,
|
|
98
|
-
observation: {
|
|
99
|
-
result: null,
|
|
100
|
-
success: false,
|
|
101
|
-
error: `Too many consecutive failures (${this.consecutiveFailures}). Stopping to prevent infinite loop. Last error: ${observation.error || 'Unknown error'}`,
|
|
102
|
-
},
|
|
103
|
-
timestamp: new Date(),
|
|
104
|
-
});
|
|
105
|
-
this.trajectory.success = false;
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
// Reset failure counter on success
|
|
111
|
-
this.consecutiveFailures = 0;
|
|
112
|
-
}
|
|
113
|
-
// 7. Check for progress (observation changed)
|
|
114
|
-
const observationHash = this.hashObservation(observation);
|
|
115
|
-
if (observationHash === this.lastObservationHash && !observation.success) {
|
|
116
|
-
// Same observation result repeated - no progress
|
|
117
|
-
this.noProgressTurns++;
|
|
118
|
-
if (this.noProgressTurns >= this.maxNoProgressTurns) {
|
|
119
|
-
this.trajectory.steps.push({
|
|
120
|
-
thought,
|
|
121
|
-
action,
|
|
122
|
-
observation: {
|
|
123
|
-
result: observation.result,
|
|
124
|
-
success: false,
|
|
125
|
-
error: `No progress detected after ${this.noProgressTurns} turns. Stopping to prevent infinite loop.`,
|
|
126
|
-
},
|
|
127
|
-
timestamp: new Date(),
|
|
128
|
-
});
|
|
129
|
-
this.trajectory.success = false;
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
// Progress detected - reset counter
|
|
135
|
-
this.noProgressTurns = 0;
|
|
136
|
-
this.lastObservationHash = observationHash;
|
|
137
|
-
}
|
|
138
|
-
// 8. Record step
|
|
139
|
-
const step = {
|
|
140
|
-
thought,
|
|
141
|
-
action,
|
|
142
|
-
observation,
|
|
143
|
-
timestamp: new Date(),
|
|
144
|
-
};
|
|
145
|
-
this.trajectory.steps.push(step);
|
|
146
|
-
// 9. Check if done
|
|
147
|
-
if (isFinalAnswer(observation)) {
|
|
148
|
-
this.trajectory.finalAnswer = observation.result;
|
|
149
|
-
this.trajectory.success = true;
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
// 10. Update context with observation
|
|
153
|
-
context = { ...context, lastObservation: observation };
|
|
154
|
-
}
|
|
155
|
-
// Check if we hit max turns without success
|
|
156
|
-
if (!this.trajectory.success && this.trajectory.steps.length >= this.maxTurns) {
|
|
157
|
-
const lastStep = this.trajectory.steps[this.trajectory.steps.length - 1];
|
|
158
|
-
if (lastStep && !lastStep.observation.error) {
|
|
159
|
-
// Add error if we hit max turns
|
|
160
|
-
lastStep.observation.error = `Reached maximum turns (${this.maxTurns}) without finding solution.`;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return this.trajectory;
|
|
164
|
-
}
|
|
165
|
-
getTrajectory() {
|
|
166
|
-
if (!this.trajectory) {
|
|
167
|
-
throw new Error('Trajectory not initialized. Execute loop first.');
|
|
168
|
-
}
|
|
169
|
-
return this.trajectory;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Hash observation to detect if it's changed (progress detection)
|
|
173
|
-
*/
|
|
174
|
-
hashObservation(observation) {
|
|
175
|
-
const key = `${observation.success}:${observation.error || ''}:${JSON.stringify(observation.result || '').substring(0, 100)}`;
|
|
176
|
-
// Simple hash function
|
|
177
|
-
let hash = 0;
|
|
178
|
-
for (let i = 0; i < key.length; i++) {
|
|
179
|
-
const char = key.charCodeAt(i);
|
|
180
|
-
hash = ((hash << 5) - hash) + char;
|
|
181
|
-
hash = hash & hash; // Convert to 32-bit integer
|
|
182
|
-
}
|
|
183
|
-
return hash.toString();
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
//# sourceMappingURL=react-loop.js.map
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Risk Tier Detector
|
|
3
|
-
* Detects risk tier for operations
|
|
4
|
-
*
|
|
5
|
-
* Phase 1: v0.5.0-alpha.0
|
|
6
|
-
*/
|
|
7
|
-
import { RiskTier } from '../entities/task.js';
|
|
8
|
-
/**
|
|
9
|
-
* Detect risk tier from file list
|
|
10
|
-
*/
|
|
11
|
-
export function detectRiskTier(files) {
|
|
12
|
-
if (!files || files.length === 0) {
|
|
13
|
-
return RiskTier.T1;
|
|
14
|
-
}
|
|
15
|
-
// Check for high-risk file patterns
|
|
16
|
-
const highRiskPatterns = [
|
|
17
|
-
/\.(env|secret|key|pem|p12|pfx)$/i, // Secrets
|
|
18
|
-
/package\.json$/i, // Dependencies
|
|
19
|
-
/\.lock$/i, // Lock files
|
|
20
|
-
/Dockerfile/i, // Container configs
|
|
21
|
-
/\.config\.(js|ts|json)$/i, // Config files
|
|
22
|
-
/config\/.*\.(yml|yaml|json|toml|ini)$/i, // Config directory files
|
|
23
|
-
/^config\//i, // Files in config directory (any file in config/)
|
|
24
|
-
/\/config\//i, // Files in config directory (anywhere in path)
|
|
25
|
-
];
|
|
26
|
-
const criticalPatterns = [
|
|
27
|
-
/\.(sql|db|sqlite)$/i, // Databases
|
|
28
|
-
/\.(sh|bat|ps1)$/i, // Scripts
|
|
29
|
-
];
|
|
30
|
-
// First pass: check ALL files for critical patterns (T3)
|
|
31
|
-
for (const file of files) {
|
|
32
|
-
for (const pattern of criticalPatterns) {
|
|
33
|
-
if (pattern.test(file)) {
|
|
34
|
-
return RiskTier.T3;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
// Second pass: check ALL files for high-risk patterns (T2)
|
|
39
|
-
for (const file of files) {
|
|
40
|
-
for (const pattern of highRiskPatterns) {
|
|
41
|
-
if (pattern.test(file)) {
|
|
42
|
-
return RiskTier.T2;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
// Multi-file operations are medium risk
|
|
47
|
-
if (files.length > 3) {
|
|
48
|
-
return RiskTier.T2;
|
|
49
|
-
}
|
|
50
|
-
return RiskTier.T1;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Detect risk tier from plan
|
|
54
|
-
*/
|
|
55
|
-
export function detectRiskTierFromPlan(plan) {
|
|
56
|
-
if (!plan) {
|
|
57
|
-
return RiskTier.T1;
|
|
58
|
-
}
|
|
59
|
-
// Check sub-plans for high-risk operations
|
|
60
|
-
const subPlans = plan.subPlans || [];
|
|
61
|
-
const highRiskTypes = ['refactor', 'implement', 'test'];
|
|
62
|
-
const criticalTypes = ['delete', 'move'];
|
|
63
|
-
for (const subPlan of subPlans) {
|
|
64
|
-
const type = subPlan.type?.toLowerCase();
|
|
65
|
-
if (criticalTypes.includes(type)) {
|
|
66
|
-
return RiskTier.T3;
|
|
67
|
-
}
|
|
68
|
-
if (highRiskTypes.includes(type)) {
|
|
69
|
-
return RiskTier.T2;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Large plans are medium risk
|
|
73
|
-
if (subPlans.length > 5) {
|
|
74
|
-
return RiskTier.T2;
|
|
75
|
-
}
|
|
76
|
-
return RiskTier.T1;
|
|
77
|
-
}
|
|
78
|
-
//# sourceMappingURL=risk-tier-detector.js.map
|
package/dist/edit.js
DELETED
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
import { generateDiff } from './chat.js';
|
|
4
|
-
import { checkPolicy } from './policy.js';
|
|
5
|
-
import { refineTask } from './iterative-refinement.js';
|
|
6
|
-
/**
|
|
7
|
-
* Fix duplicate module.exports or export statements
|
|
8
|
-
*/
|
|
9
|
-
function fixDuplicateExports(content) {
|
|
10
|
-
const lines = content.split('\n');
|
|
11
|
-
const result = [];
|
|
12
|
-
let foundModuleExports = false;
|
|
13
|
-
let foundExport = false;
|
|
14
|
-
let lastExportIndex = -1;
|
|
15
|
-
for (let i = 0; i < lines.length; i++) {
|
|
16
|
-
const line = lines[i].trim();
|
|
17
|
-
// Check for module.exports
|
|
18
|
-
if (line.startsWith('module.exports')) {
|
|
19
|
-
if (foundModuleExports) {
|
|
20
|
-
// Skip duplicate - keep the last one
|
|
21
|
-
// Remove previous export from result
|
|
22
|
-
if (lastExportIndex >= 0) {
|
|
23
|
-
result.splice(lastExportIndex, 1);
|
|
24
|
-
}
|
|
25
|
-
lastExportIndex = result.length;
|
|
26
|
-
result.push(lines[i]);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
foundModuleExports = true;
|
|
30
|
-
lastExportIndex = result.length;
|
|
31
|
-
result.push(lines[i]);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
// Check for ES6 export default
|
|
35
|
-
else if (line.startsWith('export default')) {
|
|
36
|
-
if (foundExport) {
|
|
37
|
-
// Skip duplicate
|
|
38
|
-
if (lastExportIndex >= 0) {
|
|
39
|
-
result.splice(lastExportIndex, 1);
|
|
40
|
-
}
|
|
41
|
-
lastExportIndex = result.length;
|
|
42
|
-
result.push(lines[i]);
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
foundExport = true;
|
|
46
|
-
lastExportIndex = result.length;
|
|
47
|
-
result.push(lines[i]);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
// Check for ES6 export const/function/class
|
|
51
|
-
else if (line.match(/^export\s+(const|function|class|let|var)\s+/)) {
|
|
52
|
-
// These are usually fine (one per line), but check for duplicates
|
|
53
|
-
result.push(lines[i]);
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
result.push(lines[i]);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return result.join('\n');
|
|
60
|
-
}
|
|
61
|
-
export function parseDiffStats(diffText) {
|
|
62
|
-
const lines = diffText.split('\n');
|
|
63
|
-
let linesAdded = 0;
|
|
64
|
-
let linesRemoved = 0;
|
|
65
|
-
let filesChanged = 0;
|
|
66
|
-
let currentFile = '';
|
|
67
|
-
for (const line of lines) {
|
|
68
|
-
if (line.startsWith('---')) {
|
|
69
|
-
const fileMatch = line.match(/^---\s+(.+)$/);
|
|
70
|
-
if (fileMatch && fileMatch[1] !== '/dev/null') {
|
|
71
|
-
const file = fileMatch[1].replace(/^a\//, '');
|
|
72
|
-
if (file !== currentFile) {
|
|
73
|
-
filesChanged++;
|
|
74
|
-
currentFile = file;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
else if (line.startsWith('+++')) {
|
|
79
|
-
const fileMatch = line.match(/^\+\+\+\s+(.+)$/);
|
|
80
|
-
if (fileMatch && fileMatch[1] !== '/dev/null') {
|
|
81
|
-
const file = fileMatch[1].replace(/^b\//, '');
|
|
82
|
-
if (file !== currentFile) {
|
|
83
|
-
filesChanged++;
|
|
84
|
-
currentFile = file;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
else if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
89
|
-
linesAdded++;
|
|
90
|
-
}
|
|
91
|
-
else if (line.startsWith('-') && !line.startsWith('---')) {
|
|
92
|
-
linesRemoved++;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return { linesAdded, linesRemoved, filesChanged };
|
|
96
|
-
}
|
|
97
|
-
export function applyUnifiedDiff(originalContent, diffText) {
|
|
98
|
-
const diffLines = diffText.split('\n');
|
|
99
|
-
const originalLines = originalContent.split('\n');
|
|
100
|
-
const result = [];
|
|
101
|
-
let originalIndex = 0;
|
|
102
|
-
let i = 0;
|
|
103
|
-
// Find first hunk
|
|
104
|
-
while (i < diffLines.length && !diffLines[i].startsWith('@@')) {
|
|
105
|
-
i++;
|
|
106
|
-
}
|
|
107
|
-
while (i < diffLines.length) {
|
|
108
|
-
const line = diffLines[i];
|
|
109
|
-
if (line.startsWith('@@')) {
|
|
110
|
-
// Hunk header: @@ -start,count +start,count @@
|
|
111
|
-
const match = line.match(/^@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@/);
|
|
112
|
-
if (match) {
|
|
113
|
-
const oldStart = parseInt(match[1], 10) - 1; // Convert to 0-based (line numbers are 1-based)
|
|
114
|
-
const oldCount = match[2] ? parseInt(match[2], 10) : 0;
|
|
115
|
-
// Add lines before this hunk
|
|
116
|
-
while (originalIndex < oldStart && originalIndex < originalLines.length) {
|
|
117
|
-
result.push(originalLines[originalIndex]);
|
|
118
|
-
originalIndex++;
|
|
119
|
-
}
|
|
120
|
-
i++; // Move past hunk header
|
|
121
|
-
// Process hunk lines
|
|
122
|
-
let removedCount = 0;
|
|
123
|
-
while (i < diffLines.length) {
|
|
124
|
-
const hunkLine = diffLines[i];
|
|
125
|
-
// Check for next hunk
|
|
126
|
-
if (hunkLine.startsWith('@@')) {
|
|
127
|
-
break;
|
|
128
|
-
}
|
|
129
|
-
if (hunkLine.startsWith('+') && !hunkLine.startsWith('+++')) {
|
|
130
|
-
// Added line
|
|
131
|
-
result.push(hunkLine.substring(1));
|
|
132
|
-
i++;
|
|
133
|
-
}
|
|
134
|
-
else if (hunkLine.startsWith('-') && !hunkLine.startsWith('---')) {
|
|
135
|
-
// Removed line - skip it in original
|
|
136
|
-
originalIndex++;
|
|
137
|
-
removedCount++;
|
|
138
|
-
i++;
|
|
139
|
-
}
|
|
140
|
-
else if (hunkLine.startsWith(' ')) {
|
|
141
|
-
// Context line - keep from original
|
|
142
|
-
if (originalIndex < originalLines.length) {
|
|
143
|
-
result.push(originalLines[originalIndex]);
|
|
144
|
-
}
|
|
145
|
-
originalIndex++;
|
|
146
|
-
removedCount++;
|
|
147
|
-
i++;
|
|
148
|
-
}
|
|
149
|
-
else if (hunkLine.trim() === '') {
|
|
150
|
-
// Empty line, skip
|
|
151
|
-
i++;
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
// Unknown line type, skip
|
|
155
|
-
i++;
|
|
156
|
-
}
|
|
157
|
-
// Safety check: if we've processed all expected removed lines, we might be done
|
|
158
|
-
if (oldCount > 0 && removedCount >= oldCount && !diffLines[i]?.startsWith('@@')) {
|
|
159
|
-
// Check if next line is part of this hunk or next
|
|
160
|
-
if (i < diffLines.length && !diffLines[i].startsWith('@@') && !diffLines[i].startsWith('+') && !diffLines[i].startsWith('-') && !diffLines[i].startsWith(' ')) {
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
i++;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
i++;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
// Add remaining original lines
|
|
175
|
-
while (originalIndex < originalLines.length) {
|
|
176
|
-
result.push(originalLines[originalIndex]);
|
|
177
|
-
originalIndex++;
|
|
178
|
-
}
|
|
179
|
-
return result.join('\n');
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Legacy function - kept for backward compatibility
|
|
183
|
-
* Use generateAndApplyEditWithVerification() for new code
|
|
184
|
-
*/
|
|
185
|
-
export async function generateAndApplyEdit(filepath, instruction) {
|
|
186
|
-
const fullPath = join(process.cwd(), filepath);
|
|
187
|
-
if (!existsSync(fullPath)) {
|
|
188
|
-
return {
|
|
189
|
-
success: false,
|
|
190
|
-
error: `File not found: ${filepath}`,
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
const originalContent = readFileSync(fullPath, 'utf-8');
|
|
194
|
-
// Generate diff
|
|
195
|
-
const diffText = await generateDiff(originalContent, instruction, filepath);
|
|
196
|
-
if (!diffText || diffText.trim().length === 0) {
|
|
197
|
-
return {
|
|
198
|
-
success: false,
|
|
199
|
-
error: 'No diff generated',
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
// Parse diff stats
|
|
203
|
-
const diffStats = parseDiffStats(diffText);
|
|
204
|
-
// Check policy
|
|
205
|
-
const policyResult = checkPolicy(filepath, diffStats);
|
|
206
|
-
if (!policyResult.allowed) {
|
|
207
|
-
return {
|
|
208
|
-
success: false,
|
|
209
|
-
policyResult,
|
|
210
|
-
diffStats,
|
|
211
|
-
error: policyResult.reason,
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
// Apply diff
|
|
215
|
-
try {
|
|
216
|
-
const newContent = applyUnifiedDiff(originalContent, diffText);
|
|
217
|
-
writeFileSync(fullPath, newContent, 'utf-8');
|
|
218
|
-
return {
|
|
219
|
-
success: true,
|
|
220
|
-
diffStats,
|
|
221
|
-
policyResult,
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
catch (error) {
|
|
225
|
-
return {
|
|
226
|
-
success: false,
|
|
227
|
-
diffStats,
|
|
228
|
-
policyResult,
|
|
229
|
-
error: `Failed to apply diff: ${error instanceof Error ? error.message : String(error)}`,
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* NEW: Generate and apply edit with verification and iterative refinement
|
|
235
|
-
*/
|
|
236
|
-
export async function generateAndApplyEditWithVerification(filepath, instruction, requirements) {
|
|
237
|
-
const fullPath = join(process.cwd(), filepath);
|
|
238
|
-
if (!existsSync(fullPath)) {
|
|
239
|
-
return {
|
|
240
|
-
success: false,
|
|
241
|
-
verified: false,
|
|
242
|
-
iterations: 0,
|
|
243
|
-
error: `File not found: ${filepath}`,
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
try {
|
|
247
|
-
// Read original content BEFORE modification
|
|
248
|
-
const originalContent = readFileSync(fullPath, 'utf-8');
|
|
249
|
-
// Use iterative refinement with verification
|
|
250
|
-
const refinementResult = await refineTask(fullPath, instruction, requirements, 3);
|
|
251
|
-
if (!refinementResult.success) {
|
|
252
|
-
// Rollback on failure
|
|
253
|
-
writeFileSync(fullPath, originalContent, 'utf-8');
|
|
254
|
-
return {
|
|
255
|
-
success: false,
|
|
256
|
-
verified: false,
|
|
257
|
-
iterations: refinementResult.iterations,
|
|
258
|
-
error: `Task failed after ${refinementResult.iterations} iterations`,
|
|
259
|
-
verificationErrors: refinementResult.finalResult.errors,
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
// Read final content and calculate actual diff stats
|
|
263
|
-
const finalContent = readFileSync(fullPath, 'utf-8');
|
|
264
|
-
// Calculate diff stats manually (more reliable than generating diff)
|
|
265
|
-
const originalLines = originalContent.split('\n');
|
|
266
|
-
const finalLines = finalContent.split('\n');
|
|
267
|
-
let linesAdded = 0;
|
|
268
|
-
let linesRemoved = 0;
|
|
269
|
-
// Simple line-by-line comparison
|
|
270
|
-
const maxLen = Math.max(originalLines.length, finalLines.length);
|
|
271
|
-
for (let i = 0; i < maxLen; i++) {
|
|
272
|
-
if (i >= originalLines.length) {
|
|
273
|
-
linesAdded++;
|
|
274
|
-
}
|
|
275
|
-
else if (i >= finalLines.length) {
|
|
276
|
-
linesRemoved++;
|
|
277
|
-
}
|
|
278
|
-
else if (originalLines[i] !== finalLines[i]) {
|
|
279
|
-
// Changed line - count as removed + added
|
|
280
|
-
linesRemoved++;
|
|
281
|
-
linesAdded++;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
const diffStats = {
|
|
285
|
-
linesAdded,
|
|
286
|
-
linesRemoved,
|
|
287
|
-
filesChanged: 1,
|
|
288
|
-
};
|
|
289
|
-
// Check policy
|
|
290
|
-
const policyResult = checkPolicy(filepath, diffStats);
|
|
291
|
-
return {
|
|
292
|
-
success: true,
|
|
293
|
-
verified: refinementResult.finalResult.success,
|
|
294
|
-
iterations: refinementResult.iterations,
|
|
295
|
-
diffStats,
|
|
296
|
-
policyResult,
|
|
297
|
-
verificationErrors: refinementResult.finalResult.errors.length > 0 ? refinementResult.finalResult.errors : undefined,
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
catch (error) {
|
|
301
|
-
// Rollback on error
|
|
302
|
-
if (existsSync(fullPath)) {
|
|
303
|
-
try {
|
|
304
|
-
const originalContent = readFileSync(fullPath, 'utf-8');
|
|
305
|
-
// Try to restore if we have backup (refinement should have kept original)
|
|
306
|
-
}
|
|
307
|
-
catch {
|
|
308
|
-
// Ignore rollback errors
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
return {
|
|
312
|
-
success: false,
|
|
313
|
-
verified: false,
|
|
314
|
-
iterations: 0,
|
|
315
|
-
error: `Error during verification: ${error instanceof Error ? error.message : String(error)}`,
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
//# sourceMappingURL=edit.js.map
|