orquesta-cli 0.2.90 → 0.2.92

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/cli.js CHANGED
@@ -121,6 +121,7 @@ program
121
121
  .option('--dangerously-skip-permissions', 'Skip all permission prompts (auto-approve)')
122
122
  .option('--append-system-prompt <prompt>', 'Append text to the system prompt (parity with claude CLI; used by orquesta-agent sessions)')
123
123
  .option('--append-system-prompt-file <path>', 'Read the appended system prompt from a file (orquesta-agent uses this to keep a large ~38KB system prompt out of argv — Windows CreateProcess caps the command line at 32767 chars)')
124
+ .option('--endpoint <idOrName>', 'Use a specific configured LLM endpoint for this run (id or name; "batuta" = the managed Batuta endpoint). orquesta-agent passes this to honor a per-project provider choice without changing the org default.')
124
125
  .option('--verbose', 'Enable verbose logging')
125
126
  .option('--debug', 'Enable debug logging')
126
127
  .option('--llm-log', 'Enable LLM logging')
@@ -150,6 +151,20 @@ program
150
151
  if (options.appendSystemPrompt) {
151
152
  setAppendedSystemPrompt(options.appendSystemPrompt);
152
153
  }
154
+ if (options.endpoint) {
155
+ const wanted = String(options.endpoint).toLowerCase();
156
+ const all = configManager.getAllEndpoints();
157
+ const ep = wanted === 'batuta'
158
+ ? all.find((e) => e.id === 'batuta-proxy' || e.provider === 'batuta')
159
+ : all.find((e) => e.id === options.endpoint) ||
160
+ all.find((e) => (e.name || '').toLowerCase() === wanted);
161
+ if (ep) {
162
+ await configManager.setCurrentEndpoint(ep.id);
163
+ const m = ep.models.find((x) => x.enabled) || ep.models[0];
164
+ if (m)
165
+ await configManager.setCurrentModel(m.id);
166
+ }
167
+ }
153
168
  if (options.eval) {
154
169
  await runEvalMode();
155
170
  return;
@@ -65,10 +65,12 @@ export class ConfigManager {
65
65
  }
66
66
  getCurrentModel() {
67
67
  const endpoint = this.getCurrentEndpoint();
68
- if (!endpoint || !this.config?.currentModel) {
68
+ if (!endpoint)
69
69
  return null;
70
- }
71
- return endpoint.models.find((m) => m.id === this.config?.currentModel) || null;
70
+ const byId = endpoint.models.find((m) => m.id === this.config?.currentModel);
71
+ if (byId)
72
+ return byId;
73
+ return endpoint.models.find((m) => m.enabled) || endpoint.models[0] || null;
72
74
  }
73
75
  getAllEndpoints() {
74
76
  return this.getConfig().endpoints;
@@ -1,51 +1,85 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { logger } from '../utils/logger.js';
4
- const MAX_BYTES = 32_000;
5
- const CANDIDATE_PATHS = [
4
+ const PER_FILE_MAX_BYTES = 32_000;
5
+ const TOTAL_MAX_BYTES = 48_000;
6
+ const CANDIDATE_FILES = [
6
7
  'CLAUDE.md',
7
8
  '.claude/CLAUDE.md',
9
+ 'AGENTS.md',
8
10
  'AGENT.md',
9
11
  'agent.md',
12
+ 'GEMINI.md',
13
+ 'QWEN.md',
14
+ 'KIRO.md',
15
+ ];
16
+ const CANDIDATE_DIRS = [
17
+ '.kiro/steering',
10
18
  ];
11
19
  let cachedContext;
12
- function readFirstAvailable(cwd) {
13
- for (const rel of CANDIDATE_PATHS) {
20
+ function capFile(content) {
21
+ if (Buffer.byteLength(content, 'utf-8') > PER_FILE_MAX_BYTES) {
22
+ return content.slice(0, PER_FILE_MAX_BYTES) + '\n\n[...truncated for context window]';
23
+ }
24
+ return content;
25
+ }
26
+ function collectContextFiles(cwd) {
27
+ const out = [];
28
+ const seen = new Set();
29
+ const tryAdd = (rel) => {
14
30
  const abs = path.join(cwd, rel);
15
31
  try {
16
32
  const stat = fs.statSync(abs);
17
33
  if (!stat.isFile())
18
- continue;
19
- let content = fs.readFileSync(abs, 'utf-8');
20
- if (Buffer.byteLength(content, 'utf-8') > MAX_BYTES) {
21
- content = content.slice(0, MAX_BYTES) + '\n\n[...truncated for context window]';
22
- }
23
- return { path: rel, content };
34
+ return;
35
+ const content = capFile(fs.readFileSync(abs, 'utf-8'));
36
+ const key = content.trim();
37
+ if (!key || seen.has(key))
38
+ return;
39
+ seen.add(key);
40
+ out.push({ path: rel, content });
41
+ }
42
+ catch {
43
+ }
44
+ };
45
+ for (const rel of CANDIDATE_FILES)
46
+ tryAdd(rel);
47
+ for (const dir of CANDIDATE_DIRS) {
48
+ try {
49
+ const entries = fs.readdirSync(path.join(cwd, dir)).filter(f => f.toLowerCase().endsWith('.md')).sort();
50
+ for (const f of entries)
51
+ tryAdd(path.join(dir, f));
24
52
  }
25
53
  catch {
26
- continue;
27
54
  }
28
55
  }
29
- return null;
56
+ return out;
30
57
  }
31
58
  export function getProjectContext(cwd = process.cwd()) {
32
59
  if (cachedContext !== undefined)
33
60
  return cachedContext ?? '';
34
- const hit = readFirstAvailable(cwd);
35
- if (!hit) {
61
+ const files = collectContextFiles(cwd);
62
+ if (files.length === 0) {
36
63
  cachedContext = null;
37
- logger.debug('No CLAUDE.md / AGENT.md found in cwd', { cwd });
64
+ logger.debug('No agent-instruction files (CLAUDE.md / AGENTS.md / …) found in cwd', { cwd });
38
65
  return '';
39
66
  }
40
- logger.info(`Loaded project context from ${hit.path} (${hit.content.length} chars)`);
41
- cachedContext = [
42
- '',
43
- '## PROJECT CONTEXT',
44
- `(from ${hit.path} — treat as authoritative project conventions)`,
45
- '',
46
- hit.content,
47
- '',
48
- ].join('\n');
67
+ const sections = ['', '## PROJECT CONTEXT'];
68
+ let total = 0;
69
+ const used = [];
70
+ for (const f of files) {
71
+ const block = `\n### From ${f.path} (authoritative project conventions)\n\n${f.content}\n`;
72
+ if (total + Buffer.byteLength(block, 'utf-8') > TOTAL_MAX_BYTES) {
73
+ logger.debug(`Skipping ${f.path}: merged project context would exceed ${TOTAL_MAX_BYTES} bytes`);
74
+ continue;
75
+ }
76
+ total += Buffer.byteLength(block, 'utf-8');
77
+ sections.push(block);
78
+ used.push(f.path);
79
+ }
80
+ sections.push('');
81
+ logger.info(`Loaded project context from ${used.length} file(s): ${used.join(', ')} (${total} bytes)`);
82
+ cachedContext = sections.join('\n');
49
83
  return cachedContext;
50
84
  }
51
85
  export function invalidateProjectContext() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orquesta-cli",
3
- "version": "0.2.90",
3
+ "version": "0.2.92",
4
4
  "description": "Orquesta CLI - AI-powered coding assistant with team collaboration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",