@@ -174,41 +174,53 @@ func newRegisterCmd() *cobra.Command {
174174 if registered {
175175 cfg , _ := configMgr .LoadConfig ()
176176
177- if ! force {
178- // Verify whether the agent still exists on the server.
179- // If it is gone (e.g. deleted via dashboard or a prior uninstall),
180- // the local config is stale and we can safely clean it up and
181- // proceed. If the agent is still live, block as before.
182- agentClient := api .NewClient (
183- api .WithBaseURL (serverURL ),
184- api .WithAgentSecret (cfg .AgentSecret ),
185- )
186- _ , serverErr := agentClient .GetAgentConfig (context .Background (), cfg .AgentID )
187- if serverErr == nil {
188- // Agent is alive on the server – require explicit action.
189- cmd .SilenceUsage = true
190- if ! out .IsJSON () {
191- out .Error ("Agent already registered on this machine. Run 'ggo agent unregister' first, or use --force to replace the existing registration." )
192- }
193- return agent .ErrAlreadyRegistered
177+ resolvedURL := serverURL
178+ if cfg != nil && cfg .ServerURL != "" {
179+ resolvedURL = cfg .ServerURL
180+ }
181+ agentClient := api .NewClient (
182+ api .WithBaseURL (resolvedURL ),
183+ api .WithAgentSecret (cfg .AgentSecret ),
184+ )
185+
186+ // Check if the old agent is still alive on the server.
187+ _ , serverErr := agentClient .GetAgentConfig (context .Background (), cfg .AgentID )
188+ isStale := serverErr != nil
189+
190+ if isStale {
191+ if ! out .IsJSON () {
192+ out .Warning (fmt .Sprintf ("Stale local registration found (agent %s no longer on server). Clearing and re-registering..." , cfg .AgentID ))
194193 }
195- // Agent not found on server → stale local config.
194+ } else if force {
195+ // --force: skip confirmation, auto-unregister.
196196 if ! out .IsJSON () {
197- out .Warning (fmt .Sprintf ("Stale local registration found (agent %s no longer on server). Clearing config and re-registering ..." , cfg .AgentID ))
197+ out .Info (fmt .Sprintf ("Force replacing existing registration (agent %s) ..." , cfg .AgentID ))
198198 }
199+ if deleteErr := agentClient .SelfDeleteAgent (context .Background (), cfg .AgentID ); deleteErr != nil {
200+ klog .Warningf ("Failed to delete old agent from server (continuing): agent_id=%s error=%v" , cfg .AgentID , deleteErr )
201+ }
202+ } else if out .IsJSON () {
203+ // JSON mode (non-interactive): cannot prompt, require --force.
204+ cmd .SilenceUsage = true
205+ return agent .ErrAlreadyRegistered
199206 } else {
200- // --force: attempt to delete the old agent from the server so it
201- // does not linger as an orphan record.
202- agentClient := api .NewClient (
203- api .WithBaseURL (serverURL ),
204- api .WithAgentSecret (cfg .AgentSecret ),
205- )
207+ // Interactive: show current registration and ask for confirmation.
208+ out .Warning (fmt .Sprintf ("This machine is already registered as agent %s" , cfg .AgentID ))
209+ confirmed , promptErr := tui .ConfirmPrompt ("Unregister the existing agent and re-register with the new token?" )
210+ if promptErr != nil || ! confirmed {
211+ out .Info ("Registration cancelled. Existing registration unchanged." )
212+ return nil
213+ }
206214 if deleteErr := agentClient .SelfDeleteAgent (context .Background (), cfg .AgentID ); deleteErr != nil {
207215 klog .Warningf ("Failed to delete old agent from server (continuing): agent_id=%s error=%v" , cfg .AgentID , deleteErr )
216+ if ! out .IsJSON () {
217+ out .Warning (fmt .Sprintf ("Could not remove old agent from server: %v" , deleteErr ))
218+ }
219+ } else if ! out .IsJSON () {
220+ out .Info (fmt .Sprintf ("Old agent %s unregistered from server." , cfg .AgentID ))
208221 }
209222 }
210223
211- // Remove the stale / replaced local config before re-registering.
212224 if removeErr := configMgr .RemoveConfig (); removeErr != nil {
213225 klog .Warningf ("Failed to remove local config (continuing): %v" , removeErr )
214226 }
0 commit comments