Add Coworkers implementation plan
This commit is contained in:
@@ -0,0 +1,738 @@
|
||||
# Coworkers Implementation Plan
|
||||
|
||||
## Product Direction
|
||||
|
||||
Coworkers is a new Plan-first product. Vibe Kanban is used only as a nearby source reference for execution details, not as a subtree, submodule, vendor package, or product base.
|
||||
|
||||
The target product shape is:
|
||||
|
||||
```text
|
||||
Project
|
||||
-> Plan
|
||||
-> Plan Agent discussion
|
||||
-> Task board
|
||||
-> Task agent runs
|
||||
-> Task worktrees
|
||||
-> Task commits
|
||||
-> Plan branch runtime
|
||||
-> Final user-confirmed merge
|
||||
```
|
||||
|
||||
Core rules:
|
||||
|
||||
- Coworkers owns its product model, UI, task board, and orchestration layer.
|
||||
- Vibe Kanban is cloned outside this repository as `/home/ubuntu/dh-projects/vibe-kanban` only for reference.
|
||||
- The MVP is network-accessible, single-tenant, shared-control, and local-execution.
|
||||
- The MVP has no built-in authentication.
|
||||
- All users who can access the Coworkers URL see and operate the same projects, plans, tasks, logs, and runtimes.
|
||||
- All git, agent, clone, test, worktree, and merge operations run on the Coworkers host machine.
|
||||
- A project binds to exactly one git repository on the Coworkers host machine.
|
||||
- A project repo may be an existing local repo or a remote repo cloned onto the Coworkers host machine.
|
||||
|
||||
## Technology Stack
|
||||
|
||||
Use a TypeScript monorepo for the first version:
|
||||
|
||||
```text
|
||||
Package manager: pnpm
|
||||
Runtime: Node.js
|
||||
Server: Fastify
|
||||
Web: React + Vite + TanStack Router
|
||||
DB: SQLite + Drizzle
|
||||
Realtime: SSE
|
||||
Validation: Zod
|
||||
Styling: Tailwind CSS
|
||||
```
|
||||
|
||||
Rationale:
|
||||
|
||||
- Node.js is stable for `child_process`, long-running agent processes, git CLI calls, file system operations, SQLite, and streaming logs.
|
||||
- `pnpm` keeps the monorepo standard and does not block later Bun support or a Rust execution sidecar.
|
||||
- Tailwind gives a fast, consistent UI system while the product model is still evolving.
|
||||
|
||||
## Repository Layout
|
||||
|
||||
Planned repository structure:
|
||||
|
||||
```text
|
||||
Coworkers/
|
||||
apps/
|
||||
web/
|
||||
server/
|
||||
packages/
|
||||
shared/
|
||||
ui/
|
||||
README.md
|
||||
IMPLEMENTATION_PLAN.md
|
||||
package.json
|
||||
pnpm-workspace.yaml
|
||||
```
|
||||
|
||||
Server modules:
|
||||
|
||||
```text
|
||||
apps/server/src/
|
||||
index.ts
|
||||
config/
|
||||
db/
|
||||
routes/
|
||||
services/
|
||||
git/
|
||||
execution/
|
||||
orchestrator/
|
||||
events/
|
||||
logs/
|
||||
```
|
||||
|
||||
Important internal boundaries:
|
||||
|
||||
- `routes/` only validates requests and calls services.
|
||||
- `services/` owns project, plan, task, and agent-profile application logic.
|
||||
- `git/` owns all git CLI calls.
|
||||
- `execution/` owns agent profiles, process spawning, and log streaming.
|
||||
- `orchestrator/` owns task state transitions, integration queue, and operation locks.
|
||||
- `events/` owns plan-level SSE fanout.
|
||||
- `logs/` owns operation, task-run, and plan-runtime logs.
|
||||
|
||||
## Tailwind Implementation Plan
|
||||
|
||||
Tailwind should be introduced as the default UI styling system from the first web app skeleton.
|
||||
|
||||
### Phase 1: Tailwind Setup
|
||||
|
||||
Create the web package with Vite, React, and Tailwind:
|
||||
|
||||
```text
|
||||
apps/web/
|
||||
index.html
|
||||
package.json
|
||||
postcss.config.js
|
||||
tailwind.config.ts
|
||||
tsconfig.json
|
||||
vite.config.ts
|
||||
src/
|
||||
main.tsx
|
||||
app.tsx
|
||||
styles.css
|
||||
```
|
||||
|
||||
`styles.css` should define the Tailwind layers:
|
||||
|
||||
```css
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
```
|
||||
|
||||
The Tailwind config should scan:
|
||||
|
||||
```text
|
||||
apps/web/index.html
|
||||
apps/web/src/**/*.{ts,tsx}
|
||||
packages/ui/src/**/*.{ts,tsx}
|
||||
```
|
||||
|
||||
### Phase 2: Design Tokens
|
||||
|
||||
Start with a small token set, not a large design system.
|
||||
|
||||
Recommended tokens:
|
||||
|
||||
```text
|
||||
Background: zinc/slate dark-neutral base
|
||||
Surface: layered cards and panels
|
||||
Accent: blue or violet for primary actions
|
||||
Status colors: planned, running, testing, integrated, blocked, failed
|
||||
Radii: xl and 2xl for cards/panels
|
||||
Spacing: 4/6/8 rhythm
|
||||
Font: system sans for MVP
|
||||
```
|
||||
|
||||
Expose status style helpers from `packages/ui`:
|
||||
|
||||
```text
|
||||
getPlanStatusClass(status)
|
||||
getTaskStatusClass(status)
|
||||
getOperationStatusClass(status)
|
||||
```
|
||||
|
||||
Do not overbuild tokens before the first task board is real.
|
||||
|
||||
### Phase 3: UI Package
|
||||
|
||||
Create `packages/ui` with minimal reusable primitives:
|
||||
|
||||
```text
|
||||
Button
|
||||
Badge
|
||||
Card
|
||||
Panel
|
||||
Tabs
|
||||
Input
|
||||
Textarea
|
||||
Select
|
||||
StatusPill
|
||||
EmptyState
|
||||
SplitPane
|
||||
LogViewer
|
||||
TaskCard
|
||||
TaskBoardColumn
|
||||
```
|
||||
|
||||
Avoid abstract layout frameworks early. The Plan page is the primary product surface and should drive UI extraction.
|
||||
|
||||
### Phase 4: App Shell
|
||||
|
||||
Build a network-accessible shared-control app shell:
|
||||
|
||||
```text
|
||||
Left rail: Projects / Settings
|
||||
Top bar: current project, server status, public URL warning
|
||||
Main area: route content
|
||||
```
|
||||
|
||||
The shell should make it obvious that repository paths refer to the Coworkers host machine, not the browser user's machine.
|
||||
|
||||
### Phase 5: Core Pages
|
||||
|
||||
Implement Tailwind pages in this order:
|
||||
|
||||
1. `/projects`
|
||||
2. `/projects/new`
|
||||
3. `/projects/:projectId`
|
||||
4. `/projects/:projectId/plans/new`
|
||||
5. `/projects/:projectId/plans/:planId`
|
||||
6. `/settings/agents`
|
||||
|
||||
The Plan page layout:
|
||||
|
||||
```text
|
||||
Left: Plan Agent discussion
|
||||
Center: Task board
|
||||
Right: Plan branch, runtime, validation, merge controls
|
||||
Bottom drawer: logs and diff
|
||||
```
|
||||
|
||||
Task board columns:
|
||||
|
||||
```text
|
||||
Planned
|
||||
Ready
|
||||
Running
|
||||
Testing
|
||||
Integration Queue
|
||||
Integrated
|
||||
Blocked
|
||||
```
|
||||
|
||||
### Phase 6: Runtime UI Behavior
|
||||
|
||||
Use Tailwind state styling for shared operations:
|
||||
|
||||
- Disable buttons when an operation lock exists.
|
||||
- Show `operation in progress` states directly on cards and panels.
|
||||
- Surface conflict, validation failure, and blocked states prominently.
|
||||
- Show task logs in a durable log viewer that can load historical logs and receive SSE updates.
|
||||
|
||||
## Data Directories
|
||||
|
||||
Default host-machine data layout:
|
||||
|
||||
```text
|
||||
~/.coworkers/
|
||||
coworkers.sqlite
|
||||
projects/
|
||||
worktrees/
|
||||
logs/
|
||||
operations/
|
||||
task-runs/
|
||||
plan-runtimes/
|
||||
```
|
||||
|
||||
Default clone directory:
|
||||
|
||||
```text
|
||||
~/.coworkers/projects
|
||||
```
|
||||
|
||||
Default worktree directory:
|
||||
|
||||
```text
|
||||
~/.coworkers/worktrees
|
||||
```
|
||||
|
||||
Plan worktree path:
|
||||
|
||||
```text
|
||||
~/.coworkers/worktrees/<project-id>/<plan-id>/plan
|
||||
```
|
||||
|
||||
Task worktree path:
|
||||
|
||||
```text
|
||||
~/.coworkers/worktrees/<project-id>/<plan-id>/tasks/<task-id>
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Environment variables:
|
||||
|
||||
```text
|
||||
HOST=127.0.0.1
|
||||
PORT=3000
|
||||
PUBLIC_URL=http://localhost:3000
|
||||
COWORKERS_DATA_DIR=~/.coworkers
|
||||
COWORKERS_DEFAULT_CLONE_DIR=~/.coworkers/projects
|
||||
COWORKERS_WORKTREE_DIR=~/.coworkers/worktrees
|
||||
COWORKERS_ALLOWED_ORIGINS=
|
||||
```
|
||||
|
||||
For LAN or internet access:
|
||||
|
||||
```text
|
||||
HOST=0.0.0.0
|
||||
PUBLIC_URL=http://<server-ip>:3000
|
||||
```
|
||||
|
||||
The MVP should default to `HOST=127.0.0.1`. Users must intentionally opt in to network exposure.
|
||||
|
||||
## Project Creation
|
||||
|
||||
Support two creation modes.
|
||||
|
||||
### Use Local Repo
|
||||
|
||||
The user provides a path on the Coworkers host machine.
|
||||
|
||||
Validation:
|
||||
|
||||
- Path exists.
|
||||
- Path is a directory.
|
||||
- `git rev-parse --show-toplevel` succeeds.
|
||||
- The repo is not in the middle of merge, rebase, or cherry-pick.
|
||||
- The selected base branch exists.
|
||||
- HEAD SHA can be read.
|
||||
- Remote origin can be read when available.
|
||||
- Dirty status is shown before plan creation or task execution.
|
||||
|
||||
Ownership:
|
||||
|
||||
```text
|
||||
ownership = user_owned
|
||||
```
|
||||
|
||||
### Clone Remote Repo
|
||||
|
||||
The user provides a remote URL and target directory.
|
||||
|
||||
Defaults:
|
||||
|
||||
```text
|
||||
target directory = ~/.coworkers/projects
|
||||
folder name = inferred from remote URL
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Clone happens on the Coworkers host machine.
|
||||
- Clone auth is handled by the host machine's git environment.
|
||||
- Coworkers does not manage GitHub, GitLab, or other provider tokens in the MVP.
|
||||
- Use `spawn("git", ["clone", remoteUrl, targetPath])`, not shell string interpolation.
|
||||
- Do not overwrite an existing non-empty directory.
|
||||
- Show clone operation logs.
|
||||
|
||||
Ownership:
|
||||
|
||||
```text
|
||||
clone into ~/.coworkers/projects -> coworkers_managed
|
||||
clone into a user-selected external directory -> coworkers_created_external
|
||||
```
|
||||
|
||||
## Branch and Commit Model
|
||||
|
||||
Every Plan owns a dedicated plan branch:
|
||||
|
||||
```text
|
||||
plan/<plan-slug>
|
||||
```
|
||||
|
||||
Every Task runs in an internal task branch:
|
||||
|
||||
```text
|
||||
plan/<plan-slug>/task-001-<task-slug>
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- The plan branch is created from the selected base branch.
|
||||
- The plan worktree checks out the plan branch.
|
||||
- Each task branch is created from the current plan branch.
|
||||
- Each task worktree checks out its task branch.
|
||||
- Agents modify files but do not commit or merge.
|
||||
- Coworkers creates one system task commit after a successful task run and task test.
|
||||
- Coworkers merges the task branch into the plan branch with a normal merge.
|
||||
- Coworkers does not squash task commits in the MVP.
|
||||
- Coworkers never merges a task branch directly into `main` or `master`.
|
||||
- Users validate and optionally run the app from the plan worktree.
|
||||
- Final merge is `plan branch -> base branch` and requires explicit user confirmation.
|
||||
- The MVP does not push automatically.
|
||||
|
||||
## Database Model
|
||||
|
||||
MVP tables:
|
||||
|
||||
```text
|
||||
projects
|
||||
agent_profiles
|
||||
plans
|
||||
plan_messages
|
||||
plan_tasks
|
||||
task_runs
|
||||
execution_logs
|
||||
git_operations
|
||||
operations
|
||||
plan_events
|
||||
plan_runtimes
|
||||
plan_integrations
|
||||
```
|
||||
|
||||
Important statuses:
|
||||
|
||||
```text
|
||||
Plan: draft, discussing, waiting_approval, approved, running, paused, blocked, validating, ready_to_merge, merged, cancelled, failed
|
||||
Task: planned, ready, running, testing, committed, integration_queue, integrating, integrated, blocked, failed, cancelled
|
||||
Operation: running, completed, failed, cancelled
|
||||
Runtime: running, stopped, failed
|
||||
```
|
||||
|
||||
## API Surface
|
||||
|
||||
Projects:
|
||||
|
||||
```text
|
||||
GET /api/projects
|
||||
POST /api/projects/local
|
||||
POST /api/projects/clone
|
||||
GET /api/projects/:projectId
|
||||
GET /api/projects/:projectId/status
|
||||
```
|
||||
|
||||
Agent profiles:
|
||||
|
||||
```text
|
||||
GET /api/agent-profiles
|
||||
POST /api/agent-profiles
|
||||
PATCH /api/agent-profiles/:profileId
|
||||
DELETE /api/agent-profiles/:profileId
|
||||
```
|
||||
|
||||
Plans:
|
||||
|
||||
```text
|
||||
GET /api/projects/:projectId/plans
|
||||
POST /api/projects/:projectId/plans
|
||||
GET /api/plans/:planId
|
||||
POST /api/plans/:planId/messages
|
||||
POST /api/plans/:planId/generate-structured-plan
|
||||
POST /api/plans/:planId/approve
|
||||
POST /api/plans/:planId/start
|
||||
POST /api/plans/:planId/pause
|
||||
POST /api/plans/:planId/validate
|
||||
POST /api/plans/:planId/merge-to-base
|
||||
GET /api/plans/:planId/events
|
||||
```
|
||||
|
||||
Tasks:
|
||||
|
||||
```text
|
||||
POST /api/plans/:planId/tasks
|
||||
PATCH /api/tasks/:taskId
|
||||
POST /api/tasks/:taskId/start
|
||||
POST /api/tasks/:taskId/retry
|
||||
POST /api/tasks/:taskId/cancel
|
||||
GET /api/tasks/:taskId/logs
|
||||
GET /api/tasks/:taskId/diff
|
||||
```
|
||||
|
||||
Plan runtime:
|
||||
|
||||
```text
|
||||
POST /api/plans/:planId/runtime/start
|
||||
POST /api/plans/:planId/runtime/stop
|
||||
POST /api/plans/:planId/runtime/restart
|
||||
GET /api/plans/:planId/runtime/logs
|
||||
```
|
||||
|
||||
Git and diff:
|
||||
|
||||
```text
|
||||
GET /api/plans/:planId/diff
|
||||
GET /api/plans/:planId/branch-status
|
||||
```
|
||||
|
||||
## Realtime Events
|
||||
|
||||
Use SSE for Plan pages:
|
||||
|
||||
```text
|
||||
GET /api/plans/:planId/events
|
||||
```
|
||||
|
||||
Events:
|
||||
|
||||
```text
|
||||
plan.status_changed
|
||||
plan.message_added
|
||||
plan.approved
|
||||
plan.validation_started
|
||||
plan.validation_finished
|
||||
plan.runtime_started
|
||||
plan.runtime_stopped
|
||||
plan.ready_to_merge
|
||||
plan.merged
|
||||
operation.failed
|
||||
```
|
||||
|
||||
Client behavior:
|
||||
|
||||
- Load a Plan snapshot first.
|
||||
- Connect to SSE second.
|
||||
- If SSE disconnects, reload the snapshot and reconnect.
|
||||
|
||||
## Operation Locks
|
||||
|
||||
Because multiple users can access the same app URL, critical operations need locks even without auth.
|
||||
|
||||
Rules:
|
||||
|
||||
- One active run per task.
|
||||
- One active integration queue per plan.
|
||||
- One active validation per plan.
|
||||
- One active final merge per plan.
|
||||
- One active start/stop operation per plan runtime.
|
||||
- One active setup operation per project.
|
||||
|
||||
Duplicate operations should return `409 Conflict` with the current operation state.
|
||||
|
||||
## Plan Agent
|
||||
|
||||
Plan Agent is also an `agent_profile`.
|
||||
|
||||
Plan Agent behavior:
|
||||
|
||||
- Discuss requirements with the user.
|
||||
- Ask clarifying questions.
|
||||
- Produce structured plan JSON.
|
||||
- Never modify code.
|
||||
- Never create commits.
|
||||
- Never merge branches.
|
||||
|
||||
Structured plan schema:
|
||||
|
||||
```json
|
||||
{
|
||||
"summary": "string",
|
||||
"assumptions": ["string"],
|
||||
"risks": ["string"],
|
||||
"tasks": [
|
||||
{
|
||||
"id": "task-001",
|
||||
"title": "string",
|
||||
"description": "string",
|
||||
"acceptance_criteria": ["string"],
|
||||
"depends_on": ["task-000"],
|
||||
"file_hints": ["string"],
|
||||
"recommended_agent": "string",
|
||||
"test_command": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Structured plan output must pass Zod validation before approval.
|
||||
|
||||
## Task Runner
|
||||
|
||||
Task execution flow:
|
||||
|
||||
1. Confirm task is runnable.
|
||||
2. Create task branch from current plan branch.
|
||||
3. Create task worktree.
|
||||
4. Generate task prompt.
|
||||
5. Start assigned agent process.
|
||||
6. Stream logs to files and Plan SSE.
|
||||
7. Wait for agent exit.
|
||||
8. Run task test command.
|
||||
9. Detect git diff.
|
||||
10. Create one system task commit.
|
||||
11. Queue task for plan integration.
|
||||
|
||||
Task prompt must tell agents:
|
||||
|
||||
- Implement only this task.
|
||||
- Do not commit.
|
||||
- Do not merge.
|
||||
- Do not edit unrelated files.
|
||||
- Respect the task acceptance criteria.
|
||||
- Use the provided test command when relevant.
|
||||
|
||||
## Plan Runtime and Acceptance
|
||||
|
||||
The plan worktree is the acceptance environment.
|
||||
|
||||
Users can:
|
||||
|
||||
- Start Preview from the plan worktree.
|
||||
- Stop Preview.
|
||||
- Restart Preview.
|
||||
- View runtime logs.
|
||||
- Run validation command.
|
||||
- View plan diff against base branch.
|
||||
- Confirm final merge.
|
||||
|
||||
Plan runtime commands run on the Coworkers host machine in the plan worktree directory.
|
||||
|
||||
## Vibe Kanban Reference Scope
|
||||
|
||||
After cloning `/home/ubuntu/dh-projects/vibe-kanban`, use these areas as references:
|
||||
|
||||
```text
|
||||
crates/executors
|
||||
crates/git
|
||||
crates/worktree-manager
|
||||
crates/workspace-manager
|
||||
crates/services/src/services/execution_process.rs
|
||||
crates/db/src/models/merge.rs
|
||||
```
|
||||
|
||||
Use Vibe Kanban to study:
|
||||
|
||||
- Agent profile abstraction.
|
||||
- CLI agent spawn behavior.
|
||||
- Log streaming and persistence.
|
||||
- Git worktree safety.
|
||||
- Branch and merge error handling.
|
||||
- Approval and safety boundaries.
|
||||
|
||||
Do not copy Vibe Kanban UI or product model into Coworkers.
|
||||
|
||||
## Milestones
|
||||
|
||||
### Milestone 1: Skeleton
|
||||
|
||||
- Clone Vibe Kanban outside this repo as reference.
|
||||
- Initialize pnpm monorepo.
|
||||
- Create web, server, shared, and ui packages.
|
||||
- Add Tailwind to the web app.
|
||||
- Add Fastify health API.
|
||||
- Add SQLite/Drizzle setup.
|
||||
- Add README safety and boundary notes.
|
||||
|
||||
### Milestone 2: Project and Agent Profiles
|
||||
|
||||
- Implement local repo project creation.
|
||||
- Implement clone remote repo project creation.
|
||||
- Add repo validation.
|
||||
- Add agent profile CRUD.
|
||||
- Add default data directory initialization.
|
||||
|
||||
### Milestone 3: Git Engine
|
||||
|
||||
- Implement safe git CLI wrapper with `spawn` args.
|
||||
- Implement branch creation and checks.
|
||||
- Implement worktree creation and cleanup.
|
||||
- Implement status, diff, commit, and merge.
|
||||
- Add git operation logs.
|
||||
|
||||
### Milestone 4: Plan Foundation
|
||||
|
||||
- Implement plan creation.
|
||||
- Create plan branch.
|
||||
- Create plan worktree.
|
||||
- Implement plan page layout.
|
||||
- Implement Plan SSE events.
|
||||
- Store Plan Agent messages.
|
||||
|
||||
### Milestone 5: Plan Agent and Task Board
|
||||
|
||||
- Run Plan Agent from an agent profile.
|
||||
- Validate structured plan JSON.
|
||||
- Approve plan and generate tasks.
|
||||
- Render task board.
|
||||
- Support task editing and agent assignment.
|
||||
|
||||
### Milestone 6: Task Execution
|
||||
|
||||
- Start task manually.
|
||||
- Create task branch and worktree.
|
||||
- Run assigned agent.
|
||||
- Stream task logs.
|
||||
- Run task tests.
|
||||
- Create system task commit.
|
||||
|
||||
### Milestone 7: Plan Integration
|
||||
|
||||
- Implement serialized plan integration queue.
|
||||
- Merge task branch into plan branch.
|
||||
- Handle conflicts as blocked states.
|
||||
- Update plan worktree.
|
||||
- Update plan branch head SHA.
|
||||
|
||||
### Milestone 8: Plan Runtime and Validation
|
||||
|
||||
- Start preview from plan worktree.
|
||||
- Stop preview.
|
||||
- Show runtime logs.
|
||||
- Run validation command.
|
||||
- Show plan diff.
|
||||
|
||||
### Milestone 9: Final Merge
|
||||
|
||||
- Confirm merge from plan branch to base branch.
|
||||
- Perform local merge only.
|
||||
- Do not push automatically.
|
||||
- Record merge result and errors.
|
||||
|
||||
### Milestone 10: Automation
|
||||
|
||||
- Start plan orchestration.
|
||||
- Respect task dependencies.
|
||||
- Add `max_parallel_tasks`.
|
||||
- Add retry with feedback.
|
||||
- Add file-hint conflict avoidance.
|
||||
|
||||
## MVP Acceptance Criteria
|
||||
|
||||
The MVP is complete when:
|
||||
|
||||
- A user can access Coworkers in a browser.
|
||||
- A user can create a Project from a local repo or cloned remote repo.
|
||||
- A user can create a Plan.
|
||||
- Coworkers creates a plan branch and plan worktree.
|
||||
- A user can discuss with Plan Agent and approve structured tasks.
|
||||
- Coworkers shows a task board.
|
||||
- A user can start a task manually.
|
||||
- Coworkers creates task branch and task worktree.
|
||||
- An agent modifies code in the task worktree.
|
||||
- Coworkers runs tests and creates a system task commit.
|
||||
- Coworkers merges the task branch into the plan branch.
|
||||
- A user can start the project from the plan worktree for acceptance.
|
||||
- A user can run validation on the plan branch.
|
||||
- A user can confirm final local merge from plan branch to base branch.
|
||||
- Coworkers does not push automatically.
|
||||
- Multiple browsers viewing the same Plan see the same status and logs.
|
||||
|
||||
## Explicit Non-Goals for MVP
|
||||
|
||||
- Built-in authentication.
|
||||
- Multi-tenant isolation.
|
||||
- Per-user permissions.
|
||||
- Per-user agent credentials.
|
||||
- Multi-repo Plans.
|
||||
- Automatic push.
|
||||
- GitHub PR creation.
|
||||
- Automatic conflict resolution.
|
||||
- Remote workers.
|
||||
- Audit logs by user identity.
|
||||
- Cost accounting.
|
||||
- Complex dependency graph visualization.
|
||||
Reference in New Issue
Block a user