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

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 (133) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/package.json +6 -5
  3. package/src/cli/stats-cli.ts +191 -0
  4. package/src/core/agent-session.ts +103 -1
  5. package/src/core/extensions/index.ts +2 -0
  6. package/src/core/extensions/runner.ts +31 -0
  7. package/src/core/extensions/types.ts +24 -0
  8. package/src/core/messages.ts +48 -0
  9. package/src/core/session-manager.ts +10 -1
  10. package/src/core/tools/bash.ts +5 -7
  11. package/src/core/tools/index.ts +1 -1
  12. package/src/core/tools/patch/applicator.ts +115 -17
  13. package/src/core/tools/patch/index.ts +1 -1
  14. package/src/core/tools/patch/normalize.ts +185 -10
  15. package/src/core/tools/python.ts +444 -86
  16. package/src/core/tools/task/executor.ts +2 -6
  17. package/src/core/tools/task/index.ts +30 -12
  18. package/src/core/tools/task/render.ts +163 -30
  19. package/src/core/tools/task/template.ts +37 -0
  20. package/src/core/tools/task/types.ts +6 -2
  21. package/src/core/tools/task/worker.ts +1 -1
  22. package/src/index.ts +2 -0
  23. package/src/main.ts +12 -0
  24. package/src/modes/interactive/components/python-execution.ts +180 -0
  25. package/src/modes/interactive/components/welcome.ts +1 -0
  26. package/src/modes/interactive/controllers/command-controller.ts +46 -0
  27. package/src/modes/interactive/controllers/input-controller.ts +28 -1
  28. package/src/modes/interactive/interactive-mode.ts +10 -0
  29. package/src/modes/interactive/theme/dark.json +2 -9
  30. package/src/modes/interactive/theme/defaults/alabaster.json +2 -8
  31. package/src/modes/interactive/theme/defaults/amethyst.json +2 -9
  32. package/src/modes/interactive/theme/defaults/anthracite.json +2 -9
  33. package/src/modes/interactive/theme/defaults/basalt.json +89 -88
  34. package/src/modes/interactive/theme/defaults/birch.json +2 -8
  35. package/src/modes/interactive/theme/defaults/dark-abyss.json +2 -8
  36. package/src/modes/interactive/theme/defaults/dark-arctic.json +2 -9
  37. package/src/modes/interactive/theme/defaults/dark-aurora.json +3 -2
  38. package/src/modes/interactive/theme/defaults/dark-catppuccin.json +2 -1
  39. package/src/modes/interactive/theme/defaults/dark-cavern.json +2 -8
  40. package/src/modes/interactive/theme/defaults/dark-copper.json +3 -2
  41. package/src/modes/interactive/theme/defaults/dark-cosmos.json +2 -8
  42. package/src/modes/interactive/theme/defaults/dark-cyberpunk.json +2 -9
  43. package/src/modes/interactive/theme/defaults/dark-dracula.json +2 -9
  44. package/src/modes/interactive/theme/defaults/dark-eclipse.json +2 -8
  45. package/src/modes/interactive/theme/defaults/dark-ember.json +3 -2
  46. package/src/modes/interactive/theme/defaults/dark-equinox.json +2 -8
  47. package/src/modes/interactive/theme/defaults/dark-forest.json +2 -9
  48. package/src/modes/interactive/theme/defaults/dark-github.json +2 -9
  49. package/src/modes/interactive/theme/defaults/dark-gruvbox.json +2 -9
  50. package/src/modes/interactive/theme/defaults/dark-lavender.json +3 -2
  51. package/src/modes/interactive/theme/defaults/dark-lunar.json +2 -8
  52. package/src/modes/interactive/theme/defaults/dark-midnight.json +3 -2
  53. package/src/modes/interactive/theme/defaults/dark-monochrome.json +2 -9
  54. package/src/modes/interactive/theme/defaults/dark-monokai.json +2 -9
  55. package/src/modes/interactive/theme/defaults/dark-nebula.json +2 -8
  56. package/src/modes/interactive/theme/defaults/dark-nord.json +2 -9
  57. package/src/modes/interactive/theme/defaults/dark-ocean.json +2 -9
  58. package/src/modes/interactive/theme/defaults/dark-one.json +2 -9
  59. package/src/modes/interactive/theme/defaults/dark-rainforest.json +2 -8
  60. package/src/modes/interactive/theme/defaults/dark-reef.json +2 -8
  61. package/src/modes/interactive/theme/defaults/dark-retro.json +2 -9
  62. package/src/modes/interactive/theme/defaults/dark-rose-pine.json +2 -1
  63. package/src/modes/interactive/theme/defaults/dark-sakura.json +3 -2
  64. package/src/modes/interactive/theme/defaults/dark-slate.json +3 -2
  65. package/src/modes/interactive/theme/defaults/dark-solarized.json +2 -1
  66. package/src/modes/interactive/theme/defaults/dark-solstice.json +2 -8
  67. package/src/modes/interactive/theme/defaults/dark-starfall.json +2 -8
  68. package/src/modes/interactive/theme/defaults/dark-sunset.json +2 -9
  69. package/src/modes/interactive/theme/defaults/dark-swamp.json +2 -8
  70. package/src/modes/interactive/theme/defaults/dark-synthwave.json +2 -1
  71. package/src/modes/interactive/theme/defaults/dark-taiga.json +2 -8
  72. package/src/modes/interactive/theme/defaults/dark-terminal.json +3 -2
  73. package/src/modes/interactive/theme/defaults/dark-tokyo-night.json +2 -9
  74. package/src/modes/interactive/theme/defaults/dark-tundra.json +2 -8
  75. package/src/modes/interactive/theme/defaults/dark-twilight.json +2 -8
  76. package/src/modes/interactive/theme/defaults/dark-volcanic.json +2 -8
  77. package/src/modes/interactive/theme/defaults/graphite.json +2 -9
  78. package/src/modes/interactive/theme/defaults/light-arctic.json +2 -1
  79. package/src/modes/interactive/theme/defaults/light-aurora-day.json +2 -8
  80. package/src/modes/interactive/theme/defaults/light-canyon.json +2 -8
  81. package/src/modes/interactive/theme/defaults/light-catppuccin.json +2 -1
  82. package/src/modes/interactive/theme/defaults/light-cirrus.json +2 -8
  83. package/src/modes/interactive/theme/defaults/light-coral.json +3 -2
  84. package/src/modes/interactive/theme/defaults/light-cyberpunk.json +2 -9
  85. package/src/modes/interactive/theme/defaults/light-dawn.json +2 -8
  86. package/src/modes/interactive/theme/defaults/light-dunes.json +2 -8
  87. package/src/modes/interactive/theme/defaults/light-eucalyptus.json +3 -2
  88. package/src/modes/interactive/theme/defaults/light-forest.json +2 -9
  89. package/src/modes/interactive/theme/defaults/light-frost.json +3 -2
  90. package/src/modes/interactive/theme/defaults/light-github.json +2 -1
  91. package/src/modes/interactive/theme/defaults/light-glacier.json +2 -8
  92. package/src/modes/interactive/theme/defaults/light-gruvbox.json +2 -9
  93. package/src/modes/interactive/theme/defaults/light-haze.json +2 -8
  94. package/src/modes/interactive/theme/defaults/light-honeycomb.json +3 -2
  95. package/src/modes/interactive/theme/defaults/light-lagoon.json +2 -8
  96. package/src/modes/interactive/theme/defaults/light-lavender.json +3 -2
  97. package/src/modes/interactive/theme/defaults/light-meadow.json +2 -8
  98. package/src/modes/interactive/theme/defaults/light-mint.json +3 -2
  99. package/src/modes/interactive/theme/defaults/light-monochrome.json +2 -1
  100. package/src/modes/interactive/theme/defaults/light-ocean.json +2 -9
  101. package/src/modes/interactive/theme/defaults/light-one.json +2 -8
  102. package/src/modes/interactive/theme/defaults/light-opal.json +2 -8
  103. package/src/modes/interactive/theme/defaults/light-orchard.json +2 -8
  104. package/src/modes/interactive/theme/defaults/light-paper.json +3 -2
  105. package/src/modes/interactive/theme/defaults/light-prism.json +2 -8
  106. package/src/modes/interactive/theme/defaults/light-retro.json +2 -9
  107. package/src/modes/interactive/theme/defaults/light-sand.json +3 -2
  108. package/src/modes/interactive/theme/defaults/light-savanna.json +2 -8
  109. package/src/modes/interactive/theme/defaults/light-solarized.json +2 -1
  110. package/src/modes/interactive/theme/defaults/light-soleil.json +2 -8
  111. package/src/modes/interactive/theme/defaults/light-sunset.json +2 -9
  112. package/src/modes/interactive/theme/defaults/light-synthwave.json +2 -9
  113. package/src/modes/interactive/theme/defaults/light-tokyo-night.json +2 -9
  114. package/src/modes/interactive/theme/defaults/light-wetland.json +2 -8
  115. package/src/modes/interactive/theme/defaults/light-zenith.json +2 -8
  116. package/src/modes/interactive/theme/defaults/limestone.json +2 -8
  117. package/src/modes/interactive/theme/defaults/mahogany.json +2 -9
  118. package/src/modes/interactive/theme/defaults/marble.json +2 -8
  119. package/src/modes/interactive/theme/defaults/obsidian.json +89 -88
  120. package/src/modes/interactive/theme/defaults/onyx.json +89 -88
  121. package/src/modes/interactive/theme/defaults/pearl.json +2 -8
  122. package/src/modes/interactive/theme/defaults/porcelain.json +89 -88
  123. package/src/modes/interactive/theme/defaults/quartz.json +2 -8
  124. package/src/modes/interactive/theme/defaults/sandstone.json +2 -8
  125. package/src/modes/interactive/theme/defaults/titanium.json +88 -87
  126. package/src/modes/interactive/theme/light.json +2 -8
  127. package/src/modes/interactive/theme/theme-schema.json +5 -0
  128. package/src/modes/interactive/theme/theme.ts +7 -0
  129. package/src/modes/interactive/types.ts +5 -0
  130. package/src/modes/interactive/utils/ui-helpers.ts +20 -0
  131. package/src/prompts/system/system-prompt.md +8 -0
  132. package/src/prompts/tools/python.md +40 -2
  133. package/src/prompts/tools/task.md +8 -13
