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.
Files changed (98) hide show
  1. package/dist/cli-adapter.d.ts +8 -6
  2. package/dist/cli-adapter.d.ts.map +1 -1
  3. package/dist/cli-adapter.js +599 -182
  4. package/dist/cli-adapter.js.map +1 -1
  5. package/dist/config/slash-commands.d.ts.map +1 -1
  6. package/dist/config/slash-commands.js +1 -0
  7. package/dist/config/slash-commands.js.map +1 -1
  8. package/dist/context/context-manager.d.ts +4 -1
  9. package/dist/context/context-manager.d.ts.map +1 -1
  10. package/dist/context/context-manager.js +30 -7
  11. package/dist/context/context-manager.js.map +1 -1
  12. package/dist/context/handlers/wsl-handler.d.ts +10 -0
  13. package/dist/context/handlers/wsl-handler.d.ts.map +1 -1
  14. package/dist/context/handlers/wsl-handler.js +29 -1
  15. package/dist/context/handlers/wsl-handler.js.map +1 -1
  16. package/dist/index.js +30 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/services/ai-service-client.d.ts +1 -0
  19. package/dist/services/ai-service-client.d.ts.map +1 -1
  20. package/dist/services/ai-service-client.js.map +1 -1
  21. package/dist/tools/command.d.ts.map +1 -1
  22. package/dist/tools/command.js +136 -21
  23. package/dist/tools/command.js.map +1 -1
  24. package/dist/tools/file-ops.d.ts +1 -0
  25. package/dist/tools/file-ops.d.ts.map +1 -1
  26. package/dist/tools/file-ops.js +131 -0
  27. package/dist/tools/file-ops.js.map +1 -1
  28. package/dist/tools/inspect-symbol.js +27 -27
  29. package/dist/tools/inspect-symbol.js.map +1 -1
  30. package/dist/tools/plan-mode.d.ts +55 -19
  31. package/dist/tools/plan-mode.d.ts.map +1 -1
  32. package/dist/tools/plan-mode.js +204 -123
  33. package/dist/tools/plan-mode.js.map +1 -1
  34. package/dist/tools/reproduce_issue.d.ts +2 -0
  35. package/dist/tools/reproduce_issue.d.ts.map +1 -0
  36. package/dist/tools/reproduce_issue.js +166 -0
  37. package/dist/tools/reproduce_issue.js.map +1 -0
  38. package/dist/tools/types.d.ts +1 -1
  39. package/dist/tools/types.d.ts.map +1 -1
  40. package/dist/tools/validation.d.ts.map +1 -1
  41. package/dist/tools/validation.js +4 -3
  42. package/dist/tools/validation.js.map +1 -1
  43. package/dist/types/index.d.ts +11 -1
  44. package/dist/types/index.d.ts.map +1 -1
  45. package/dist/ui/components/App.d.ts +6 -6
  46. package/dist/ui/components/App.d.ts.map +1 -1
  47. package/dist/ui/components/App.js +228 -62
  48. package/dist/ui/components/App.js.map +1 -1
  49. package/dist/ui/components/DiffViewer.d.ts.map +1 -1
  50. package/dist/ui/components/DiffViewer.js +69 -58
  51. package/dist/ui/components/DiffViewer.js.map +1 -1
  52. package/dist/ui/components/FileTagAutocomplete.d.ts +11 -0
  53. package/dist/ui/components/FileTagAutocomplete.d.ts.map +1 -0
  54. package/dist/ui/components/FileTagAutocomplete.js +27 -0
  55. package/dist/ui/components/FileTagAutocomplete.js.map +1 -0
  56. package/dist/ui/components/InputBox.d.ts.map +1 -1
  57. package/dist/ui/components/InputBox.js +209 -7
  58. package/dist/ui/components/InputBox.js.map +1 -1
  59. package/dist/ui/components/InteractiveShell.d.ts.map +1 -1
  60. package/dist/ui/components/InteractiveShell.js +177 -13
  61. package/dist/ui/components/InteractiveShell.js.map +1 -1
  62. package/dist/ui/components/MessageDisplay.d.ts.map +1 -1
  63. package/dist/ui/components/MessageDisplay.js +3 -3
  64. package/dist/ui/components/MessageDisplay.js.map +1 -1
  65. package/dist/ui/components/PlanAcceptedMessage.d.ts +12 -0
  66. package/dist/ui/components/PlanAcceptedMessage.d.ts.map +1 -0
  67. package/dist/ui/components/PlanAcceptedMessage.js +22 -0
  68. package/dist/ui/components/PlanAcceptedMessage.js.map +1 -0
  69. package/dist/ui/components/PlanReviewScreen.d.ts +14 -0
  70. package/dist/ui/components/PlanReviewScreen.d.ts.map +1 -0
  71. package/dist/ui/components/PlanReviewScreen.js +52 -0
  72. package/dist/ui/components/PlanReviewScreen.js.map +1 -0
  73. package/dist/ui/components/StreamingMessageDisplay.d.ts.map +1 -1
  74. package/dist/ui/components/StreamingMessageDisplay.js +3 -3
  75. package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
  76. package/dist/ui/components/TaskCompletedMessage.d.ts +14 -0
  77. package/dist/ui/components/TaskCompletedMessage.d.ts.map +1 -0
  78. package/dist/ui/components/TaskCompletedMessage.js +25 -0
  79. package/dist/ui/components/TaskCompletedMessage.js.map +1 -0
  80. package/dist/ui/components/ToolExecutionMessage.d.ts.map +1 -1
  81. package/dist/ui/components/ToolExecutionMessage.js +207 -20
  82. package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
  83. package/dist/utils/conversation-logger.d.ts +127 -0
  84. package/dist/utils/conversation-logger.d.ts.map +1 -0
  85. package/dist/utils/conversation-logger.js +283 -0
  86. package/dist/utils/conversation-logger.js.map +1 -0
  87. package/dist/utils/editor-utils.d.ts +37 -0
  88. package/dist/utils/editor-utils.d.ts.map +1 -1
  89. package/dist/utils/editor-utils.js +212 -1
  90. package/dist/utils/editor-utils.js.map +1 -1
  91. package/dist/utils/input-classifier.d.ts.map +1 -1
  92. package/dist/utils/input-classifier.js +10 -3
  93. package/dist/utils/input-classifier.js.map +1 -1
  94. package/dist/utils/markdown-parser.d.ts.map +1 -1
  95. package/dist/utils/markdown-parser.js +4 -2
  96. package/dist/utils/markdown-parser.js.map +1 -1
  97. package/package.json +1 -1
  98. 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,EAChF,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
