codebot-ai 1.9.0 → 2.0.0

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 CHANGED
@@ -4,7 +4,7 @@
4
4
  [![license](https://img.shields.io/npm/l/codebot-ai.svg)](https://github.com/zanderone1980/codebot-ai/blob/main/LICENSE)
5
5
  [![node](https://img.shields.io/node/v/codebot-ai.svg)](https://nodejs.org)
6
6
 
7
- **Zero-dependency autonomous AI agent.** Works with any LLM — local or cloud. Code, browse the web, run commands, search, automate routines, and more.
7
+ **Zero-dependency autonomous AI coding agent with enterprise security.** Works with any LLM — local or cloud. Code, browse the web, run commands, search, automate routines, and more. Includes VS Code extension, GitHub Action, policy engine, risk scoring, and hash-chained audit trail.
8
8
 
9
9
  Built by [Ascendral Software Development & Innovation](https://github.com/AscendralSoftware).
10
10
 
@@ -22,6 +22,27 @@ That's it. The setup wizard launches on first run — pick your model, paste an
22
22
  npx codebot-ai
23
23
  ```
24
24
 
25
+ ### VS Code Extension
26
+
27
+ Install from the VS Code Marketplace: search for **CodeBot AI**, or:
28
+
29
+ ```bash
30
+ code --install-extension codebot-ai-vscode-2.0.0.vsix
31
+ ```
32
+
33
+ Features: sidebar chat panel, inline diff preview, status bar (tokens, cost, risk level), and full theme integration.
34
+
35
+ ### GitHub Action
36
+
37
+ ```yaml
38
+ - uses: zanderone1980/codebot-ai/actions/codebot@v2
39
+ with:
40
+ task: review # or: fix, scan
41
+ api-key: ${{ secrets.ANTHROPIC_API_KEY }}
42
+ ```
43
+
44
+ Tasks: `review` (PR code review), `fix` (auto-fix CI failures), `scan` (security scan with SARIF upload).
45
+
25
46
  ## What Can It Do?
26
47
 
27
48
  - **Write & edit code** — reads your codebase, makes targeted edits, runs tests
@@ -101,6 +122,8 @@ echo "explain this error" | codebot # Pipe mode
101
122
  /usage Show token usage for this session
102
123
  /clear Clear conversation
103
124
  /compact Force context compaction
125
+ /metrics Show session metrics (token counts, latency, costs)
126
+ /risk Show risk assessment history
104
127
  /config Show configuration
105
128
  /quit Exit
106
129
  ```
@@ -217,16 +240,31 @@ Connect external tool servers via [Model Context Protocol](https://modelcontextp
217
240
 
218
241
  MCP tools appear automatically with the `mcp_<server>_<tool>` prefix.
219
242
 
243
+ ## Security
244
+
245
+ CodeBot v2.0.0 is built with security as a core architectural principle:
246
+
247
+ - **Policy engine** — declarative JSON policies control tool access, filesystem scope, and execution limits
248
+ - **Risk scoring** — every tool call receives a 0-100 risk score based on 6 weighted factors
249
+ - **Secret detection** — scans for AWS keys, GitHub tokens, JWTs, private keys before writing
250
+ - **Sandbox execution** — Docker-based sandboxing with network, CPU, and memory limits
251
+ - **Audit trail** — hash-chained JSONL log with `--verify-audit` integrity check
252
+ - **SARIF export** — `--export-audit sarif` for GitHub Code Scanning integration
253
+ - **SSRF protection** — blocks localhost, private IPs, cloud metadata endpoints
254
+ - **Path safety** — blocks writes to system directories, detects path traversal
255
+
256
+ See [SECURITY.md](SECURITY.md) and [docs/HARDENING.md](docs/HARDENING.md) for the full security model.
257
+
220
258
  ## Stability
221
259
 
222
- CodeBot v1.3.0 is hardened for continuous operation:
260
+ CodeBot is hardened for continuous operation:
223
261
 
224
262
  - **Automatic retry** — network errors, rate limits (429), and server errors (5xx) retry with exponential backoff
225
263
  - **Stream recovery** — if the LLM connection drops mid-response, the agent loop retries on the next iteration
226
264
  - **Context compaction** — when the conversation exceeds the model's context window, messages are intelligently summarized
227
265
  - **Process resilience** — unhandled exceptions and rejections are caught, logged, and the REPL keeps running
228
266
  - **Routine timeouts** — scheduled tasks are capped at 5 minutes to prevent the scheduler from hanging
229
- - **99 tests** — comprehensive suite covering error recovery, retry logic, tool execution, and edge cases
267
+ - **483 tests** — comprehensive suite covering core agent, security, extension, and action
230
268
 
231
269
  ## Programmatic API
232
270
 
@@ -245,6 +283,7 @@ const agent = new Agent({
245
283
  provider,
246
284
  model: 'claude-sonnet-4-6',
247
285
  autoApprove: true,
286
+ projectRoot: '/path/to/project', // optional, defaults to cwd
248
287
  });
249
288
 
250
289
  for await (const event of agent.run('list all TypeScript files')) {
package/dist/agent.d.ts CHANGED
@@ -19,6 +19,7 @@ export declare class Agent {
19
19
  private tokenTracker;
20
20
  private metricsCollector;
21
21
  private riskScorer;
22
+ private projectRoot;
22
23
  private branchCreated;
23
24
  private askPermission;
24
25
  private onMessage?;
@@ -28,6 +29,7 @@ export declare class Agent {
28
29
  providerName?: string;
29
30
  maxIterations?: number;
30
31
  autoApprove?: boolean;
32
+ projectRoot?: string;
31
33
  askPermission?: (tool: string, args: Record<string, unknown>) => Promise<boolean>;
32
34
  onMessage?: (message: Message) => void;
33
35
  });
package/dist/agent.js CHANGED
@@ -108,15 +108,17 @@ class Agent {
108
108
  tokenTracker;
109
109
  metricsCollector;
110
110
  riskScorer;
111
+ projectRoot;
111
112
  branchCreated = false;
112
113
  askPermission;
113
114
  onMessage;
114
115
  constructor(opts) {
115
116
  this.provider = opts.provider;
116
117
  this.model = opts.model;
118
+ this.projectRoot = opts.projectRoot || process.cwd();
117
119
  // Load policy FIRST — tools need it for filesystem/git enforcement
118
- this.policyEnforcer = new policy_1.PolicyEnforcer((0, policy_1.loadPolicy)(process.cwd()), process.cwd());
119
- this.tools = new tools_1.ToolRegistry(process.cwd(), this.policyEnforcer);
120
+ this.policyEnforcer = new policy_1.PolicyEnforcer((0, policy_1.loadPolicy)(this.projectRoot), this.projectRoot);
121
+ this.tools = new tools_1.ToolRegistry(this.projectRoot, this.policyEnforcer);
120
122
  this.context = new manager_1.ContextManager(opts.model, opts.provider);
121
123
  // Use policy-defined max iterations as default, CLI overrides
122
124
  this.maxIterations = opts.maxIterations || this.policyEnforcer.getMaxIterations();
@@ -135,7 +137,7 @@ class Agent {
135
137
  this.tokenTracker.setCostLimit(costLimit);
136
138
  // Load plugins
137
139
  try {
138
- const plugins = (0, plugins_1.loadPlugins)(process.cwd());
140
+ const plugins = (0, plugins_1.loadPlugins)(this.projectRoot);
139
141
  for (const plugin of plugins) {
140
142
  this.tools.register(plugin);
141
143
  }
@@ -569,9 +571,8 @@ class Agent {
569
571
  return null;
570
572
  try {
571
573
  const { execSync } = require('child_process');
572
- const cwd = process.cwd();
573
574
  const currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {
574
- cwd, encoding: 'utf-8', timeout: 5000,
575
+ cwd: this.projectRoot, encoding: 'utf-8', timeout: 5000,
575
576
  }).trim();
576
577
  if (currentBranch !== 'main' && currentBranch !== 'master') {
577
578
  this.branchCreated = true;
@@ -584,7 +585,7 @@ class Agent {
584
585
  const slug = this.sanitizeSlug(firstUserMsg?.content || 'task');
585
586
  const branchName = `${prefix}${timestamp}-${slug}`;
586
587
  execSync(`git checkout -b "${branchName}"`, {
587
- cwd, encoding: 'utf-8', timeout: 10000,
588
+ cwd: this.projectRoot, encoding: 'utf-8', timeout: 10000,
588
589
  });
589
590
  this.branchCreated = true;
590
591
  return branchName;
@@ -633,7 +634,7 @@ class Agent {
633
634
  buildSystemPrompt(supportsTools) {
634
635
  let repoMap = '';
635
636
  try {
636
- repoMap = (0, repo_map_1.buildRepoMap)(process.cwd());
637
+ repoMap = (0, repo_map_1.buildRepoMap)(this.projectRoot);
637
638
  }
638
639
  catch {
639
640
  repoMap = 'Project structure: (unable to scan)';
@@ -641,7 +642,7 @@ class Agent {
641
642
  // Load persistent memory
642
643
  let memoryBlock = '';
643
644
  try {
644
- const memory = new memory_1.MemoryManager(process.cwd());
645
+ const memory = new memory_1.MemoryManager(this.projectRoot);
645
646
  memoryBlock = memory.getContextBlock();
646
647
  }
647
648
  catch {
package/dist/cli.js CHANGED
@@ -52,7 +52,7 @@ const sandbox_1 = require("./sandbox");
52
52
  const replay_1 = require("./replay");
53
53
  const risk_1 = require("./risk");
54
54
  const sarif_1 = require("./sarif");
55
- const VERSION = '1.9.0';
55
+ const VERSION = '2.0.0';
56
56
  const C = {
57
57
  reset: '\x1b[0m',
58
58
  bold: '\x1b[1m',
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export declare const VERSION = "2.0.0";
1
2
  export { Agent } from './agent';
2
3
  export { OpenAIProvider } from './providers/openai';
3
4
  export { AnthropicProvider } from './providers/anthropic';
package/dist/index.js CHANGED
@@ -14,7 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.sarifToString = exports.exportSarif = exports.RiskScorer = exports.MetricsCollector = exports.listReplayableSessions = exports.compareOutputs = exports.loadSessionForReplay = exports.ReplayProvider = exports.verifyMessages = exports.verifyMessage = exports.signMessage = exports.deriveSessionKey = exports.CapabilityChecker = exports.detectProvider = exports.getModelInfo = exports.PROVIDER_DEFAULTS = exports.MODEL_REGISTRY = exports.loadMCPTools = exports.loadPlugins = exports.parseToolCalls = exports.MemoryManager = exports.SessionManager = exports.buildRepoMap = exports.ContextManager = exports.ToolRegistry = exports.AnthropicProvider = exports.OpenAIProvider = exports.Agent = void 0;
17
+ exports.sarifToString = exports.exportSarif = exports.RiskScorer = exports.MetricsCollector = exports.listReplayableSessions = exports.compareOutputs = exports.loadSessionForReplay = exports.ReplayProvider = exports.verifyMessages = exports.verifyMessage = exports.signMessage = exports.deriveSessionKey = exports.CapabilityChecker = exports.detectProvider = exports.getModelInfo = exports.PROVIDER_DEFAULTS = exports.MODEL_REGISTRY = exports.loadMCPTools = exports.loadPlugins = exports.parseToolCalls = exports.MemoryManager = exports.SessionManager = exports.buildRepoMap = exports.ContextManager = exports.ToolRegistry = exports.AnthropicProvider = exports.OpenAIProvider = exports.Agent = exports.VERSION = void 0;
18
+ exports.VERSION = '2.0.0';
18
19
  var agent_1 = require("./agent");
19
20
  Object.defineProperty(exports, "Agent", { enumerable: true, get: function () { return agent_1.Agent; } });
20
21
  var openai_1 = require("./providers/openai");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebot-ai",
3
- "version": "1.9.0",
3
+ "version": "2.0.0",
4
4
  "description": "Zero-dependency autonomous AI agent. Code, browse, search, automate. Works with any LLM — Ollama, Claude, GPT, Gemini, DeepSeek, Groq, Mistral, Grok.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",