@@ -32,7 +32,6 @@
32
32
  "dim": "lavenderGray",
33
33
  "text": "",
34
34
  "thinkingText": "dustyRose",
35
-
36
35
  "selectedBg": "selectedBg",
37
36
  "userMessageBg": "userMsgBg",
38
37
  "userMessageText": "",
@@ -44,7 +43,6 @@
44
43
  "toolErrorBg": "toolErrorBg",
45
44
  "toolTitle": "",
46
45
  "toolOutput": "dustyRose",
47
-
48
46
  "mdHeading": "warmGold",
49
47
  "mdLink": "quartzPurple",
50
48
  "mdLinkUrl": "lavenderGray",
@@ -55,11 +53,9 @@
55
53
  "mdQuoteBorder": "softRose",
56
54
  "mdHr": "softRose",
57
55
  "mdListBullet": "roseGreen",
58
-
59
56
  "toolDiffAdded": "roseGreen",
60
57
  "toolDiffRemoved": "roseRed",
61
58
  "toolDiffContext": "dustyRose",
62
-
63
59
  "syntaxComment": "#7fa090",
64
60
  "syntaxKeyword": "#8070a0",
65
61
  "syntaxFunction": "#c07088",
@@ -69,16 +65,13 @@
69
65
  "syntaxType": "#9e6b7b",