+ {"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,CAiB3D;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"}
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"}
@@ -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 \s* (zero or more whitespace) on BOTH sides
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
- // and trailing newlines, allowing the replacement to set them fresh.
20
- const finalPattern = `\\s*${internalPattern}\\s*`;
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":"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"}
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,kFAAkF;IAClF,wEAAwE;IACxE,wEAAwE;IACxE,sEAAsE;IACtE,MAAM,YAAY,GAAG,gBAAgB,eAAe,eAAe,CAAC;IAEpE,OAAO,IAAI,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,aAAa;IACxB;;;;;;;;OAQG;IACH,KAAK,CAAC,gBAAgB,CACpB,QAAgB,EAChB,aAAqB,EACrB,WAAmB,EACnB,GAAW;QAEX,IAAI,CAAC;YACH,oBAAoB;YACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YAE7C,uBAAuB;YACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,OAAO;oBACL,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,mBAAmB,QAAQ,EAAE;oBACpC,UAAU,EAAE,iGAAiG;iBAC9G,CAAC;YACJ,CAAC;YAED,oBAAoB;YACpB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEnD,oDAAoD;YACpD,MAAM,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAErE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YACxD,CAAC;YAED,6BAA6B;YAC7B,IAAI,YAAY,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;gBAC3B,OAAO,IAAI,CAAC,wBAAwB,CAAC,kBAAkB,EAAE;oBACvD,KAAK,EAAE,YAAY,CAAC,KAAK;iBAC1B,CAAC,CAAC;YACL,CAAC;YAED,oBAAoB;YACpB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,qBAAqB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBACpF,UAAU,EAAE,2DAA2D;aACxE,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACK,kBAAkB,CACxB,OAAe,EACf,OAAe;QAEf,oCAAoC;QACpC,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAChD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACjC,CAAC;QAED,mCAAmC;QACnC,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAErC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACrC,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;IACjD,CAAC;IAED;;;;;;OAMG;IACK,wBAAwB,CAC9B,KAAsB,EACtB,OAA+B;QAE/B,QAAQ,KAAK,EAAE,CAAC;YACd,KAAK,WAAW;gBACd,OAAO;oBACL,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,qEAAqE;oBAC5E,UAAU,EACR,oQAAoQ;iBACvQ,CAAC;YAEJ,KAAK,kBAAkB;gBACrB,OAAO;oBACL,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,mBAAmB,OAAO,CAAC,KAAK,wCAAwC;oBAC/E,UAAU,EACR,sGAAsG;iBACzG,CAAC;YAEJ;gBACE,OAAO;oBACL,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,2BAA2B;oBAClC,UAAU,EAAE,sCAAsC;iBACnD,CAAC;QACN,CAAC;IACH,CAAC;CACF"}
@@ -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":"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"}
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
- tasks: string[];
49
- question: string;
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":"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"}
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: 'Preview', fullDiff: approvalRequest.preview.fullDiff })),
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
- // If we don't have a current assistant message, create one for the thoughts
213
- if (!prev.currentMessage || prev.currentMessage.role !== 'assistant') {
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: state.currentWorkingDirectory,
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
- // Don't add tool messages if we're not on chat screen
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 same name and executing, update it and move to history
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 // Keep AI working state active (more tool calls or response may follow)
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
- // Move ANY current message to history before showing tool
600
- newHistory = [...prev.messageHistory, prev.currentMessage];
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: toolMessage,
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
- // IMPORTANT: Preserve current message before adding tool to history
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 // Keep AI working state active
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 edit_file)
635
- const isFileOperation = (request.operationType === 'write_file' || request.operationType === 'write_to_file' || request.operationType === 'edit_file') && request.preview;
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
- // Clear screen and return to chat
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
- resolve(approved);
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
- ...plan,
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(Box, { flexDirection: "column" },
1207
- React.createElement(Box, { marginBottom: 1 },
1208
- React.createElement(Text, { bold: true, color: "#00ccff" }, "\uD83D\uDCCB Implementation Plan")),
1209
- React.createElement(Box, { flexDirection: "column", marginBottom: 1, paddingX: 2 },
1210
- React.createElement(Text, { bold: true, color: "#ffaa00" }, "Tasks:"),
1211
- state.planApprovalRequest.tasks.map((task, index) => (React.createElement(Box, { key: index, marginTop: 1 },
1212
- React.createElement(Text, { color: "#666666" },
1213
- index + 1,
1214
- ". "),
1215
- React.createElement(Text, null, task))))),
1216
- React.createElement(Box, { marginTop: 1 },
1217
- React.createElement(Text, { color: "#00ccff" }, state.planApprovalRequest.question)),
1218
- React.createElement(ConfirmPrompt, { message: "Implement this plan?", onYes: () => {
1219
- const resolve = state.planApprovalRequest?.resolve;
1220
- if (resolve) {
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
- setState(prev => ({
1236
- ...prev,
1237
- screen: 'chat',
1238
- planApprovalRequest: undefined
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) {