diff --git a/packages/kilo-gateway/src/server/routes.ts b/packages/kilo-gateway/src/server/routes.ts index cb1890fe80f..44e36e3a3e3 100644 --- a/packages/kilo-gateway/src/server/routes.ts +++ b/packages/kilo-gateway/src/server/routes.ts @@ -8,7 +8,7 @@ import { fetchProfile, fetchBalance } from "../api/profile.js" import { fetchKilocodeNotifications, KilocodeNotificationSchema } from "../api/notifications.js" import { fetchOrganizationModes, clearModesCache } from "../api/modes.js" -import { KILO_API_BASE, HEADER_FEATURE } from "../api/constants.js" +import { KILO_API_BASE, HEADER_FEATURE, HEADER_ORGANIZATIONID } from "../api/constants.js" import { buildKiloHeaders } from "../headers.js" import type { ImportDeps, DrizzleDb } from "../cloud-sessions.js" import { fetchCloudSession, fetchCloudSessionForImport, importSessionToDb } from "../cloud-sessions.js" @@ -536,12 +536,16 @@ export function createKiloRoutes(deps: KiloRoutesDeps) { const token = auth.type === "api" ? auth.key : auth.type === "oauth" ? auth.access : undefined if (!token) return c.json({ error: "No valid token found" }, 401) - const response = await fetch(`${KILO_API_BASE}/api/kiloclaw/status`, { - headers: { - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - }, - }) + const organizationId = auth.type === "oauth" ? auth.accountId : undefined + const headers: Record = { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + } + if (organizationId) { + headers[HEADER_ORGANIZATIONID] = organizationId + } + + const response = await fetch(`${KILO_API_BASE}/api/kiloclaw/status`, { headers }) if (!response.ok) { const text = await response.text() @@ -589,12 +593,16 @@ export function createKiloRoutes(deps: KiloRoutesDeps) { const token = auth.type === "api" ? auth.key : auth.type === "oauth" ? auth.access : undefined if (!token) return c.json({ error: "No valid token found" }, 401) - const response = await fetch(`${KILO_API_BASE}/api/kiloclaw/chat-credentials`, { - headers: { - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - }, - }) + const organizationId = auth.type === "oauth" ? auth.accountId : undefined + const headers: Record = { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + } + if (organizationId) { + headers[HEADER_ORGANIZATIONID] = organizationId + } + + const response = await fetch(`${KILO_API_BASE}/api/kiloclaw/chat-credentials`, { headers }) if (!response.ok) { const text = await response.text() diff --git a/packages/opencode/src/kilocode/components/dialog-claw-setup.tsx b/packages/opencode/src/kilocode/components/dialog-claw-setup.tsx index 145777d026f..e9e000f046c 100644 --- a/packages/opencode/src/kilocode/components/dialog-claw-setup.tsx +++ b/packages/opencode/src/kilocode/components/dialog-claw-setup.tsx @@ -13,10 +13,12 @@ import { useTheme } from "@tui/context/theme" import { useDialog } from "@tui/ui/dialog" import { Link } from "@tui/ui/link" -export function DialogClawSetup() { +export function DialogClawSetup(props: { orgId?: string | null }) { const { theme } = useTheme() const dialog = useDialog() + const url = props.orgId ? `https://app.kilo.ai/organizations/${props.orgId}/claw` : "https://app.kilo.ai/claw" + useKeyboard((evt: any) => { if (evt.name === "return") { dialog.clear() @@ -56,7 +58,7 @@ export function DialogClawSetup() { {"🦀 "} - + Try KiloClaw diff --git a/packages/opencode/src/kilocode/components/dialog-claw-upgrade.tsx b/packages/opencode/src/kilocode/components/dialog-claw-upgrade.tsx index df07b48e139..5047901bcc4 100644 --- a/packages/opencode/src/kilocode/components/dialog-claw-upgrade.tsx +++ b/packages/opencode/src/kilocode/components/dialog-claw-upgrade.tsx @@ -13,10 +13,12 @@ import { useTheme } from "@tui/context/theme" import { useDialog } from "@tui/ui/dialog" import { Link } from "@tui/ui/link" -export function DialogClawUpgrade() { +export function DialogClawUpgrade(props: { orgId?: string | null }) { const { theme } = useTheme() const dialog = useDialog() + const url = props.orgId ? `https://app.kilo.ai/organizations/${props.orgId}/claw` : "https://app.kilo.ai/claw" + useKeyboard((evt: any) => { if (evt.name === "return") { dialog.clear() @@ -44,7 +46,7 @@ export function DialogClawUpgrade() { - + Dashboard diff --git a/packages/opencode/src/kilocode/kilo-commands.tsx b/packages/opencode/src/kilocode/kilo-commands.tsx index cb14f0ab009..e622b35ee22 100644 --- a/packages/opencode/src/kilocode/kilo-commands.tsx +++ b/packages/opencode/src/kilocode/kilo-commands.tsx @@ -52,13 +52,17 @@ export function registerKiloCommands(useSDK: () => UseSDK) { enabled: isKiloConnected(), hidden: !isKiloConnected(), onSelect: async () => { - // Check instance status first - const res = await sdk.client.kilo.claw.status().catch(() => null) + // Fetch profile (for org context) and instance status in parallel + const [profileRes, res] = await Promise.all([ + sdk.client.kilo.profile().catch(() => null), + sdk.client.kilo.claw.status().catch(() => null), + ]) + const orgId = profileRes?.data?.currentOrgId ?? null const status = res?.data as ClawStatus | undefined // No instance provisioned if (!status || !status.userId || res.error) { - dialog.replace(() => ) + dialog.replace(() => ) return } @@ -67,7 +71,7 @@ export function registerKiloCommands(useSDK: () => UseSDK) { if (!creds?.data || creds.error) { // Instance exists but no chat credentials — needs upgrade - dialog.replace(() => ) + dialog.replace(() => ) return }