mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-28 19:11:03 +08:00
fix(agent-manager): extract pending-create below the app size cap
PR #12931 grew AgentManagerApp.tsx to 2808 lines, over its 2800 max-lines ESLint cap. Main's push workflows path-filter the lint job so the breakage is latent there, but every kilo-vscode PR fails merge CI. Extract the cross-project pending-create controller into pending-create.ts instead of raising the cap.
This commit is contained in:
@@ -5,6 +5,7 @@ import { join } from "node:path"
|
||||
const root = join(__dirname, "..", "..")
|
||||
const dialog = readFileSync(join(root, "webview-ui", "agent-manager", "NewWorktreeDialog.tsx"), "utf8")
|
||||
const app = readFileSync(join(root, "webview-ui", "agent-manager", "AgentManagerApp.tsx"), "utf8")
|
||||
const pending = readFileSync(join(root, "webview-ui", "agent-manager", "pending-create.ts"), "utf8")
|
||||
const importer = readFileSync(join(root, "src", "agent-manager", "worktree-importer.ts"), "utf8")
|
||||
const css = readFileSync(join(root, "webview-ui", "agent-manager", "agent-manager.css"), "utf8")
|
||||
|
||||
@@ -20,9 +21,10 @@ describe("Agent Manager New Worktree project targeting", () => {
|
||||
})
|
||||
|
||||
it("does not replace a pending cross-project activation", () => {
|
||||
expect(app).toContain("if (pendingCreate()) return")
|
||||
expect(pending).toContain("if (pending()) return")
|
||||
expect(app).toContain("usePendingCreate(activeProjectId")
|
||||
expect(app).toContain('msg.type === "agentManager.importResult"')
|
||||
expect(app).toContain("!msg.success && pendingCreate()?.projectId === msg.projectId")
|
||||
expect(app).toContain("!msg.success) creation.abandon(msg.projectId)")
|
||||
})
|
||||
|
||||
it("tags branch and import responses with their owning project", () => {
|
||||
|
||||
@@ -27,7 +27,6 @@ import type {
|
||||
AgentManagerWorktreeDiffLoadingMessage,
|
||||
AgentManagerWorktreeDiffNoticeMessage,
|
||||
AgentManagerDiffBranchesMessage,
|
||||
AgentManagerImportResultMessage,
|
||||
AgentManagerApplyWorktreeDiffResultMessage,
|
||||
AgentManagerWorktreeStatsMessage,
|
||||
AgentManagerLocalStatsMessage,
|
||||
@@ -181,6 +180,7 @@ import { clampPanelWidth, maxPanelWidth, minPanelWidth } from "./side-panel-layo
|
||||
import { buildShortcutCategories } from "./shortcuts"
|
||||
import { tracker } from "./telemetry"
|
||||
import { createChatFocus, hasQuestionOption } from "./focus"
|
||||
import { usePendingCreate } from "./pending-create"
|
||||
import "./agent-manager.css"
|
||||
import "./agent-manager-review.css"
|
||||
import { cycleAgent as cycle } from "../src/context/session-agent"
|
||||
@@ -268,12 +268,12 @@ const AgentManagerContent: Component = () => {
|
||||
const [currentProjectId, setCurrentProjectId] = createSignal<string | undefined>()
|
||||
const [projectStates, setProjectStates] = createSignal<Record<string, AgentManagerStateMessage>>({})
|
||||
const activeProjectId = () => projectList().find((p) => p.active)?.id ?? currentProjectId()
|
||||
const [pendingCreate, setPendingCreate] = createSignal<{ projectId: string }>()
|
||||
const scheduleCreate = (projectId: string) => {
|
||||
if (projectId === activeProjectId()) return
|
||||
if (pendingCreate()) return
|
||||
setPendingCreate({ projectId })
|
||||
}
|
||||
const creation = usePendingCreate(activeProjectId, (projectId, worktreeId) =>
|
||||
vscode.postMessage({
|
||||
type: "agentManager.activateSelection",
|
||||
target: { projectId, kind: "worktree", worktreeId },
|
||||
}),
|
||||
)
|
||||
const isActivePayload = (pid: string | undefined) =>
|
||||
projectList().length === 0 || pid === undefined || pid === activeProjectId()
|
||||
|
||||
@@ -1394,15 +1394,7 @@ const AgentManagerContent: Component = () => {
|
||||
|
||||
if (msg.type === "agentManager.worktreeSetup") {
|
||||
const ev = msg as AgentManagerWorktreeSetupMessage
|
||||
const pending = pendingCreate()
|
||||
if (ev.status === "ready" && ev.projectId && pending?.projectId === ev.projectId && ev.worktreeId) {
|
||||
setPendingCreate(undefined)
|
||||
vscode.postMessage({
|
||||
type: "agentManager.activateSelection",
|
||||
target: { projectId: ev.projectId, kind: "worktree", worktreeId: ev.worktreeId },
|
||||
})
|
||||
}
|
||||
if (ev.status === "error" && pending?.projectId === ev.projectId) setPendingCreate(undefined)
|
||||
creation.setup(ev)
|
||||
const store = ev.projectId ? registry.ensure(ev.projectId) : registry.active()
|
||||
const updateBusy: Setter<Map<string, WorktreeBusyState>> = (value) => store.setBusy(value)
|
||||
if (ev.status === "ready" || ev.status === "error") {
|
||||
@@ -1444,8 +1436,7 @@ const AgentManagerContent: Component = () => {
|
||||
}
|
||||
}
|
||||
|
||||
if (msg.type === "agentManager.importResult" && !msg.success && pendingCreate()?.projectId === msg.projectId)
|
||||
setPendingCreate(undefined)
|
||||
if (msg.type === "agentManager.importResult" && !msg.success) creation.abandon(msg.projectId)
|
||||
|
||||
if (msg.type === "agentManager.sessionAdded") {
|
||||
const ev = msg as { type: string; sessionId: string; worktreeId: string }
|
||||
@@ -1488,7 +1479,7 @@ const AgentManagerContent: Component = () => {
|
||||
// When a multi-version progress update arrives, mark newly created worktrees as loading
|
||||
if ((msg as { type: string }).type === "agentManager.multiVersionProgress") {
|
||||
const ev = msg as unknown as AgentManagerMultiVersionProgressMessage
|
||||
if (ev.status === "done" && pendingCreate()?.projectId === ev.projectId) setPendingCreate(undefined)
|
||||
if (ev.status === "done") creation.abandon(ev.projectId)
|
||||
if (ev.status === "done" && ev.groupId) {
|
||||
// Clear busy state for all worktrees in this group
|
||||
const store = ev.projectId ? registry.ensure(ev.projectId) : registry.active()
|
||||
@@ -1914,7 +1905,7 @@ const AgentManagerContent: Component = () => {
|
||||
projects={multiProject() ? projectList : undefined}
|
||||
activeProjectId={activeProjectId()}
|
||||
defaultBase={defaultBase}
|
||||
onCreate={scheduleCreate}
|
||||
onCreate={creation.schedule}
|
||||
/>
|
||||
))
|
||||
}
|
||||
@@ -2393,7 +2384,7 @@ const AgentManagerContent: Component = () => {
|
||||
currentSessionID={session.currentSessionID}
|
||||
mode={mode}
|
||||
defaultBase={defaultBase}
|
||||
onCreate={scheduleCreate}
|
||||
onCreate={creation.schedule}
|
||||
bindings={kb()}
|
||||
t={t}
|
||||
onSearchRef={(ref) => (sidebarSearchMenu = ref)}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { createSignal } from "solid-js"
|
||||
|
||||
/**
|
||||
* Tracks a cross-project worktree creation so the target project is activated
|
||||
* once its worktree is ready, and abandons the pending activation when the
|
||||
* creation fails or completes through another flow.
|
||||
*/
|
||||
export function usePendingCreate(
|
||||
active: () => string | undefined,
|
||||
activate: (projectId: string, worktreeId: string) => void,
|
||||
) {
|
||||
const [pending, setPending] = createSignal<{ projectId: string }>()
|
||||
|
||||
const schedule = (projectId: string) => {
|
||||
if (projectId === active()) return
|
||||
if (pending()) return
|
||||
setPending({ projectId })
|
||||
}
|
||||
|
||||
const abandon = (projectId?: string) => {
|
||||
if (pending()?.projectId === projectId) setPending(undefined)
|
||||
}
|
||||
|
||||
const setup = (ev: { status: string; projectId?: string; worktreeId?: string }) => {
|
||||
if (pending()?.projectId !== ev.projectId) return
|
||||
if (ev.status === "ready" && ev.projectId && ev.worktreeId) {
|
||||
setPending(undefined)
|
||||
activate(ev.projectId, ev.worktreeId)
|
||||
}
|
||||
if (ev.status === "error") setPending(undefined)
|
||||
}
|
||||
|
||||
return { schedule, abandon, setup }
|
||||
}
|
||||
Reference in New Issue
Block a user