orquesta-cli 0.2.45 → 0.2.47

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.
Files changed (40) hide show
  1. package/dist/agents/planner/index.js +2 -1
  2. package/dist/cli.js +17 -16
  3. package/dist/constants.d.ts +1 -1
  4. package/dist/constants.js +1 -1
  5. package/dist/core/commands/clear.d.ts +3 -0
  6. package/dist/core/commands/clear.js +22 -0
  7. package/dist/core/commands/compact.d.ts +3 -0
  8. package/dist/core/commands/compact.js +45 -0
  9. package/dist/core/commands/help.d.ts +3 -0
  10. package/dist/core/commands/help.js +50 -0
  11. package/dist/core/commands/index.d.ts +3 -0
  12. package/dist/core/commands/index.js +11 -0
  13. package/dist/core/commands/memory.d.ts +3 -0
  14. package/dist/core/commands/memory.js +40 -0
  15. package/dist/core/commands/registry.d.ts +11 -0
  16. package/dist/core/commands/registry.js +25 -0
  17. package/dist/core/commands/types.d.ts +10 -0
  18. package/dist/core/commands/types.js +2 -0
  19. package/dist/core/event-bus.d.ts +20 -0
  20. package/dist/core/event-bus.js +35 -0
  21. package/dist/core/git-context.d.ts +11 -0
  22. package/dist/core/git-context.js +62 -0
  23. package/dist/core/ignore-filter.d.ts +4 -0
  24. package/dist/core/ignore-filter.js +50 -0
  25. package/dist/core/llm/llm-client.d.ts +1 -0
  26. package/dist/core/llm/llm-client.js +118 -40
  27. package/dist/core/onboarding.d.ts +3 -0
  28. package/dist/core/onboarding.js +48 -0
  29. package/dist/core/slash-command-handler.js +8 -135
  30. package/dist/eval/eval-runner.d.ts +1 -0
  31. package/dist/eval/eval-runner.js +22 -0
  32. package/dist/orchestration/plan-executor.js +77 -71
  33. package/dist/prompts/shared/tool-usage.js +0 -1
  34. package/dist/prompts/system/plan-execute.js +50 -57
  35. package/dist/tools/llm/simple/file-tools.js +12 -1
  36. package/dist/tools/llm/simple/final-response-tool.js +7 -11
  37. package/dist/tools/registry.js +63 -10
  38. package/dist/ui/components/PlanExecuteApp.d.ts +1 -0
  39. package/dist/ui/components/PlanExecuteApp.js +59 -22
  40. package/package.json +8 -4
@@ -3,6 +3,7 @@ import { buildPlanningSystemPrompt } from '../../prompts/agents/planning.js';
3
3
  import { toolRegistry } from '../../tools/registry.js';
4
4
  import { getProjectContext } from '../../core/project-context.js';
5
5
  import { getMemoryPrompt } from '../../core/memory.js';
