Skip to content

Commit 6c69286

Browse files
committed
only run file change hooks once turn is about to end
1 parent 7d7939d commit 6c69286

File tree

2 files changed

+34
-34
lines changed

2 files changed

+34
-34
lines changed

npm-app/src/cli.ts

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import {
2323
killAllBackgroundProcesses,
2424
sendKillSignalToAllBackgroundProcesses,
2525
} from './background-process-manager'
26-
import { setMessages } from './chat-storage'
2726
import { checkpointManager } from './checkpoints/checkpoint-manager'
2827
import { detectApiKey, handleApiKeyInput } from './cli-handlers/api-key'
2928
import {
@@ -65,7 +64,6 @@ import {
6564
resetShell,
6665
} from './utils/terminal'
6766

68-
import { type CodebuffMessage } from 'common/types/message'
6967
import { CONFIG_DIR } from './credentials'
7068
import { loadCodebuffConfig } from './json-config/parser'
7169
import { logAndHandleStartup } from './startup-process-handler'
@@ -799,18 +797,6 @@ export class CLI {
799797
await saveCheckpoint(cleanedInput, Client.getInstance(), this.readyPromise)
800798
Spinner.get().start()
801799

802-
Client.getInstance().lastChanges = []
803-
804-
const newMessage: CodebuffMessage = {
805-
role: 'user',
806-
content: cleanedInput,
807-
}
808-
809-
const client = Client.getInstance()
810-
if (client.agentState) {
811-
setMessages([...client.agentState.messageHistory, newMessage])
812-
}
813-
814800
this.isReceivingResponse = true
815801

816802
const { responsePromise, stopResponse } =
@@ -941,10 +927,10 @@ export class CLI {
941927
Client.getInstance().close() // Close WebSocket
942928

943929
const client = Client.getInstance()
944-
930+
945931
// Check for organization coverage first
946932
const coverage = await client.checkRepositoryCoverage()
947-
933+
948934
// Calculate session usage and total for display
949935
const totalCreditsUsedThisSession = Object.values(client.creditsByPromptId)
950936
.flat()
@@ -957,7 +943,7 @@ export class CLI {
957943
exitUsageMessage += '.'
958944
}
959945
console.log(exitUsageMessage)
960-
946+
961947
if (coverage.isCovered && coverage.organizationName) {
962948
// When covered by an organization, show organization information
963949
console.log(

npm-app/src/client.ts

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
1-
import {
2-
existsSync,
3-
mkdirSync,
4-
readFileSync,
5-
unlinkSync,
6-
writeFileSync,
7-
} from 'fs'
8-
import os from 'os'
91
import { spawn } from 'child_process'
102
import {
3+
ClientAction,
114
FileChanges,
125
FileChangeSchema,
136
InitResponseSchema,
@@ -17,8 +10,15 @@ import {
1710
ServerAction,
1811
UsageReponseSchema,
1912
UsageResponse,
20-
ClientAction,
2113
} from 'common/actions'
14+
import {
15+
existsSync,
16+
mkdirSync,
17+
readFileSync,
18+
unlinkSync,
19+
writeFileSync,
20+
} from 'fs'
21+
import os from 'os'
2222

2323
import { ApiKeyType, READABLE_NAME } from 'common/api-keys/constants'
2424
import {
@@ -43,6 +43,7 @@ import { User } from 'common/util/credentials'
4343
import { ProjectFileContext } from 'common/util/file'
4444
import { pluralize } from 'common/util/string'
4545
import { APIRealtimeClient } from 'common/websockets/websocket-client'
46+
import path from 'path'
4647
import {
4748
blue,
4849
blueBright,
@@ -54,8 +55,6 @@ import {
5455
} from 'picocolors'
5556
import { match, P } from 'ts-pattern'
5657
import { z } from 'zod'
57-
import gitUrlParse from 'git-url-parse'
58-
import path from 'path'
5958

6059
import packageJson from '../package.json'
6160
import { getBackgroundProcessUpdates } from './background-process-manager'
@@ -82,10 +81,10 @@ import { identifyUser, trackEvent } from './utils/analytics'
8281
import { getRepoMetrics, gitCommandIsAvailable } from './utils/git'
8382
import { logger, loggerContext } from './utils/logger'
8483
import { Spinner } from './utils/spinner'
84+
import { readNewTerminalOutput } from './utils/terminal'
8585
import { toolRenderers } from './utils/tool-renderers'
8686
import { createXMLStreamParser } from './utils/xml-stream-parser'
8787
import { getScrapedContentBlocks, parseUrlsFromContent } from './web-scraper'
88-
import { readNewTerminalOutput } from './utils/terminal'
8988

9089
const LOW_BALANCE_THRESHOLD = 100
9190

@@ -164,6 +163,7 @@ export class Client {
164163
public pendingTopUpMessageAmount: number = 0
165164
public fileContext: ProjectFileContext | undefined
166165
public lastChanges: FileChanges = []
166+
public filesChangedForHook: string[] = []
167167
public agentState: AgentState | undefined
168168
public originalFileVersions: Record<string, string | null> = {}
169169
public creditsByPromptId: Record<string, number[]> = {}
@@ -842,7 +842,17 @@ export class Client {
842842
throw new Error('Agent state not initialized')
843843
}
844844

845+
setMessages([
846+
...this.agentState.messageHistory,
847+
{
848+
role: 'user',
849+
content: prompt,
850+
},
851+
])
852+
845853
this.agentState.agentStepsRemaining = loadCodebuffConfig()?.maxAgentSteps
854+
this.lastChanges = []
855+
this.filesChangedForHook = []
846856

847857
const userInputId =
848858
`mc-input-` + Math.random().toString(36).substring(2, 15)
@@ -1062,7 +1072,6 @@ export class Client {
10621072

10631073
this.agentState = a.agentState
10641074
const toolResults: ToolResult[] = [...a.toolResults]
1065-
const changedFiles: string[] = []
10661075

10671076
for (const toolCall of a.toolCalls) {
10681077
try {
@@ -1071,12 +1080,16 @@ export class Client {
10711080
isComplete = true
10721081
continue
10731082
}
1074-
if (toolCall.name === 'write_file') {
1083+
if (
1084+
toolCall.name === 'write_file' ||
1085+
toolCall.name === 'str_replace' ||
1086+
toolCall.name === 'create_plan'
1087+
) {
10751088
// Save lastChanges for `diff` command
10761089
this.lastChanges.push(FileChangeSchema.parse(toolCall.parameters))
10771090
this.hadFileChanges = true
10781091
// Track the changed file path
1079-
changedFiles.push(toolCall.parameters.path)
1092+
this.filesChangedForHook.push(toolCall.parameters.path)
10801093
}
10811094
if (
10821095
toolCall.name === 'run_terminal_command' &&
@@ -1126,14 +1139,15 @@ export class Client {
11261139
this.fileContext = await getProjectFileContext(getProjectRoot(), {})
11271140
}
11281141

1129-
if (changedFiles.length > 0) {
1142+
if (this.filesChangedForHook.length > 0 && isComplete) {
11301143
// Run file change hooks with the actual changed files
11311144
const { toolResults: hookToolResults, someHooksFailed } =
1132-
await runFileChangeHooks(changedFiles)
1145+
await runFileChangeHooks(this.filesChangedForHook)
11331146
toolResults.push(...hookToolResults)
11341147
if (someHooksFailed) {
11351148
isComplete = false
11361149
}
1150+
this.filesChangedForHook = []
11371151
}
11381152

11391153
if (!isComplete) {

0 commit comments

Comments
 (0)