Skip to content

Commit 60dd4a6

Browse files
committed
glob matcher tool component
1 parent 6926b1e commit 60dd4a6

File tree

3 files changed

+86
-3
lines changed

3 files changed

+86
-3
lines changed

.agents/file-explorer/glob-matcher.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { JSONValue } from '@codebuff/common/types/json'
12
import { publisher } from '../constants'
23

34
import type { SecretAgentDefinition } from '../types/secret-agent-definition'
@@ -33,24 +34,40 @@ const globMatcher: SecretAgentDefinition = {
3334
'Mechanically runs multiple glob pattern matches and returns all matching files',
3435
model: 'anthropic/claude-sonnet-4.5',
3536
publisher,
36-
outputMode: 'all_messages',
37+
outputMode: 'structured_output',
3738
includeMessageHistory: false,
38-
toolNames: ['glob'],
39+
toolNames: ['glob', 'set_output'],
3940
spawnableAgents: [],
4041
inputSchema: {
4142
params: paramsSchema,
4243
},
4344
handleSteps: function* ({ params }) {
4445
const patterns: GlobQuery[] = params?.patterns ?? []
4546

47+
const toolResults: JSONValue[] = []
4648
for (const query of patterns) {
47-
yield {
49+
const { toolResult } = yield {
4850
toolName: 'glob',
4951
input: {
5052
pattern: query.pattern,
5153
cwd: query.cwd,
5254
},
5355
}
56+
if (toolResult) {
57+
toolResults.push(
58+
...toolResult
59+
.filter((result) => result.type === 'json')
60+
.map((result) => result.value),
61+
)
62+
}
63+
}
64+
65+
yield {
66+
toolName: 'set_output',
67+
input: {
68+
results: toolResults,
69+
},
70+
includeToolCall: false,
5471
}
5572
},
5673
}

cli/src/components/tools/glob.tsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { SimpleToolCallItem } from './tool-call-item'
2+
import { defineToolComponent } from './types'
3+
4+
import type { ToolRenderConfig } from './types'
5+
6+
/**
7+
* UI component for glob tool.
8+
* Displays a single line showing the glob pattern and number of matching files.
9+
* Does not support expand/collapse - always shows as a single line.
10+
*/
11+
export const GlobComponent = defineToolComponent({
12+
toolName: 'glob',
13+
14+
render(toolBlock, theme, options): ToolRenderConfig | null {
15+
const input = toolBlock.input as any
16+
const pattern = input?.pattern ?? ''
17+
const cwd = input?.cwd ?? ''
18+
19+
// Parse output to get file count
20+
let fileCount = 0
21+
let hasError = false
22+
23+
if (toolBlock.output) {
24+
const outputArray = Array.isArray(toolBlock.output)
25+
? toolBlock.output
26+
: [toolBlock.output]
27+
28+
for (const item of outputArray) {
29+
const output = item as any
30+
if (output?.type === 'json' && output?.value) {
31+
const value = output.value as any
32+
if (value.errorMessage) {
33+
hasError = true
34+
} else if (typeof value.count === 'number') {
35+
fileCount = value.count
36+
}
37+
}
38+
}
39+
}
40+
41+
if (!pattern) {
42+
return null
43+
}
44+
45+
// Build single-line summary
46+
let summary = pattern
47+
48+
if (cwd) {
49+
summary += ` in ${cwd}`
50+
}
51+
52+
if (hasError) {
53+
summary += ' (error)'
54+
}
55+
// TODO(James): Reenable when we pass tool results as an object
56+
// else {
57+
// summary += ` (${fileCount} file${fileCount === 1 ? '' : 's'})`
58+
// }
59+
60+
return {
61+
content: <SimpleToolCallItem name="Glob" description={summary} />,
62+
}
63+
},
64+
})

cli/src/components/tools/registry.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { CodeSearchComponent } from './code-search'
2+
import { GlobComponent } from './glob'
23
import { ListDirectoryComponent } from './list-directory'
34
import { ReadFilesComponent } from './read-files'
45
import { ReadSubtreeComponent } from './read-subtree'
@@ -23,6 +24,7 @@ import type { ToolName } from '@codebuff/sdk'
2324
*/
2425
const toolComponentRegistry = new Map<ToolName, ToolComponent>([
2526
[CodeSearchComponent.toolName, CodeSearchComponent],
27+
[GlobComponent.toolName, GlobComponent],
2628
[ListDirectoryComponent.toolName, ListDirectoryComponent],
2729
[RunTerminalCommandComponent.toolName, RunTerminalCommandComponent],
2830
[ReadFilesComponent.toolName, ReadFilesComponent],

0 commit comments

Comments
 (0)