orquesta-cli 0.2.44 → 0.2.46

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 +3 -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/memory.d.ts +7 -0
  28. package/dist/core/memory.js +55 -0
  29. package/dist/core/onboarding.d.ts +3 -0
  30. package/dist/core/onboarding.js +48 -0
  31. package/dist/core/slash-command-handler.js +8 -99
  32. package/dist/orchestration/plan-executor.js +78 -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
@@ -38,6 +38,7 @@ import { readHookConfig } from '../../orquesta/hook-init.js';
38
38
  import { remotePhone } from '../../orquesta/remote-phone.js';
39
39
  import { logger } from '../../utils/logger.js';
40
40
  import { usageTracker } from '../../core/usage-tracker.js';
41
+ import { estimateCost, formatCostUsd } from '../../core/pricing.js';
41
42
  import { UpdateNotification } from '../UpdateNotification.js';
42
43
  import { checkForCliUpdate, runCliUpdate, setSkippedVersion } from '../../utils/update-checker.js';
43
44
  import { setToolExecutionCallback, setTellToUserCallback, setToolResponseCallback, setPlanCreatedCallback, setTodoStartCallback, setTodoCompleteCallback, setTodoFailCallback, setCompactCallback, setAssistantResponseCallback, setToolApprovalCallback, setReasoningCallback, } from '../../tools/llm/simple/file-tools.js';
@@ -88,7 +89,7 @@ function getStatusText({ phase, todos, currentToolName }) {
88
89
  }
89
90
  return `${progressPrefix}Processing`;
90
91
  }
