orquesta-cli 0.2.95 → 0.2.96

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.
@@ -60,6 +60,8 @@ export declare class ConfigManager {
60
60
  setMaxParallelWorkers(n: number): Promise<void>;
61
61
  isRefinerEnabled(): boolean;
62
62
  setRefinerEnabled(enabled: boolean): Promise<void>;
63
+ isSingleAgentMode(): boolean;
64
+ setSingleAgentMode(enabled: boolean): Promise<void>;
63
65
  isWorktreeIsolationEnabled(): boolean;
64
66
  setWorktreeIsolationEnabled(enabled: boolean): Promise<void>;
65
67
  }
@@ -415,6 +415,16 @@ export class ConfigManager {
415
415
  config.orchestration.refinerEnabled = enabled;
416
416
  await this.saveConfig();
417
417
  }
418
+ isSingleAgentMode() {
419
+ return this.config?.orchestration?.singleAgentMode ?? false;
420
+ }
421
+ async setSingleAgentMode(enabled) {
422
+ const config = this.getConfig();
423
+ if (!config.orchestration)
424
+ config.orchestration = {};
425
+ config.orchestration.singleAgentMode = enabled;
426
+ await this.saveConfig();
427
+ }
418
428
  isWorktreeIsolationEnabled() {
419
429
  return this.config?.orchestration?.worktreeIsolation ?? false;
420
430
  }
@@ -141,7 +141,8 @@ export async function executeSlashCommand(command, context) {
141
141
  const parallel = configManager.getMaxParallelWorkers();
142
142
  const refiner = configManager.isRefinerEnabled() ? 'on' : 'off';
143
143
  const worktree = configManager.isWorktreeIsolationEnabled() ? 'on' : 'off';
144
- return `Multi-role orchestration\n\n${lines.join('\n')}\n\n max parallel workers: ${parallel}\n refiner pass: ${refiner}\n worktree isolation: ${worktree}\n\nUsage:\n /role planner <model-id>\n /role executor <model-id>\n /role refiner <model-id> | off\n /role parallel <N>\n /role worktree on|off\n /role clear`;
144
+ const single = configManager.isSingleAgentMode() ? 'on' : 'off';
145
+ return `Multi-role orchestration\n\n${lines.join('\n')}\n\n max parallel workers: ${parallel}\n refiner pass: ${refiner}\n worktree isolation: ${worktree}\n single-agent mode: ${single}\n\nUsage:\n /role planner <model-id>\n /role executor <model-id>\n /role refiner <model-id> | off\n /role parallel <N>\n /role worktree on|off\n /role single on|off (skip planner; one accumulative agent — best for debugging)\n /role clear`;
145
146
  };
146
147
  let body;
