Compare commits

...

4 Commits

Author SHA1 Message Date
Peter Steinberger
af8ab49f13 fix: satisfy discord and gateway typing 2026-01-03 02:52:04 +01:00
Peter Steinberger
dcafc78024 docs: note onboarding scroll gutter 2026-01-03 02:47:56 +01:00
Peter Steinberger
a1ebc99c7b fix: respect onboarding scroll indicator preference 2026-01-03 02:47:34 +01:00
Shadow
ddc976004a macOS: add onboarding scroll gutter 2026-01-03 02:47:31 +01:00
5 changed files with 22 additions and 10 deletions

View File

@ -55,6 +55,7 @@
### Fixes
- Gog calendar: format date ranges as RFC 3339 with timezone to satisfy Google Calendar API (thanks @jayhickey).
- macOS onboarding: add scrollable page gutter for overflowing content (#105) — thanks @thewilloftheshadow.
- Chat UI: keep the chat scrolled to the latest message after switching sessions.
- Auto-reply: stream completed reply blocks as soon as they finish (configurable default + break); skip empty tool-only blocks unless verbose.
- Discord: avoid duplicate sends when block streaming is enabled (race with typing hook).

View File

@ -133,10 +133,16 @@ extension OnboardingView {
}
func onboardingPage(@ViewBuilder _ content: () -> some View) -> some View {
VStack(spacing: 16) {
content()
Spacer()
let scrollIndicatorGutter: CGFloat = 18
return ScrollView {
VStack(spacing: 16) {
content()
Spacer(minLength: 0)
}
.frame(maxWidth: .infinity, alignment: .top)
.padding(.trailing, scrollIndicatorGutter)
}
.scrollIndicators(.automatic)
.padding(.horizontal, 28)
.frame(width: self.pageWidth, alignment: .top)
}

View File

@ -442,7 +442,7 @@ extension OnboardingView {
}
func permissionsPage() -> some View {
self.onboardingPage {
return self.onboardingPage {
Text("Grant permissions")
.font(.largeTitle.weight(.semibold))
Text("These macOS permissions let Clawdis automate apps and capture context on this Mac.")

View File

@ -396,6 +396,11 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
MediaType: media?.contentType,
MediaUrl: media?.path,
};
const replyTarget = ctxPayload.To ?? undefined;
if (!replyTarget) {
runtime.error?.(danger("discord: missing reply target"));
return;
}
if (isDirectMessage) {
const sessionCfg = cfg.session;
@ -430,7 +435,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
.then(async () => {
await deliverReplies({
replies: [payload],
target: ctxPayload.To,
target: replyTarget,
token,
runtime,
replyToMode,
@ -473,7 +478,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
await deliverReplies({
replies,
target: ctxPayload.To,
target: replyTarget,
token,
runtime,
replyToMode,
@ -482,7 +487,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
didSendReply = true;
if (isVerbose()) {
logVerbose(
`discord: delivered ${replies.length} reply${replies.length === 1 ? "" : "ies"} to ${ctxPayload.To}`,
`discord: delivered ${replies.length} reply${replies.length === 1 ? "" : "ies"} to ${replyTarget}`,
);
}
if (

View File

@ -27,6 +27,7 @@ export async function callGateway<T = unknown>(
const config = loadConfig();
const isRemoteMode = config.gateway?.mode === "remote";
const remote = isRemoteMode ? config.gateway?.remote : undefined;
const authToken = config.gateway?.auth?.token;
const url =
(typeof opts.url === "string" && opts.url.trim().length > 0
? opts.url.trim()
@ -44,9 +45,8 @@ export async function callGateway<T = unknown>(
? remote.token.trim()
: undefined
: process.env.CLAWDIS_GATEWAY_TOKEN?.trim() ||
(typeof config.gateway?.auth?.token === "string" &&
config.gateway.auth.token.trim().length > 0
? config.gateway.auth.token.trim()
(typeof authToken === "string" && authToken.trim().length > 0
? authToken.trim()
: undefined));
const password =
(typeof opts.password === "string" && opts.password.trim().length > 0