Files
kilocode/packages/kilo-vscode/tests/unit/indexing-consent.test.ts
T
marius-kilocode 46b7e55f8d feat(vscode): multi-project Agent Manager with per-project state, sessions, and lifecycle
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.
2026-07-27 16:44:57 +02:00

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)
})
})