70
66
  "syntaxOperator": "#3a2830",
71
67
  "syntaxPunctuation": "#3a2830",
72
-
73
68
  "thinkingOff": "softRose",
74
69
  "thinkingMinimal": "#a898b0",
75
70
  "thinkingLow": "#8070a0",
76
71
  "thinkingMedium": "#c07088",
77
72
  "thinkingHigh": "#9e6b7b",
78
73
  "thinkingXhigh": "#8b4560",
79
-
80
74
  "bashMode": "roseGreen",
81
-
82
75
  "statusLineBg": "#f5e8ed",
83
76
  "statusLineSep": "#9e6b7b",
84
77
  "statusLineModel": "#8070a0",
@@ -92,7 +85,8 @@
92
85
  "statusLineUntracked": 139,
93
86
  "statusLineOutput": 132,
94
87
  "statusLineCost": 132,
95
- "statusLineSubagents": "rosePink"
88
+ "statusLineSubagents": "rosePink",
89
+ "pythonMode": "#f0c040"
96
90
  },
97
91
  "export": {
98
92
  "pageBg": "#fbf7f9",
@@ -31,7 +31,6 @@
31
31
  "dim": "darkGray",
32
32
  "text": "",
33
33
  "thinkingText": "mediumGray",
34
-
35
34
  "selectedBg": "selectedBg",
36
35
  "userMessageBg": "userMsgBg",
37
36
  "userMessageText": "",
@@ -43,7 +42,6 @@
43
42
  "toolErrorBg": "toolErrorBg",
44
43
  "toolTitle": "",
45
44
  "toolOutput": "mediumGray",
46
-
47
45
  "mdHeading": "amber",
48
46
  "mdLink": "terracotta",
49
47
  "mdLinkUrl": "mediumGray",
@@ -54,11 +52,9 @@
54
52
  "mdQuoteBorder": "erosion",
55
53
  "mdHr": "erosion",
56
54
  "mdListBullet": "sage",
57
-
58
55
  "toolDiffAdded": "sage",
59
56
  "toolDiffRemoved": "rust",
60
57
  "toolDiffContext": "mediumGray",
61
-
62
58
  "syntaxComment": "#688058",
63
59
  "syntaxKeyword": "#b86040",
64
60
  "syntaxFunction": "#c87850",
@@ -68,16 +64,13 @@
68
64
  "syntaxType": "#8a6848",
69
65
  "syntaxOperator": "#302820",
70
66
  "syntaxPunctuation": "#302820",
71
-
72
67
  "thinkingOff": "erosion",
73
68
  "thinkingMinimal": "#a89888",
74
69
  "thinkingLow": "#c87850",
75
70
  "thinkingMedium": "#b86040",
76
71
  "thinkingHigh": "#a05030",
77
72
  "thinkingXhigh": "#903020",
78
-
79
73
  "bashMode": "sage",
80
-
81
74
  "statusLineBg": "#ebe0d0",
82
75
  "statusLineSep": "#9a8878",
83
76
  "statusLineModel": "#a05030",
@@ -91,7 +84,8 @@
91
84
  "statusLineUntracked": 95,
92
85
  "statusLineOutput": 131,
93
86
  "statusLineCost": 131,
94
- "statusLineSubagents": "rust"
87
+ "statusLineSubagents": "rust",
88
+ "pythonMode": "amber"
95
89
  },
