Skip to content

Commit 41ddb7d

Browse files
author
ShayBC
committed
Resolved merge conflicts
2 parents c04adc6 + 2773208 commit 41ddb7d

30 files changed

+1015
-627
lines changed

.changeset/chilly-bugs-pay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"roo-cline": patch
3+
---
4+
5+
Delete task confirmation enhancements

.changeset/tasty-grapes-suffer.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"roo-cline": patch
3+
---
4+
5+
Fix maxTokens defaults for Claude 3.7 Sonnet models

.changeset/young-hornets-taste.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"roo-cline": patch
3+
---
4+
5+
Prettier thinking blocks

.github/pull_request_template.md

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,35 @@
1-
<!-- **Note:** Consider creating PRs as a DRAFT. For early feedback and self-review. -->
1+
## Context
22

3-
## Description
3+
<!-- Brief description of WHAT you’re doing and WHY. -->
44

5-
## Type of change
5+
## Implementation
66

7-
<!-- Please ignore options that are not relevant -->
7+
<!--
88
9-
- [ ] Bug fix (non-breaking change which fixes an issue)
10-
- [ ] New feature
11-
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
12-
- [ ] This change requires a documentation update
9+
Some description of HOW you achieved it. Perhaps give a high level description of the program flow. Did you need to refactor something? What tradeoffs did you take? Are there things in here which you’d particularly like people to pay close attention to?
1310
14-
## How Has This Been Tested?
11+
-->
1512

16-
<!-- Please describe the tests that you ran to verify your changes -->
13+
## Screenshots
1714

18-
## Checklist:
15+
| before | after |
16+
| ------ | ----- |
17+
| | |
1918

20-
<!-- Go over all the following points, and put an `x` in all the boxes that apply -->
19+
## How to Test
2120

22-
- [ ] My code follows the patterns of this project
23-
- [ ] I have performed a self-review of my own code
24-
- [ ] I have commented my code, particularly in hard-to-understand areas
25-
- [ ] I have made corresponding changes to the documentation
21+
<!--
2622
27-
## Additional context
23+
A straightforward scenario of how to test your changes will help reviewers that are not familiar with the part of the code that you are changing but want to see it in action. This section can include a description or step-by-step instructions of how to get to the state of v2 that your change affects.
2824
29-
<!-- Add any other context or screenshots about the pull request here -->
25+
A "How To Test" section can look something like this:
3026
31-
## Related Issues
27+
- Sign in with a user with tracks
28+
- Activate `show_awesome_cat_gifs` feature (add `?feature.show_awesome_cat_gifs=1` to your URL)
29+
- You should see a GIF with cats dancing
3230
33-
<!-- List any related issues here. Use the GitHub issue linking syntax: #issue-number -->
31+
-->
3432

35-
## Reviewers
33+
## Get in Touch
3634

