@oh-my-pi/pi-coding-agent 6.9.0 → 7.0.0

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 (143) hide show
  1. package/CHANGELOG.md +173 -51
  2. package/examples/sdk/04-skills.ts +1 -1
  3. package/package.json +6 -5
  4. package/src/cli/stats-cli.ts +191 -0
  5. package/src/core/agent-session.ts +214 -4
  6. package/src/core/auth-storage.ts +524 -202
  7. package/src/core/bash-executor.ts +1 -1
  8. package/src/core/extensions/index.ts +2 -0
  9. package/src/core/extensions/runner.ts +31 -0
  10. package/src/core/extensions/types.ts +24 -0
  11. package/src/core/messages.ts +48 -0
  12. package/src/core/model-registry.ts +7 -0
  13. package/src/core/python-executor.ts +29 -8
  14. package/src/core/python-gateway-coordinator.ts +55 -1
  15. package/src/core/python-prelude.py +201 -8
  16. package/src/core/session-manager.ts +10 -1
  17. package/src/core/tools/bash.ts +5 -7
  18. package/src/core/tools/find.ts +18 -5
  19. package/src/core/tools/index.ts +1 -1
  20. package/src/core/tools/lsp/index.ts +13 -2
  21. package/src/core/tools/patch/applicator.ts +115 -17
  22. package/src/core/tools/patch/index.ts +1 -1
  23. package/src/core/tools/patch/normalize.ts +185 -10
  24. package/src/core/tools/python.ts +445 -86
  25. package/src/core/tools/read.ts +4 -4
  26. package/src/core/tools/task/executor.ts +2 -6
  27. package/src/core/tools/task/index.ts +30 -12
  28. package/src/core/tools/task/render.ts +163 -30
  29. package/src/core/tools/task/template.ts +37 -0
  30. package/src/core/tools/task/types.ts +6 -2
  31. package/src/core/tools/task/worker.ts +1 -1
  32. package/src/index.ts +2 -0
  33. package/src/main.ts +12 -0
  34. package/src/modes/interactive/components/python-execution.ts +180 -0
  35. package/src/modes/interactive/components/welcome.ts +1 -0
  36. package/src/modes/interactive/controllers/command-controller.ts +395 -0
  37. package/src/modes/interactive/controllers/input-controller.ts +83 -8
  38. package/src/modes/interactive/interactive-mode.ts +16 -1
  39. package/src/modes/interactive/theme/dark.json +2 -9
  40. package/src/modes/interactive/theme/defaults/alabaster.json +2 -8
  41. package/src/modes/interactive/theme/defaults/amethyst.json +2 -9
  42. package/src/modes/interactive/theme/defaults/anthracite.json +2 -9
  43. package/src/modes/interactive/theme/defaults/basalt.json +89 -88
  44. package/src/modes/interactive/theme/defaults/birch.json +2 -8
  45. package/src/modes/interactive/theme/defaults/dark-abyss.json +2 -8
  46. package/src/modes/interactive/theme/defaults/dark-arctic.json +2 -9
  47. package/src/modes/interactive/theme/defaults/dark-aurora.json +3 -2
  48. package/src/modes/interactive/theme/defaults/dark-catppuccin.json +2 -1
  49. package/src/modes/interactive/theme/defaults/dark-cavern.json +2 -8
  50. package/src/modes/interactive/theme/defaults/dark-copper.json +3 -2
  51. package/src/modes/interactive/theme/defaults/dark-cosmos.json +2 -8
  52. package/src/modes/interactive/theme/defaults/dark-cyberpunk.json +2 -9
  53. package/src/modes/interactive/theme/defaults/dark-dracula.json +2 -9
  54. package/src/modes/interactive/theme/defaults/dark-eclipse.json +2 -8
  55. package/src/modes/interactive/theme/defaults/dark-ember.json +3 -2
  56. package/src/modes/interactive/theme/defaults/dark-equinox.json +2 -8
  57. package/src/modes/interactive/theme/defaults/dark-forest.json +2 -9
  58. package/src/modes/interactive/theme/defaults/dark-github.json +2 -9
  59. package/src/modes/interactive/theme/defaults/dark-gruvbox.json +2 -9
  60. package/src/modes/interactive/theme/defaults/dark-lavender.json +3 -2
  61. package/src/modes/interactive/theme/defaults/dark-lunar.json +2 -8
  62. package/src/modes/interactive/theme/defaults/dark-midnight.json +3 -2
  63. package/src/modes/interactive/theme/defaults/dark-monochrome.json +2 -9
  64. package/src/modes/interactive/theme/defaults/dark-monokai.json +2 -9
  65. package/src/modes/interactive/theme/defaults/dark-nebula.json +2 -8
  66. package/src/modes/interactive/theme/defaults/dark-nord.json +2 -9
  67. package/src/modes/interactive/theme/defaults/dark-ocean.json +2 -9
  68. package/src/modes/interactive/theme/defaults/dark-one.json +2 -9
  69. package/src/modes/interactive/theme/defaults/dark-rainforest.json +2 -8
  70. package/src/modes/interactive/theme/defaults/dark-reef.json +2 -8
  71. package/src/modes/interactive/theme/defaults/dark-retro.json +2 -9
  72. package/src/modes/interactive/theme/defaults/dark-rose-pine.json +2 -1
  73. package/src/modes/interactive/theme/defaults/dark-sakura.json +3 -2
  74. package/src/modes/interactive/theme/defaults/dark-slate.json +3 -2
  75. package/src/modes/interactive/theme/defaults/dark-solarized.json +2 -1
  76. package/src/modes/interactive/theme/defaults/dark-solstice.json +2 -8
  77. package/src/modes/interactive/theme/defaults/dark-starfall.json +2 -8
  78. package/src/modes/interactive/theme/defaults/dark-sunset.json +2 -9
  79. package/src/modes/interactive/theme/defaults/dark-swamp.json +2 -8
  80. package/src/modes/interactive/theme/defaults/dark-synthwave.json +2 -1
  81. package/src/modes/interactive/theme/defaults/dark-taiga.json +2 -8
  82. package/src/modes/interactive/theme/defaults/dark-terminal.json +3 -2
  83. package/src/modes/interactive/theme/defaults/dark-tokyo-night.json +2 -9
  84. package/src/modes/interactive/theme/defaults/dark-tundra.json +2 -8
  85. package/src/modes/interactive/theme/defaults/dark-twilight.json +2 -8
  86. package/src/modes/interactive/theme/defaults/dark-volcanic.json +2 -8
  87. package/src/modes/interactive/theme/defaults/graphite.json +2 -9
  88. package/src/modes/interactive/theme/defaults/light-arctic.json +2 -1
  89. package/src/modes/interactive/theme/defaults/light-aurora-day.json +2 -8
  90. package/src/modes/interactive/theme/defaults/light-canyon.json +2 -8
  91. package/src/modes/interactive/theme/defaults/light-catppuccin.json +2 -1
  92. package/src/modes/interactive/theme/defaults/light-cirrus.json +2 -8
  93. package/src/modes/interactive/theme/defaults/light-coral.json +3 -2
  94. package/src/modes/interactive/theme/defaults/light-cyberpunk.json +2 -9
  95. package/src/modes/interactive/theme/defaults/light-dawn.json +2 -8
  96. package/src/modes/interactive/theme/defaults/light-dunes.json +2 -8
  97. package/src/modes/interactive/theme/defaults/light-eucalyptus.json +3 -2
  98. package/src/modes/interactive/theme/defaults/light-forest.json +2 -9
  99. package/src/modes/interactive/theme/defaults/light-frost.json +3 -2
  100. package/src/modes/interactive/theme/defaults/light-github.json +2 -1
  101. package/src/modes/interactive/theme/defaults/light-glacier.json +2 -8
  102. package/src/modes/interactive/theme/defaults/light-gruvbox.json +2 -9
  103. package/src/modes/interactive/theme/defaults/light-haze.json +2 -8
  104. package/src/modes/interactive/theme/defaults/light-honeycomb.json +3 -2
  105. package/src/modes/interactive/theme/defaults/light-lagoon.json +2 -8
  106. package/src/modes/interactive/theme/defaults/light-lavender.json +3 -2
  107. package/src/modes/interactive/theme/defaults/light-meadow.json +2 -8
  108. package/src/modes/interactive/theme/defaults/light-mint.json +3 -2
  109. package/src/modes/interactive/theme/defaults/light-monochrome.json +2 -1
  110. package/src/modes/interactive/theme/defaults/light-ocean.json +2 -9
  111. package/src/modes/interactive/theme/defaults/light-one.json +2 -8
  112. package/src/modes/interactive/theme/defaults/light-opal.json +2 -8
  113. package/src/modes/interactive/theme/defaults/light-orchard.json +2 -8
  114. package/src/modes/interactive/theme/defaults/light-paper.json +3 -2
  115. package/src/modes/interactive/theme/defaults/light-prism.json +2 -8
  116. package/src/modes/interactive/theme/defaults/light-retro.json +2 -9
  117. package/src/modes/interactive/theme/defaults/light-sand.json +3 -2
  118. package/src/modes/interactive/theme/defaults/light-savanna.json +2 -8
  119. package/src/modes/interactive/theme/defaults/light-solarized.json +2 -1
  120. package/src/modes/interactive/theme/defaults/light-soleil.json +2 -8
  121. package/src/modes/interactive/theme/defaults/light-sunset.json +2 -9
  122. package/src/modes/interactive/theme/defaults/light-synthwave.json +2 -9
  123. package/src/modes/interactive/theme/defaults/light-tokyo-night.json +2 -9
  124. package/src/modes/interactive/theme/defaults/light-wetland.json +2 -8
  125. package/src/modes/interactive/theme/defaults/light-zenith.json +2 -8
  126. package/src/modes/interactive/theme/defaults/limestone.json +2 -8
  127. package/src/modes/interactive/theme/defaults/mahogany.json +2 -9
  128. package/src/modes/interactive/theme/defaults/marble.json +2 -8
  129. package/src/modes/interactive/theme/defaults/obsidian.json +89 -88
  130. package/src/modes/interactive/theme/defaults/onyx.json +89 -88
  131. package/src/modes/interactive/theme/defaults/pearl.json +2 -8
  132. package/src/modes/interactive/theme/defaults/porcelain.json +89 -88
  133. package/src/modes/interactive/theme/defaults/quartz.json +2 -8
  134. package/src/modes/interactive/theme/defaults/sandstone.json +2 -8
  135. package/src/modes/interactive/theme/defaults/titanium.json +88 -87
  136. package/src/modes/interactive/theme/light.json +2 -8
  137. package/src/modes/interactive/theme/theme-schema.json +5 -0
  138. package/src/modes/interactive/theme/theme.ts +7 -0
  139. package/src/modes/interactive/types.ts +7 -1
  140. package/src/modes/interactive/utils/ui-helpers.ts +20 -0
  141. package/src/prompts/system/system-prompt.md +88 -78
  142. package/src/prompts/tools/python.md +39 -2
  143. package/src/prompts/tools/task.md +8 -13