6
+ import { getGitContextPrompt } from '../../core/git-context.js';
6
7
  export class PlanningLLM {
7
8
  llmClient;
8
9
  askUserCallback = null;
@@ -23,7 +24,7 @@ export class PlanningLLM {
23
24
  const toolSummary = toolRegistry.getToolSummaryForPlanning();
24
25
  const optionalToolsInfo = toolRegistry.getEnabledOptionalToolsInfo();
25
26
  const projectContext = getProjectContext();
26
- const systemPrompt = buildPlanningSystemPrompt(toolSummary, optionalToolsInfo) + projectContext + getMemoryPrompt();
27
+ const systemPrompt = buildPlanningSystemPrompt(toolSummary, optionalToolsInfo) + projectContext + getMemoryPrompt() + getGitContextPrompt();
27
28
  const clarificationMessages = [];
28
29
  const messages = [
29
30
  {
package/dist/cli.js CHANGED
@@ -28,6 +28,7 @@ import { connectWithToken, showConnectionStatus, disconnectFromOrquesta, switchP
28
28
  import { syncOrquestaConfigs } from './orquesta/config-sync.js';
29
29
  import { scanProviders, scanProvider, toEndpointConfig } from './core/config/auto-detect.js';
30
30
  import { PROVIDERS } from './core/config/providers.js';
31
+ import { shouldShowOnboarding, runOnboarding } from './core/onboarding.js';
31
32
  const require = createRequire(import.meta.url);
32
33
  const packageJson = require('../package.json');
33
34
  const program = new Command();
@@ -75,7 +76,7 @@ program
75
76
  .name('orquesta')
76
77
  .description('Orquesta CLI - AI-powered coding assistant with local LLM support')
77
78
  .version(packageJson.version)
78
- .helpOption(false);
79
+ .helpOption('-h, --help', 'Show help');
79
80
  program
80
81
  .option('-p, --print <prompt>', 'Execute a prompt and exit (non-interactive mode)')
81
82
  .option('--dangerously-skip-permissions', 'Skip all permission prompts (auto-approve)')
@@ -96,6 +97,7 @@ program
96
97
  .option('--init', 'Enable the Claude Code hook in this directory (reuses your login; or pass --token)')
97
98
  .option('--disable-hook', 'Disable the Claude Code hook in this directory')
98
99
  .option('--update', 'Update orquesta-cli to the latest published version and exit')
100
+ .option('-c, --continue', 'Resume the most recent conversation session')
99
101
  .action(async (options) => {
100
102
  if (options.appendSystemPrompt) {
101
103
  setAppendedSystemPrompt(options.appendSystemPrompt);
@@ -118,6 +120,9 @@ program
118
120
  return;
119
121
  }
120
122
  await configManager.initialize();
123
+ if (shouldShowOnboarding()) {
124
+ await runOnboarding();
125
+ }
121
126
  if (options.status) {
122
127
  showConnectionStatus();
123
128
  return;
@@ -273,24 +278,19 @@ program
273
278
  nodeVersion: process.version,
274
279
  });
275
280
  logger.flow('Config manager already initialized');
276
- spinner.text = chalk.cyan('Loading tools...');
277
- logger.flow('Initializing optional tools');
278
- await initializeOptionalTools();
279
- logger.flow('Optional tools initialized');
280
- if (configManager.hasOrquestaConnection() && configManager.shouldAutoSync()) {
281
- spinner.text = chalk.cyan('Syncing with Orquesta...');
282
- logger.flow('Auto-syncing with Orquesta');
283
- try {
284
- const syncResult = await syncOrquestaConfigs();
281
+ spinner.text = chalk.cyan('Loading...');
282
+ const toolsPromise = initializeOptionalTools().then(() => {
283
+ logger.flow('Optional tools initialized');
284
+ });
285
+ const syncPromise = (configManager.hasOrquestaConnection() && configManager.shouldAutoSync())
286
+ ? syncOrquestaConfigs().then(syncResult => {
285
287
  if (syncResult.success && (syncResult.added > 0 || syncResult.updated > 0)) {
286
288
  logger.flow('Orquesta sync complete', { added: syncResult.added, updated: syncResult.updated });
287
289
  }
288
- }
289
- catch (error) {
290
+ }).catch(error => {
290
291
  logger.warn('Orquesta sync failed', { error: error instanceof Error ? error.message : String(error) });
291
- }
292
- }
293
- spinner.text = chalk.cyan('Connecting to LLM...');
292
+ })
293
+ : Promise.resolve();
294
294
  let llmClient = null;
295
295
  let modelInfo = { model: 'Not configured', endpoint: 'Not configured' };
296
296
  if (configManager.hasEndpoints()) {
@@ -307,13 +307,14 @@ program
307
307
  else {
308
308
  logger.flow('No LLM endpoints configured');
309
309
  }
310
+ await Promise.all([toolsPromise, syncPromise]);
310
311
  spinner.stop();
311
312
  process.stdout.write('\x1B[2J\x1B[0f');
312
313
  if (options.verbose || options.debug) {
313
314
  console.log(chalk.cyan('Starting Orquesta CLI...\n'));
314
315
  }
315
316
  try {
316
- const { waitUntilExit } = render(React.createElement(PlanExecuteApp, { llmClient, modelInfo }), { exitOnCtrlC: false });
317
+ const { waitUntilExit } = render(React.createElement(PlanExecuteApp, { llmClient, modelInfo, resumeLastSession: !!options.continue }), { exitOnCtrlC: false });
317
318
  await waitUntilExit();
318
319
  }
319
320
  catch (error) {
@@ -5,5 +5,5 @@ export declare const DOCS_DIR: string;
5
5
  export declare const BACKUPS_DIR: string;
6
6
  export declare const PROJECTS_DIR: string;
7
7
  export declare function cwdToProjectSegment(cwd?: string): string;
8
- export declare const APP_VERSION = "4.2.2";
8
+ export declare const APP_VERSION = "0.2.45";
9
9
  //# sourceMappingURL=constants.d.ts.map
package/dist/constants.js CHANGED
@@ -12,5 +12,5 @@ export function cwdToProjectSegment(cwd = process.cwd()) {
12
12
  .replace(/[:*?"<>|]/g, '')
13
13
  .replace(/^-+/, '');
14
14
  }
15
- export const APP_VERSION = '4.2.2';
15
+ export const APP_VERSION = '0.2.45';
16
16
  //# sourceMappingURL=constants.js.map
@@ -0,0 +1,3 @@
1
+ import { SlashCommand } from './types.js';
2
+ export declare const clearCommand: SlashCommand;
3
+ //# sourceMappingURL=clear.d.ts.map
@@ -0,0 +1,22 @@
1
+ import { logger } from '../../utils/logger.js';
2
+ import { resetBatutaSession } from '../routing-state.js';
3
+ export const clearCommand = {
4
+ name: '/clear',
5
+ description: 'Clear conversation and TODOs',
6
+ async execute(context, _rawInput) {
7
+ logger.flow('Clear command - resetting messages and todos');
8
+ context.setMessages([]);
9
+ context.setTodos([]);
10
+ resetBatutaSession();
11
+ logger.exit('executeSlashCommand', { handled: true, command: 'clear' });
12
+ return {
13
+ handled: true,
14
+ shouldContinue: false,
15
+ updatedContext: {
16
+ messages: [],
17
+ todos: [],
18
+ },
19
+ };
20
+ },
21
+ };
22
+ //# sourceMappingURL=clear.js.map
@@ -0,0 +1,3 @@
1
+ import { SlashCommand } from './types.js';
2
+ export declare const compactCommand: SlashCommand;
3
+ //# sourceMappingURL=compact.d.ts.map
@@ -0,0 +1,45 @@
1
+ import { logger } from '../../utils/logger.js';
2
+ export const compactCommand = {
3
+ name: '/compact',
4
+ description: 'Compact conversation to free up context',
5
+ async execute(context, _rawInput) {
6
+ logger.flow('Compact command received');
7
+ if (context.onCompact) {
8
+ logger.flow('Executing compact callback');
9
+ const result = await context.onCompact();
10
+ logger.vars({ name: 'compactSuccess', value: result.success }, { name: 'originalCount', value: result.originalMessageCount }, { name: 'newCount', value: result.newMessageCount });
11
+ const compactMessage = result.success
12
+ ? `✅ Conversation compacted successfully. (${result.originalMessageCount} → ${result.newMessageCount} messages)`
13
+ : `❌ Compact failed: ${result.error}`;
14
+ const baseMessages = (result.success && result.compactedMessages)
15
+ ? result.compactedMessages
16
+ : context.messages;
17
+ const updatedMessages = [
18
+ ...baseMessages,
19
+ { role: 'assistant', content: compactMessage },
20
+ ];
21
+ context.setMessages(updatedMessages);
22
+ return {
23
+ handled: true,
24
+ shouldContinue: false,
25
+ updatedContext: {
26
+ messages: updatedMessages,
27
+ },
28
+ };
29
+ }
30
+ const fallbackMessage = '/compact is only available in interactive mode.';
31
+ const updatedMessages = [
32
+ ...context.messages,
33
+ { role: 'assistant', content: fallbackMessage },
34
+ ];
35
+ context.setMessages(updatedMessages);
36
+ return {
37
+ handled: true,
38
+ shouldContinue: false,
39
+ updatedContext: {
40
+ messages: updatedMessages,
41
+ },
42
+ };
43
+ },
44
+ };
45
+ //# sourceMappingURL=compact.js.map
@@ -0,0 +1,3 @@
1
+ import { SlashCommand } from './types.js';
2
+ export declare const helpCommand: SlashCommand;
3
+ //# sourceMappingURL=help.d.ts.map
@@ -0,0 +1,50 @@
1
+ export const helpCommand = {
2
+ name: '/help',
3
+ description: 'Show available commands',
4
+ async execute(context, _rawInput) {
5
+ const helpMessage = `
6
+ Available commands:
7
+ /exit, /quit - Exit the application
8
+ /clear - Clear conversation and TODOs
9
+ /compact - Compact conversation to free up context
10
+ /memory - Persistent memory: /memory add <note> | list | remove <n> | clear
11
+ /settings - Open settings menu
12
+ /model - Switch between LLM models
13
+ /project - Switch between Orquesta projects
14
+ /tool - Enable/disable optional tools (Browser, Background)
15
+ /load - Load a saved session
16
+ /usage - Show token usage statistics
17
+ /cost - Estimated USD spend this process (by model)
18
+ /route - Pin Batuta Auto tier (fast/balanced/premium/auto)
19
+ /sync - Bidirectional sync with Orquesta dashboard (pull & push LLM configs)
20
+ /login - Sign in to Orquesta via browser (opens getorquesta.com)
21
+ /logout - Sign out of Orquesta (clears token, keeps local LLM configs)
22
+ /whoami - Show current Orquesta connection
23
+ /hook - Claude Code hook here: /hook status | enable | disable
24
+ /remote-phone - Drive this session from your phone: on | off | status
25
+ /update - Update orquesta-cli to the latest version
26
+
27
+ Keyboard shortcuts:
28
+ Ctrl+C - Exit
29
+ Ctrl+T - Toggle TODO details
30
+ ESC - Interrupt current execution
31
+ @ - File browser
32
+ / - Command autocomplete
33
+
34
+ Note: All conversations are automatically saved.
35
+ `;
36
+ const updatedMessages = [
37
+ ...context.messages,
38
+ { role: 'assistant', content: helpMessage },
39
+ ];
40
+ context.setMessages(updatedMessages);
41
+ return {
42
+ handled: true,
43
+ shouldContinue: false,
44
+ updatedContext: {
45
+ messages: updatedMessages,
46
+ },
47
+ };
48
+ },
49
+ };
50
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1,3 @@
1
+ export { commandRegistry } from './registry.js';
2
+ export type { SlashCommand, CommandContext, CommandResult } from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,11 @@
1
+ import { commandRegistry } from './registry.js';
2
+ import { clearCommand } from './clear.js';
3
+ import { compactCommand } from './compact.js';
4
+ import { memoryCommand } from './memory.js';
5
+ import { helpCommand } from './help.js';
6
+ commandRegistry.register(clearCommand);
7
+ commandRegistry.register(compactCommand);
8
+ commandRegistry.register(memoryCommand);
9
+ commandRegistry.register(helpCommand);
10
+ export { commandRegistry } from './registry.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,3 @@
1
+ import { SlashCommand } from './types.js';
2
+ export declare const memoryCommand: SlashCommand;
3
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1,40 @@
1
+ import { addMemory, removeMemory, clearMemory, listMemory } from '../memory.js';
2
+ export const memoryCommand = {
3
+ name: '/memory',
4
+ description: 'Persistent memory: /memory add <note> | list | remove <n> | clear',
5
+ async execute(context, rawInput) {
6
+ const sub = rawInput.slice('/memory'.length).trim();
7
+ const reply = (content) => {
8
+ const updatedMessages = [...context.messages, { role: 'assistant', content }];
9
+ context.setMessages(updatedMessages);
10
+ return { handled: true, shouldContinue: false, updatedContext: { messages: updatedMessages } };
11
+ };
12
+ if (sub.startsWith('add ')) {
13
+ const note = sub.slice(4).trim();
14
+ if (!note)
15
+ return reply('Usage: /memory add <note>');
16
+ addMemory(note);
17
+ return reply(`✓ Saved to memory: "${note}"`);
18
+ }
19
+ if (sub === 'list' || sub === '') {
20
+ const entries = listMemory();
21
+ if (entries.length === 0)
22
+ return reply('Memory is empty. Use `/memory add <note>` to save preferences.');
23
+ const list = entries.map((e, i) => ` ${i + 1}. ${e}`).join('\n');
24
+ return reply(`📝 User memory (${entries.length} entries):\n${list}\n\nCommands: /memory add <note> | remove <n> | clear`);
25
+ }
26
+ if (sub.startsWith('remove ')) {
27
+ const idx = parseInt(sub.slice(7).trim(), 10);
28
+ if (isNaN(idx))
29
+ return reply('Usage: /memory remove <number>');
30
+ const ok = removeMemory(idx);
31
+ return reply(ok ? `✓ Removed entry #${idx}` : `Entry #${idx} not found`);
32
+ }
33
+ if (sub === 'clear') {
34
+ clearMemory();
35
+ return reply('✓ Memory cleared');
36
+ }
37
+ return reply('Usage: /memory add <note> | list | remove <n> | clear');
38
+ },
39
+ };
40
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1,11 @@
1
+ import { SlashCommand, CommandContext, CommandResult } from './types.js';
2
+ declare class CommandRegistry {
3
+ private commands;
4
+ register(command: SlashCommand): void;
5
+ get(name: string): SlashCommand | undefined;
6
+ execute(commandName: string, context: CommandContext, rawInput: string): Promise<CommandResult | null>;
7
+ getAll(): SlashCommand[];
8
+ }
9
+ export declare const commandRegistry: CommandRegistry;
10
+ export {};
11
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1,25 @@
1
+ class CommandRegistry {
2
+ commands = new Map();
3
+ register(command) {
4
+ this.commands.set(command.name, command);
5
+ if (command.aliases) {
6
+ for (const alias of command.aliases) {
7
+ this.commands.set(alias, command);
8
+ }
9
+ }
10
+ }
11
+ get(name) {
12
+ return this.commands.get(name);
13
+ }
14
+ async execute(commandName, context, rawInput) {
15
+ const command = this.commands.get(commandName);
16
+ if (!command)
17
+ return null;
18
+ return command.execute(context, rawInput);
19
+ }
20
+ getAll() {
21
+ return [...new Set(this.commands.values())];
22
+ }
23
+ }
24
+ export const commandRegistry = new CommandRegistry();
25
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1,10 @@
1
+ import { CommandHandlerContext, CommandExecutionResult } from '../slash-command-handler.js';
2
+ export type CommandContext = CommandHandlerContext;
3
+ export type CommandResult = CommandExecutionResult;
4
+ export interface SlashCommand {
5
+ name: string;
6
+ aliases?: string[];
7
+ description: string;
8
+ execute(context: CommandContext, rawInput: string): Promise<CommandResult>;
9
+ }
10
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,20 @@
1
+ type EventHandler<T = unknown> = (data: T) => void;
2
+ declare class EventBus {
3
+ private handlers;
4
+ on<T>(event: string, handler: EventHandler<T>): () => void;
5
+ emit<T>(event: string, data: T): void;
6
+ off(event: string, handler: EventHandler): void;
7
+ clear(): void;
8
+ }
9
+ export declare const eventBus: EventBus;
10
+ export declare const Events: {
11
+ readonly TOOL_START: "tool:start";
12
+ readonly TOOL_RESULT: "tool:result";
13
+ readonly TODO_UPDATE: "todo:update";
14
+ readonly STREAMING_TOKEN: "streaming:token";
15
+ readonly MODEL_CHANGED: "model:changed";
16
+ readonly SESSION_SAVED: "session:saved";
17
+ readonly FINAL_RESPONSE: "final:response";
18
+ };
19
+ export {};
20
+ //# sourceMappingURL=event-bus.d.ts.map
@@ -0,0 +1,35 @@
1
+ class EventBus {
2
+ handlers = new Map();
3
+ on(event, handler) {
4
+ if (!this.handlers.has(event)) {
5
+ this.handlers.set(event, new Set());
6
+ }
7
+ this.handlers.get(event).add(handler);
8
+ return () => this.off(event, handler);
9
+ }
10
+ emit(event, data) {
11
+ const handlers = this.handlers.get(event);
12
+ if (handlers) {
13
+ for (const handler of handlers) {
14
+ handler(data);
15
+ }
16
+ }
17
+ }
18
+ off(event, handler) {
19
+ this.handlers.get(event)?.delete(handler);
20
+ }
21
+ clear() {
22
+ this.handlers.clear();
23
+ }
24
+ }
25
+ export const eventBus = new EventBus();
26
+ export const Events = {
27
+ TOOL_START: 'tool:start',
28
+ TOOL_RESULT: 'tool:result',
29
+ TODO_UPDATE: 'todo:update',
30
+ STREAMING_TOKEN: 'streaming:token',
31
+ MODEL_CHANGED: 'model:changed',
32
+ SESSION_SAVED: 'session:saved',
33
+ FINAL_RESPONSE: 'final:response',
34
+ };
35
+ //# sourceMappingURL=event-bus.js.map
@@ -0,0 +1,11 @@
1
+ interface GitContext {
2
+ branch: string;
3
+ staged: string[];
4
+ unstaged: string[];
5
+ untracked: string[];
6
+ diffSummary: string;
7
+ }
8
+ export declare function getGitContext(): GitContext | null;
9
+ export declare function getGitContextPrompt(): string;
10
+ export {};
11
+ //# sourceMappingURL=git-context.d.ts.map
@@ -0,0 +1,62 @@
1
+ import { execSync } from 'child_process';
2
+ import { detectGitRepo } from '../utils/git-utils.js';
3
+ const MAX_DIFF_CHARS = 8000;
4
+ function run(cmd) {
5
+ try {
6
+ return execSync(cmd, { encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] }).trim();
7
+ }
8
+ catch {
9
+ return '';
10
+ }
11
+ }
12
+ export function getGitContext() {
13
+ if (!detectGitRepo())
14
+ return null;
15
+ const branch = run('git branch --show-current') || 'HEAD';
16
+ const statusOutput = run('git status --porcelain');
17
+ if (!statusOutput)
18
+ return { branch, staged: [], unstaged: [], untracked: [], diffSummary: '' };
19
+ const staged = [];
20
+ const unstaged = [];
21
+ const untracked = [];
22
+ for (const line of statusOutput.split('\n')) {
23
+ if (!line)
24
+ continue;
25
+ const x = line[0], y = line[1];
26
+ const file = line.slice(3);
27
+ if (x === '?') {
28
+ untracked.push(file);
29
+ continue;
30
+ }
31
+ if (x !== ' ' && x !== '?')
32
+ staged.push(file);
33
+ if (y !== ' ' && y !== '?')
34
+ unstaged.push(file);
35
+ }
36
+ let diffSummary = run('git diff --stat HEAD 2>/dev/null');
37
+ if (diffSummary.length > MAX_DIFF_CHARS) {
38
+ diffSummary = diffSummary.slice(0, MAX_DIFF_CHARS) + '\n[...truncated]';
39
+ }
40
+ return { branch, staged, unstaged, untracked, diffSummary };
41
+ }
42
+ export function getGitContextPrompt() {
43
+ const ctx = getGitContext();
44
+ if (!ctx)
45
+ return '';
46
+ const totalChanged = ctx.staged.length + ctx.unstaged.length + ctx.untracked.length;
47
+ if (totalChanged === 0)
48
+ return '';
49
+ const parts = ['\n\n<git_context>', `Branch: ${ctx.branch}`];
50
+ if (ctx.staged.length > 0) {
51
+ parts.push(`Staged (${ctx.staged.length}): ${ctx.staged.slice(0, 15).join(', ')}${ctx.staged.length > 15 ? '...' : ''}`);
52
+ }
53
+ if (ctx.unstaged.length > 0) {
54
+ parts.push(`Modified (${ctx.unstaged.length}): ${ctx.unstaged.slice(0, 15).join(', ')}${ctx.unstaged.length > 15 ? '...' : ''}`);
55
+ }
56
+ if (ctx.untracked.length > 0) {
57
+ parts.push(`Untracked (${ctx.untracked.length}): ${ctx.untracked.slice(0, 10).join(', ')}${ctx.untracked.length > 10 ? '...' : ''}`);
58
+ }
59
+ parts.push('</git_context>');
60
+ return parts.join('\n');
61
+ }
62
+ //# sourceMappingURL=git-context.js.map
@@ -0,0 +1,4 @@
1
+ export declare function getIgnorePatterns(): string[];
2
+ export declare function shouldIgnore(filePath: string): boolean;
3
+ export declare function resetIgnoreCache(): void;
4
+ //# sourceMappingURL=ignore-filter.d.ts.map
@@ -0,0 +1,50 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { minimatch } from 'minimatch';
4
+ let patterns = null;
5
+ function loadPatterns() {
6
+ if (patterns !== null)
7
+ return patterns;
8
+ const cwd = process.cwd();
9
+ const orquestaIgnore = path.join(cwd, '.orquestaignore');
10
+ const gitIgnore = path.join(cwd, '.gitignore');
11
+ let content = '';
12
+ try {
13
+ content = fs.readFileSync(orquestaIgnore, 'utf-8');
14
+ }
15
+ catch {
16
+ try {
17
+ content = fs.readFileSync(gitIgnore, 'utf-8');
18
+ }
19
+ catch {
20
+ patterns = [];
21
+ return patterns;
22
+ }
23
+ }
24
+ patterns = content
25
+ .split('\n')
26
+ .map(line => line.trim())
27
+ .filter(line => line.length > 0 && !line.startsWith('#'));
28
+ return patterns;
29
+ }
30
+ export function getIgnorePatterns() {
31
+ return loadPatterns();
32
+ }
33
+ export function shouldIgnore(filePath) {
34
+ const pats = loadPatterns();
35
+ const rel = path.relative(process.cwd(), path.resolve(filePath)).replace(/\\/g, '/');
36
+ for (const pat of pats) {
37
+ if (minimatch(rel, pat, { dot: true }) || minimatch(rel, `${pat}/**`, { dot: true })) {
38
+ return true;
39
+ }
40
+ const basename = path.basename(rel);
41
+ if (!pat.includes('/') && minimatch(basename, pat, { dot: true })) {
42
+ return true;
43
+ }
44
+ }
45
+ return false;
46
+ }
47
+ export function resetIgnoreCache() {
48
+ patterns = null;
49
+ }
50
+ //# sourceMappingURL=ignore-filter.js.map
@@ -45,6 +45,7 @@ export declare class LLMClient {
45
45
  private modelName;
46
46
  private currentAbortController;
47
47
  private isInterrupted;
48
+ onStreamingContent: ((token: string) => void) | null;
48
49
  private static readonly DEFAULT_MAX_RETRIES;
49
50
  constructor();
50
51
  private preprocessMessages;