@@ -140,22 +140,27 @@ async function initSubmodules() {
140140 console . log ( "\nDone." )
141141}
142142
143+ // ---------------------------------------------------------------------------
144+ // sync helpers
145+ // ---------------------------------------------------------------------------
146+ function hasGitChanges ( paths : string [ ] ) : boolean {
147+ const status = execSafe ( `git status --porcelain -- ${ paths . join ( " " ) } ` )
148+ return status !== null && status . trim ( ) !== ""
149+ }
150+
151+ function commitChanges ( paths : string [ ] , message : string ) {
152+ exec ( `git add -- ${ paths . join ( " " ) } ` )
153+ exec ( `git commit -m ${ JSON . stringify ( message ) } ` )
154+ }
155+
143156// ---------------------------------------------------------------------------
144157// sync
145158// ---------------------------------------------------------------------------
146159async function syncSubmodules ( ) {
147- // 1. Update each vendor submodule
148- process . stdout . write ( "Updating vendor submodules... " )
149- for ( const name of Object . keys ( vendors ) ) {
150- const submodulePath = `vendor/${ name } `
151- if ( isSubmoduleRegistered ( submodulePath ) ) {
152- execSafe ( `git submodule update --remote --merge ${ submodulePath } ` )
153- }
154- }
155- console . log ( "done\n" )
160+ const committed : string [ ] = [ ]
156161
157- // 2 . Sync Type 2 vendor skills → plugins/{plugin}/skills/{skill}/
158- console . log ( "Syncing vendor skills to plugins..." )
162+ // 1 . Sync Type 2 vendor skills → plugins/{plugin}/skills/{skill}/ + commit per vendor
163+ console . log ( "Syncing vendor skills to plugins...\n " )
159164 for ( const [ name , config ] of Object . entries ( vendors ) ) {
160165 const submodulePath = `vendor/${ name } `
161166 const vendorPath = join ( ROOT , submodulePath )
@@ -165,12 +170,20 @@ async function syncSubmodules() {
165170 continue
166171 }
167172
173+ // Update submodule to latest
174+ process . stdout . write ( `[${ name } ] updating submodule... ` )
175+ execSafe ( `git submodule update --remote --merge ${ submodulePath } ` )
176+ const sha = getGitSha ( vendorPath )
177+ console . log ( `${ sha ?. slice ( 0 , 7 ) ?? "?" } ` )
178+
168179 const vendorSkillsDir = join ( vendorPath , "skills" )
169180 if ( ! existsSync ( vendorSkillsDir ) ) {
170181 console . warn ( ` ! no skills/ in vendor/${ name } ` )
171182 continue
172183 }
173184
185+ const changedPaths : string [ ] = [ submodulePath ]
186+
174187 for ( const [ srcSkill , outSkill ] of Object . entries ( config . skills ) ) {
175188 const src = join ( vendorSkillsDir , srcSkill )
176189 const plugin = SKILL_TO_PLUGIN [ outSkill ]
@@ -185,8 +198,9 @@ async function syncSubmodules() {
185198
186199 ensurePlugin ( plugin )
187200 const dest = join ( PLUGINS_DIR , plugin , "skills" , outSkill )
201+ const destRelative = `plugins/${ plugin } /skills/${ outSkill } `
188202
189- process . stdout . write ( ` ${ srcSkill } → plugins/ ${ plugin } /skills/ ${ outSkill } ... ` )
203+ process . stdout . write ( ` ${ srcSkill } → ${ destRelative } ... ` )
190204 rmSync ( dest , { recursive : true , force : true } )
191205 mkdirSync ( dest , { recursive : true } )
192206 cpSync ( src , dest , { recursive : true } )
@@ -202,16 +216,41 @@ async function syncSubmodules() {
202216 }
203217
204218 // Write SYNC.md
205- const sha = getGitSha ( vendorPath )
206219 const date = new Date ( ) . toISOString ( ) . split ( "T" ) [ 0 ]
207220 writeFileSync ( join ( dest , "SYNC.md" ) , `# Sync Info\n\n- **Source:** \`vendor/${ name } /skills/${ srcSkill } \`\n- **Git SHA:** \`${ sha } \`\n- **Synced:** ${ date } \n` )
208221
222+ changedPaths . push ( destRelative )
209223 console . log ( "done" )
210224 }
225+
226+ // turborepo: also sync command file
227+ if ( name === "turborepo" ) {
228+ const turborepoCommandSrc = join ( PLUGINS_DIR , "turborepo/skills/turborepo/command/turborepo.md" )
229+ if ( existsSync ( turborepoCommandSrc ) ) {
230+ const commandsDir = join ( PLUGINS_DIR , "turborepo/commands" )
231+ mkdirSync ( commandsDir , { recursive : true } )
232+ const dest = join ( commandsDir , "turborepo.md" )
233+ rmSync ( dest , { force : true } )
234+ cpSync ( turborepoCommandSrc , dest )
235+ changedPaths . push ( "plugins/turborepo/commands/turborepo.md" )
236+ console . log ( " turborepo command synced" )
237+ }
238+ }
239+
240+ // Commit this vendor's changes
241+ if ( hasGitChanges ( changedPaths ) ) {
242+ const shortSha = sha ?. slice ( 0 , 7 ) ?? "unknown"
243+ commitChanges ( changedPaths , `chore(sync): sync ${ name } to ${ shortSha } ` )
244+ committed . push ( name )
245+ console . log ( ` → committed: chore(sync): sync ${ name } to ${ shortSha } \n` )
246+ } else {
247+ console . log ( ` → no changes\n` )
248+ }
211249 }
212250
213- // 3. Copy Type 3 manual skills from vendor/antfu-skills/skills/ → plugins/{plugin}/skills/
214- console . log ( "\nCopying manual skills to plugins..." )
251+ // 2. Copy Type 3 manual skills from vendor/antfu-skills/skills/ → plugins/{plugin}/skills/
252+ console . log ( "Syncing manual skills to plugins..." )
253+ const manualPaths : string [ ] = [ ]
215254 for ( const skill of [ "antfu" ] ) {
216255 const plugin = SKILL_TO_PLUGIN [ skill ]
217256 if ( ! plugin ) continue
@@ -228,22 +267,25 @@ async function syncSubmodules() {
228267 process . stdout . write ( ` ${ skill } → plugins/${ plugin } /skills/${ skill } ... ` )
229268 rmSync ( dest , { recursive : true , force : true } )
230269 cpSync ( src , dest , { recursive : true } )
270+ manualPaths . push ( `plugins/${ plugin } /skills/${ skill } ` )
231271 console . log ( "done" )
232272 }
233273
234- // 4. turborepo: copy command file
235- const turborepoCommandSrc = join ( PLUGINS_DIR , "turborepo/skills/turborepo/command/turborepo.md" )
236- if ( existsSync ( turborepoCommandSrc ) ) {
237- const commandsDir = join ( PLUGINS_DIR , "turborepo/commands" )
238- mkdirSync ( commandsDir , { recursive : true } )
239- const dest = join ( commandsDir , "turborepo.md" )
240- rmSync ( dest , { force : true } )
241- cpSync ( turborepoCommandSrc , dest )
242- console . log ( "\n turborepo command synced" )
274+ if ( manualPaths . length > 0 && hasGitChanges ( manualPaths ) ) {
275+ const sha = getGitSha ( join ( ROOT , "vendor/antfu-skills" ) )
276+ const shortSha = sha ?. slice ( 0 , 7 ) ?? "unknown"
277+ commitChanges ( manualPaths , `chore(sync): sync antfu manual skills to ${ shortSha } ` )
278+ committed . push ( "antfu-skills" )
279+ console . log ( ` → committed: chore(sync): sync antfu manual skills to ${ shortSha } ` )
280+ } else {
281+ console . log ( " → no changes" )
243282 }
244283
245- const pluginCount = new Set ( Object . values ( SKILL_TO_PLUGIN ) ) . size
246- console . log ( `\nDone. Synced skills for ${ pluginCount } plugins.` )
284+ if ( committed . length === 0 ) {
285+ console . log ( "\nAll skills are up to date. Nothing to commit." )
286+ } else {
287+ console . log ( `\nDone. ${ committed . length } commit(s): ${ committed . join ( ", " ) } ` )
288+ }
247289}
248290
249291// ---------------------------------------------------------------------------
0 commit comments