mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-28 19:11:03 +08:00
46b7e55f8d
Add an experimental multi-project mode to the Agent Manager sidebar behind kilo-code.new.experimental.multiProject (default off). A persistent project registry catalogs additional git repositories across restarts, while the workspace repository stays the pinned default project. Extension: - Immutable per-project contexts own all repository-bound services (state, worktrees, setup scripts, stale tracking, pollers) with generation-based invalidation and fail-closed trust checks. - ProjectContexts manage activation, expansion, and fast switching; session routes resolve directories exactly per project via a shared route service. - pushProjectSessions caches each project's session list and re-posts it on fresh skips; session.created/updated/deleted SSE events upsert into the owning project's cache so externally created sessions appear immediately. - Selection restore persists the active target per project and falls back to the local context silently when the remembered target is gone. - Worktree lifecycle handlers extracted into provider-lifecycle.ts with an explicit deps object instead of ambient project scope. - initializeState and onRequestState always refresh sessions: with zero managed sessions the listing never ran and the sidebar skeletons forever. - Log instead of dropping silently when a state-gated message is not ready. Webview: - ProjectList accordion with per-project sidebar body, search, actions, and default-branch dialog; selecting a project header restores its target. - Local session tabs and terminal contexts are bucketed per project so open tabs never leak across projects sharing the LOCAL context. - The active project's session list overlays the live session store so new sessions show without waiting for a backend re-list. - SectionHeader requires a DragDropProvider ancestor; the multi-project body now provides one (its absence crashed the whole webview render). - SidebarBody and TabBar extracted out of AgentManagerApp (3215 to 2748 lines); AgentManagerProvider down to 1887 with caps lowered accordingly. Also includes the config write revision bindings and per-project indexing consent groundwork that rode along on this branch.
48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
import { describe, expect, it } from "bun:test"
|
|
import { IndexingConsentStore } from "../../src/indexing-consent"
|
|
|
|
describe("IndexingConsentStore", () => {
|
|
it("isolates consent by canonical project id", async () => {
|
|
let value: unknown
|
|
const store = new IndexingConsentStore(
|
|
{
|
|
read: () => value,
|
|
write: (next) => {
|
|
value = next
|
|
},
|
|
},
|
|
async (dir) => (dir.includes("alias") ? "/repo/a" : dir),
|
|
)
|
|
const first = await store.project("/repo/a")
|
|
const alias = await store.project("/alias/a")
|
|
const second = await store.project("/repo/b")
|
|
|
|
await store.set(first.id, true)
|
|
|
|
expect(alias.id).toBe(first.id)
|
|
expect(store.enabled(alias.id)).toBe(true)
|
|
expect(store.enabled(second.id)).toBe(false)
|
|
})
|
|
|
|
it("serializes concurrent updates without dropping another project", async () => {
|
|
let value: unknown
|
|
const store = new IndexingConsentStore(
|
|
{
|
|
read: () => value,
|
|
write: async (next) => {
|
|
await Promise.resolve()
|
|
value = next
|
|
},
|
|
},
|
|
async (dir) => dir,
|
|
)
|
|
const first = await store.project("/repo/a")
|
|
const second = await store.project("/repo/b")
|
|
|
|
await Promise.all([store.set(first.id, true), store.set(second.id, true)])
|
|
|
|
expect(store.enabled(first.id)).toBe(true)
|
|
expect(store.enabled(second.id)).toBe(true)
|
|
})
|
|
})
|