@@ -1,89 +1,90 @@
1
1
  {
2
- "$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/theme-schema.json",
3
- "name": "titanium",
4
- "vars": {
5
- "brushedTitanium": "#151820",
6
- "darkTitanium": "#0f1216",
7
- "electricBlue": "#00b4ff",
8
- "deepBlue": "#0082b3",
9
- "titaniumGold": "#d4c090",
10
- "brightAluminum": "#e8ecf4",
11
- "dimAluminum": "#9ca3b0",
12
- "warningAmber": "#ffb347",
13
- "readoutGreen": "#00ff88",
14
- "alertRed": "#ff4757",
15
- "subtleGray": "#2a3038"
16
- },
17
- "colors": {
18
- "accent": "electricBlue",
19
- "border": "subtleGray",
20
- "borderAccent": "electricBlue",
21
- "borderMuted": "#1f252d",
22
- "success": "readoutGreen",
23
- "error": "alertRed",
24
- "warning": "warningAmber",
25
- "muted": "dimAluminum",
26
- "dim": "#6b7280",
27
- "text": "",
28
- "thinkingText": "dimAluminum",
29
- "selectedBg": "deepBlue",
30
- "userMessageBg": "darkTitanium",
31
- "userMessageText": "",
32
- "customMessageBg": "subtleGray",
33
- "customMessageText": "",
34
- "customMessageLabel": "titaniumGold",
35
- "toolPendingBg": "darkTitanium",
36
- "toolSuccessBg": "darkTitanium",
37
- "toolErrorBg": "#1a0f10",
38
- "toolTitle": "",
39
- "toolOutput": "dimAluminum",
40
- "mdHeading": "electricBlue",
41
- "mdLink": "electricBlue",
42
- "mdLinkUrl": "deepBlue",
43
- "mdCode": "readoutGreen",
44
- "mdCodeBlock": "dimAluminum",
45
- "mdCodeBlockBorder": "subtleGray",
46
- "mdQuote": "dimAluminum",
47
- "mdQuoteBorder": "subtleGray",
48
- "mdHr": "subtleGray",
49
- "mdListBullet": "electricBlue",
50
- "toolDiffAdded": "readoutGreen",
51
- "toolDiffRemoved": "alertRed",
52
- "toolDiffContext": "dimAluminum",
53
- "syntaxComment": "#6b7280",
54
- "syntaxKeyword": "electricBlue",
55
- "syntaxFunction": "readoutGreen",
56
- "syntaxVariable": "brightAluminum",
57
- "syntaxString": "titaniumGold",
58
- "syntaxNumber": "warningAmber",
59
- "syntaxType": "electricBlue",
60
- "syntaxOperator": "electricBlue",
61
- "syntaxPunctuation": "dimAluminum",
62
- "thinkingOff": "#4a5058",
63
- "thinkingMinimal": "#5a6068",
64
- "thinkingLow": "#6a7078",
65
- "thinkingMedium": "dimAluminum",
66
- "thinkingHigh": "electricBlue",
67
- "thinkingXhigh": "titaniumGold",
68
- "bashMode": "readoutGreen",
69
- "statusLineBg": "darkTitanium",
70
- "statusLineSep": "subtleGray",
71
- "statusLineModel": "electricBlue",
72
- "statusLinePath": "brightAluminum",
73
- "statusLineGitClean": "readoutGreen",
74
- "statusLineGitDirty": "warningAmber",
75
- "statusLineContext": "dimAluminum",
76
- "statusLineSpend": "titaniumGold",
77
- "statusLineStaged": "readoutGreen",
78
- "statusLineDirty": "warningAmber",
79
- "statusLineUntracked": "dimAluminum",
80
- "statusLineOutput": "deepBlue",
81
- "statusLineCost": "titaniumGold",
82
- "statusLineSubagents": "electricBlue"
83
- },
84
- "export": {
85
- "pageBg": "brushedTitanium",
86
- "cardBg": "darkTitanium",
87
- "infoBg": "subtleGray"
88
- }
2
+ "$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/theme-schema.json",
3
+ "name": "titanium",
4
+ "vars": {
5
+ "brushedTitanium": "#151820",
6
+ "darkTitanium": "#0f1216",
7
+ "electricBlue": "#00b4ff",
8
+ "deepBlue": "#0082b3",
9
+ "titaniumGold": "#d4c090",
10
+ "brightAluminum": "#e8ecf4",
11
+ "dimAluminum": "#9ca3b0",
12
+ "warningAmber": "#ffb347",
13
+ "readoutGreen": "#00ff88",
14
+ "alertRed": "#ff4757",
15
+ "subtleGray": "#2a3038"
16
+ },
17
+ "colors": {
18
+ "accent": "electricBlue",
19
+ "border": "subtleGray",
20
+ "borderAccent": "electricBlue",
21
+ "borderMuted": "#1f252d",
22
+ "success": "readoutGreen",
23
+ "error": "alertRed",
24
+ "warning": "warningAmber",
25
+ "muted": "dimAluminum",
26
+ "dim": "#6b7280",
27
+ "text": "",
28
+ "thinkingText": "dimAluminum",
29
+ "selectedBg": "deepBlue",
30
+ "userMessageBg": "darkTitanium",
31
+ "userMessageText": "",
32
+ "customMessageBg": "subtleGray",
33
+ "customMessageText": "",
34
+ "customMessageLabel": "titaniumGold",
35
+ "toolPendingBg": "darkTitanium",
36
+ "toolSuccessBg": "darkTitanium",
37
+ "toolErrorBg": "#1a0f10",
38
+ "toolTitle": "",
39
+ "toolOutput": "dimAluminum",
40
+ "mdHeading": "electricBlue",
41
+ "mdLink": "electricBlue",
42
+ "mdLinkUrl": "deepBlue",
43
+ "mdCode": "readoutGreen",
44
+ "mdCodeBlock": "dimAluminum",
45
+ "mdCodeBlockBorder": "subtleGray",
46
+ "mdQuote": "dimAluminum",
47
+ "mdQuoteBorder": "subtleGray",
48
+ "mdHr": "subtleGray",
49
+ "mdListBullet": "electricBlue",
50
+ "toolDiffAdded": "readoutGreen",
51
+ "toolDiffRemoved": "alertRed",
52
+ "toolDiffContext": "dimAluminum",
53
+ "syntaxComment": "#6b7280",
54
+ "syntaxKeyword": "electricBlue",
55
+ "syntaxFunction": "readoutGreen",
56
+ "syntaxVariable": "brightAluminum",
57
+ "syntaxString": "titaniumGold",
58
+ "syntaxNumber": "warningAmber",
59
+ "syntaxType": "electricBlue",
60
+ "syntaxOperator": "electricBlue",
61
+ "syntaxPunctuation": "dimAluminum",
62
+ "thinkingOff": "#4a5058",
63
+ "thinkingMinimal": "#5a6068",
64
+ "thinkingLow": "#6a7078",
65
+ "thinkingMedium": "dimAluminum",
66
+ "thinkingHigh": "electricBlue",
67
+ "thinkingXhigh": "titaniumGold",
68
+ "bashMode": "readoutGreen",
69
+ "statusLineBg": "darkTitanium",
70
+ "statusLineSep": "subtleGray",
71
+ "statusLineModel": "electricBlue",
72
+ "statusLinePath": "brightAluminum",
73
+ "statusLineGitClean": "readoutGreen",
74
+ "statusLineGitDirty": "warningAmber",
75
+ "statusLineContext": "dimAluminum",
76
+ "statusLineSpend": "titaniumGold",
77
+ "statusLineStaged": "readoutGreen",
78
+ "statusLineDirty": "warningAmber",
79
+ "statusLineUntracked": "dimAluminum",
80
+ "statusLineOutput": "deepBlue",
81
+ "statusLineCost": "titaniumGold",
82
+ "statusLineSubagents": "electricBlue",
83
+ "pythonMode": "#f0c040"
84
+ },
85
+ "export": {
86
+ "pageBg": "brushedTitanium",
87
+ "cardBg": "darkTitanium",
88
+ "infoBg": "subtleGray"
89
+ }
89
90
  }