96
90
  "export": {
97
91
  "pageBg": "#f5ede3",
@@ -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
  // ============================================================================
@@ -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;
@@ -137,6 +141,7 @@ export interface InteractiveModeContext {
137
141
  handleDebugCommand(): Promise<void>;
138
142
  handleArminSaysHi(): void;
139
143
  handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
144
+ handlePythonCommand(code: string, excludeFromContext?: boolean): Promise<void>;
140
145
  handleCompactCommand(customInstructions?: string): Promise<void>;
141
146
  executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<void>;
142
147
  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 {
@@ -200,6 +200,13 @@ Do not open a file hoping to find something. Know where to look first.
200
200
  - When summarizing: plain text, file paths. Do not echo content back.
201
201
  {{/ifAny}}
202
202
  - Be brief. Show file paths clearly.
203
+ {{#has tools "ask"}}
204
+
205
+ ### Concurrent work
206
+ Other agents or the user may be editing files concurrently.
207
+ When file contents differ from expectations or edits fail: re-read and adapt.
208
+ **Ask before** `git checkout/restore/reset`, bulk overwrites, or deleting code you didn't write.
209
+ {{/has}}
203
210
  </practice>
204
211
 
205
212
  <method>
@@ -324,6 +331,7 @@ Keep going until finished.
324
331
  - Do not write code before stating assumptions.
325
332
  - Do not claim correctness you haven't verified.
326
333
  - Do not handle only the happy path.
334
+ {{#has tools "ask"}}- If files differ from expectations, ask before discarding uncommitted work.{{/has}}
327
335
 
328
336
 
329
337
  Let edge cases surface before you handle them. Let the failure modes exist in your mind before you prevent them. Let the code be smaller than your first instinct.
@@ -1,4 +1,42 @@
1
- Executes Python code in an IPython kernel (session or per-call) with optional timeout.
1
+ Executes Python cells sequentially in a persistent IPython kernel.
2
+
3
+ ## How to use (REPL discipline)
4
+
5
+ The kernel persists between calls and between cells. **Imports, variables, and functions survive.** Use this.
6
+
7
+ **Work incrementally:**
8
+ - One logical step per cell (imports, define a function, test it, use it)
9
+ - Pass multiple small cells in one call—they execute sequentially
10
+ - Define small functions you can reuse and debug individually
11
+ - Put explanations in the assistant message or cell title, **not** inside code
12
+
13
+ **When something fails:**
14
+ - The error tells you which cell failed (e.g., "Cell 3 failed")
15
+ - Earlier cells already ran—their state persists in the kernel
16
+ - Resubmit with only the fixed cell (or the fixed cell + remaining cells)
17
+ - Do NOT rewrite working cells or re-import modules
18
+
19
+ **Anti-patterns to avoid:**
20
+ - Putting everything in one giant cell
21
+ - Re-importing modules you already imported
22
+ - Rewriting working code when only one part failed
23
+ - Large functions that are hard to debug piece by piece
24
+
25
+ ```python
26
+ # BAD: One giant cell
27
+ cells: [{
28
+ "title": "all-in-one",
29
+ "code": "import json\nfrom pathlib import Path\ndef process_all_files():\n # 50 lines...\n pass\nresult = process_all_files()"
30
+ }]
31
+
32
+ # GOOD: Multiple small cells
33
+ cells: [
34
+ {"title": "imports", "code": "import json\nfrom pathlib import Path"},
35
+ {"title": "parse helper", "code": "def parse_config(path):\n return json.loads(Path(path).read_text())"},
36
+ {"title": "test helper", "code": "parse_config('config.json')"},
37
+ {"title": "use helper", "code": "configs = [parse_config(p) for p in Path('.').glob('*.json')]"}
38
+ ]
39
+ ```
2
40
 
3
41
  ## When to use Python
4
42
 
@@ -75,7 +113,7 @@ cols(read("data.tsv"), 0, 2, sep="\t")
75
113
 
76
114
  - Code executes as IPython cells; users see the full cell output (including rendered figures, tables, etc.)
77
115
  - Kernel persists for the session by default; per-call mode uses a fresh kernel each call. Use `reset: true` to clear state when session mode is active
78
- - Use `workdir` parameter instead of `os.chdir()` in tool call
116
+ - Use `cwd` parameter instead of `os.chdir()` in tool call
79
117
  - Use `plt.show()` to display figures
80
118
  - Use `display()` from IPython.display for rich output (HTML, Markdown, images, etc.)
81
119
  - Output streams in real time, truncated after 50KB
@@ -49,12 +49,12 @@ Agents with "Output: structured" have a fixed schema enforced via frontmatter; y
49
49
  ## Parameters
50
50
 
51
51
  - `agent`: Agent type to use for all tasks
52
- - `context`: **Required context from conversation** - include ALL relevant info: requirements, schemas, decisions, constraints. Subagents cannot see chat history.
53
- - `model`: (optional) Model override (fuzzy matching, e.g., "sonnet", "opus")
54
- - `tasks`: Array of `{id, task, description}` - tasks to run in parallel (max {{MAX_PARALLEL_TASKS}}, {{MAX_CONCURRENCY}} concurrent)
52
+ - `context`: Template with `{{placeholders}}` for multi-task. Each placeholder is filled from task vars.
53
+ - `model`: (optional) Model override for all tasks (fuzzy matching, e.g., "sonnet", "opus")
54
+ - `tasks`: Array of `{id, description, vars}` - tasks to run in parallel (max {{MAX_PARALLEL_TASKS}}, {{MAX_CONCURRENCY}} concurrent)
55
55
  - `id`: Short CamelCase identifier for display (max 20 chars, e.g., "SessionStore", "LspRefactor")
56
- - `task`: The task prompt for the agent
57
56
  - `description`: Short human-readable description of what the task does
57
+ - `vars`: Object with keys matching `{{placeholders}}` in context
58
58
  - `output`: (optional) JTD schema for structured subagent output (used by the complete tool)
59
59
 
60
60
  ## Example
@@ -65,7 +65,7 @@ assistant: I'll execute the refactoring plan.
65
65
  assistant: Uses the Task tool:
66
66
  {
67
67
  "agent": "task",
68
- "context": "Refactoring the auth module into separate concerns.\n\nPlan:\n1. AuthProvider - Extract React context and provider from src/auth/index.tsx\n2. AuthApi - Extract API calls to src/auth/api.ts, use existing fetchJson helper\n3. AuthTypes - Move types to src/auth/types.ts, re-export from index\n\nConstraints:\n- Preserve all existing exports from src/auth/index.tsx\n- Use project's fetchJson (src/utils/http.ts), don't use raw fetch\n- No new dependencies",
68
+ "context": "Refactoring the auth module into separate concerns.\n\nPlan:\n1. AuthProvider - Extract React context and provider from src/auth/index.tsx\n2. AuthApi - Extract API calls to src/auth/api.ts, use existing fetchJson helper\n3. AuthTypes - Move types to types.ts, re-export from index\n\nConstraints:\n- Preserve all existing exports from src/auth/index.tsx\n- Use project's fetchJson (src/utils/http.ts), don't use raw fetch\n- No new dependencies\n\nTask: {{step}}\n\nFiles: {{files}}",
69
69
  "output": {
70
70
  "properties": {
71
71
  "summary": { "type": "string" },
@@ -74,14 +74,9 @@ assistant: Uses the Task tool:
74
74
  }
75
75
  },
76
76
  "tasks": [
77
- { "id": "AuthProvider", "task": "Execute step 1: Extract AuthProvider and AuthContext", "description": "Extract React context" },
78
- { "id": "AuthApi", "task": "Execute step 2: Extract API calls to api.ts", "description": "Extract API layer" },
79
- { "id": "AuthTypes", "task": "Execute step 3: Move types to types.ts", "description": "Extract types" }
77
+ { "id": "AuthProvider", "description": "Extract React context", "vars": { "step": "Execute step 1: Extract AuthProvider and AuthContext", "files": "src/auth/index.tsx" } },
78
+ { "id": "AuthApi", "description": "Extract API layer", "vars": { "step": "Execute step 2: Extract API calls to api.ts", "files": "src/auth/api.ts" } },
79
+ { "id": "AuthTypes", "description": "Extract types", "vars": { "step": "Execute step 3: Move types to types.ts", "files": "src/auth/types.ts" } }
80
80
  ]
81
81
  }
82
82
  </example>
83
-
84
- Key points:
85
- - **Plan in context**: The full plan is written once; each task references its step without repeating shared constraints
86
- - **Parallel execution**: 3 agents run concurrently, each owning one step - no duplicated work
87
- - **Structured output**: JTD schema ensures consistent reporting across all agents