fix: improve onboarding auth UX

This commit is contained in:
Peter Steinberger
2026-01-02 15:03:38 +01:00
parent f57f892409
commit ad9d6f616d
5 changed files with 37 additions and 7 deletions

View File

@@ -46,6 +46,8 @@
### Fixes
- Chat UI: keep the chat scrolled to the latest message after switching sessions.
- CLI onboarding: persist gateway token in config so local CLI auth works; recommend auth Off unless you need multi-machine access.
- Control UI: accept a `?token=` URL param to auto-fill Gateway auth; onboarding now opens the dashboard with token auth when configured.
- Agent prompt: remove hardcoded user name in system prompt example.
- Chat UI: add extra top padding before the first message bubble in Web Chat (macOS/iOS/Android).
- Control UI: refine Web Chat session selector styling (chevron spacing + background).
- WebChat: stream live updates for sessions even when runs start outside the chat UI.

View File

@@ -10,7 +10,7 @@ describe("buildAgentSystemPromptAppend", () => {
expect(prompt).toContain("## User Identity");
expect(prompt).toContain(
"Owner numbers: +123, +456. Treat messages from these numbers as the user (Peter).",
"Owner numbers: +123, +456. Treat messages from these numbers as the user.",
);
});

View File

@@ -25,7 +25,7 @@ export function buildAgentSystemPromptAppend(params: {
.filter(Boolean);
const ownerLine =
ownerNumbers.length > 0
? `Owner numbers: ${ownerNumbers.join(", ")}. Treat messages from these numbers as the user (Peter).`
? `Owner numbers: ${ownerNumbers.join(", ")}. Treat messages from these numbers as the user.`
: undefined;
const reasoningHint = params.reasoningTagHint
? [
@@ -36,7 +36,7 @@ export function buildAgentSystemPromptAppend(params: {
"Only text inside <final> is shown to the user; everything else is discarded and never seen by the user.",
"Example:",
"<think>Short internal reasoning.</think>",
"<final>Hey Peter! What would you like to do next?</final>",
"<final>Hey there! What would you like to do next?</final>",
].join(" ")
: undefined;
const runtimeInfo = params.runtimeInfo;

View File

@@ -495,9 +495,18 @@ export async function runInteractiveOnboarding(
note(
(() => {
const links = resolveControlUiLinks({ bind, port });
return [`Web UI: ${links.httpUrl}`, `Gateway WS: ${links.wsUrl}`].join(
"\n",
);
const tokenParam =
authMode === "token" && gatewayToken
? `?token=${encodeURIComponent(gatewayToken)}`
: "";
const authedUrl = `${links.httpUrl}${tokenParam}`;
return [
`Web UI: ${links.httpUrl}`,
tokenParam ? `Web UI (with token): ${authedUrl}` : undefined,
`Gateway WS: ${links.wsUrl}`,
]
.filter(Boolean)
.join("\n");
})(),
"Control UI",
);
@@ -511,7 +520,11 @@ export async function runInteractiveOnboarding(
);
if (wantsOpen) {
const links = resolveControlUiLinks({ bind, port });
await openUrl(links.httpUrl);
const tokenParam =
authMode === "token" && gatewayToken
? `?token=${encodeURIComponent(gatewayToken)}`
: "";
await openUrl(`${links.httpUrl}${tokenParam}`);
}
outro("Onboarding complete.");

View File

@@ -186,6 +186,7 @@ export class ClawdisApp extends LitElement {
this.syncThemeWithSettings();
this.attachThemeListener();
window.addEventListener("popstate", this.popStateHandler);
this.applySettingsFromUrl();
this.connect();
this.startNodesPolling();
}
@@ -334,6 +335,20 @@ export class ClawdisApp extends LitElement {
}
}
private applySettingsFromUrl() {
if (!window.location.search) return;
const params = new URLSearchParams(window.location.search);
const token = params.get("token")?.trim();
if (!token) return;
if (!this.settings.token) {
this.applySettings({ ...this.settings, token });
}
params.delete("token");
const url = new URL(window.location.href);
url.search = params.toString();
window.history.replaceState({}, "", url.toString());
}
setTab(next: Tab) {
if (this.tab !== next) this.tab = next;
void this.refreshActiveTab();