@neetru/cli 2.13.0 → 2.14.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/CHANGELOG.md +20 -0
- package/dist/commands/autocomplete.d.ts +1 -1
- package/dist/commands/autocomplete.js +35 -34
- package/dist/commands/autocomplete.js.map +1 -1
- package/dist/commands/code.d.ts +48 -0
- package/dist/commands/code.js +433 -0
- package/dist/commands/code.js.map +1 -0
- package/dist/commands/deploy.d.ts +10 -0
- package/dist/commands/deploy.js +22 -4
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/ui.d.ts +1 -1
- package/dist/commands/ui.js +9 -0
- package/dist/commands/ui.js.map +1 -1
- package/dist/index.js +28 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/ai/orchestrator.js +6 -1
- package/dist/lib/ai/orchestrator.js.map +1 -1
- package/dist/lib/api-client.d.ts +1 -0
- package/dist/lib/api-client.js +4 -3
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/code-agent-files.d.ts +9 -0
- package/dist/lib/code-agent-files.js +213 -0
- package/dist/lib/code-agent-files.js.map +1 -0
- package/dist/lib/code-agent-protocol.d.ts +16 -0
- package/dist/lib/code-agent-protocol.js +34 -0
- package/dist/lib/code-agent-protocol.js.map +1 -0
- package/dist/lib/code-agent-settings.d.ts +20 -0
- package/dist/lib/code-agent-settings.js +38 -0
- package/dist/lib/code-agent-settings.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
const DEFAULT_IGNORES = new Set([
|
|
5
|
+
'.git',
|
|
6
|
+
'.hg',
|
|
7
|
+
'.svn',
|
|
8
|
+
'node_modules',
|
|
9
|
+
'.next',
|
|
10
|
+
'dist',
|
|
11
|
+
'build',
|
|
12
|
+
'coverage',
|
|
13
|
+
'.turbo',
|
|
14
|
+
]);
|
|
15
|
+
const MAX_FILE_BYTES = 250_000;
|
|
16
|
+
const MAX_FILE_CHARS = 40_000;
|
|
17
|
+
const MAX_LIST_FILES = 300;
|
|
18
|
+
const MAX_SEARCH_MATCHES = 80;
|
|
19
|
+
function normalizeForCompare(value) {
|
|
20
|
+
return process.platform === 'win32' ? value.toLowerCase() : value;
|
|
21
|
+
}
|
|
22
|
+
function isInside(root, target) {
|
|
23
|
+
const rootCmp = normalizeForCompare(root);
|
|
24
|
+
const targetCmp = normalizeForCompare(target);
|
|
25
|
+
return targetCmp === rootCmp || targetCmp.startsWith(`${rootCmp}${path.sep}`);
|
|
26
|
+
}
|
|
27
|
+
export function resolveInside(rootDir, inputPath) {
|
|
28
|
+
const root = path.resolve(rootDir);
|
|
29
|
+
const resolved = path.resolve(root, inputPath);
|
|
30
|
+
if (!isInside(root, resolved)) {
|
|
31
|
+
throw new Error(`Path fora do cwd: ${inputPath}`);
|
|
32
|
+
}
|
|
33
|
+
// Contenção lexical nao basta: um symlink/junction DENTRO do cwd pode
|
|
34
|
+
// apontar pra fora (ex: `leak -> ~/.config/neetru-cli/auth.json`) e vazar
|
|
35
|
+
// pro contexto do gateway. Resolve o path real e reconfirma a contencao —
|
|
36
|
+
// só roda se o arquivo existir (achado do Codex review 2026-07-09).
|
|
37
|
+
if (fs.existsSync(resolved)) {
|
|
38
|
+
const realRoot = fs.realpathSync(root);
|
|
39
|
+
const realResolved = fs.realpathSync(resolved);
|
|
40
|
+
if (!isInside(realRoot, realResolved)) {
|
|
41
|
+
throw new Error(`Path fora do cwd (symlink aponta pra fora): ${inputPath}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return resolved;
|
|
45
|
+
}
|
|
46
|
+
function toRelative(rootDir, fullPath) {
|
|
47
|
+
return path.relative(path.resolve(rootDir), fullPath).replace(/\\/g, '/');
|
|
48
|
+
}
|
|
49
|
+
// Arquivos que tipicamente carregam segredo bruto — bloqueados mesmo dentro
|
|
50
|
+
// do cwd. Path injection pelo modelo (README/issue com NEETRU_TOOL embutido)
|
|
51
|
+
// nao consegue fazer a IA ler .env/chave/credencial e mandar de volta pro
|
|
52
|
+
// gateway (achado do Codex review 2026-07-09).
|
|
53
|
+
const SECRET_PATH_PATTERN = /(^|[\\/])(\.env(\..+)?|[^\\/]+\.(pem|key|pfx|p12)|id_rsa\w*|id_ed25519\w*|credentials\.json|service[-_]?account.*\.json)$/i;
|
|
54
|
+
function isSecretPath(relativePath) {
|
|
55
|
+
return SECRET_PATH_PATTERN.test(relativePath);
|
|
56
|
+
}
|
|
57
|
+
// Redação defense-in-depth: mesmo em arquivos "normais", uma linha com cara
|
|
58
|
+
// de segredo hardcoded nao vai pro contexto do gateway em texto claro.
|
|
59
|
+
const SECRET_LINE_PATTERN = /((?:api[_-]?key|secret|token|password|passwd)\s*[:=]\s*['"]?)([A-Za-z0-9_\-.\/+]{12,})/gi;
|
|
60
|
+
function redactSecrets(content) {
|
|
61
|
+
return content.replace(SECRET_LINE_PATTERN, '$1[REDACTED]');
|
|
62
|
+
}
|
|
63
|
+
export function readFileContext(rootDir, inputPath) {
|
|
64
|
+
const fullPath = resolveInside(rootDir, inputPath);
|
|
65
|
+
const relative = toRelative(rootDir, fullPath);
|
|
66
|
+
if (isSecretPath(relative)) {
|
|
67
|
+
throw new Error(`Leitura bloqueada: "${relative}" parece conter segredo (.env/chave/credencial). ` +
|
|
68
|
+
'Cole o trecho necessario manualmente se precisar que a IA veja.');
|
|
69
|
+
}
|
|
70
|
+
const stat = fs.statSync(fullPath);
|
|
71
|
+
if (!stat.isFile())
|
|
72
|
+
throw new Error(`Nao e arquivo: ${inputPath}`);
|
|
73
|
+
if (stat.size > MAX_FILE_BYTES) {
|
|
74
|
+
throw new Error(`Arquivo muito grande para contexto: ${inputPath} (${stat.size} bytes)`);
|
|
75
|
+
}
|
|
76
|
+
const content = redactSecrets(fs.readFileSync(fullPath, 'utf8'));
|
|
77
|
+
const clipped = content.length > MAX_FILE_CHARS
|
|
78
|
+
? `${content.slice(0, MAX_FILE_CHARS)}\n\n[TRUNCADO: arquivo maior que ${MAX_FILE_CHARS} chars]`
|
|
79
|
+
: content;
|
|
80
|
+
return `--- ${relative} ---\n${clipped}`;
|
|
81
|
+
}
|
|
82
|
+
function walkFiles(rootDir) {
|
|
83
|
+
const out = [];
|
|
84
|
+
function walk(dir) {
|
|
85
|
+
if (out.length >= MAX_LIST_FILES)
|
|
86
|
+
return;
|
|
87
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
88
|
+
if (DEFAULT_IGNORES.has(entry.name))
|
|
89
|
+
continue;
|
|
90
|
+
const full = path.join(dir, entry.name);
|
|
91
|
+
if (entry.isDirectory()) {
|
|
92
|
+
walk(full);
|
|
93
|
+
}
|
|
94
|
+
else if (entry.isFile()) {
|
|
95
|
+
out.push(toRelative(rootDir, full));
|
|
96
|
+
}
|
|
97
|
+
if (out.length >= MAX_LIST_FILES)
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
walk(path.resolve(rootDir));
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
export function listFiles(rootDir, pattern = '') {
|
|
105
|
+
const git = spawnSync('git', ['ls-files'], { cwd: rootDir, encoding: 'utf8' });
|
|
106
|
+
let files = git.status === 0
|
|
107
|
+
? git.stdout.split(/\r?\n/).filter(Boolean)
|
|
108
|
+
: walkFiles(rootDir);
|
|
109
|
+
const needle = pattern.trim().toLowerCase();
|
|
110
|
+
if (needle)
|
|
111
|
+
files = files.filter((file) => file.toLowerCase().includes(needle));
|
|
112
|
+
return files.slice(0, MAX_LIST_FILES);
|
|
113
|
+
}
|
|
114
|
+
export function searchFiles(rootDir, query) {
|
|
115
|
+
const needle = query;
|
|
116
|
+
if (!needle)
|
|
117
|
+
return [];
|
|
118
|
+
const matches = [];
|
|
119
|
+
for (const file of listFiles(rootDir)) {
|
|
120
|
+
if (matches.length >= MAX_SEARCH_MATCHES)
|
|
121
|
+
break;
|
|
122
|
+
if (isSecretPath(file))
|
|
123
|
+
continue;
|
|
124
|
+
try {
|
|
125
|
+
const full = resolveInside(rootDir, file);
|
|
126
|
+
const stat = fs.statSync(full);
|
|
127
|
+
if (!stat.isFile() || stat.size > MAX_FILE_BYTES)
|
|
128
|
+
continue;
|
|
129
|
+
const lines = redactSecrets(fs.readFileSync(full, 'utf8')).split(/\r?\n/);
|
|
130
|
+
for (let i = 0; i < lines.length; i++) {
|
|
131
|
+
if (lines[i].includes(needle)) {
|
|
132
|
+
matches.push(`${file}:${i + 1}: ${lines[i].slice(0, 240)}`);
|
|
133
|
+
if (matches.length >= MAX_SEARCH_MATCHES)
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return matches;
|
|
143
|
+
}
|
|
144
|
+
export function runCodeTool(rootDir, request) {
|
|
145
|
+
try {
|
|
146
|
+
if (request.tool === 'read_file') {
|
|
147
|
+
if (typeof request.path !== 'string' || !request.path.trim()) {
|
|
148
|
+
return 'ERRO: read_file exige path string.';
|
|
149
|
+
}
|
|
150
|
+
return readFileContext(rootDir, request.path);
|
|
151
|
+
}
|
|
152
|
+
if (request.tool === 'list_files') {
|
|
153
|
+
const pattern = typeof request.pattern === 'string' ? request.pattern : '';
|
|
154
|
+
return listFiles(rootDir, pattern).join('\n') || '(nenhum arquivo encontrado)';
|
|
155
|
+
}
|
|
156
|
+
if (request.tool === 'search') {
|
|
157
|
+
if (typeof request.query !== 'string' || !request.query) {
|
|
158
|
+
return 'ERRO: search exige query string.';
|
|
159
|
+
}
|
|
160
|
+
return searchFiles(rootDir, request.query).join('\n') || '(nenhuma ocorrencia encontrada)';
|
|
161
|
+
}
|
|
162
|
+
if (request.tool === 'invalid')
|
|
163
|
+
return `ERRO: ${request.error ?? 'tool invalida'}`;
|
|
164
|
+
return `ERRO: tool desconhecida: ${request.tool}`;
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
return `ERRO: ${error instanceof Error ? error.message : String(error)}`;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const ANSI_GREEN = '\x1B[32m';
|
|
171
|
+
const ANSI_RED = '\x1B[31m';
|
|
172
|
+
const ANSI_CYAN = '\x1B[36m';
|
|
173
|
+
const ANSI_DIM = '\x1B[2m';
|
|
174
|
+
const ANSI_RESET = '\x1B[0m';
|
|
175
|
+
function colorDiffLine(line) {
|
|
176
|
+
if (line.startsWith('+++') || line.startsWith('---'))
|
|
177
|
+
return `${ANSI_DIM}${line}${ANSI_RESET}`;
|
|
178
|
+
if (line.startsWith('+'))
|
|
179
|
+
return `${ANSI_GREEN}${line}${ANSI_RESET}`;
|
|
180
|
+
if (line.startsWith('-'))
|
|
181
|
+
return `${ANSI_RED}${line}${ANSI_RESET}`;
|
|
182
|
+
if (line.startsWith('@@'))
|
|
183
|
+
return `${ANSI_CYAN}${line}${ANSI_RESET}`;
|
|
184
|
+
if (line.startsWith('diff --git') || line.startsWith('index '))
|
|
185
|
+
return `${ANSI_DIM}${line}${ANSI_RESET}`;
|
|
186
|
+
return line;
|
|
187
|
+
}
|
|
188
|
+
/** Colore um unified diff linha a linha: `+` verde, `-` vermelho, `@@`/headers dim/cyan. */
|
|
189
|
+
export function renderColoredDiff(patch) {
|
|
190
|
+
return patch
|
|
191
|
+
.split('\n')
|
|
192
|
+
.map(colorDiffLine)
|
|
193
|
+
.join('\n');
|
|
194
|
+
}
|
|
195
|
+
export function applyUnifiedPatch(rootDir, patch) {
|
|
196
|
+
const check = spawnSync('git', ['apply', '--check', '-'], {
|
|
197
|
+
cwd: rootDir,
|
|
198
|
+
input: patch,
|
|
199
|
+
encoding: 'utf8',
|
|
200
|
+
});
|
|
201
|
+
if (check.status !== 0) {
|
|
202
|
+
throw new Error((check.stderr || check.stdout || 'git apply --check falhou').trim());
|
|
203
|
+
}
|
|
204
|
+
const apply = spawnSync('git', ['apply', '-'], {
|
|
205
|
+
cwd: rootDir,
|
|
206
|
+
input: patch,
|
|
207
|
+
encoding: 'utf8',
|
|
208
|
+
});
|
|
209
|
+
if (apply.status !== 0) {
|
|
210
|
+
throw new Error((apply.stderr || apply.stdout || 'git apply falhou').trim());
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=code-agent-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-agent-files.js","sourceRoot":"","sources":["../../src/lib/code-agent-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface CodeToolRequest {
|
|
2
|
+
tool: string;
|
|
3
|
+
path?: unknown;
|
|
4
|
+
pattern?: unknown;
|
|
5
|
+
query?: unknown;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function parseToolRequest(text: string): CodeToolRequest | null;
|
|
9
|
+
/**
|
|
10
|
+
* So aceita o bloco explicito `NEETRU_PATCH ... NEETRU_END` do protocolo —
|
|
11
|
+
* SEM fallback pra diff em bloco fenced ou texto solto. Um diff meramente
|
|
12
|
+
* citado (ex: injetado via README/issue) nao pode ser confundido com uma
|
|
13
|
+
* instrucao real de patch, especialmente com `--yes` (achado do Codex
|
|
14
|
+
* review 2026-07-09).
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractPatch(text: string): string | null;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function parseToolRequest(text) {
|
|
2
|
+
for (const line of String(text || '').split(/\r?\n/)) {
|
|
3
|
+
const idx = line.indexOf('NEETRU_TOOL');
|
|
4
|
+
if (idx === -1)
|
|
5
|
+
continue;
|
|
6
|
+
const raw = line.slice(idx + 'NEETRU_TOOL'.length).trim();
|
|
7
|
+
if (!raw)
|
|
8
|
+
continue;
|
|
9
|
+
try {
|
|
10
|
+
const parsed = JSON.parse(raw);
|
|
11
|
+
if (parsed && typeof parsed === 'object' && typeof parsed.tool === 'string') {
|
|
12
|
+
return parsed;
|
|
13
|
+
}
|
|
14
|
+
return { tool: 'invalid', error: `NEETRU_TOOL precisa conter {"tool":"..."}` };
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return { tool: 'invalid', error: `JSON invalido em NEETRU_TOOL: ${raw}` };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* So aceita o bloco explicito `NEETRU_PATCH ... NEETRU_END` do protocolo —
|
|
24
|
+
* SEM fallback pra diff em bloco fenced ou texto solto. Um diff meramente
|
|
25
|
+
* citado (ex: injetado via README/issue) nao pode ser confundido com uma
|
|
26
|
+
* instrucao real de patch, especialmente com `--yes` (achado do Codex
|
|
27
|
+
* review 2026-07-09).
|
|
28
|
+
*/
|
|
29
|
+
export function extractPatch(text) {
|
|
30
|
+
const source = String(text || '');
|
|
31
|
+
const marker = source.match(/NEETRU_PATCH\s*([\s\S]*?)\s*NEETRU_END/);
|
|
32
|
+
return marker?.[1] ? `${marker[1].trim()}\n` : null;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=code-agent-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-agent-protocol.js","sourceRoot":"","sources":["../../src/lib/code-agent-protocol.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACxC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,SAAS;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,IAAI,CAAC,GAAG;YAAE,SAAS;QAEnB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;YAC1C,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAQ,MAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACpG,OAAO,MAAyB,CAAC;YACnC,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,2CAA2C,EAAE,CAAC;QACjF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,iCAAiC,GAAG,EAAE,EAAE,CAAC;QAC5E,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;IACtE,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const DEFAULT_CODE_MODEL = "llama-3.3-70b-versatile";
|
|
2
|
+
export declare const DEFAULT_CODE_MAX_TURNS = 8;
|
|
3
|
+
export declare const DEFAULT_CODE_MAX_TOKENS = 4096;
|
|
4
|
+
export declare const DEFAULT_CODE_TEMPERATURE = 0.2;
|
|
5
|
+
export interface ResolveCodeModelInput {
|
|
6
|
+
cliModel?: string;
|
|
7
|
+
envModel?: string;
|
|
8
|
+
configuredGatewayModel?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ResolvedCodeModel {
|
|
11
|
+
model: string;
|
|
12
|
+
warning?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function isAnthropicModel(model: string | undefined): boolean;
|
|
15
|
+
export declare function resolveCodeModel(input: ResolveCodeModelInput): ResolvedCodeModel;
|
|
16
|
+
export declare function parseBoundedNumber(value: unknown, fallback: number, limits: {
|
|
17
|
+
min: number;
|
|
18
|
+
max: number;
|
|
19
|
+
integer?: boolean;
|
|
20
|
+
}): number;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const DEFAULT_CODE_MODEL = 'llama-3.3-70b-versatile';
|
|
2
|
+
export const DEFAULT_CODE_MAX_TURNS = 8;
|
|
3
|
+
export const DEFAULT_CODE_MAX_TOKENS = 4096;
|
|
4
|
+
export const DEFAULT_CODE_TEMPERATURE = 0.2;
|
|
5
|
+
export function isAnthropicModel(model) {
|
|
6
|
+
if (!model)
|
|
7
|
+
return false;
|
|
8
|
+
return /(^|\/)(claude-|anthropic)/i.test(model) || /claude/i.test(model);
|
|
9
|
+
}
|
|
10
|
+
function firstNonEmpty(...values) {
|
|
11
|
+
return values.find((value) => typeof value === 'string' && value.trim().length > 0)?.trim();
|
|
12
|
+
}
|
|
13
|
+
export function resolveCodeModel(input) {
|
|
14
|
+
const explicit = firstNonEmpty(input.cliModel, input.envModel);
|
|
15
|
+
if (explicit)
|
|
16
|
+
return { model: explicit };
|
|
17
|
+
const configured = firstNonEmpty(input.configuredGatewayModel);
|
|
18
|
+
if (configured && !isAnthropicModel(configured))
|
|
19
|
+
return { model: configured };
|
|
20
|
+
if (configured && isAnthropicModel(configured)) {
|
|
21
|
+
return {
|
|
22
|
+
model: DEFAULT_CODE_MODEL,
|
|
23
|
+
warning: `gatewayModel local esta apontando para "${configured}"; ` +
|
|
24
|
+
`neetru code usara ${DEFAULT_CODE_MODEL} por padrao para ficar no caminho Groq/NVIDIA.`,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return { model: DEFAULT_CODE_MODEL };
|
|
28
|
+
}
|
|
29
|
+
export function parseBoundedNumber(value, fallback, limits) {
|
|
30
|
+
if (value === undefined || value === null || value === '')
|
|
31
|
+
return fallback;
|
|
32
|
+
const n = Number(value);
|
|
33
|
+
if (!Number.isFinite(n))
|
|
34
|
+
return fallback;
|
|
35
|
+
const bounded = Math.min(limits.max, Math.max(limits.min, n));
|
|
36
|
+
return limits.integer ? Math.floor(bounded) : bounded;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=code-agent-settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-agent-settings.js","sourceRoot":"","sources":["../../src/lib/code-agent-settings.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG,yBAAyB,CAAC;AAC5D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACxC,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAC5C,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAa5C,MAAM,UAAU,gBAAgB,CAAC,KAAyB;IACxD,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,OAAO,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,aAAa,CAAC,GAAG,MAAiC;IACzD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;AAC9F,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IAC3D,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/D,IAAI,QAAQ;QAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAEzC,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC/D,IAAI,UAAU,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAE9E,IAAI,UAAU,IAAI,gBAAgB,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/C,OAAO;YACL,KAAK,EAAE,kBAAkB;YACzB,OAAO,EACL,2CAA2C,UAAU,KAAK;gBAC1D,qBAAqB,kBAAkB,gDAAgD;SAC1F,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,KAAc,EACd,QAAgB,EAChB,MAAuD;IAEvD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IAC3E,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9D,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AACxD,CAAC"}
|
package/package.json
CHANGED