@@ -29,7 +29,6 @@
29
29
  "dim": "dimGray",
30
30
  "text": "",
31
31
  "thinkingText": "mediumGray",
32
-
33
32
  "selectedBg": "selectedBg",
34
33
  "userMessageBg": "userMsgBg",
35
34
  "userMessageText": "",
@@ -41,7 +40,6 @@
41
40
  "toolErrorBg": "toolErrorBg",
42
41
  "toolTitle": "",
43
42
  "toolOutput": "mediumGray",
44
-
45
43
  "mdHeading": "yellow",
46
44
  "mdLink": "blue",
47
45
  "mdLinkUrl": "dimGray",
@@ -52,11 +50,9 @@
52
50
  "mdQuoteBorder": "mediumGray",
53
51
  "mdHr": "mediumGray",
54
52
  "mdListBullet": "green",
55
-
56
53
  "toolDiffAdded": "green",
57
54
  "toolDiffRemoved": "red",
58
55
  "toolDiffContext": "mediumGray",
59
-
60
56
  "syntaxComment": "#008000",
61
57
  "syntaxKeyword": "#0000FF",
62
58
  "syntaxFunction": "#795E26",
@@ -66,16 +62,13 @@
66
62
  "syntaxType": "#267F99",
67
63
  "syntaxOperator": "#000000",
