You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Rank the no-account copy as the buttons rank it, and harden its links
Read the sentence in the order the routes are weighted: GitHub sign-in leads,
as the primary button; the provider sign-in follows; reload and docs trail,
being the copy's only links rather than buttons. Reload and docs become their
own sentences — kept as trailing clauses they would have fallen under the "if
you already set up Claude elsewhere" conditional, which does not scope docs.
Addresses review feedback: build both `command:` hrefs through
`createCommandUri` instead of by hand (`encodeURIComponent` leaves `)` alone,
so an agent id containing one closed the markdown link destination early), and
escape the host-supplied display name and sign-in provider before interpolating
them into markdown this banner trusts for two commands.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
returnsetupMarkdown(localize('agentHost.sdkSetup.noAccountDescription.all',"If you already set up {0} elsewhere, [reload {0} configuration]({1}). Sign in to GitHub to use GitHub Copilot models, sign in to {2} to use your {2} subscription, or [learn more]({3}) for other ways to set up {0}.",displayName,reload,provider,docs));
113
+
returnsetupMarkdown(localize('agentHost.sdkSetup.noAccountDescription.all',"Sign in to GitHub to use GitHub Copilot models, or sign in to {2} to use your {2} subscription. If you already set up {0} elsewhere, [reload {0} configuration]({1}). [Learn more]({3}) about other ways to set up {0}.",name,reload,provider,docs));
119
114
}
120
115
if(provider){
121
-
returnsetupMarkdown(localize('agentHost.sdkSetup.noAccountDescription.signIn',"If you already set up {0} elsewhere, [reload {0} configuration]({1}). Sign in to GitHub to use GitHub Copilot models, or sign in to {2} to use your {2} subscription.",displayName,reload,provider));
116
+
returnsetupMarkdown(localize('agentHost.sdkSetup.noAccountDescription.signIn',"Sign in to GitHub to use GitHub Copilot models, or sign in to {2} to use your {2} subscription. If you already set up {0} elsewhere, [reload {0} configuration]({1}).",name,reload,provider));
122
117
}
123
118
if(docs){
124
-
returnsetupMarkdown(localize('agentHost.sdkSetup.noAccountDescription.docs',"If you already set up {0} elsewhere, [reload {0} configuration]({1}). Sign in to GitHub to use GitHub Copilot models, or [learn more]({2}) for other ways to set up {0}.",displayName,reload,docs));
119
+
returnsetupMarkdown(localize('agentHost.sdkSetup.noAccountDescription.docs',"Sign in to GitHub to use GitHub Copilot models. If you already set up {0} elsewhere, [reload {0} configuration]({1}). [Learn more]({2}) about other ways to set up {0}.",name,reload,docs));
125
120
}
126
-
returnsetupMarkdown(localize('agentHost.sdkSetup.noAccountDescription',"If you already set up {0} elsewhere, [reload {0} configuration]({1}). Sign in to GitHub to use GitHub Copilot models.",displayName,reload));
121
+
returnsetupMarkdown(localize('agentHost.sdkSetup.noAccountDescription',"Sign in to GitHub to use GitHub Copilot models. If you already set up {0} elsewhere, [reload {0} configuration]({1}).",name,reload));
// Leads every variant, as the primary button does.
128
+
constgitHub='Sign in to GitHub to use GitHub Copilot models';
130
129
// Unconditional: setup finished in a terminal has no completion signal, so
131
130
// every agent needs the "look again" route whatever else it declares.
132
-
constreload=`If you already set up Claude elsewhere, [reload Claude configuration](command:${AGENT_SDK_SETUP_RELOAD_COMMAND_ID}?%22claude%22).`;
131
+
constreload=`If you already set up Claude elsewhere, [reload Claude configuration](command:${AGENT_SDK_SETUP_RELOAD_COMMAND_ID}?%255B%2522claude%2522%255D).`;
132
+
// The agent id, like every button carries — the command resolves the URL
133
+
// from the agent's own declaration rather than trusting the banner's copy.
134
+
constdocs=`[Learn more](command:${AGENT_SDK_SETUP_OPEN_DOCS_COMMAND_ID}?%255B%2522claude%2522%255D) about other ways to set up Claude.`;
gitHubOnly: `${reload} Sign in to GitHub to use GitHub Copilot models.`,
141
-
docs: `${reload}Sign in to GitHub to use GitHub Copilot models, or [learn more](${docs}) for other ways to set up Claude.`,
142
-
signIn: `${reload} Sign in to GitHub to use GitHub Copilot models, or sign in to ChatGPT to use your ChatGPT subscription.`,
143
-
both: `${reload} Sign in to GitHub to use GitHub Copilot models, sign in to ChatGPT to use your ChatGPT subscription, or [learn more](${docs}) for other ways to set up Claude.`,
142
+
gitHubOnly: `${gitHub}. ${reload}`,
143
+
docs: `${gitHub}. ${reload}${docs}`,
144
+
signIn: `${gitHub}, or sign in to ChatGPT to use your ChatGPT subscription.${reload}`,
145
+
both: `${gitHub}, or sign in to ChatGPT to use your ChatGPT subscription. ${reload}${docs}`,
144
146
});
145
147
});
146
148
149
+
test('a name carrying markdown is escaped, so the host cannot forge a third link',()=>{
150
+
// Both nouns arrive from the host, and this description is trusted for two
151
+
// commands — an unescaped `[]()` in either would render as a link to one of
`Sign in to GitHub to use GitHub Copilot models, or sign in to Chat\\[G\\]PT to use your Chat\\[G\\]PT subscription. If you already set up ${name} elsewhere, [reload ${name} configuration](command:${AGENT_SDK_SETUP_RELOAD_COMMAND_ID}?%255B%2522claude%2522%255D). [Learn more](command:${AGENT_SDK_SETUP_OPEN_DOCS_COMMAND_ID}?%255B%2522claude%2522%255D) about other ways to set up ${name}.`);
162
+
});
163
+
147
164
test('the copy is trusted for its own two commands alone, so its links render and reach nothing else',()=>{
148
165
// Untrusted markdown renders a `command:` link as inert text, which would
149
166
// leave both routes with no affordance at all now that neither has a button.
0 commit comments