147
148
  try {
@@ -166,6 +167,12 @@ export async function executeSlashCommand(command, context) {
166
167
  await configManager.setWorktreeIsolationEnabled(args[1] === 'on');
167
168
  body = `Worktree isolation: ${args[1]}.`;
168
169
  }
170
+ else if (args[0] === 'single' && (args[1] === 'on' || args[1] === 'off')) {
171
+ await configManager.setSingleAgentMode(args[1] === 'on');
172
+ body = args[1] === 'on'
173
+ ? 'Single-agent mode ON — planner/orchestrator bypassed; one accumulative agent (best for debugging/investigation).'
174
+ : 'Single-agent mode OFF — planner + orchestrator restored.';
175
+ }
169
176
  else if ((args[0] === 'planner' || args[0] === 'executor' || args[0] === 'refiner') && args[1]) {
170
177
  const role = args[0];
171
178
  if (role === 'refiner' && args[1] === 'off') {
@@ -106,6 +106,29 @@ export class PlanExecutor {
106
106
  throw new Error('INTERRUPTED');
107
107
  }
108
108
  let currentMessages = messages;
109
+ if (configManager.isSingleAgentMode()) {
110
+ logger.flow('Single-agent mode — bypassing planner/orchestrator');
111
+ callbacks.setExecutionPhase('executing');
112
+ callbacks.setCurrentActivity('Working (single-agent)');
113
+ const saTools = toolRegistry.getLLMToolDefinitions();
114
+ const lastUserIdx = currentMessages.map(m => m.role).lastIndexOf('user');
115
+ const saMessages = (lastUserIdx >= 0 && currentMessages[lastUserIdx]?.content === userMessage)
116
+ ? currentMessages
117
+ : [...currentMessages, { role: 'user', content: userMessage }];
118
+ const saExecutorModel = configManager.getRoleModel('executor');
119
+ const saResult = await llmClient.chatCompletionWithTools(saMessages, saTools, {
120
+ getPendingMessage: callbacks.getPendingMessage,
121
+ clearPendingMessage: callbacks.clearPendingMessage,
122
+ ...(saExecutorModel ? { model: saExecutorModel } : {}),
123
+ });
124
+ currentMessages = [...saMessages, ...saResult.allMessages.slice(saMessages.length)];
125
+ callbacks.setMessages([...currentMessages]);
126
+ sessionManager.autoSaveCurrentSession(currentMessages);
127
+ callbacks.setExecutionPhase('idle');
128
+ auditLog.emit(auditSid, 'run.complete', { runId, mode: 'single-agent', success: true });
129
+ logger.exit('PlanExecutor.executePlanMode', { singleAgent: true });
130
+ return;
131
+ }
109
132
  callbacks.setCurrentActivity('Thinking');
110
133
  const plannerModel = configManager.getRoleModel('planner');
111
134
  const planningLLM = new PlanningLLM(llmClient, plannerModel ?? undefined);
@@ -126,6 +126,7 @@ export interface OrchestrationConfig {
126
126
  maxParallelWorkers?: number;
127
127
  refinerEnabled?: boolean;
128
128
  worktreeIsolation?: boolean;
129
+ singleAgentMode?: boolean;
129
130
  }
130
131
  export interface OpenConfig {
131
132
  version: string;
@@ -3,7 +3,7 @@ import { Box, Text } from 'ink';
3
3
  import Spinner from 'ink-spinner';
4
4
  import { logger } from '../../utils/logger.js';
5
5
  const STATUS_CONFIG = {
6
- completed: { icon: '☑', color: 'gray' },
6
+ completed: { icon: '☑', color: 'green' },
7
7
  in_progress: { icon: '☐', color: 'white' },
8
8
  failed: { icon: '☒', color: 'red' },
9
9
  pending: { icon: '☐', color: 'gray' },
@@ -57,7 +57,7 @@ export const TodoListView = ({ todos, showProgressBar = true, }) => {
57
57
  React.createElement(Box, null,
58
58
  React.createElement(Box, { width: 2 }, isInProgress ? (React.createElement(Text, { color: "blueBright" },
59
59
  React.createElement(Spinner, { type: "dots2" }))) : (React.createElement(Text, { color: config.color }, config.icon))),
60
- React.createElement(Text, { color: isCompleted ? 'gray' : isInProgress ? 'white' : 'gray', dimColor: isCompleted, strikethrough: isCompleted, bold: isInProgress }, todo.title),
60
+ React.createElement(Text, { color: isCompleted ? 'green' : isInProgress ? 'white' : 'gray', dimColor: false, bold: isInProgress }, todo.title),
61
61
  isInProgress && React.createElement(Text, { color: "blueBright" }, " \u2190"),
62
62
  todo.dependsOn && todo.dependsOn.length > 0 && (React.createElement(Text, { color: "gray", dimColor: true },
63
63
  " (after ",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orquesta-cli",
3
- "version": "0.2.95",
3
+ "version": "0.2.96",
4
4
  "description": "Orquesta CLI - AI-powered coding assistant with team collaboration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",