68
64
  "syntaxPunctuation": "#000000",
69
-
70
65
  "thinkingOff": "lightGray",
71
66
  "thinkingMinimal": "#767676",
72
67
  "thinkingLow": "blue",
73
68
  "thinkingMedium": "teal",
74
69
  "thinkingHigh": "#875f87",
75
70
  "thinkingXhigh": "#8b008b",
76
-
77
71
  "bashMode": "green",
78
-
79
72
  "statusLineBg": "#e0e0e0",
80
73
  "statusLineSep": "#808080",
81
74
  "statusLineModel": "#875f87",
@@ -89,7 +82,8 @@
89
82
  "statusLineUntracked": 31,
90
83
  "statusLineOutput": 133,
91
84
  "statusLineCost": 133,
92
- "statusLineSubagents": "teal"
85
+ "statusLineSubagents": "teal",
86
+ "pythonMode": "yellow"
93
87
  },
94
88
  "export": {
95
89
  "pageBg": "#f8f8f8",
@@ -86,6 +86,7 @@
86
86
  "thinkingHigh",
87
87
  "thinkingXhigh",
88
88
  "bashMode",
89
+ "pythonMode",
89
90
  "statusLineBg",
90
91
  "statusLineSep",
91
92
  "statusLineModel",
@@ -306,6 +307,10 @@
306
307
  "$ref": "#/$defs/colorValue",
307
308
  "description": "Editor border color in bash mode"
308
309
  },
