@@ -79,6 +79,9 @@ import {
7979 DOMAIN_HELP ,
8080 BUILD_DIR_HINT ,
8181 DOMAIN_HINT ,
82+ CONTRACTS_RENAME_NOTICE_TITLE ,
83+ CONTRACTS_RENAME_NOTICE_BODY ,
84+ CONTRACTS_RENAME_NOTICE_HINT ,
8285} from "./promptHelp.js" ;
8386import { ContractPipelineStatusAdapter } from "../contractPipelineStatus.js" ;
8487import { ContractDeployStatusView , precomputeContractDeployDisplay } from "../contractDeployUi.js" ;
@@ -117,6 +120,7 @@ export type Stage =
117120 | { kind : "prompt-build" }
118121 | { kind : "prompt-signer" }
119122 | { kind : "prompt-contracts" }
123+ | { kind : "prompt-contracts-notice" }
120124 | { kind : "prompt-buildDir" }
121125 | { kind : "prompt-domain" }
122126 | { kind : "validate-domain" ; domain : string }
@@ -367,14 +371,27 @@ export function DeployScreen({
367371 initialIndex = { 0 }
368372 onSelect = { ( yes ) => {
369373 setDeployContracts ( yes ) ;
370- const nextSkipBuild = yes ? false : skipBuild ;
371374 if ( yes ) setSkipBuild ( false ) ;
372- advance ( nextSkipBuild , mode , yes ) ;
375+ // Redeploying contracts is when the CDM-name ownership
376+ // footgun bites (a mod ships names the signer doesn't
377+ // own). Gate "yes" on an explicit rename ack; "no"
378+ // skips straight ahead. The notice lives outside
379+ // pickNextStage, so the headless --contracts path
380+ // never hits it.
381+ if ( yes ) setStage ( { kind : "prompt-contracts-notice" } ) ;
382+ else advance ( skipBuild , mode , false ) ;
373383 } }
374384 />
375385 </ Box >
376386 ) }
377387
388+ { stage . kind === "prompt-contracts-notice" && (
389+ < ContractsRenameNotice
390+ onContinue = { ( ) => advance ( false , mode , true ) }
391+ onExit = { ( ) => onDone ( null , { graceful : true } ) }
392+ />
393+ ) }
394+
378395 { stage . kind === "prompt-buildDir" && (
379396 < Box flexDirection = "column" >
380397 < PromptHint text = { BUILD_DIR_HINT } />
@@ -670,6 +687,35 @@ function AckStage({ onContinue, onExit }: { onContinue: () => void; onExit: () =
670687 ) ;
671688}
672689
690+ /**
691+ * Interstitial shown when the user opts to redeploy contracts. Warns that CDM
692+ * package names are owned by their first deployer, so a mod (or any project that
693+ * edited someone else's contracts) must rename before publishing or the deploy
694+ * fails late. Enter continues; Esc exits the flow gracefully so they can rename.
695+ */
696+ function ContractsRenameNotice ( {
697+ onContinue,
698+ onExit,
699+ } : {
700+ onContinue : ( ) => void ;
701+ onExit : ( ) => void ;
702+ } ) {
703+ useInput ( ( _input , key ) => {
704+ if ( key . return ) onContinue ( ) ;
705+ else if ( key . escape ) onExit ( ) ;
706+ } ) ;
707+ return (
708+ < Box flexDirection = "column" >
709+ < Callout tone = "warning" title = { CONTRACTS_RENAME_NOTICE_TITLE } >
710+ < Text > { CONTRACTS_RENAME_NOTICE_BODY } </ Text >
711+ </ Callout >
712+ < Box marginTop = { 1 } >
713+ < Hint > { CONTRACTS_RENAME_NOTICE_HINT } </ Hint >
714+ </ Box >
715+ </ Box >
716+ ) ;
717+ }
718+
673719// ── Domain validation ────────────────────────────────────────────────────────
674720
675721function ValidateDomainStage ( {
0 commit comments