codebot-ai 1.6.0 → 1.8.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/dist/agent.d.ts +22 -0
- package/dist/agent.js +138 -5
- package/dist/audit.d.ts +31 -9
- package/dist/audit.js +85 -11
- package/dist/capabilities.d.ts +48 -0
- package/dist/capabilities.js +187 -0
- package/dist/cli.js +265 -26
- package/dist/history.d.ts +7 -3
- package/dist/history.js +55 -8
- package/dist/index.d.ts +6 -0
- package/dist/index.js +13 -1
- package/dist/integrity.d.ts +35 -0
- package/dist/integrity.js +135 -0
- package/dist/policy.d.ts +132 -0
- package/dist/policy.js +444 -0
- package/dist/providers/anthropic.d.ts +1 -0
- package/dist/providers/anthropic.js +4 -0
- package/dist/providers/openai.d.ts +1 -0
- package/dist/providers/openai.js +4 -0
- package/dist/replay.d.ts +55 -0
- package/dist/replay.js +196 -0
- package/dist/sandbox.d.ts +65 -0
- package/dist/sandbox.js +214 -0
- package/dist/telemetry.d.ts +73 -0
- package/dist/telemetry.js +286 -0
- package/dist/tools/batch-edit.d.ts +3 -0
- package/dist/tools/batch-edit.js +12 -0
- package/dist/tools/edit.d.ts +3 -0
- package/dist/tools/edit.js +11 -0
- package/dist/tools/execute.js +29 -4
- package/dist/tools/git.d.ts +5 -0
- package/dist/tools/git.js +31 -0
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.js +6 -6
- package/dist/tools/write.d.ts +3 -0
- package/dist/tools/write.js +11 -0
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
package/dist/policy.js
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Policy Engine for CodeBot v1.7.0
|
|
4
|
+
*
|
|
5
|
+
* Loads, validates, and enforces declarative security policies.
|
|
6
|
+
* Policy files: .codebot/policy.json (project) + ~/.codebot/policy.json (global)
|
|
7
|
+
* Project policy overrides global policy where specified.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.PolicyEnforcer = exports.DEFAULT_POLICY = void 0;
|
|
44
|
+
exports.loadPolicy = loadPolicy;
|
|
45
|
+
exports.generateDefaultPolicyFile = generateDefaultPolicyFile;
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const os = __importStar(require("os"));
|
|
49
|
+
const capabilities_1 = require("./capabilities");
|
|
50
|
+
// ── Default Policy ──
|
|
51
|
+
exports.DEFAULT_POLICY = {
|
|
52
|
+
version: '1.0',
|
|
53
|
+
execution: {
|
|
54
|
+
sandbox: 'auto',
|
|
55
|
+
network: false, // safe default: no network in sandbox
|
|
56
|
+
timeout_seconds: 120,
|
|
57
|
+
max_memory_mb: 512,
|
|
58
|
+
},
|
|
59
|
+
filesystem: {
|
|
60
|
+
writable_paths: [], // empty = all project paths allowed
|
|
61
|
+
read_only_paths: [],
|
|
62
|
+
denied_paths: ['.env', '.env.local', '.env.production'],
|
|
63
|
+
allow_outside_project: false,
|
|
64
|
+
},
|
|
65
|
+
tools: {
|
|
66
|
+
enabled: [], // empty = all tools enabled
|
|
67
|
+
disabled: [],
|
|
68
|
+
permissions: {},
|
|
69
|
+
},
|
|
70
|
+
secrets: {
|
|
71
|
+
block_on_detect: true, // safe default: block writes containing secrets
|
|
72
|
+
scan_on_write: true,
|
|
73
|
+
allowed_patterns: [],
|
|
74
|
+
},
|
|
75
|
+
git: {
|
|
76
|
+
always_branch: true, // safe default: auto-branch on first write
|
|
77
|
+
branch_prefix: 'codebot/',
|
|
78
|
+
require_tests_before_commit: false,
|
|
79
|
+
never_push_main: true,
|
|
80
|
+
},
|
|
81
|
+
mcp: {
|
|
82
|
+
allowed_servers: [], // empty = all allowed
|
|
83
|
+
blocked_servers: [],
|
|
84
|
+
},
|
|
85
|
+
limits: {
|
|
86
|
+
max_iterations: 50,
|
|
87
|
+
max_file_size_kb: 500,
|
|
88
|
+
max_files_per_operation: 20,
|
|
89
|
+
cost_limit_usd: 0, // 0 = no limit
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
// ── Policy Loader ──
|
|
93
|
+
/**
|
|
94
|
+
* Load and merge policies from project + global locations.
|
|
95
|
+
* Project policy overrides global where specified.
|
|
96
|
+
*/
|
|
97
|
+
function loadPolicy(projectRoot) {
|
|
98
|
+
const root = projectRoot || process.cwd();
|
|
99
|
+
// Load global policy
|
|
100
|
+
const globalPath = path.join(os.homedir(), '.codebot', 'policy.json');
|
|
101
|
+
const globalPolicy = loadPolicyFile(globalPath);
|
|
102
|
+
// Load project policy
|
|
103
|
+
const projectPath = path.join(root, '.codebot', 'policy.json');
|
|
104
|
+
const projectPolicy = loadPolicyFile(projectPath);
|
|
105
|
+
// Merge: defaults ← global ← project (project wins)
|
|
106
|
+
return mergePolicies(exports.DEFAULT_POLICY, globalPolicy, projectPolicy);
|
|
107
|
+
}
|
|
108
|
+
function loadPolicyFile(filePath) {
|
|
109
|
+
try {
|
|
110
|
+
if (!fs.existsSync(filePath))
|
|
111
|
+
return null;
|
|
112
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
113
|
+
const parsed = JSON.parse(content);
|
|
114
|
+
if (!validatePolicy(parsed))
|
|
115
|
+
return null;
|
|
116
|
+
return parsed;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Basic validation — ensures the policy file has a recognizable shape.
|
|
124
|
+
* Does NOT throw — returns false for invalid policies (fail-open with defaults).
|
|
125
|
+
*/
|
|
126
|
+
function validatePolicy(obj) {
|
|
127
|
+
if (!obj || typeof obj !== 'object')
|
|
128
|
+
return false;
|
|
129
|
+
const p = obj;
|
|
130
|
+
// Version check
|
|
131
|
+
if (p.version !== undefined && typeof p.version !== 'string')
|
|
132
|
+
return false;
|
|
133
|
+
// Type check each section
|
|
134
|
+
if (p.execution !== undefined && typeof p.execution !== 'object')
|
|
135
|
+
return false;
|
|
136
|
+
if (p.filesystem !== undefined && typeof p.filesystem !== 'object')
|
|
137
|
+
return false;
|
|
138
|
+
if (p.tools !== undefined && typeof p.tools !== 'object')
|
|
139
|
+
return false;
|
|
140
|
+
if (p.secrets !== undefined && typeof p.secrets !== 'object')
|
|
141
|
+
return false;
|
|
142
|
+
if (p.git !== undefined && typeof p.git !== 'object')
|
|
143
|
+
return false;
|
|
144
|
+
if (p.mcp !== undefined && typeof p.mcp !== 'object')
|
|
145
|
+
return false;
|
|
146
|
+
if (p.limits !== undefined && typeof p.limits !== 'object')
|
|
147
|
+
return false;
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Deep merge policies. Later arguments override earlier ones.
|
|
152
|
+
* Only defined keys in higher-priority policies override lower ones.
|
|
153
|
+
*/
|
|
154
|
+
function mergePolicies(...policies) {
|
|
155
|
+
const result = {};
|
|
156
|
+
for (const policy of policies) {
|
|
157
|
+
if (!policy)
|
|
158
|
+
continue;
|
|
159
|
+
for (const [key, value] of Object.entries(policy)) {
|
|
160
|
+
if (value === undefined || value === null)
|
|
161
|
+
continue;
|
|
162
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
163
|
+
// Deep merge objects
|
|
164
|
+
result[key] = { ...(result[key] || {}), ...value };
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
result[key] = value;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
// ── Policy Enforcer ──
|
|
174
|
+
class PolicyEnforcer {
|
|
175
|
+
policy;
|
|
176
|
+
projectRoot;
|
|
177
|
+
constructor(policy, projectRoot) {
|
|
178
|
+
this.policy = policy || loadPolicy(projectRoot);
|
|
179
|
+
this.projectRoot = projectRoot || process.cwd();
|
|
180
|
+
}
|
|
181
|
+
getPolicy() {
|
|
182
|
+
return this.policy;
|
|
183
|
+
}
|
|
184
|
+
// ── Tool Access ──
|
|
185
|
+
/** Check if a tool is enabled by policy. Returns { allowed, reason }. */
|
|
186
|
+
isToolAllowed(toolName) {
|
|
187
|
+
const tools = this.policy.tools;
|
|
188
|
+
if (!tools)
|
|
189
|
+
return { allowed: true };
|
|
190
|
+
// If explicit disabled list contains it, block
|
|
191
|
+
if (tools.disabled && tools.disabled.length > 0) {
|
|
192
|
+
if (tools.disabled.includes(toolName)) {
|
|
193
|
+
return { allowed: false, reason: `Tool "${toolName}" is disabled by policy` };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// If explicit enabled list exists and is non-empty, only those tools are allowed
|
|
197
|
+
if (tools.enabled && tools.enabled.length > 0) {
|
|
198
|
+
if (!tools.enabled.includes(toolName)) {
|
|
199
|
+
return { allowed: false, reason: `Tool "${toolName}" is not in the enabled tools list` };
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return { allowed: true };
|
|
203
|
+
}
|
|
204
|
+
/** Get the permission level for a tool (policy override or null for default). */
|
|
205
|
+
getToolPermission(toolName) {
|
|
206
|
+
return this.policy.tools?.permissions?.[toolName] || null;
|
|
207
|
+
}
|
|
208
|
+
// ── Filesystem Access ──
|
|
209
|
+
/** Check if a path is writable according to policy. */
|
|
210
|
+
isPathWritable(filePath) {
|
|
211
|
+
const fs_policy = this.policy.filesystem;
|
|
212
|
+
if (!fs_policy)
|
|
213
|
+
return { allowed: true };
|
|
214
|
+
const resolved = path.resolve(filePath);
|
|
215
|
+
const relative = path.relative(this.projectRoot, resolved);
|
|
216
|
+
// Check denied paths first (highest priority)
|
|
217
|
+
if (fs_policy.denied_paths && fs_policy.denied_paths.length > 0) {
|
|
218
|
+
for (const denied of fs_policy.denied_paths) {
|
|
219
|
+
const deniedResolved = path.resolve(this.projectRoot, denied);
|
|
220
|
+
if (resolved === deniedResolved || resolved.startsWith(deniedResolved + path.sep)) {
|
|
221
|
+
return { allowed: false, reason: `Path "${relative}" is denied by policy` };
|
|
222
|
+
}
|
|
223
|
+
// Also check as a glob-like prefix
|
|
224
|
+
if (this.matchesPattern(relative, denied)) {
|
|
225
|
+
return { allowed: false, reason: `Path "${relative}" matches denied pattern "${denied}"` };
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Check read-only paths
|
|
230
|
+
if (fs_policy.read_only_paths && fs_policy.read_only_paths.length > 0) {
|
|
231
|
+
for (const ro of fs_policy.read_only_paths) {
|
|
232
|
+
const roResolved = path.resolve(this.projectRoot, ro);
|
|
233
|
+
if (resolved === roResolved || resolved.startsWith(roResolved + path.sep)) {
|
|
234
|
+
return { allowed: false, reason: `Path "${relative}" is read-only by policy` };
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// Check writable paths (if specified, only these are writable)
|
|
239
|
+
if (fs_policy.writable_paths && fs_policy.writable_paths.length > 0) {
|
|
240
|
+
let matched = false;
|
|
241
|
+
for (const wp of fs_policy.writable_paths) {
|
|
242
|
+
const wpResolved = path.resolve(this.projectRoot, wp);
|
|
243
|
+
if (resolved === wpResolved || resolved.startsWith(wpResolved + path.sep)) {
|
|
244
|
+
matched = true;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
if (this.matchesPattern(relative, wp)) {
|
|
248
|
+
matched = true;
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (!matched) {
|
|
253
|
+
return { allowed: false, reason: `Path "${relative}" is not in the writable paths list` };
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return { allowed: true };
|
|
257
|
+
}
|
|
258
|
+
// ── Execution Policy ──
|
|
259
|
+
/** Get sandbox mode. */
|
|
260
|
+
getSandboxMode() {
|
|
261
|
+
return this.policy.execution?.sandbox || 'auto';
|
|
262
|
+
}
|
|
263
|
+
/** Check if network is allowed for executed commands. */
|
|
264
|
+
isNetworkAllowed() {
|
|
265
|
+
return this.policy.execution?.network !== false;
|
|
266
|
+
}
|
|
267
|
+
/** Get execution timeout in milliseconds. */
|
|
268
|
+
getTimeoutMs() {
|
|
269
|
+
const seconds = this.policy.execution?.timeout_seconds || 120;
|
|
270
|
+
return seconds * 1000;
|
|
271
|
+
}
|
|
272
|
+
/** Get max memory in MB for sandbox. */
|
|
273
|
+
getMaxMemoryMb() {
|
|
274
|
+
return this.policy.execution?.max_memory_mb || 512;
|
|
275
|
+
}
|
|
276
|
+
// ── Git Policy ──
|
|
277
|
+
/** Check if agent should always work on a branch. */
|
|
278
|
+
shouldAlwaysBranch() {
|
|
279
|
+
return this.policy.git?.always_branch === true;
|
|
280
|
+
}
|
|
281
|
+
/** Get branch prefix for auto-created branches. */
|
|
282
|
+
getBranchPrefix() {
|
|
283
|
+
return this.policy.git?.branch_prefix || 'codebot/';
|
|
284
|
+
}
|
|
285
|
+
/** Check if pushing to main/master is blocked. */
|
|
286
|
+
isMainPushBlocked() {
|
|
287
|
+
return this.policy.git?.never_push_main !== false; // default true
|
|
288
|
+
}
|
|
289
|
+
// ── Secrets Policy ──
|
|
290
|
+
/** Should secrets block writes (vs just warn)? */
|
|
291
|
+
shouldBlockSecrets() {
|
|
292
|
+
return this.policy.secrets?.block_on_detect === true;
|
|
293
|
+
}
|
|
294
|
+
/** Should scan for secrets on write? */
|
|
295
|
+
shouldScanSecrets() {
|
|
296
|
+
return this.policy.secrets?.scan_on_write !== false; // default true
|
|
297
|
+
}
|
|
298
|
+
// ── MCP Policy ──
|
|
299
|
+
/** Check if an MCP server is allowed. */
|
|
300
|
+
isMcpServerAllowed(serverName) {
|
|
301
|
+
const mcp = this.policy.mcp;
|
|
302
|
+
if (!mcp)
|
|
303
|
+
return { allowed: true };
|
|
304
|
+
// Blocked list takes priority
|
|
305
|
+
if (mcp.blocked_servers && mcp.blocked_servers.length > 0) {
|
|
306
|
+
if (mcp.blocked_servers.includes(serverName)) {
|
|
307
|
+
return { allowed: false, reason: `MCP server "${serverName}" is blocked by policy` };
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// If allowed list is non-empty, only those servers are allowed
|
|
311
|
+
if (mcp.allowed_servers && mcp.allowed_servers.length > 0) {
|
|
312
|
+
if (!mcp.allowed_servers.includes(serverName)) {
|
|
313
|
+
return { allowed: false, reason: `MCP server "${serverName}" is not in the allowed list` };
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return { allowed: true };
|
|
317
|
+
}
|
|
318
|
+
// ── Limits ──
|
|
319
|
+
/** Get max iterations for the agent loop. */
|
|
320
|
+
getMaxIterations() {
|
|
321
|
+
return this.policy.limits?.max_iterations || 50;
|
|
322
|
+
}
|
|
323
|
+
/** Get max file size in bytes for write operations. */
|
|
324
|
+
getMaxFileSizeBytes() {
|
|
325
|
+
return (this.policy.limits?.max_file_size_kb || 500) * 1024;
|
|
326
|
+
}
|
|
327
|
+
/** Get cost limit in USD (0 = no limit). */
|
|
328
|
+
getCostLimitUsd() {
|
|
329
|
+
return this.policy.limits?.cost_limit_usd || 0;
|
|
330
|
+
}
|
|
331
|
+
// ── Capabilities (v1.8.0) ──
|
|
332
|
+
/** Get capability restrictions for a tool. undefined = unrestricted. */
|
|
333
|
+
getToolCapabilities(toolName) {
|
|
334
|
+
return this.policy.tools?.capabilities?.[toolName];
|
|
335
|
+
}
|
|
336
|
+
/** Check a specific capability for a tool. Returns { allowed, reason }. */
|
|
337
|
+
checkCapability(toolName, capabilityType, value) {
|
|
338
|
+
const caps = this.policy.tools?.capabilities;
|
|
339
|
+
if (!caps)
|
|
340
|
+
return { allowed: true };
|
|
341
|
+
const checker = new capabilities_1.CapabilityChecker(caps, this.projectRoot);
|
|
342
|
+
return checker.checkCapability(toolName, capabilityType, value);
|
|
343
|
+
}
|
|
344
|
+
// ── Helpers ──
|
|
345
|
+
/**
|
|
346
|
+
* Simple glob-like pattern matching:
|
|
347
|
+
* - `*` matches any single path component
|
|
348
|
+
* - `**` matches any number of path components
|
|
349
|
+
* - `.env` matches exact filename
|
|
350
|
+
*/
|
|
351
|
+
matchesPattern(relativePath, pattern) {
|
|
352
|
+
// Exact match
|
|
353
|
+
if (relativePath === pattern)
|
|
354
|
+
return true;
|
|
355
|
+
// Simple prefix match (handles ./src, ./tests)
|
|
356
|
+
const cleanPattern = pattern.replace(/^\.\//, '');
|
|
357
|
+
const cleanPath = relativePath.replace(/^\.\//, '');
|
|
358
|
+
if (cleanPath === cleanPattern)
|
|
359
|
+
return true;
|
|
360
|
+
if (cleanPath.startsWith(cleanPattern + '/'))
|
|
361
|
+
return true;
|
|
362
|
+
if (cleanPath.startsWith(cleanPattern + path.sep))
|
|
363
|
+
return true;
|
|
364
|
+
// Basename match (handles .env, .env.local)
|
|
365
|
+
if (!pattern.includes('/') && !pattern.includes(path.sep)) {
|
|
366
|
+
if (path.basename(relativePath) === pattern)
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
369
|
+
// Glob-like: ** matches any depth
|
|
370
|
+
if (pattern.includes('**')) {
|
|
371
|
+
const regex = new RegExp('^' +
|
|
372
|
+
pattern
|
|
373
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
374
|
+
.replace(/\*\*/g, '.*')
|
|
375
|
+
.replace(/\*/g, '[^/]*') +
|
|
376
|
+
'$');
|
|
377
|
+
return regex.test(cleanPath);
|
|
378
|
+
}
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
exports.PolicyEnforcer = PolicyEnforcer;
|
|
383
|
+
/**
|
|
384
|
+
* Generate a default policy file content for `codebot --init-policy`.
|
|
385
|
+
*/
|
|
386
|
+
function generateDefaultPolicyFile() {
|
|
387
|
+
return JSON.stringify({
|
|
388
|
+
version: '1.0',
|
|
389
|
+
execution: {
|
|
390
|
+
sandbox: 'auto',
|
|
391
|
+
network: false,
|
|
392
|
+
timeout_seconds: 120,
|
|
393
|
+
max_memory_mb: 512,
|
|
394
|
+
},
|
|
395
|
+
filesystem: {
|
|
396
|
+
writable_paths: [],
|
|
397
|
+
read_only_paths: [],
|
|
398
|
+
denied_paths: ['.env', '.env.local', '.env.production'],
|
|
399
|
+
allow_outside_project: false,
|
|
400
|
+
},
|
|
401
|
+
tools: {
|
|
402
|
+
enabled: [],
|
|
403
|
+
disabled: [],
|
|
404
|
+
permissions: {
|
|
405
|
+
execute: 'always-ask',
|
|
406
|
+
write_file: 'prompt',
|
|
407
|
+
edit_file: 'prompt',
|
|
408
|
+
},
|
|
409
|
+
capabilities: {
|
|
410
|
+
execute: {
|
|
411
|
+
shell_commands: [
|
|
412
|
+
'npm', 'npx', 'node', 'git', 'tsc', 'eslint', 'prettier',
|
|
413
|
+
'jest', 'vitest', 'pytest', 'make', 'cargo', 'go', 'python',
|
|
414
|
+
'python3', 'ruby', 'php', 'java', 'javac', 'mvn', 'gradle',
|
|
415
|
+
'docker', 'ls', 'cat', 'head', 'tail', 'wc', 'sort', 'uniq',
|
|
416
|
+
'find', 'which', 'echo', 'pwd', 'env', 'date',
|
|
417
|
+
],
|
|
418
|
+
max_output_kb: 500,
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
},
|
|
422
|
+
secrets: {
|
|
423
|
+
block_on_detect: true,
|
|
424
|
+
scan_on_write: true,
|
|
425
|
+
},
|
|
426
|
+
git: {
|
|
427
|
+
always_branch: true,
|
|
428
|
+
branch_prefix: 'codebot/',
|
|
429
|
+
require_tests_before_commit: false,
|
|
430
|
+
never_push_main: true,
|
|
431
|
+
},
|
|
432
|
+
mcp: {
|
|
433
|
+
allowed_servers: [],
|
|
434
|
+
blocked_servers: [],
|
|
435
|
+
},
|
|
436
|
+
limits: {
|
|
437
|
+
max_iterations: 50,
|
|
438
|
+
max_file_size_kb: 500,
|
|
439
|
+
max_files_per_operation: 20,
|
|
440
|
+
cost_limit_usd: 0,
|
|
441
|
+
},
|
|
442
|
+
}, null, 2) + '\n';
|
|
443
|
+
}
|
|
444
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LLMProvider, Message, ToolSchema, StreamEvent, ProviderConfig } from '../types';
|
|
2
2
|
export declare class AnthropicProvider implements LLMProvider {
|
|
3
3
|
name: string;
|
|
4
|
+
temperature?: number;
|
|
4
5
|
private config;
|
|
5
6
|
constructor(config: ProviderConfig);
|
|
6
7
|
chat(messages: Message[], tools?: ToolSchema[]): AsyncGenerator<StreamEvent>;
|
|
@@ -4,6 +4,7 @@ exports.AnthropicProvider = void 0;
|
|
|
4
4
|
const retry_1 = require("../retry");
|
|
5
5
|
class AnthropicProvider {
|
|
6
6
|
name;
|
|
7
|
+
temperature;
|
|
7
8
|
config;
|
|
8
9
|
constructor(config) {
|
|
9
10
|
this.config = config;
|
|
@@ -22,6 +23,9 @@ class AnthropicProvider {
|
|
|
22
23
|
max_tokens: 8192,
|
|
23
24
|
stream: true,
|
|
24
25
|
};
|
|
26
|
+
if (this.temperature !== undefined) {
|
|
27
|
+
body.temperature = this.temperature;
|
|
28
|
+
}
|
|
25
29
|
if (systemPrompt) {
|
|
26
30
|
body.system = systemPrompt;
|
|
27
31
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LLMProvider, Message, ToolSchema, StreamEvent, ProviderConfig } from '../types';
|
|
2
2
|
export declare class OpenAIProvider implements LLMProvider {
|
|
3
3
|
name: string;
|
|
4
|
+
temperature?: number;
|
|
4
5
|
private config;
|
|
5
6
|
private supportsTools;
|
|
6
7
|
constructor(config: ProviderConfig);
|
package/dist/providers/openai.js
CHANGED
|
@@ -5,6 +5,7 @@ const registry_1 = require("./registry");
|
|
|
5
5
|
const retry_1 = require("../retry");
|
|
6
6
|
class OpenAIProvider {
|
|
7
7
|
name;
|
|
8
|
+
temperature;
|
|
8
9
|
config;
|
|
9
10
|
supportsTools;
|
|
10
11
|
constructor(config) {
|
|
@@ -25,6 +26,9 @@ class OpenAIProvider {
|
|
|
25
26
|
messages: messages.map(m => this.formatMessage(m)),
|
|
26
27
|
stream: true,
|
|
27
28
|
};
|
|
29
|
+
if (this.temperature !== undefined) {
|
|
30
|
+
body.temperature = this.temperature;
|
|
31
|
+
}
|
|
28
32
|
if (tools?.length && this.supportsTools) {
|
|
29
33
|
body.tools = tools;
|
|
30
34
|
}
|
package/dist/replay.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Replay Engine for CodeBot v1.8.0
|
|
3
|
+
*
|
|
4
|
+
* Replays saved sessions by feeding recorded assistant responses
|
|
5
|
+
* instead of calling the LLM. Tool calls are re-executed and outputs
|
|
6
|
+
* compared against recorded results to detect environment divergences.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* codebot --replay <session-id>
|
|
10
|
+
* codebot --replay (replays latest session)
|
|
11
|
+
*/
|
|
12
|
+
import { Message, LLMProvider, ToolSchema, StreamEvent } from './types';
|
|
13
|
+
/**
|
|
14
|
+
* Mock LLM provider that feeds recorded assistant messages.
|
|
15
|
+
* Used during replay to bypass actual LLM calls.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ReplayProvider implements LLMProvider {
|
|
18
|
+
name: string;
|
|
19
|
+
private assistantMessages;
|
|
20
|
+
private callIndex;
|
|
21
|
+
constructor(assistantMessages: Message[]);
|
|
22
|
+
chat(_messages: Message[], _tools?: ToolSchema[]): AsyncGenerator<StreamEvent>;
|
|
23
|
+
}
|
|
24
|
+
export interface SessionReplayData {
|
|
25
|
+
messages: Message[];
|
|
26
|
+
assistantMessages: Message[];
|
|
27
|
+
userMessages: Message[];
|
|
28
|
+
toolResults: Map<string, string>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Load a session from disk and prepare it for replay.
|
|
32
|
+
* Returns null if session doesn't exist or is empty.
|
|
33
|
+
*/
|
|
34
|
+
export declare function loadSessionForReplay(sessionId: string): SessionReplayData | null;
|
|
35
|
+
export interface ReplayDivergence {
|
|
36
|
+
toolCallId: string;
|
|
37
|
+
toolName: string;
|
|
38
|
+
type: 'output_mismatch';
|
|
39
|
+
diff: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Compare recorded vs actual tool output.
|
|
43
|
+
* Returns null if identical, or a diff description.
|
|
44
|
+
*/
|
|
45
|
+
export declare function compareOutputs(recorded: string, actual: string): string | null;
|
|
46
|
+
/**
|
|
47
|
+
* List sessions available for replay.
|
|
48
|
+
*/
|
|
49
|
+
export declare function listReplayableSessions(limit?: number): Array<{
|
|
50
|
+
id: string;
|
|
51
|
+
preview: string;
|
|
52
|
+
messageCount: number;
|
|
53
|
+
date: string;
|
|
54
|
+
}>;
|
|
55
|
+
//# sourceMappingURL=replay.d.ts.map
|