310
+ "pythonMode": {
311
+ "$ref": "#/$defs/colorValue",
312
+ "description": "Editor border color in python mode"
313
+ },
309
314
  "statusLineBg": {
310
315
  "$ref": "#/$defs/colorValue",
311
316
  "description": "Status line background"
@@ -897,6 +897,8 @@ const ThemeJsonSchema = Type.Object({
897
897
  thinkingXhigh: ColorValueSchema,
898
898
  // Bash Mode (1 color)
899
899
  bashMode: ColorValueSchema,
900
+ // Python Mode (1 color)
901
+ pythonMode: ColorValueSchema,
900
902
  // Footer Status Line
901
903
  statusLineBg: ColorValueSchema,
902
904
  statusLineSep: ColorValueSchema,
@@ -974,6 +976,7 @@ export type ThemeColor =
974
976
  | "thinkingHigh"
975
977
  | "thinkingXhigh"
976
978
  | "bashMode"
979
+ | "pythonMode"
977
980
  | "statusLineSep"
978
981
  | "statusLineModel"
979
982
  | "statusLinePath"
@@ -1374,6 +1377,10 @@ export class Theme {
1374
1377
  return (str: string) => this.fg("bashMode", str);
1375
1378
  }
1376
1379
 
1380
+ getPythonModeBorderColor(): (str: string) => string {
1381
+ return (str: string) => this.fg("pythonMode", str);
1382
+ }
1383
+
1377
1384
  // ============================================================================
1378
1385
  // Symbol Methods
1379
1386
  // ============================================================================
@@ -1,5 +1,5 @@
1
1
  import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
2
- import type { AssistantMessage, ImageContent, Message } from "@oh-my-pi/pi-ai";
2
+ import type { AssistantMessage, ImageContent, Message, UsageReport } from "@oh-my-pi/pi-ai";
3
3
  import type { Component, Container, Loader, Spacer, Text, TUI } from "@oh-my-pi/pi-tui";
4
4
  import type { AgentSession, AgentSessionEvent } from "../../core/agent-session";
5
5
  import type { ExtensionUIContext } from "../../core/extensions/index";
@@ -15,6 +15,7 @@ import type { CustomEditor } from "./components/custom-editor";
15
15
  import type { HookEditorComponent } from "./components/hook-editor";
16
16
  import type { HookInputComponent } from "./components/hook-input";
17
17
  import type { HookSelectorComponent } from "./components/hook-selector";
18
+ import type { PythonExecutionComponent } from "./components/python-execution";
18
19
  import type { StatusLineComponent } from "./components/status-line";
19
20
  import type { ToolExecutionHandle } from "./components/tool-execution";
20
21
  import type { Theme } from "./theme/theme";
@@ -64,6 +65,9 @@ export interface InteractiveModeContext {
64
65
  pendingTools: Map<string, ToolExecutionHandle>;
65
66
  pendingBashComponents: BashExecutionComponent[];
66
67
  bashComponent: BashExecutionComponent | undefined;
68
+ pendingPythonComponents: PythonExecutionComponent[];
69
+ pythonComponent: PythonExecutionComponent | undefined;
70
+ isPythonMode: boolean;
67
71
  streamingComponent: AssistantMessageComponent | undefined;
68
72
  streamingMessage: AssistantMessage | undefined;
69
73
  loadingAnimation: Loader | undefined;
@@ -130,6 +134,7 @@ export interface InteractiveModeContext {
130
134
  handleShareCommand(): Promise<void>;
131
135
  handleCopyCommand(): Promise<void>;
132
136
  handleSessionCommand(): void;
137
+ handleUsageCommand(reports?: UsageReport[] | null): Promise<void>;
133
138
  handleChangelogCommand(): void;
134
139
  handleHotkeysCommand(): void;
135
140
  handleDumpCommand(): Promise<void>;
@@ -137,6 +142,7 @@ export interface InteractiveModeContext {
137
142
  handleDebugCommand(): Promise<void>;
138
143
  handleArminSaysHi(): void;
139
144
  handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
145
+ handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
140
146
  handleCompactCommand(customInstructions?: string): Promise<void>;
141
147
  executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<void>;
142
148
  openInBrowser(urlOrPath: string): void;
@@ -10,6 +10,7 @@ import { BranchSummaryMessageComponent } from "../components/branch-summary-mess
10
10
  import { CompactionSummaryMessageComponent } from "../components/compaction-summary-message";
11
11
  import { CustomMessageComponent } from "../components/custom-message";
12
12
  import { DynamicBorder } from "../components/dynamic-border";
13
+ import { PythonExecutionComponent } from "../components/python-execution";
13
14
  import { ReadToolGroupComponent } from "../components/read-tool-group";
14
15
  import { ToolExecutionComponent } from "../components/tool-execution";
15
16
  import { UserMessageComponent } from "../components/user-message";
@@ -83,6 +84,20 @@ export class UiHelpers {
83
84
  this.ctx.chatContainer.addChild(component);
84
85
  break;
85
86
  }
87
+ case "pythonExecution": {
88
+ const component = new PythonExecutionComponent(message.code, this.ctx.ui, message.excludeFromContext);
89
+ if (message.output) {
90
+ component.appendOutput(message.output);
91
+ }
92
+ component.setComplete(
93
+ message.exitCode,
94
+ message.cancelled,
95
+ message.truncated ? ({ truncated: true } as TruncationResult) : undefined,
96
+ message.fullOutputPath,
97
+ );
98
+ this.ctx.chatContainer.addChild(component);
99
+ break;
100
+ }
86
101
  case "hookMessage":
87
102
  case "custom": {
88
103
  if (message.display) {
@@ -461,6 +476,11 @@ export class UiHelpers {
461
476
  this.ctx.chatContainer.addChild(component);
462
477
  }
463
478
  this.ctx.pendingBashComponents = [];
479
+ for (const component of this.ctx.pendingPythonComponents) {
480
+ this.ctx.pendingMessagesContainer.removeChild(component);
481
+ this.ctx.chatContainer.addChild(component);
482
+ }
483
+ this.ctx.pendingPythonComponents = [];
464
484
  }
465
485
 
466
486
  findLastAssistantMessage(): AssistantMessage | undefined {