37-
<!-- @mention specific team members or individuals who should review this PR -->
35+
<!-- We'd love to have a way to chat with you about your changes if necessary. If you're in the [Roo Code Discord](https://discord.gg/roocode), please share your handle here. -->

src/api/providers/openrouter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ export async function getOpenRouterModels() {
278278
modelInfo.supportsPromptCache = true
279279
modelInfo.cacheWritesPrice = 3.75
280280
modelInfo.cacheReadsPrice = 0.3
281-
modelInfo.maxTokens = 64_000
281+
modelInfo.maxTokens = rawModel.id === "anthropic/claude-3.7-sonnet:thinking" ? 64_000 : 16_384
282282
break
283283
case rawModel.id.startsWith("anthropic/claude-3.5-sonnet-20240620"):
284284
modelInfo.supportsPromptCache = true

src/core/Cline.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
everyLineHasLineNumbers,
2323
truncateOutput,
2424
} from "../integrations/misc/extract-text"
25-
import { TerminalManager } from "../integrations/terminal/TerminalManager"
25+
import { TerminalManager, ExitCodeDetails } from "../integrations/terminal/TerminalManager"
2626
import { UrlContentFetcher } from "../services/browser/UrlContentFetcher"
2727
import { listFiles } from "../services/glob/list-files"
2828
import { regexSearchFiles } from "../services/ripgrep"
@@ -159,7 +159,7 @@ export class Cline {
159159
throw new Error("Either historyItem or task/images must be provided")
160160
}
161161

162-
this.taskId = crypto.randomUUID()
162+
this.taskId = historyItem ? historyItem.id : crypto.randomUUID()
163163
this.taskNumber = -1
164164
this.apiConfiguration = apiConfiguration
165165
this.api = buildApiHandler(apiConfiguration)
@@ -173,10 +173,6 @@ export class Cline {
173173
this.diffViewProvider = new DiffViewProvider(cwd)
174174
this.enableCheckpoints = enableCheckpoints ?? false
175175

176-
if (historyItem) {
177-
this.taskId = historyItem.id
178-
}
179-
180176
// Initialize diffStrategy based on current state
181177
this.updateDiffStrategy(Experiments.isEnabled(experiments ?? {}, EXPERIMENT_IDS.DIFF_STRATEGY))
182178

@@ -927,10 +923,21 @@ export class Cline {
927923
})
928924

929925
let completed = false
930-
process.once("completed", () => {
926+
let exitDetails: ExitCodeDetails | undefined
927+
process.once("completed", (output?: string) => {
928+
// Use provided output if available, otherwise keep existing result.
929+
if (output) {
930+
lines = output.split("\n")
931+
}
931932
completed = true
932933
})
933934

935+
process.once("shell_execution_complete", (id: number, details: ExitCodeDetails) => {
936+
if (id === terminalInfo.id) {
937+
exitDetails = details
938+
}
939+
})
940+
934941
process.once("no_shell_integration", async () => {
935942
await this.say("shell_integration_warning")
936943
})
@@ -962,7 +969,18 @@ export class Cline {
962969
}
963970

964971
if (completed) {
965-
return [false, `Command executed.${result.length > 0 ? `\nOutput:\n${result}` : ""}`]
972+
let exitStatus = "No exit code available"
973+
if (exitDetails !== undefined) {
974+
if (exitDetails.signal) {
975+
exitStatus = `Process terminated by signal ${exitDetails.signal} (${exitDetails.signalName})`
976+
if (exitDetails.coreDumpPossible) {
977+
exitStatus += " - core dump possible"
978+
}
979+
} else {
980+
exitStatus = `Exit code: ${exitDetails.exitCode}`
981+
}
982+
}
983+
return [false, `Command executed. ${exitStatus}${result.length > 0 ? `\nOutput:\n${result}` : ""}`]
966984
} else {
967985
return [
968986
false,

src/integrations/terminal/TerminalManager.ts

Lines changed: 169 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -70,43 +70,192 @@ Interestingly, some environments like Cursor enable these APIs even without the
7070
This approach allows us to leverage advanced features when available while ensuring broad compatibility.
7171
*/
7272
declare module "vscode" {
73+
// https://github.com/microsoft/vscode/blob/f0417069c62e20f3667506f4b7e53ca0004b4e3e/src/vscode-dts/vscode.d.ts#L7442
74+
// interface Terminal {
75+
// shellIntegration?: {
76+
// cwd?: vscode.Uri
77+
// executeCommand?: (command: string) => {
78+
// read: () => AsyncIterable<string>
79+
// }
80+
// }
81+
// }
7382
// https://github.com/microsoft/vscode/blob/f0417069c62e20f3667506f4b7e53ca0004b4e3e/src/vscode-dts/vscode.d.ts#L10794
7483
interface Window {
7584
onDidStartTerminalShellExecution?: (
7685
listener: (e: any) => any,
7786
thisArgs?: any,
7887
disposables?: vscode.Disposable[],
7988
) => vscode.Disposable
89+
onDidEndTerminalShellExecution?: (
90+
listener: (e: { terminal: vscode.Terminal; exitCode?: number; shellType?: string }) => any,
91+
thisArgs?: any,
92+
disposables?: vscode.Disposable[],
93+
) => vscode.Disposable
8094
}
8195
}
8296

83-
// Extend the Terminal type to include our custom properties
84-
type ExtendedTerminal = vscode.Terminal & {
85-
shellIntegration?: {
86-
cwd?: vscode.Uri
87-
executeCommand?: (command: string) => {
88-
read: () => AsyncIterable<string>
89-
}
90-
}
97+
export interface ExitCodeDetails {
98+
exitCode: number | undefined
99+
signal?: number | undefined
100+
signalName?: string
101+
coreDumpPossible?: boolean
91102
}
92103

93104
export class TerminalManager {
94105
private terminalIds: Set<number> = new Set()
95106
private processes: Map<number, TerminalProcess> = new Map()
96107
private disposables: vscode.Disposable[] = []
97108

109+
private interpretExitCode(exitCode: number | undefined): ExitCodeDetails {
110+
if (exitCode === undefined) {
111+
return { exitCode }
112+
}
113+
114+
if (exitCode <= 128) {
115+
return { exitCode }
116+
}
117+
118+
const signal = exitCode - 128
119+
const signals: Record<number, string> = {
120+
// Standard signals
121+
1: "SIGHUP",
122+
2: "SIGINT",
123+
3: "SIGQUIT",
124+
4: "SIGILL",
125+
5: "SIGTRAP",
126+
6: "SIGABRT",
127+
7: "SIGBUS",
128+
8: "SIGFPE",
129+
9: "SIGKILL",
130+
10: "SIGUSR1",
131+
11: "SIGSEGV",
132+
12: "SIGUSR2",
133+
13: "SIGPIPE",
134+
14: "SIGALRM",
135+
15: "SIGTERM",
136+
16: "SIGSTKFLT",
137+
17: "SIGCHLD",
138+
18: "SIGCONT",
139+
19: "SIGSTOP",
140+
20: "SIGTSTP",
141+
21: "SIGTTIN",
142+
22: "SIGTTOU",
143+
23: "SIGURG",
144+
24: "SIGXCPU",
145+
25: "SIGXFSZ",
146+
26: "SIGVTALRM",
147+
27: "SIGPROF",
148+
28: "SIGWINCH",
149+
29: "SIGIO",
150+
30: "SIGPWR",
151+
31: "SIGSYS",
152+
153+
// Real-time signals base
154+
34: "SIGRTMIN",
155+
156+
// SIGRTMIN+n signals
157+
35: "SIGRTMIN+1",
158+
36: "SIGRTMIN+2",
159+
37: "SIGRTMIN+3",
160+
38: "SIGRTMIN+4",
161+
39: "SIGRTMIN+5",
162+
40: "SIGRTMIN+6",
163+
41: "SIGRTMIN+7",
164+
42: "SIGRTMIN+8",
165+
43: "SIGRTMIN+9",
166+
44: "SIGRTMIN+10",
167+
45: "SIGRTMIN+11",
168+
46: "SIGRTMIN+12",
169+
47: "SIGRTMIN+13",
170+
48: "SIGRTMIN+14",
171+
49: "SIGRTMIN+15",
172+
173+
// SIGRTMAX-n signals
174+
50: "SIGRTMAX-14",
175+
51: "SIGRTMAX-13",
176+
52: "SIGRTMAX-12",
177+
53: "SIGRTMAX-11",
178+
54: "SIGRTMAX-10",
179+
55: "SIGRTMAX-9",
180+
56: "SIGRTMAX-8",
181+
57: "SIGRTMAX-7",
182+
58: "SIGRTMAX-6",
183+
59: "SIGRTMAX-5",
184+
60: "SIGRTMAX-4",
185+
61: "SIGRTMAX-3",
186+
62: "SIGRTMAX-2",
187+
63: "SIGRTMAX-1",
188+
64: "SIGRTMAX",
189+
}
190+
191+
// These signals may produce core dumps:
192+
// SIGQUIT, SIGILL, SIGABRT, SIGBUS, SIGFPE, SIGSEGV
193+
const coreDumpPossible = new Set([3, 4, 6, 7, 8, 11])
194+
195+
return {
196+
exitCode,
197+
signal,
198+
signalName: signals[signal] || `Unknown Signal (${signal})`,
199+
coreDumpPossible: coreDumpPossible.has(signal),
200+
}
201+
}
202+
98203
constructor() {
99-
let disposable: vscode.Disposable | undefined
204+
let startDisposable: vscode.Disposable | undefined
205+
let endDisposable: vscode.Disposable | undefined
100206
try {
101-
disposable = (vscode.window as vscode.Window).onDidStartTerminalShellExecution?.(async (e) => {
102-
// Creating a read stream here results in a more consistent output. This is most obvious when running the `date` command.
103-
e?.execution?.read()
207+
// onDidStartTerminalShellExecution
208+
startDisposable = (vscode.window as vscode.Window).onDidStartTerminalShellExecution?.(async (e) => {
209+
// Get a handle to the stream as early as possible:
210+
const stream = e?.execution.read()
211+
const terminalInfo = TerminalRegistry.getTerminalInfoByTerminal(e.terminal)
212+
if (stream && terminalInfo) {
213+
const process = this.processes.get(terminalInfo.id)
214+
if (process) {
215+
terminalInfo.stream = stream
216+
terminalInfo.running = true
217+
terminalInfo.streamClosed = false
218+
process.emit("stream_available", terminalInfo.id, stream)
219+
}
220+
} else {
221+
console.error("[TerminalManager] Stream failed, not registered for terminal")
222+
}
223+
224+
console.info("[TerminalManager] Shell execution started:", {
225+
hasExecution: !!e?.execution,
226+
command: e?.execution?.commandLine?.value,
227+
terminalId: terminalInfo?.id,
228+
})
229+
})
230+
231+
// onDidEndTerminalShellExecution
232+
endDisposable = (vscode.window as vscode.Window).onDidEndTerminalShellExecution?.(async (e) => {
233+
const exitDetails = this.interpretExitCode(e?.exitCode)
234+
console.info("[TerminalManager] Shell execution ended:", {
235+
...exitDetails,
236+
})
237+
238+
// Signal completion to any waiting processes
239+
for (const id of this.terminalIds) {
240+
const info = TerminalRegistry.getTerminal(id)
241+
if (info && info.terminal === e.terminal) {
242+
info.running = false
243+
const process = this.processes.get(id)
244+
if (process) {
245+
process.emit("shell_execution_complete", id, exitDetails)
246+
}
247+
break
248+
}
249+
}
104250
})
105251
} catch (error) {
106-
// console.error("Error setting up onDidEndTerminalShellExecution", error)
252+
console.error("[TerminalManager] Error setting up shell execution handlers:", error)
253+
}
254+
if (startDisposable) {
255+
this.disposables.push(startDisposable)
107256
}
108-
if (disposable) {
109-
this.disposables.push(disposable)
257+
if (endDisposable) {
258+
this.disposables.push(endDisposable)
110259
}
111260
}
112261

@@ -140,19 +289,16 @@ export class TerminalManager {
140289
})
141290

142291
// if shell integration is already active, run the command immediately
143-
const terminal = terminalInfo.terminal as ExtendedTerminal
144-
if (terminal.shellIntegration) {
292+
if (terminalInfo.terminal.shellIntegration) {
145293
process.waitForShellIntegration = false
146-
process.run(terminal, command)
294+
process.run(terminalInfo.terminal, command)
147295
} else {
148296
// docs recommend waiting 3s for shell integration to activate
149-
pWaitFor(() => (terminalInfo.terminal as ExtendedTerminal).shellIntegration !== undefined, {
150-
timeout: 4000,
151-
}).finally(() => {
297+
pWaitFor(() => terminalInfo.terminal.shellIntegration !== undefined, { timeout: 4000 }).finally(() => {
152298
const existingProcess = this.processes.get(terminalInfo.id)
153299
if (existingProcess && existingProcess.waitForShellIntegration) {
154300
existingProcess.waitForShellIntegration = false
155-
existingProcess.run(terminal, command)
301+
existingProcess.run(terminalInfo.terminal, command)
156302
}
157303
})
158304
}
@@ -168,8 +314,7 @@ export class TerminalManager {
168314
if (t.busy) {
169315
return false
170316
}
171-
const terminal = t.terminal as ExtendedTerminal
172-
const terminalCwd = terminal.shellIntegration?.cwd // one of cline's commands could have changed the cwd of the terminal
317+
const terminalCwd = t.terminal.shellIntegration?.cwd // one of cline's commands could have changed the cwd of the terminal
173318
if (!terminalCwd) {
174319
return false
175320
}

0 commit comments

Comments
 (0)