Skip to content

Commit f7412d2

Browse files
committed
feat: add createHookable function
1 parent 770f7ec commit f7412d2

File tree

1 file changed

+55
-48
lines changed

1 file changed

+55
-48
lines changed

libs/roo-rocket/src/rr/hookable.ts

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,62 +10,69 @@ import { createHooks } from 'hookable'
1010
import { logger } from '~/helpers/logger'
1111

1212
/**
13-
* Main hookable instance of Roo Rocket, with default hooks registered.
13+
* Workaround for unjs/hookable#116
1414
*/
15-
const hookable = createHooks() as NonNullable<UnpackOptions['hookable']>
15+
export function createHookable(): NonNullable<UnpackOptions['hookable']> {
16+
const instance = createHooks() as NonNullable<UnpackOptions['hookable']>
1617

17-
// Hook to only allow specific file patterns
18-
hookable.hook('onFrameFile', ({ filePath, skipFile }) => {
19-
if (!/^\.(?:roomodes|roo\/.*)$/.test(filePath)) {
20-
logger.warn(`Unallowed frame structure found: ${filePath}, skipping...`)
21-
skipFile()
22-
}
23-
})
18+
// Hook to only allow specific file patterns
19+
instance.hook('onFrameFile', ({ filePath, skipFile }) => {
20+
if (!/^\.(?:roomodes|roo\/.*)$/.test(filePath)) {
21+
logger.warn(`Unallowed frame structure found: ${filePath}, skipping...`)
22+
skipFile()
23+
}
24+
})
2425

25-
// Hooks to handle .roomodes merging
26-
hookable.hook('onFileOutput', async (state) => {
27-
if (state.filePath.endsWith('.roomodes')) {
28-
state.mergeType = 'json'
29-
state.isValidFileToMerge = true
30-
}
31-
})
32-
hookable.hook('onFileOutputJsonMerge', async (state) => {
33-
if (state.filePath.endsWith('.roomodes')) {
34-
const existingModeSlugs = new Set<string>()
35-
const oldData = JSON.parse(await readFile(state.filePath, 'utf8'))
36-
const newData = JSON.parse(state.data)
37-
const mergedData = defu(newData, oldData)
38-
const dedupedModes = mergedData.customModes.filter((mode: any) => {
39-
if (existingModeSlugs.has(mode.slug)) {
40-
logger.info(`Present roomode entry overwritten: ${mode.slug}`)
41-
return false
42-
}
26+
// Hooks to handle .roomodes merging
27+
instance.hook('onFileOutput', async (state) => {
28+
if (state.filePath.endsWith('.roomodes')) {
29+
state.mergeType = 'json'
30+
state.isValidFileToMerge = true
31+
}
32+
})
33+
instance.hook('onFileOutputJsonMerge', async (state) => {
34+
if (state.filePath.endsWith('.roomodes')) {
35+
const existingModeSlugs = new Set<string>()
36+
const oldData = JSON.parse(await readFile(state.filePath, 'utf8'))
37+
const newData = JSON.parse(state.data)
38+
const mergedData = defu(newData, oldData)
39+
const dedupedModes = mergedData.customModes.filter((mode: any) => {
40+
if (existingModeSlugs.has(mode.slug)) {
41+
logger.info(`Present roomode entry overwritten: ${mode.slug}`)
42+
return false
43+
}
4344

44-
return existingModeSlugs.add(mode.slug) && true
45-
})
45+
return existingModeSlugs.add(mode.slug) && true
46+
})
4647

47-
const result = { ...mergedData, customModes: dedupedModes }
48-
state.mergeResult = JSON.stringify(result, null, 2)
49-
}
50-
})
48+
const result = { ...mergedData, customModes: dedupedModes }
49+
state.mergeResult = JSON.stringify(result, null, 2)
50+
}
51+
})
5152

52-
// Hook to handle mcp.json merging
53-
hookable.hook('onFileOutputJsonMerge', async (state) => {
54-
if (state.filePath.endsWith('.roo/mcp.json')) {
55-
const oldData = JSON.parse(await readFile(state.filePath, 'utf8'))
56-
const newData = JSON.parse(state.data)
57-
const mergedData = structuredClone(newData)
58-
for (const [key, value] of Object.entries(oldData.mcpServers)) {
59-
if (key in mergedData.mcpServers) {
60-
logger.info(`Present mcp server entry overwritten: ${key}`)
61-
continue
53+
// Hook to handle mcp.json merging
54+
instance.hook('onFileOutputJsonMerge', async (state) => {
55+
if (state.filePath.endsWith('.roo/mcp.json')) {
56+
const oldData = JSON.parse(await readFile(state.filePath, 'utf8'))
57+
const newData = JSON.parse(state.data)
58+
const mergedData = structuredClone(newData)
59+
for (const [key, value] of Object.entries(oldData.mcpServers)) {
60+
if (key in mergedData.mcpServers) {
61+
logger.info(`Present mcp server entry overwritten: ${key}`)
62+
continue
63+
}
64+
65+
mergedData.mcpServers[key] = value
6266
}
6367

64-
mergedData.mcpServers[key] = value
68+
state.mergeResult = JSON.stringify(mergedData, null, 2)
6569
}
70+
})
6671

67-
state.mergeResult = JSON.stringify(mergedData, null, 2)
68-
}
69-
})
72+
return instance
73+
}
7074

71-
export { hookable }
75+
/**
76+
* Main hookable instance of Roo Rocket, with default hooks registered.
77+
*/
78+
export const hookable: NonNullable<UnpackOptions['hookable']> = createHookable()

0 commit comments

Comments
 (0)