11#!/usr/bin/env node
22
3- import type { UnpackOptions } from 'config-rocket/cli'
4- import { readFile } from 'node:fs/promises'
53import { defineCommand , runMain } from 'citty'
64import { getValidGhRepoReleaseAssets , promptSelectGhAsset , unpackFromUrl } from 'config-rocket/cli'
7- import defu from 'defu'
8- import { createHooks } from 'hookable'
9- import { logger } from '~/helpers/logger'
10-
11- // Main hookable instance
12- const rooRocketUnpackHookable = createHooks ( ) as NonNullable < UnpackOptions [ 'hookable' ] >
13-
14- // Hook to only allow specific file patterns
15- rooRocketUnpackHookable . hook ( 'onFrameFile' , ( { filePath, skipFile } ) => {
16- if ( ! / ^ \. (?: r o o m o d e s | r o o \/ .* ) $ / . test ( filePath ) ) {
17- logger . warn ( `Unallowed frame structure found: ${ filePath } , skipping...` )
18- skipFile ( )
19- }
20- } )
21-
22- // Hooks to handle .roomodes merging
23- rooRocketUnpackHookable . hook ( 'onFileOutput' , async ( state ) => {
24- if ( state . filePath . endsWith ( '.roomodes' ) ) {
25- state . mergeType = 'json'
26- state . isValidFileToMerge = true
27- }
28- } )
29- rooRocketUnpackHookable . hook ( 'onFileOutputJsonMerge' , async ( state ) => {
30- if ( state . filePath . endsWith ( '.roomodes' ) ) {
31- const existingModeSlugs = new Set < string > ( )
32- const oldData = JSON . parse ( await readFile ( state . filePath , 'utf8' ) )
33- const newData = JSON . parse ( state . data )
34- const mergedData = defu ( newData , oldData )
35- const dedupedModes = mergedData . customModes . filter ( ( mode : any ) => {
36- if ( existingModeSlugs . has ( mode . slug ) ) {
37- logger . info ( `Present roomode entry overwritten: ${ mode . slug } ` )
38- return false
39- }
40-
41- return existingModeSlugs . add ( mode . slug ) && true
42- } )
43-
44- const result = { ...mergedData , customModes : dedupedModes }
45- state . mergeResult = JSON . stringify ( result , null , 2 )
46- }
47- } )
48-
49- // Hook to handle mcp.json merging
50- rooRocketUnpackHookable . hook ( 'onFileOutputJsonMerge' , async ( state ) => {
51- if ( state . filePath . endsWith ( '.roo/mcp.json' ) ) {
52- const oldData = JSON . parse ( await readFile ( state . filePath , 'utf8' ) )
53- const newData = JSON . parse ( state . data )
54- const mergedData = structuredClone ( newData )
55- for ( const [ key , value ] of Object . entries ( oldData . mcpServers ) ) {
56- if ( key in mergedData . mcpServers ) {
57- logger . info ( `Present mcp server entry overwritten: ${ key } ` )
58- continue
59- }
60-
61- mergedData . mcpServers [ key ] = value
62- }
63-
64- state . mergeResult = JSON . stringify ( mergedData , null , 2 )
65- }
66- } )
5+ import { hookable } from '~/rr/hookable'
676
687const main = defineCommand ( {
698 meta : {
@@ -114,7 +53,7 @@ const main = defineCommand({
11453 return await unpackFromUrl ( url , {
11554 nonAssemblyBehavior,
11655 sha256,
117- hookable : rooRocketUnpackHookable ,
56+ hookable,
11857 } )
11958 }
12059
@@ -138,7 +77,7 @@ const main = defineCommand({
13877 return await unpackFromUrl ( selectedAsset . browser_download_url , {
13978 nonAssemblyBehavior,
14079 sha256,
141- hookable : rooRocketUnpackHookable ,
80+ hookable,
14281 } )
14382 } ,
14483} )
0 commit comments