@@ -73,7 +73,7 @@ const {
7373 uninstallScheduledTask,
7474} = await import ( "./schtasks.js" ) ;
7575
76- function resolveStartupEntryPath ( env : Record < string , string > , extension = "cmd " ) {
76+ function resolveStartupEntryPath ( env : Record < string , string > , extension = "vbs " ) {
7777 const taskName = env . OPENCLAW_WINDOWS_TASK_NAME ?? "OpenClaw Gateway" ;
7878 return path . join (
7979 env . APPDATA ,
@@ -86,8 +86,11 @@ function resolveStartupEntryPath(env: Record<string, string>, extension = "cmd")
8686 ) ;
8787}
8888
89- async function writeStartupFallbackEntry ( env : Record < string , string > ) {
90- const startupEntryPath = resolveStartupEntryPath ( env ) ;
89+ async function writeStartupFallbackEntry (
90+ env : Record < string , string > ,
91+ extension : "cmd" | "vbs" = "vbs" ,
92+ ) {
93+ const startupEntryPath = resolveStartupEntryPath ( env , extension ) ;
9194 await fs . mkdir ( path . dirname ( startupEntryPath ) , { recursive : true } ) ;
9295 await fs . writeFile ( startupEntryPath , "@echo off\r\n" , "utf8" ) ;
9396 return startupEntryPath ;
@@ -292,24 +295,22 @@ describe("Windows startup fallback", () => {
292295 const startupEntryPath = resolveStartupEntryPath ( env ) ;
293296 const startupScript = await fs . readFile ( startupEntryPath , "utf8" ) ;
294297 expect ( result . scriptPath ) . toBe ( resolveTaskScriptPath ( env ) ) ;
295- expect ( startupScript ) . toContain ( 'start "" /min cmd.exe /d /c' ) ;
298+ expect ( startupScript ) . toContain ( "WScript.Shell" ) ;
296299 expect ( startupScript ) . toContain ( "gateway.cmd" ) ;
300+ expect ( startupScript ) . toContain ( `Run """${ result . scriptPath } """, 0, False` ) ;
297301 expectStartupFallbackSpawn ( ) ;
298302 expect ( childUnref ) . toHaveBeenCalled ( ) ;
299303 expect ( printed ) . toContain ( "Installed Windows login item" ) ;
300304 } ) ;
301305 } ) ;
302306
303- it ( "uses a hidden Startup-folder launcher when requested " , async ( ) => {
307+ it ( "uses a hidden Startup-folder launcher by default " , async ( ) => {
304308 await withWindowsEnv ( "openclaw-win-startup-" , async ( { env } ) => {
305309 addStartupFallbackMissingResponses ( [
306310 { code : 5 , stdout : "" , stderr : "ERROR: Access is denied." } ,
307311 ] ) ;
308312
309- const result = await installGatewayScheduledTask ( {
310- ...env ,
311- OPENCLAW_WINDOWS_TASK_HIDDEN_LAUNCHER : "1" ,
312- } ) ;
313+ const result = await installGatewayScheduledTask ( env ) ;
313314
314315 const startupEntryPath = resolveStartupEntryPath ( env , "vbs" ) ;
315316 const startupScript = await fs . readFile ( startupEntryPath , "utf8" ) ;
@@ -637,7 +638,7 @@ describe("Windows startup fallback", () => {
637638 it ( "keeps legacy Startup-folder cmd entries visible after hidden launcher opt-in" , async ( ) => {
638639 await withWindowsEnv ( "openclaw-win-startup-" , async ( { env } ) => {
639640 addStartupFallbackMissingResponses ( ) ;
640- await writeStartupFallbackEntry ( env ) ;
641+ await writeStartupFallbackEntry ( env , "cmd" ) ;
641642
642643 await expect (
643644 isScheduledTaskInstalled ( {
@@ -650,10 +651,26 @@ describe("Windows startup fallback", () => {
650651 } ) ;
651652 } ) ;
652653
654+ it ( "keeps legacy Startup-folder vbs entries visible after hidden launcher opt-out" , async ( ) => {
655+ await withWindowsEnv ( "openclaw-win-startup-" , async ( { env } ) => {
656+ addStartupFallbackMissingResponses ( ) ;
657+ await writeStartupFallbackEntry ( env , "vbs" ) ;
658+
659+ await expect (
660+ isScheduledTaskInstalled ( {
661+ env : {
662+ ...env ,
663+ OPENCLAW_WINDOWS_TASK_HIDDEN_LAUNCHER : "0" ,
664+ } ,
665+ } ) ,
666+ ) . resolves . toBe ( true ) ;
667+ } ) ;
668+ } ) ;
669+
653670 it ( "removes legacy Startup-folder cmd entries after hidden launcher opt-in" , async ( ) => {
654671 await withWindowsEnv ( "openclaw-win-startup-" , async ( { env } ) => {
655672 schtasksResponses . push ( { code : 0 , stdout : "" , stderr : "" } ) ;
656- const startupEntryPath = await writeStartupFallbackEntry ( env ) ;
673+ const startupEntryPath = await writeStartupFallbackEntry ( env , "cmd" ) ;
657674 const stdout = new PassThrough ( ) ;
658675
659676 await uninstallScheduledTask ( {
@@ -668,6 +685,24 @@ describe("Windows startup fallback", () => {
668685 } ) ;
669686 } ) ;
670687
688+ it ( "removes legacy Startup-folder vbs entries after hidden launcher opt-out" , async ( ) => {
689+ await withWindowsEnv ( "openclaw-win-startup-" , async ( { env } ) => {
690+ schtasksResponses . push ( { code : 0 , stdout : "" , stderr : "" } ) ;
691+ const startupEntryPath = await writeStartupFallbackEntry ( env , "vbs" ) ;
692+ const stdout = new PassThrough ( ) ;
693+
694+ await uninstallScheduledTask ( {
695+ env : {
696+ ...env ,
697+ OPENCLAW_WINDOWS_TASK_HIDDEN_LAUNCHER : "0" ,
698+ } ,
699+ stdout,
700+ } ) ;
701+
702+ await expect ( fs . access ( startupEntryPath ) ) . rejects . toThrow ( ) ;
703+ } ) ;
704+ } ) ;
705+
671706 it ( "reports runtime from the gateway listener when using the Startup fallback" , async ( ) => {
672707 await withWindowsEnv ( "openclaw-win-startup-" , async ( { env } ) => {
673708 addStartupFallbackMissingResponses ( ) ;
0 commit comments