centaurus-cli 2.8.0 → 2.8.2
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-adapter.d.ts +8 -6
- package/dist/cli-adapter.d.ts.map +1 -1
- package/dist/cli-adapter.js +599 -182
- package/dist/cli-adapter.js.map +1 -1
- package/dist/config/slash-commands.d.ts.map +1 -1
- package/dist/config/slash-commands.js +1 -0
- package/dist/config/slash-commands.js.map +1 -1
- package/dist/context/context-manager.d.ts +4 -1
- package/dist/context/context-manager.d.ts.map +1 -1
- package/dist/context/context-manager.js +30 -7
- package/dist/context/context-manager.js.map +1 -1
- package/dist/context/handlers/wsl-handler.d.ts +10 -0
- package/dist/context/handlers/wsl-handler.d.ts.map +1 -1
- package/dist/context/handlers/wsl-handler.js +29 -1
- package/dist/context/handlers/wsl-handler.js.map +1 -1
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -1
- package/dist/services/ai-service-client.d.ts +1 -0
- package/dist/services/ai-service-client.d.ts.map +1 -1
- package/dist/services/ai-service-client.js.map +1 -1
- package/dist/tools/command.d.ts.map +1 -1
- package/dist/tools/command.js +136 -21
- package/dist/tools/command.js.map +1 -1
- package/dist/tools/file-ops.d.ts +1 -0
- package/dist/tools/file-ops.d.ts.map +1 -1
- package/dist/tools/file-ops.js +131 -0
- package/dist/tools/file-ops.js.map +1 -1
- package/dist/tools/inspect-symbol.js +27 -27
- package/dist/tools/inspect-symbol.js.map +1 -1
- package/dist/tools/plan-mode.d.ts +55 -19
- package/dist/tools/plan-mode.d.ts.map +1 -1
- package/dist/tools/plan-mode.js +204 -123
- package/dist/tools/plan-mode.js.map +1 -1
- package/dist/tools/reproduce_issue.d.ts +2 -0
- package/dist/tools/reproduce_issue.d.ts.map +1 -0
- package/dist/tools/reproduce_issue.js +166 -0
- package/dist/tools/reproduce_issue.js.map +1 -0
- package/dist/tools/types.d.ts +1 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/validation.d.ts.map +1 -1
- package/dist/tools/validation.js +4 -3
- package/dist/tools/validation.js.map +1 -1
- package/dist/types/index.d.ts +11 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/ui/components/App.d.ts +6 -6
- package/dist/ui/components/App.d.ts.map +1 -1
- package/dist/ui/components/App.js +228 -62
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/DiffViewer.d.ts.map +1 -1
- package/dist/ui/components/DiffViewer.js +69 -58
- package/dist/ui/components/DiffViewer.js.map +1 -1
- package/dist/ui/components/FileTagAutocomplete.d.ts +11 -0
- package/dist/ui/components/FileTagAutocomplete.d.ts.map +1 -0
- package/dist/ui/components/FileTagAutocomplete.js +27 -0
- package/dist/ui/components/FileTagAutocomplete.js.map +1 -0
- package/dist/ui/components/InputBox.d.ts.map +1 -1
- package/dist/ui/components/InputBox.js +209 -7
- package/dist/ui/components/InputBox.js.map +1 -1
- package/dist/ui/components/InteractiveShell.d.ts.map +1 -1
- package/dist/ui/components/InteractiveShell.js +177 -13
- package/dist/ui/components/InteractiveShell.js.map +1 -1
- package/dist/ui/components/MessageDisplay.d.ts.map +1 -1
- package/dist/ui/components/MessageDisplay.js +3 -3
- package/dist/ui/components/MessageDisplay.js.map +1 -1
- package/dist/ui/components/PlanAcceptedMessage.d.ts +12 -0
- package/dist/ui/components/PlanAcceptedMessage.d.ts.map +1 -0
- package/dist/ui/components/PlanAcceptedMessage.js +22 -0
- package/dist/ui/components/PlanAcceptedMessage.js.map +1 -0
- package/dist/ui/components/PlanReviewScreen.d.ts +14 -0
- package/dist/ui/components/PlanReviewScreen.d.ts.map +1 -0
- package/dist/ui/components/PlanReviewScreen.js +52 -0
- package/dist/ui/components/PlanReviewScreen.js.map +1 -0
- package/dist/ui/components/StreamingMessageDisplay.d.ts.map +1 -1
- package/dist/ui/components/StreamingMessageDisplay.js +3 -3
- package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
- package/dist/ui/components/TaskCompletedMessage.d.ts +14 -0
- package/dist/ui/components/TaskCompletedMessage.d.ts.map +1 -0
- package/dist/ui/components/TaskCompletedMessage.js +25 -0
- package/dist/ui/components/TaskCompletedMessage.js.map +1 -0
- package/dist/ui/components/ToolExecutionMessage.d.ts.map +1 -1
- package/dist/ui/components/ToolExecutionMessage.js +207 -20
- package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
- package/dist/utils/conversation-logger.d.ts +127 -0
- package/dist/utils/conversation-logger.d.ts.map +1 -0
- package/dist/utils/conversation-logger.js +283 -0
- package/dist/utils/conversation-logger.js.map +1 -0
- package/dist/utils/editor-utils.d.ts +37 -0
- package/dist/utils/editor-utils.d.ts.map +1 -1
- package/dist/utils/editor-utils.js +212 -1
- package/dist/utils/editor-utils.js.map +1 -1
- package/dist/utils/input-classifier.d.ts.map +1 -1
- package/dist/utils/input-classifier.js +10 -3
- package/dist/utils/input-classifier.js.map +1 -1
- package/dist/utils/markdown-parser.d.ts.map +1 -1
- package/dist/utils/markdown-parser.js +4 -2
- package/dist/utils/markdown-parser.js.map +1 -1
- package/package.json +1 -1
- package/prompts/system-prompt-autonomous.md +0 -377
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,GAAG,CAAC;IACpB,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,eAAe,EAAE,CACf,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EAC1F,aAAa,CAAC,EAAE,YAAY,GAAG,WAAW,GAAG,iBAAiB,GAAG,eAAe,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,GAAG,CAAC;IACpB,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,eAAe,EAAE,CACf,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EAC1F,aAAa,CAAC,EAAE,YAAY,GAAG,WAAW,GAAG,iBAAiB,GAAG,eAAe,GAAG,iBAAiB,EACpG,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KACnC,OAAO,CAAC,OAAO,GAAG;QAAE,QAAQ,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,KAAK,IAAI,CAAC;IACvE,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEzG,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;CACvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/tools/validation.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAeD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/tools/validation.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAeD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkB3D;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB;;;;;;;;OAQG;IACG,gBAAgB,CACpB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,gBAAgB,CAAC;IA0C5B;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;;;;;OAMG;IACH,OAAO,CAAC,wBAAwB;CA6BjC"}
|
package/dist/tools/validation.js
CHANGED
|
@@ -14,10 +14,11 @@ export function createFlexibleRegex(pattern) {
|
|
|
14
14
|
const tokens = escaped.trim().split(/\s+/);
|
|
15
15
|
// 3. Rejoin with \s+ (one or more whitespace characters)
|
|
16
16
|
const internalPattern = tokens.join('\\s+');
|
|
17
|
-
// 4. Wrap with \
|
|
17
|
+
// 4. Wrap with [^\S\r\n]* (zero or more whitespace EXCEPT newlines) on BOTH sides
|
|
18
18
|
// This ensures we match and consume the file's existing indentation
|
|
19
|
-
//
|
|
20
|
-
|
|
19
|
+
// but NOT the trailing newlines, preventing accidental line merging.
|
|
20
|
+
// [^\S\r\n] matches any whitespace character that is not CR or LF.
|
|
21
|
+
const finalPattern = `[^\\S\\r\\n]*${internalPattern}[^\\S\\r\\n]*`;
|
|
21
22
|
return new RegExp(finalPattern, 'g');
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/tools/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAwB7B;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,qCAAqC;IACrC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAE/D,qCAAqC;IACrC,6CAA6C;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE3C,yDAAyD;IACzD,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5C,
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/tools/validation.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export interface AgenticLoopStats {
|
|
|
41
41
|
}
|
|
42
42
|
export interface ToolExecution {
|
|
43
43
|
toolName: string;
|
|
44
|
-
status: 'executing' | 'completed' | 'error';
|
|
44
|
+
status: 'pending' | 'executing' | 'completed' | 'error';
|
|
45
45
|
result?: string;
|
|
46
46
|
error?: string;
|
|
47
47
|
arguments?: Record<string, any>;
|
|
@@ -77,6 +77,16 @@ export interface Message {
|
|
|
77
77
|
tool_calls?: ToolCall[];
|
|
78
78
|
thoughts?: string[];
|
|
79
79
|
thinkingDuration?: number;
|
|
80
|
+
taskCompletion?: {
|
|
81
|
+
taskNumber: number;
|
|
82
|
+
totalTasks: number;
|
|
83
|
+
taskDescription: string;
|
|
84
|
+
completionNote?: string;
|
|
85
|
+
};
|
|
86
|
+
planAccepted?: {
|
|
87
|
+
planTitle?: string;
|
|
88
|
+
totalTasks?: number;
|
|
89
|
+
};
|
|
80
90
|
}
|
|
81
91
|
export interface ToolCall {
|
|
82
92
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,QAAQ,GAAG,eAAe,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,CAAC;IACtF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { SubshellContext } from '../../context/types.js';
|
|
3
|
+
import { Plan, PlanStep } from '../../tools/plan-mode.js';
|
|
3
4
|
interface AppProps {
|
|
4
5
|
onMessage: (message: string) => Promise<void>;
|
|
5
6
|
onCancelRequest: () => void;
|
|
@@ -21,7 +22,7 @@ interface AppProps {
|
|
|
21
22
|
onPickerSelection: (selection: string, type: 'model') => Promise<void>;
|
|
22
23
|
onToolExecutionUpdate: (callback: (update: {
|
|
23
24
|
toolName: string;
|
|
24
|
-
status: 'executing' | 'completed' | 'error';
|
|
25
|
+
status: 'pending' | 'executing' | 'completed' | 'error';
|
|
25
26
|
result?: string;
|
|
26
27
|
error?: string;
|
|
27
28
|
arguments?: Record<string, any>;
|
|
@@ -35,7 +36,7 @@ interface AppProps {
|
|
|
35
36
|
language?: string;
|
|
36
37
|
fullDiff?: string;
|
|
37
38
|
};
|
|
38
|
-
operationType?: 'write_file' | 'edit_file' | 'execute_command';
|
|
39
|
+
operationType?: 'write_file' | 'write_to_file' | 'edit_file' | 'execute_command' | 'multi_edit_file';
|
|
39
40
|
operationDetails?: Record<string, any>;
|
|
40
41
|
}) => Promise<boolean>) => void;
|
|
41
42
|
onToolStreamingOutput: (callback: (update: {
|
|
@@ -44,10 +45,9 @@ interface AppProps {
|
|
|
44
45
|
type: 'stdout' | 'stderr';
|
|
45
46
|
}) => void) => void;
|
|
46
47
|
onPlanModeChange: (callback: (planMode: boolean) => void) => void;
|
|
47
|
-
onPlanApprovalRequest: (callback: (plan:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}) => Promise<boolean>) => void;
|
|
48
|
+
onPlanApprovalRequest: (callback: (plan: Plan) => Promise<boolean>) => void;
|
|
49
|
+
onPlanCreated: (callback: (plan: Plan) => void) => void;
|
|
50
|
+
onTaskCompleted: (callback: (task: PlanStep, taskNumber: number, totalTasks: number, completionNote?: string) => void) => void;
|
|
51
51
|
onCommandModeChange: (callback: (commandMode: boolean) => void) => void;
|
|
52
52
|
onToggleCommandMode: () => void;
|
|
53
53
|
onCwdChange: (callback: (cwd: string) => void) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../src/ui/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAqBrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../src/ui/components/App.tsx"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,9 @@ import { VersionUpdatePrompt } from './VersionUpdatePrompt.js';
|
|
|
18
18
|
import { InteractiveShell } from './InteractiveShell.js';
|
|
19
19
|
import { checkForUpdates } from '../../utils/version-checker.js';
|
|
20
20
|
import { runInteractiveEditor, runWSLEditor, runDockerEditor, runSSHEditor } from '../../utils/editor-utils.js';
|
|
21
|
+
import { PlanReviewScreen } from './PlanReviewScreen.js';
|
|
22
|
+
import { TaskCompletedMessage } from './TaskCompletedMessage.js';
|
|
23
|
+
import { PlanAcceptedMessage } from './PlanAcceptedMessage.js';
|
|
21
24
|
// Banner item with stable timestamp - created once outside component
|
|
22
25
|
const BANNER_ITEM = { id: '__banner__', role: '__banner__', content: '', timestamp: new Date(0) };
|
|
23
26
|
const MessageList = React.memo(({ history, current, showBanner }) => {
|
|
@@ -30,6 +33,15 @@ const MessageList = React.memo(({ history, current, showBanner }) => {
|
|
|
30
33
|
if (item.id === '__banner__') {
|
|
31
34
|
return React.createElement(WelcomeBanner, { key: "__banner__" });
|
|
32
35
|
}
|
|
36
|
+
// Special rendering for task completion messages
|
|
37
|
+
const msg = item;
|
|
38
|
+
if (msg.taskCompletion) {
|
|
39
|
+
return (React.createElement(TaskCompletedMessage, { key: item.id, taskNumber: msg.taskCompletion.taskNumber, totalTasks: msg.taskCompletion.totalTasks, taskDescription: msg.taskCompletion.taskDescription, completionNote: msg.taskCompletion.completionNote }));
|
|
40
|
+
}
|
|
41
|
+
// Special rendering for plan accepted messages
|
|
42
|
+
if (msg.planAccepted) {
|
|
43
|
+
return (React.createElement(PlanAcceptedMessage, { key: item.id, planTitle: msg.planAccepted.planTitle, totalTasks: msg.planAccepted.totalTasks }));
|
|
44
|
+
}
|
|
33
45
|
return React.createElement(MessageDisplay, { key: item.id, message: item });
|
|
34
46
|
}),
|
|
35
47
|
current && !history.some(msg => msg.id === current.id) && (current.role === 'assistant' && current.shouldStream !== false ? (React.createElement(StreamingMessageDisplay, { key: current.id, message: current })) : (React.createElement(MessageDisplay, { key: current.id, message: current })))));
|
|
@@ -56,13 +68,13 @@ const ApprovalSection = React.memo(({ approvalRequest, onApprove }) => {
|
|
|
56
68
|
const handleNo = React.useCallback(() => onApprove(false), [onApprove]);
|
|
57
69
|
return (React.createElement(Box, { flexDirection: "column", marginY: 1 },
|
|
58
70
|
approvalRequest.preview && approvalRequest.preview.type === 'code' && (React.createElement(FileCreationPreview, { content: approvalRequest.preview.content, filePath: approvalRequest.operationDetails?.file_path || 'New File' })),
|
|
59
|
-
approvalRequest.preview && approvalRequest.preview.type === 'diff' && (React.createElement(DiffViewer, { diff: approvalRequest.preview.content, filePath: '
|
|
71
|
+
approvalRequest.preview && approvalRequest.preview.type === 'diff' && (React.createElement(DiffViewer, { diff: approvalRequest.preview.content, filePath: approvalRequest.operationDetails?.file_path || 'Modified File', fullDiff: approvalRequest.preview.fullDiff })),
|
|
60
72
|
React.createElement(ConfirmPrompt, { message: approvalRequest.message, onYes: handleYes, onNo: handleNo })));
|
|
61
73
|
}, (prevProps, nextProps) => {
|
|
62
74
|
// Only re-render if the approval request message changes
|
|
63
75
|
return prevProps.approvalRequest.message === nextProps.approvalRequest.message;
|
|
64
76
|
});
|
|
65
|
-
export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode, onResponseReceived, onDirectMessage, onResponseStream, onThoughtStream, onThoughtComplete, onPickerSetup, onPickerSelection, onToolExecutionUpdate, onToolApprovalRequest, onToolStreamingOutput, onPlanModeChange, onPlanApprovalRequest, onCommandModeChange, onToggleCommandMode, onCwdChange, onModelChange, onSubshellContextChange, onPasswordRequest, onShellInput, onShellSignal, onKillProcess, onInteractiveEditorMode }) => {
|
|
77
|
+
export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode, onResponseReceived, onDirectMessage, onResponseStream, onThoughtStream, onThoughtComplete, onPickerSetup, onPickerSelection, onToolExecutionUpdate, onToolApprovalRequest, onToolStreamingOutput, onPlanModeChange, onPlanApprovalRequest, onPlanCreated, onTaskCompleted, onCommandModeChange, onToggleCommandMode, onCwdChange, onModelChange, onSubshellContextChange, onPasswordRequest, onShellInput, onShellSignal, onKillProcess, onInteractiveEditorMode }) => {
|
|
66
78
|
const { exit } = useApp();
|
|
67
79
|
const autoAcceptRef = React.useRef(false);
|
|
68
80
|
// Helper to clear screen
|
|
@@ -209,10 +221,20 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
209
221
|
// Ignore logging errors
|
|
210
222
|
}
|
|
211
223
|
setState(prev => {
|
|
212
|
-
//
|
|
213
|
-
|
|
224
|
+
// Check if current message is a thought-only message (empty content with thinkingDuration)
|
|
225
|
+
// These should NOT trigger new message creation - they're waiting for tool execution
|
|
226
|
+
const isThoughtOnlyMessage = prev.currentMessage?.role === 'assistant' &&
|
|
227
|
+
prev.currentMessage.content.trim() === '' &&
|
|
228
|
+
prev.currentMessage.thinkingDuration !== undefined;
|
|
229
|
+
// If we don't have a current assistant message, OR the current one already has thinkingDuration
|
|
230
|
+
// (meaning it's from a completed turn), create a new one for the thoughts
|
|
231
|
+
// BUT: Don't create new if current is a thought-only message waiting for tool
|
|
232
|
+
const needsNewMessage = !prev.currentMessage ||
|
|
233
|
+
prev.currentMessage.role !== 'assistant' ||
|
|
234
|
+
(prev.currentMessage.thinkingDuration !== undefined && !isThoughtOnlyMessage);
|
|
235
|
+
if (needsNewMessage) {
|
|
214
236
|
try {
|
|
215
|
-
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Creating new assistant message for thoughts\n`);
|
|
237
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Creating new assistant message for thoughts (reason: ${!prev.currentMessage ? 'no current' : prev.currentMessage.role !== 'assistant' ? 'not assistant' : 'has thinkingDuration'})\n`);
|
|
216
238
|
}
|
|
217
239
|
catch (e) {
|
|
218
240
|
// Ignore logging errors
|
|
@@ -231,13 +253,31 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
231
253
|
shouldStream: true,
|
|
232
254
|
thoughts: last3Lines
|
|
233
255
|
};
|
|
256
|
+
// If we have a completed assistant message (with thinkingDuration), move it to history
|
|
257
|
+
// BUT: Don't move thought-only messages - they're waiting for tool execution
|
|
258
|
+
let newHistory = prev.messageHistory;
|
|
259
|
+
if (prev.currentMessage && prev.currentMessage.role === 'assistant' &&
|
|
260
|
+
prev.currentMessage.thinkingDuration !== undefined &&
|
|
261
|
+
prev.currentMessage.content.trim() !== '') { // Only move if has actual content
|
|
262
|
+
newHistory = [...prev.messageHistory, prev.currentMessage];
|
|
263
|
+
}
|
|
234
264
|
return {
|
|
235
265
|
...prev,
|
|
266
|
+
messageHistory: newHistory,
|
|
236
267
|
currentMessage: newMessage,
|
|
237
268
|
isLoading: false,
|
|
238
269
|
isAiWorking: true
|
|
239
270
|
};
|
|
240
271
|
}
|
|
272
|
+
// If current is thought-only message, just skip this new thought chunk
|
|
273
|
+
// (don't accumulate - the tool will handle displaying)
|
|
274
|
+
if (isThoughtOnlyMessage) {
|
|
275
|
+
try {
|
|
276
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Skipping thought chunk - current is thought-only message waiting for tool\n`);
|
|
277
|
+
}
|
|
278
|
+
catch (e) { }
|
|
279
|
+
return prev;
|
|
280
|
+
}
|
|
241
281
|
// Accumulate the new thought chunk with existing thought text
|
|
242
282
|
// Add a newline between chunks to separate them
|
|
243
283
|
thoughtAccumulatorRef.current += '\n' + thought;
|
|
@@ -485,7 +525,9 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
485
525
|
pendingShellRef.current = {
|
|
486
526
|
timeoutId,
|
|
487
527
|
command,
|
|
488
|
-
cwd
|
|
528
|
+
// Use the cwd from update.arguments (already computed correctly in cli-adapter.ts)
|
|
529
|
+
// This has the correct remote CWD for WSL/Docker/SSH contexts
|
|
530
|
+
cwd: update.arguments?.cwd || state.currentWorkingDirectory,
|
|
489
531
|
output: ''
|
|
490
532
|
};
|
|
491
533
|
return;
|
|
@@ -563,8 +605,40 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
563
605
|
}
|
|
564
606
|
}
|
|
565
607
|
setState(prev => {
|
|
566
|
-
//
|
|
608
|
+
// Debug logging to trace tool display issues
|
|
609
|
+
try {
|
|
610
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] onToolExecutionUpdate setState - toolName: ${update.toolName}, status: ${update.status}\n`);
|
|
611
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Current state: screen=${prev.screen}, currentMessage.role=${prev.currentMessage?.role}, currentMessage.id=${prev.currentMessage?.id}, historyLen=${prev.messageHistory.length}\n`);
|
|
612
|
+
if (prev.currentMessage?.thinkingDuration !== undefined) {
|
|
613
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Current message has thinkingDuration: ${prev.currentMessage.thinkingDuration}s\n`);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
catch (e) { }
|
|
617
|
+
// IMPORTANT: When on approval screen, we still need to track completed tools
|
|
618
|
+
// but we should NOT try to update the display (will be handled when returning to chat)
|
|
619
|
+
// For 'executing' status on approval screen, the tool is waiting for approval, so skip
|
|
567
620
|
if (prev.screen !== 'chat') {
|
|
621
|
+
// Only track completed tools, skip executing tools (they need approval flow)
|
|
622
|
+
if (update.status === 'completed' || update.status === 'error') {
|
|
623
|
+
try {
|
|
624
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Tool ${update.toolName} completed while on ${prev.screen} screen, adding to history\n`);
|
|
625
|
+
}
|
|
626
|
+
catch (e) { }
|
|
627
|
+
// Add completed tool directly to history
|
|
628
|
+
const completedToolMessage = {
|
|
629
|
+
id: `tool-${update.toolName}-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
|
630
|
+
role: 'tool',
|
|
631
|
+
content: '',
|
|
632
|
+
timestamp: new Date(),
|
|
633
|
+
toolExecution: { ...update }
|
|
634
|
+
};
|
|
635
|
+
return {
|
|
636
|
+
...prev,
|
|
637
|
+
messageHistory: [...prev.messageHistory, completedToolMessage],
|
|
638
|
+
isAiWorking: true
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
// Skip 'executing' status when not on chat screen
|
|
568
642
|
return prev;
|
|
569
643
|
}
|
|
570
644
|
const toolMessage = {
|
|
@@ -574,12 +648,16 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
574
648
|
timestamp: new Date(),
|
|
575
649
|
toolExecution: { ...update }
|
|
576
650
|
};
|
|
577
|
-
// If current message is a tool with
|
|
651
|
+
// If current message is a tool with matching execution, update it and move to history
|
|
578
652
|
if (prev.currentMessage?.role === 'tool' &&
|
|
579
|
-
prev.currentMessage.toolExecution?.toolName === update.toolName &&
|
|
580
653
|
prev.currentMessage.toolExecution?.status === 'executing' &&
|
|
581
654
|
update.status !== 'executing') {
|
|
582
655
|
// Tool completed - move to history with updated status
|
|
656
|
+
// Note: We now match ANY executing tool, not just same toolName (handles overlapping tools)
|
|
657
|
+
try {
|
|
658
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Tool ${update.toolName} completed, moving current tool to history\n`);
|
|
659
|
+
}
|
|
660
|
+
catch (e) { }
|
|
583
661
|
const completedToolMessage = {
|
|
584
662
|
...prev.currentMessage,
|
|
585
663
|
toolExecution: { ...update }
|
|
@@ -588,38 +666,72 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
588
666
|
...prev,
|
|
589
667
|
messageHistory: [...prev.messageHistory, completedToolMessage],
|
|
590
668
|
currentMessage: null,
|
|
591
|
-
isAiWorking: true
|
|
669
|
+
isAiWorking: true
|
|
592
670
|
};
|
|
593
671
|
}
|
|
672
|
+
// For pending status, don't modify state yet - wait for executing
|
|
673
|
+
// This ensures thought-only messages stay as currentMessage until executing arrives
|
|
674
|
+
if (update.status === 'pending') {
|
|
675
|
+
try {
|
|
676
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Tool ${update.toolName} pending - skipping state modification, waiting for executing\n`);
|
|
677
|
+
}
|
|
678
|
+
catch (e) { }
|
|
679
|
+
return prev; // Return unchanged state
|
|
680
|
+
}
|
|
594
681
|
// If starting new tool execution
|
|
595
682
|
if (update.status === 'executing') {
|
|
596
683
|
// IMPORTANT: Always preserve current message by moving it to history first
|
|
597
684
|
let newHistory = prev.messageHistory;
|
|
685
|
+
let pendingThinkingDuration = undefined;
|
|
598
686
|
if (prev.currentMessage) {
|
|
599
|
-
//
|
|
600
|
-
|
|
687
|
+
// Check if this is a thought-only message (empty content but has thinkingDuration)
|
|
688
|
+
const isThoughtOnlyMessage = prev.currentMessage.role === 'assistant' &&
|
|
689
|
+
prev.currentMessage.content.trim() === '' &&
|
|
690
|
+
prev.currentMessage.thinkingDuration !== undefined;
|
|
691
|
+
if (isThoughtOnlyMessage) {
|
|
692
|
+
// Carry the thinkingDuration to the tool message, don't add empty message to history
|
|
693
|
+
pendingThinkingDuration = prev.currentMessage.thinkingDuration;
|
|
694
|
+
try {
|
|
695
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Found thought-only message, saving thinkingDuration ${pendingThinkingDuration}s for tool ${update.toolName}\n`);
|
|
696
|
+
}
|
|
697
|
+
catch (e) { }
|
|
698
|
+
}
|
|
699
|
+
else {
|
|
700
|
+
try {
|
|
701
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Moving current message (${prev.currentMessage.role}) to history for new tool ${update.toolName}\n`);
|
|
702
|
+
}
|
|
703
|
+
catch (e) { }
|
|
704
|
+
// Move ANY current message to history before showing tool
|
|
705
|
+
newHistory = [...prev.messageHistory, prev.currentMessage];
|
|
706
|
+
}
|
|
601
707
|
}
|
|
708
|
+
// Create tool message with thinkingDuration if applicable
|
|
709
|
+
const toolMessageWithDuration = {
|
|
710
|
+
...toolMessage,
|
|
711
|
+
thinkingDuration: pendingThinkingDuration
|
|
712
|
+
};
|
|
602
713
|
return {
|
|
603
714
|
...prev,
|
|
604
715
|
messageHistory: newHistory,
|
|
605
|
-
currentMessage:
|
|
716
|
+
currentMessage: toolMessageWithDuration,
|
|
606
717
|
isLoading: false,
|
|
607
718
|
isAiWorking: true
|
|
608
719
|
};
|
|
609
720
|
}
|
|
610
|
-
// For completed tools without a current executing one
|
|
611
|
-
|
|
721
|
+
// For completed tools without a current executing one (edge case)
|
|
722
|
+
try {
|
|
723
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Tool ${update.toolName} completed without current executing tool, adding to history\n`);
|
|
724
|
+
}
|
|
725
|
+
catch (e) { }
|
|
612
726
|
let newHistory = prev.messageHistory;
|
|
613
|
-
// If there's a current message, move it to history first
|
|
614
727
|
if (prev.currentMessage) {
|
|
615
728
|
newHistory = [...prev.messageHistory, prev.currentMessage];
|
|
616
729
|
}
|
|
617
|
-
// Add tool message to history
|
|
618
730
|
return {
|
|
619
731
|
...prev,
|
|
620
732
|
messageHistory: [...newHistory, toolMessage],
|
|
621
733
|
currentMessage: null,
|
|
622
|
-
isAiWorking: true
|
|
734
|
+
isAiWorking: true
|
|
623
735
|
};
|
|
624
736
|
});
|
|
625
737
|
});
|
|
@@ -631,8 +743,11 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
631
743
|
if (autoAcceptRef.current) {
|
|
632
744
|
return true;
|
|
633
745
|
}
|
|
634
|
-
// Check if this is a file operation with preview (write_file, write_to_file, or
|
|
635
|
-
const isFileOperation = (request.operationType === 'write_file' ||
|
|
746
|
+
// Check if this is a file operation with preview (write_file, write_to_file, edit_file, or multi_edit_file)
|
|
747
|
+
const isFileOperation = (request.operationType === 'write_file' ||
|
|
748
|
+
request.operationType === 'write_to_file' ||
|
|
749
|
+
request.operationType === 'edit_file' ||
|
|
750
|
+
request.operationType === 'multi_edit_file') && request.preview;
|
|
636
751
|
if (isFileOperation) {
|
|
637
752
|
// File operations: Clear screen and switch to approval screen (focused view)
|
|
638
753
|
clearScreen();
|
|
@@ -647,15 +762,21 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
647
762
|
operationType: request.operationType,
|
|
648
763
|
operationDetails: request.operationDetails,
|
|
649
764
|
resolve: (approved) => {
|
|
650
|
-
//
|
|
651
|
-
clearScreen();
|
|
652
|
-
// Switch back to chat and clear approval request
|
|
765
|
+
// First unmount the approval section to stop rendering
|
|
653
766
|
setState(prev => ({
|
|
654
767
|
...prev,
|
|
655
|
-
screen: 'chat',
|
|
656
768
|
approvalRequest: undefined,
|
|
657
769
|
}));
|
|
658
|
-
|
|
770
|
+
// Use a small timeout to let the unmount visual update flush
|
|
771
|
+
// Then clear screen and return to chat
|
|
772
|
+
setTimeout(() => {
|
|
773
|
+
clearScreen();
|
|
774
|
+
setState(prev => ({
|
|
775
|
+
...prev,
|
|
776
|
+
screen: 'chat',
|
|
777
|
+
}));
|
|
778
|
+
resolve(approved);
|
|
779
|
+
}, 10);
|
|
659
780
|
}
|
|
660
781
|
},
|
|
661
782
|
isLoading: false
|
|
@@ -781,7 +902,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
781
902
|
...prev,
|
|
782
903
|
screen: 'plan-approval',
|
|
783
904
|
planApprovalRequest: {
|
|
784
|
-
|
|
905
|
+
plan,
|
|
785
906
|
resolve
|
|
786
907
|
},
|
|
787
908
|
isLoading: false
|
|
@@ -789,6 +910,46 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
789
910
|
});
|
|
790
911
|
});
|
|
791
912
|
}, [clearScreen]);
|
|
913
|
+
// Set up callback for plan created notification (optional - for future use)
|
|
914
|
+
React.useEffect(() => {
|
|
915
|
+
onPlanCreated((plan) => {
|
|
916
|
+
// The plan will be displayed via the plan-approval screen
|
|
917
|
+
// This callback can be used for additional notifications if needed
|
|
918
|
+
try {
|
|
919
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Plan created: ${plan.title} with ${plan.steps.length} tasks\n`);
|
|
920
|
+
}
|
|
921
|
+
catch (e) { }
|
|
922
|
+
});
|
|
923
|
+
}, [onPlanCreated]);
|
|
924
|
+
// Set up callback for task completion
|
|
925
|
+
React.useEffect(() => {
|
|
926
|
+
onTaskCompleted((task, taskNumber, totalTasks, completionNote) => {
|
|
927
|
+
// Add task completion message to history
|
|
928
|
+
setState(prev => {
|
|
929
|
+
const taskCompletedMessage = {
|
|
930
|
+
id: `task-complete-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
|
931
|
+
role: 'system',
|
|
932
|
+
content: '', // We'll render this specially
|
|
933
|
+
timestamp: new Date(),
|
|
934
|
+
taskCompletion: {
|
|
935
|
+
taskNumber,
|
|
936
|
+
totalTasks,
|
|
937
|
+
taskDescription: task.description,
|
|
938
|
+
completionNote
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
// Move current message to history if exists
|
|
942
|
+
const newHistory = prev.currentMessage
|
|
943
|
+
? [...prev.messageHistory, prev.currentMessage, taskCompletedMessage]
|
|
944
|
+
: [...prev.messageHistory, taskCompletedMessage];
|
|
945
|
+
return {
|
|
946
|
+
...prev,
|
|
947
|
+
messageHistory: newHistory,
|
|
948
|
+
currentMessage: null
|
|
949
|
+
};
|
|
950
|
+
});
|
|
951
|
+
});
|
|
952
|
+
}, [onTaskCompleted]);
|
|
792
953
|
// Set up callback for password requests
|
|
793
954
|
React.useEffect(() => {
|
|
794
955
|
onPasswordRequest(async (message) => {
|
|
@@ -905,6 +1066,8 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
905
1066
|
// Ctrl+F handling - toggle shell focus
|
|
906
1067
|
if (key.ctrl && input === 'f') {
|
|
907
1068
|
if (state.shellState && state.shellState.isRunning) {
|
|
1069
|
+
// Clear screen when entering/exiting focus mode to remove persisted Static content
|
|
1070
|
+
clearScreen();
|
|
908
1071
|
setState(prev => ({
|
|
909
1072
|
...prev,
|
|
910
1073
|
shellState: prev.shellState ? {
|
|
@@ -1140,11 +1303,13 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
1140
1303
|
}
|
|
1141
1304
|
return (React.createElement(Box, { flexDirection: "column" },
|
|
1142
1305
|
state.screen === 'chat' && (React.createElement(React.Fragment, null,
|
|
1143
|
-
React.createElement(MessageList, { history: state.messageHistory, current: state.currentMessage, showBanner: true }),
|
|
1306
|
+
!state.shellState?.isFocused && (React.createElement(MessageList, { history: state.messageHistory, current: state.currentMessage, showBanner: true })),
|
|
1144
1307
|
state.shellState && (React.createElement(InteractiveShell, { command: state.shellState.command, cwd: state.shellState.cwd, isRunning: state.shellState.isRunning, output: state.shellState.output, exitCode: state.shellState.exitCode, error: state.shellState.error, isFocused: state.shellState.isFocused, onResize: state.shellState.onResize, onInput: (input) => {
|
|
1145
1308
|
// PTY MODE: Send everything immediately
|
|
1146
1309
|
onShellInput(input);
|
|
1147
1310
|
}, onFocusChange: (focused) => {
|
|
1311
|
+
// Clear screen when entering/exiting focus mode
|
|
1312
|
+
clearScreen();
|
|
1148
1313
|
setState(prev => ({
|
|
1149
1314
|
...prev,
|
|
1150
1315
|
shellState: prev.shellState ? {
|
|
@@ -1155,7 +1320,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
1155
1320
|
}, onSignal: (signal) => {
|
|
1156
1321
|
onShellSignal(signal);
|
|
1157
1322
|
} })),
|
|
1158
|
-
state.isAiWorking && !state.shellState && (React.createElement(Box, { marginBottom: 1, paddingLeft: 1 },
|
|
1323
|
+
state.isAiWorking && !state.shellState && !state.approvalRequest && (React.createElement(Box, { marginBottom: 1, paddingLeft: 1 },
|
|
1159
1324
|
React.createElement(LoadingIndicator, { key: "loading-indicator" }),
|
|
1160
1325
|
React.createElement(AgentTimer, { key: "agent-timer" }))),
|
|
1161
1326
|
!state.shellState?.isFocused && (state.approvalRequest ? (React.createElement(ApprovalSection, { key: `approval-${state.approvalRequest.message}`, approvalRequest: state.approvalRequest, onApprove: (approved) => {
|
|
@@ -1203,41 +1368,42 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
|
|
|
1203
1368
|
});
|
|
1204
1369
|
}
|
|
1205
1370
|
} })),
|
|
1206
|
-
state.screen === 'plan-approval' && state.planApprovalRequest && (React.createElement(
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
resolve(true);
|
|
1222
|
-
}
|
|
1223
|
-
setState(prev => ({
|
|
1224
|
-
...prev,
|
|
1225
|
-
screen: 'chat',
|
|
1226
|
-
planApprovalRequest: undefined,
|
|
1227
|
-
isLoading: true,
|
|
1228
|
-
isAiWorking: true
|
|
1229
|
-
}));
|
|
1230
|
-
}, onNo: () => {
|
|
1231
|
-
const resolve = state.planApprovalRequest?.resolve;
|
|
1232
|
-
if (resolve) {
|
|
1233
|
-
resolve(false);
|
|
1371
|
+
state.screen === 'plan-approval' && state.planApprovalRequest && (React.createElement(PlanReviewScreen, { plan: state.planApprovalRequest.plan, onApprove: () => {
|
|
1372
|
+
const resolve = state.planApprovalRequest?.resolve;
|
|
1373
|
+
const plan = state.planApprovalRequest?.plan;
|
|
1374
|
+
if (resolve) {
|
|
1375
|
+
resolve(true);
|
|
1376
|
+
}
|
|
1377
|
+
// Add "Plan Accepted" message to history
|
|
1378
|
+
const planAcceptedMessage = {
|
|
1379
|
+
id: `plan-accepted-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
|
1380
|
+
role: 'system',
|
|
1381
|
+
content: '',
|
|
1382
|
+
timestamp: new Date(),
|
|
1383
|
+
planAccepted: {
|
|
1384
|
+
planTitle: plan?.title,
|
|
1385
|
+
totalTasks: plan?.steps?.length
|
|
1234
1386
|
}
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1387
|
+
};
|
|
1388
|
+
setState(prev => ({
|
|
1389
|
+
...prev,
|
|
1390
|
+
screen: 'chat',
|
|
1391
|
+
planApprovalRequest: undefined,
|
|
1392
|
+
messageHistory: [...prev.messageHistory, planAcceptedMessage],
|
|
1393
|
+
isLoading: true,
|
|
1394
|
+
isAiWorking: true
|
|
1395
|
+
}));
|
|
1396
|
+
}, onEdit: () => {
|
|
1397
|
+
const resolve = state.planApprovalRequest?.resolve;
|
|
1398
|
+
if (resolve) {
|
|
1399
|
+
resolve(false);
|
|
1400
|
+
}
|
|
1401
|
+
setState(prev => ({
|
|
1402
|
+
...prev,
|
|
1403
|
+
screen: 'chat',
|
|
1404
|
+
planApprovalRequest: undefined
|
|
1405
|
+
}));
|
|
1406
|
+
} })),
|
|
1241
1407
|
state.screen === 'password-prompt' && state.passwordRequest && (React.createElement(PasswordPrompt, { message: state.passwordRequest.message, onSubmit: (password) => {
|
|
1242
1408
|
const resolve = state.passwordRequest?.resolve;
|
|
1243
1409
|
if (resolve) {
|