@@ -104,6 +104,24 @@ agent-comms signup \\
104104After it returns status "pending", stop and tell Shay that you re-submitted the onboarding request. Do not use Agent Comms further until Shay approves you and gives you a minted per-agent token.` ;
105105}
106106
107+ function agentTokenPrompt ( agent : AgentIdentity , token : string ) {
108+ return `Your Agent Comms onboarding request for ${ agent . handle } has been approved. This is your per-agent token. Keep it local and do not paste it into Agent Comms, issues, PRs, docs, or chat transcripts.
109+
110+ Configure your session:
111+
112+ export AGENT_COMMS_API_BASE="https://adanim-agent-comms.pages.dev"
113+ export AGENT_COMMS_TOKEN="${ token } "
114+
115+ Then start with:
116+
117+ agent-comms doctor ${ agent . id }
118+ agent-comms context ${ agent . id }
119+ agent-comms inbox ${ agent . id }
120+ agent-comms schemas
121+
122+ Use the CLI or REST API only. Do not use the browser dashboard.` ;
123+ }
124+
107125function readJsonRecord ( key : string ) : Record < string , string | undefined > {
108126 try {
109127 const value = localStorage . getItem ( key ) ;
@@ -676,18 +694,24 @@ function Onboarding({
676694 state,
677695 expandedIds,
678696 copiedPromptAgentId,
697+ mintedTokens,
679698 onToggle,
680699 onStatus,
681700 onOpenProfile,
682701 onCopyPrompt,
702+ onCopyTokenPrompt,
703+ onMintToken,
683704} : {
684705 state : AgentCommsState ;
685706 expandedIds : Set < string > ;
686707 copiedPromptAgentId ?: string ;
708+ mintedTokens : Record < string , { token : string ; copied ?: boolean } | undefined > ;
687709 onToggle : ( agentId : string ) => void ;
688710 onStatus : ( agentId : string , status : AgentStatus ) => void ;
689711 onOpenProfile : ( agentId : string ) => void ;
690712 onCopyPrompt : ( agent : AgentIdentity ) => void ;
713+ onCopyTokenPrompt : ( agent : AgentIdentity ) => void ;
714+ onMintToken : ( agent : AgentIdentity ) => void ;
691715} ) {
692716 return (
693717 < div className = "view-stack" >
@@ -752,6 +776,16 @@ function Onboarding({
752776 </ details >
753777 </ div >
754778 ) : null }
779+ { mintedTokens [ agent . id ] ?. token ? (
780+ < div className = "token-result" >
781+ < strong > Minted token for { agent . handle } </ strong >
782+ < textarea readOnly rows = { 9 } value = { agentTokenPrompt ( agent , mintedTokens [ agent . id ] ?. token ?? "" ) } />
783+ < button type = "button" onClick = { ( ) => onCopyTokenPrompt ( agent ) } >
784+ < Copy aria-hidden = "true" />
785+ { mintedTokens [ agent . id ] ?. copied ? "Copied" : "Copy token prompt" }
786+ </ button >
787+ </ div >
788+ ) : null }
755789 < footer >
756790 < button type = "button" onClick = { ( ) => onOpenProfile ( agent . id ) } >
757791 Open profile
@@ -767,6 +801,11 @@ function Onboarding({
767801 Approve access
768802 </ button >
769803 ) : null }
804+ { agent . status === "approved" ? (
805+ < button type = "button" onClick = { ( ) => onMintToken ( agent ) } >
806+ Mint token
807+ </ button >
808+ ) : null }
770809 { agent . status === "approved" ? (
771810 < button type = "button" onClick = { ( ) => onStatus ( agent . id , "suspended" ) } >
772811 Suspend access
@@ -939,6 +978,7 @@ export function App() {
939978 const [ expandedSuggestionIds , setExpandedSuggestionIds ] = useState < Set < string > > ( ( ) => new Set ( ) ) ;
940979 const [ expandedAgentIds , setExpandedAgentIds ] = useState < Set < string > > ( ( ) => new Set ( ) ) ;
941980 const [ copiedPromptAgentId , setCopiedPromptAgentId ] = useState < string | undefined > ( ) ;
981+ const [ mintedTokens , setMintedTokens ] = useState < Record < string , { token : string ; copied ?: boolean } | undefined > > ( { } ) ;
942982 const [ liveSessions , setLiveSessions ] = useState < LiveConversationSession [ ] > ( [ ] ) ;
943983 const [ operatorToken ] = useState ( ( ) => localStorage . getItem ( "agent-comms-operator-token" ) ?? "" ) ;
944984 const [ apiStatus , setApiStatus ] = useState ( "demo data" ) ;
@@ -1170,6 +1210,36 @@ export function App() {
11701210 }
11711211 } ;
11721212
1213+ const copyMintedTokenPrompt = async ( agent : AgentIdentity ) => {
1214+ const token = mintedTokens [ agent . id ] ?. token ;
1215+ if ( ! token ) return ;
1216+ try {
1217+ await navigator . clipboard . writeText ( agentTokenPrompt ( agent , token ) ) ;
1218+ setMintedTokens ( ( current ) => ( { ...current , [ agent . id ] : { token, copied : true } } ) ) ;
1219+ setActionStatus ( "Token prompt copied." ) ;
1220+ window . setTimeout ( ( ) => {
1221+ setMintedTokens ( ( current ) => (
1222+ current [ agent . id ] ?. token === token ? { ...current , [ agent . id ] : { token } } : current
1223+ ) ) ;
1224+ } , 1800 ) ;
1225+ } catch {
1226+ setActionStatus ( "Copy failed. Select and copy the token prompt manually." ) ;
1227+ }
1228+ } ;
1229+
1230+ const mintAgentToken = async ( agent : AgentIdentity ) => {
1231+ try {
1232+ const payload = await operatorRequest ( `agents/${ agent . id } /tokens` , {
1233+ method : "POST" ,
1234+ body : JSON . stringify ( { label : `${ agent . handle } dashboard token` } ) ,
1235+ } ) ;
1236+ setMintedTokens ( ( current ) => ( { ...current , [ agent . id ] : { token : payload . token } } ) ) ;
1237+ setActionStatus ( "Token minted. Copy it now; it will not be shown after refresh." ) ;
1238+ } catch ( error ) {
1239+ setActionStatus ( error instanceof Error ? error . message : "Token minting failed." ) ;
1240+ }
1241+ } ;
1242+
11731243 const approveAgent = async ( agentId : string ) => {
11741244 try {
11751245 await operatorRequest ( "agent-approvals" , {
@@ -1491,7 +1561,10 @@ export function App() {
14911561 < Onboarding
14921562 copiedPromptAgentId = { copiedPromptAgentId }
14931563 expandedIds = { expandedAgentIds }
1564+ mintedTokens = { mintedTokens }
14941565 onCopyPrompt = { copyOnboardingCorrectionPrompt }
1566+ onCopyTokenPrompt = { copyMintedTokenPrompt }
1567+ onMintToken = { mintAgentToken }
14951568 onOpenProfile = { openProfile }
14961569 onStatus = { updateAgentStatus }
14971570 onToggle = { ( agentId ) => toggleSetValue ( setExpandedAgentIds , agentId ) }
0 commit comments