diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8ba072..ad18bbb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,33 +9,20 @@ permissions: contents: read jobs: - core: - strategy: - matrix: - os: [ubuntu-latest, windows-latest] - runs-on: ${{ matrix.os }} + verify: + runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 with: node-version: 22 cache: npm + cache-dependency-path: | + package-lock.json + desktop/package-lock.json - run: npm ci - run: npm run check - - run: npm audit --omit=dev - - desktop: - runs-on: ubuntu-latest - defaults: - run: - working-directory: desktop - steps: - - uses: actions/checkout@v7 - - uses: actions/setup-node@v7 - with: - node-version: 22 - cache: npm - cache-dependency-path: desktop/package-lock.json - run: npm ci + working-directory: desktop - run: npm run typecheck - - run: npm audit --omit=dev + working-directory: desktop diff --git a/.github/workflows/dependency-audit.yml b/.github/workflows/dependency-audit.yml new file mode 100644 index 0000000..f149c9b --- /dev/null +++ b/.github/workflows/dependency-audit.yml @@ -0,0 +1,28 @@ +name: Dependency Audit + +on: + schedule: + - cron: "17 9 * * 1" + workflow_dispatch: + +permissions: + contents: read + +jobs: + audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-node@v7 + with: + node-version: 22 + cache: npm + cache-dependency-path: | + package-lock.json + desktop/package-lock.json + - run: npm ci + - run: npm audit --omit=dev + - run: npm ci + working-directory: desktop + - run: npm audit --omit=dev + working-directory: desktop diff --git a/README.md b/README.md index 542a00a..13ebaea 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Coding agents are effective inside one task and one checkout. The harder problem - manager-owned commits retained under `refs/codepilot/runs/...` - collision detection, integration branches, repository validation, and deterministic review - Git-native task provenance and generated GitHub pull-request descriptions -- an Electron desktop control plane for projects, task queues, knowledge, and live agent events +- an Electron desktop control plane with local/remote Git onboarding, project-scoped PM threads, task queues, knowledge, and live agent events ## Trust boundary @@ -30,6 +30,7 @@ codePilot filters parent conversation identifiers and common unrelated secrets f - Node.js 22+ - Git +- GitHub CLI for repository cloning and pull-request publication - Codex CLI and/or Claude Code, already installed and authenticated - Windows, macOS, or Linux for the CLI; the packaged desktop flow is currently Windows-first @@ -74,6 +75,10 @@ npm run desktop:dev Build the Windows package with `npm run desktop:build`; output is written under `desktop/out/`. Automatic task deployment is off by default. +The Projects screen can register an existing local Git checkout or clone an HTTPS/SSH remote into the configured projects directory. Credentials are never accepted in repository URLs; Git's configured credential helper or SSH agent owns authentication. After registration, onboarding asks the operator to review the App Core start command, repository-relative working directory, and local URL before Project Manager begins; this step saves configuration but never launches the app. Each registered repository has its own Project Manager thread, conversation, backlog, knowledge, and run database. Turns are serialized within one project while different projects can think and execute concurrently, even as the desktop switches between them. Removing a project only unregisters it from the workspace; its repository and `.codepilot` data remain on disk so it can be onboarded again later. + +Settings includes a GitHub connection panel backed by the official `gh` browser login. GitHub CLI stores the credential in the operating-system credential store; codePilot receives only redacted account/status metadata. GitHub writes require both the global **Allow GitHub write operations** switch and an explicit **Create GitHub pull request** selection for that deployment. Today those writes are limited to pushing the generated integration branch and opening its pull request—codePilot does not merge, delete, change repository settings, or grant access. + The older local Next.js dashboard is deliberately absent from the public tree because it contains a separately licensed UI kit. Electron is the supported public UI. ## Worker configuration diff --git a/desktop/src/active-agents.tsx b/desktop/src/active-agents.tsx index eac6672..2616ade 100644 --- a/desktop/src/active-agents.tsx +++ b/desktop/src/active-agents.tsx @@ -3,7 +3,7 @@ import { ChevronDownIcon, FolderOpenIcon, StopCircleIcon } from "@heroicons/reac import type { ActiveAgent } from "./types"; import { collapseLifecycleEvents, EventView } from "./event-view"; -export function ActiveAgents() { +export function ActiveAgents({ projectId }: { projectId: string }) { const [agents, setAgents] = useState([]), [expanded, setExpanded] = useState>(new Set()), [messages, setMessages] = useState>({}), @@ -15,7 +15,7 @@ export function ActiveAgents() { logs = useRef(new Map()); async function refresh() { try { - const next = await window.codepilot.getActiveAgents(); + const next = await window.codepilot.getActiveAgents(projectId); setAgents(next); setExpanded((current) => { const copy = new Set(current); @@ -34,7 +34,7 @@ export function ActiveAgents() { void refresh(); const timer = setInterval(() => void refresh(), 1200); return () => clearInterval(timer); - }, []); + }, [projectId]); useEffect(() => { const frame = requestAnimationFrame(() => { for (const [taskId, element] of logs.current) @@ -55,7 +55,7 @@ export function ActiveAgents() { setSending(agent.taskId); setError(""); try { - setAgents(await window.codepilot.guideAgent(agent.taskId, message)); + setAgents(await window.codepilot.guideAgent(projectId, agent.taskId, message)); setMessages((current) => ({ ...current, [agent.taskId]: "" })); } catch (cause) { setError(cause instanceof Error ? cause.message : String(cause)); @@ -67,7 +67,7 @@ export function ActiveAgents() { setInterrupting(agent.taskId); setError(""); try { - const result = await window.codepilot.interruptAgent(agent.taskId); + const result = await window.codepilot.interruptAgent(projectId, agent.taskId); setFeedback(result.feedback); setAgents(result.agents); } catch (cause) { @@ -90,7 +90,7 @@ export function ActiveAgents() {

- + {agents.length > 1 && <> + +