feat(kilo-sessions): send git remote URL and branch to ingest

Add gitUrl and gitBranch fields to kilo_meta so shared sessions
include repository context. Resolves the best remote (origin > single
available > upstream) and fetches the URL with a 10s in-flight cache.
This commit is contained in:
Evgeny Shurakov
2026-02-18 22:38:46 +01:00
parent e02debf27b
commit a2d18131a8
3 changed files with 60 additions and 2 deletions
@@ -16,6 +16,8 @@ export namespace IngestQueue {
data: {
platform: string
orgId?: string
gitUrl?: string
gitBranch?: string
}
}
| {
@@ -10,6 +10,9 @@ import { clearInFlightCache, withInFlightCache } from "@/kilo-sessions/inflight-
import type * as SDK from "@kilocode/sdk/v2"
import z from "zod"
import { KILO_API_BASE } from "@kilocode/kilo-gateway"
import { $ } from "bun"
import { Instance } from "@/project/instance"
import { Vcs } from "@/project/vcs"
export namespace KiloSessions {
const log = Log.create({ service: "kilo-sessions" })
@@ -23,6 +26,7 @@ export namespace KiloSessions {
const tokenKey = "kilo-sessions:token"
const orgKey = "kilo-sessions:org"
const clientKey = "kilo-sessions:client"
const gitUrlKey = "kilo-sessions:git-url"
const ttlMs = 10_000
@@ -31,6 +35,7 @@ export namespace KiloSessions {
clearInFlightCache(tokenValidKey)
clearInFlightCache(clientKey)
clearInFlightCache(orgKey)
clearInFlightCache(gitUrlKey)
}
async function authValid(token: string) {
@@ -370,13 +375,55 @@ export namespace KiloSessions {
])
}
async function getGitUrl(): Promise<string | undefined> {
return withInFlightCache(gitUrlKey, ttlMs, async () => {
const result = await $`git remote`
.quiet()
.nothrow()
.cwd(Instance.worktree)
.text()
.catch(() => "")
const remotes = result
.split("\n")
.map((line) => line.trim())
.filter(Boolean)
if (remotes.length === 0) return undefined
const remote = remotes.includes("origin")
? "origin"
: remotes.length === 1
? remotes[0]
: remotes.includes("upstream")
? "upstream"
: undefined
if (!remote) return undefined
const url = await $`git config --get remote.${remote}.url`
.quiet()
.nothrow()
.cwd(Instance.worktree)
.text()
.then((x) => x.trim())
.catch(() => "")
return url || undefined
})
}
async function meta() {
const platform = process.env["KILO_PLATFORM"] || "cli"
const orgId = await getOrgId()
const gitBranch = await Vcs.branch().catch(() => undefined)
const gitUrl = await getGitUrl().catch(() => undefined)
return {
platform,
...(orgId ? { orgId } : {}),
...(gitUrl ? { gitUrl } : {}),
...(gitBranch ? { gitBranch } : {}),
}
}
@@ -137,9 +137,16 @@ describe("share ingest queue", () => {
}),
})
await q.sync("s7", [{ type: "kilo_meta", data: { platform: "cli" } }])
await q.sync("s7", [
{ type: "kilo_meta", data: { platform: "cli", gitUrl: "https://github.com/old/repo.git", gitBranch: "main" } },
])
clock.now = 100
await q.sync("s7", [{ type: "kilo_meta", data: { platform: "vscode", orgId: "org-1" } }])
await q.sync("s7", [
{
type: "kilo_meta",
data: { platform: "vscode", orgId: "org-1", gitUrl: "https://github.com/new/repo.git", gitBranch: "feature" },
},
])
clock.now = 1000
sched.run()
@@ -149,6 +156,8 @@ describe("share ingest queue", () => {
expect((sent[0] as any).data[0].type).toBe("kilo_meta")
expect((sent[0] as any).data[0].data.platform).toBe("vscode")
expect((sent[0] as any).data[0].data.orgId).toBe("org-1")
expect((sent[0] as any).data[0].data.gitUrl).toBe("https://github.com/new/repo.git")
expect((sent[0] as any).data[0].data.gitBranch).toBe("feature")
})
test("network failure retries and fill preserves newer updates", async () => {