91
- export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
92
+ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo, resumeLastSession }) => {
92
93
  const { exit } = useApp();
93
94
  const hookBinding = useMemo(() => {
94
95
  const cfg = readHookConfig(process.cwd());
@@ -103,6 +104,7 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
103
104
  const [messages, setMessages] = useState([]);
104
105
  const { input, setInput, handleHistoryPrev, handleHistoryNext, addToHistory } = useInputHistory();
105
106
  const [isProcessing, setIsProcessing] = useState(false);
107
+ const [streamingText, setStreamingText] = useState('');
106
108
  const [updatePhase, setUpdatePhase] = useState('hidden');
107
109
  const [updateLatest, setUpdateLatest] = useState('');
108
110
  const [updateProgress, setUpdateProgress] = useState('');
@@ -168,6 +170,21 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
168
170
  useEffect(() => {
169
171
  sessionManager.setLogEntries(logEntries);
170
172
  }, [logEntries]);
173
+ useEffect(() => {
174
+ if (!resumeLastSession)
175
+ return;
176
+ (async () => {
177
+ const sessions = await sessionManager.listSessions();
178
+ if (sessions.length === 0)
179
+ return;
180
+ const last = sessions[0];
181
+ const data = await sessionManager.loadSession(last.id);
182
+ if (data && data.messages.length > 0) {
183
+ setMessages(data.messages);
184
+ addLog({ type: 'session_restored', content: `↩ Resumed session (${data.messages.filter(m => m.role === 'user').length} messages)` });
185
+ }
186
+ })();
187
+ }, [resumeLastSession]);
171
188
  const fileBrowserState = useFileBrowserState(input, isProcessing);
172
189
  const commandBrowserState = useCommandBrowserState(input, isProcessing);
173
190
  const planExecutionState = usePlanExecution(pendingMessageCallbacks);
@@ -261,6 +278,7 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
261
278
  }, [addLog]);
262
279
  useEffect(() => {
263
280
  setAssistantResponseCallback((content) => {
281
+ setStreamingText('');
264
282
  addLog({
265
283
  type: 'assistant_message',
266
284
  content,
@@ -271,6 +289,17 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
271
289
  setAssistantResponseCallback(null);
272
290
  };
273
291
  }, [addLog]);
292
+ useEffect(() => {
293
+ if (llmClient) {
294
+ llmClient.onStreamingContent = (token) => {
295
+ setStreamingText(prev => prev + token);
296
+ };
297
+ }
298
+ return () => {
299
+ if (llmClient)
300
+ llmClient.onStreamingContent = null;
301
+ };
302
+ }, [llmClient]);
274
303
  useEffect(() => {
275
304
  setReasoningCallback((content, _isStreaming) => {
276
305
  addLog({
@@ -432,29 +461,30 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
432
461
  logger.startTimer('app-init');
433
462
  try {
434
463
  setInitStep('health');
435
- logger.flow('Running health check');
464
+ logger.flow('Running health check + docs init in parallel');
436
465
  setHealthStatus('checking');
437
- if (configManager.hasEndpoints()) {
438
- const healthResults = await LLMClient.healthCheckAll();
439
- let hasHealthy = false;
440
- for (const [endpointId, modelResults] of healthResults) {
441
- logger.vars({ name: 'endpointId', value: endpointId }, { name: 'healthyModels', value: modelResults.filter(r => r.healthy).length });
442
- if (modelResults.some((r) => r.healthy)) {
443
- hasHealthy = true;
466
+ const healthPromise = (async () => {
467
+ if (configManager.hasEndpoints()) {
468
+ const healthResults = await LLMClient.healthCheckAll();
469
+ let hasHealthy = false;
470
+ for (const [endpointId, modelResults] of healthResults) {
471
+ logger.vars({ name: 'endpointId', value: endpointId }, { name: 'healthyModels', value: modelResults.filter(r => r.healthy).length });
472
+ if (modelResults.some((r) => r.healthy)) {
473
+ hasHealthy = true;
474
+ }
444
475
  }
476
+ logger.state('Health status', 'checking', hasHealthy ? 'healthy' : 'unhealthy');
477
+ setHealthStatus(hasHealthy ? 'healthy' : 'unhealthy');
478
+ await configManager.updateAllHealthStatus(healthResults);
445
479
  }
446
- logger.state('Health status', 'checking', hasHealthy ? 'healthy' : 'unhealthy');
447
- setHealthStatus(hasHealthy ? 'healthy' : 'unhealthy');
448
- await configManager.updateAllHealthStatus(healthResults);
449
- }
450
- else {
451
- setHealthStatus('unknown');
452
- }
453
- setInitStep('docs');
454
- logger.flow('Initializing docs directory');
455
- await initializeDocsDirectory().catch((err) => {
480
+ else {
481
+ setHealthStatus('unknown');
482
+ }
483
+ })();
484
+ const docsPromise = initializeDocsDirectory().catch((err) => {
456
485
  logger.warn('Docs directory initialization warning', { error: err });
457
486
  });
487
+ await Promise.all([healthPromise, docsPromise]);
458
488
  setInitStep('config');
459
489
  logger.flow('Checking configuration');
460
490
  if (!configManager.hasEndpoints()) {
@@ -938,6 +968,7 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
938
968
  let updatedMessages = [...messages, userMsg];
939
969
  setMessages(updatedMessages);
940
970
  setIsProcessing(true);
971
+ setStreamingText('');
941
972
  setActivityStartTime(Date.now());
942
973
  setSubActivities([]);
943
974
  if (llmClient) {
@@ -1389,8 +1420,10 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
1389
1420
  React.createElement(Static, { items: logEntries }, (entry) => renderLogEntry(entry)),
1390
1421
  pendingToolApproval && (React.createElement(Box, { marginY: 1 },
1391
1422
  React.createElement(ApprovalDialog, { toolName: pendingToolApproval.toolName, args: pendingToolApproval.args, reason: pendingToolApproval.reason, onResponse: handleApprovalResponse }))),
1392
- isProcessing && (planExecutionState.executionPhase === 'planning' || planExecutionState.todos.length === 0) && !pendingToolApproval && !isDocsSearching && (React.createElement(Box, { marginY: 1 },
1393
- React.createElement(ActivityIndicator, { activity: getCurrentActivityType(), startTime: activityStartTime, detail: activityDetail, subActivities: subActivities, modelName: currentModelInfo.model }))),
1423
+ isProcessing && (planExecutionState.executionPhase === 'planning' || planExecutionState.todos.length === 0) && !pendingToolApproval && !isDocsSearching && (React.createElement(Box, { marginY: 1, flexDirection: "column" },
1424
+ React.createElement(ActivityIndicator, { activity: getCurrentActivityType(), startTime: activityStartTime, detail: activityDetail, subActivities: subActivities, modelName: currentModelInfo.model }),
1425
+ streamingText && (React.createElement(Box, { marginTop: 1, paddingX: 1 },
1426
+ React.createElement(Text, { wrap: "wrap" }, streamingText))))),
1394
1427
  isDocsSearching && (React.createElement(DocsSearchProgress, { logs: docsSearchLogs, isSearching: isDocsSearching })),
1395
1428
  planExecutionState.todos.length > 0 && (React.createElement(Box, { marginTop: 2, marginBottom: 1 },
1396
1429
  React.createElement(TodoPanel, { todos: planExecutionState.todos, currentTodoId: planExecutionState.currentTodoId, isProcessing: isProcessing }))),
@@ -1458,7 +1491,11 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
1458
1491
  ' ',
1459
1492
  "(esc to interrupt \u00B7 ",
1460
1493
  formatElapsedTime(sessionElapsed),
1461
- sessionTokens > 0 && ` · ↑ ${formatTokensCompact(sessionTokens)} tokens`,
1494
+ sessionTokens > 0 && (() => {
1495
+ const usage = usageTracker.getSessionUsage();
1496
+ const cost = estimateCost(currentModelInfo.model, usage.inputTokens, usage.outputTokens);
1497
+ return ` · ↑ ${formatTokensCompact(sessionTokens)} tokens${cost ? ` · ${formatCostUsd(cost)}` : ''}`;
1498
+ })(),
1462
1499
  ")"))),
1463
1500
  React.createElement(Box, null,
1464
1501
  (() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orquesta-cli",
3
- "version": "0.2.44",
3
+ "version": "0.2.46",
4
4
  "description": "Orquesta CLI - AI-powered coding assistant with team collaboration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,14 +11,16 @@
11
11
  "scripts": {
12
12
  "preinstall": "node scripts/check-node.cjs",
13
13
  "build": "tsc",
14
+ "test": "vitest run",
15
+ "test:watch": "vitest",
14
16
  "postbuild": "chmod +x dist/cli.js",
15
- "dev": "ts-node src/cli.ts",
17
+ "dev": "tsx watch src/cli.ts",
16
18
  "start": "node dist/cli.js",
17
19
  "watch": "tsc --watch",
18
20
  "lint": "eslint src/**/*.ts",
19
21
  "lint:fix": "eslint src/**/*.ts --fix",
20
22
  "format": "prettier --write \"src/**/*.ts\"",
21
- "test": "cd tests && python -m pytest test_eval.py -v",
23
+ "test:eval": "cd tests && python -m pytest test_eval.py -v",
22
24
  "test:quick": "cd tests && python -m pytest test_eval.py -v -m 'not slow'",
23
25
  "prepr": "npm run lint && npm run build",
24
26
  "bun:build": "node scripts/inject-version.js && npm run build && bun build dist/cli.js --compile --outfile bin/lcli && cp node_modules/yoga-wasm-web/dist/yoga.wasm bin/",
@@ -126,7 +128,9 @@
126
128
  "react-devtools-core": "^4.28.5",
127
129
  "react-dom": "^18.3.1",
128
130
  "ts-node": "^10.9.2",
131
+ "tsx": "^4.19.0",
129
132
  "typescript": "^5.3.3",
130
- "vite": "^7.3.1"
133
+ "vite": "^7.3.1",
134
+ "vitest": "^3.2.1"
131
135
  }
132
136
  }