Vibecode GitHub Copilot
track this build5 phases, 15 steps, beginner friendly0%⌨️ featured in the best vibe coding tools
You can use open-source editor agents and local/API models, but Copilot's value is editor integration, model routing, GitHub context, completions, and managed usage.
You are building a lean indie version of GitHub Copilot. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # GitHub Copilot · indie build A Tabby server on your own machine or a GPU box, serving fill-in-the-middle completions to VS Code and JetBrains through official plugins, indexing your repositories for context, with latency measured rather than assumed and an acceptance rate you can compare against the subscription you left. Estimated effort: **weekend**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Completion server | Tabby, self-hosted | purpose-built for this, with fill-in-the-middle support, repository indexing and editor plugins already written | | Completion model | A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware | these are trained to fill a gap between a prefix and a suffix, which is not what a chat model does | | Hardware | An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal | Tabby's CUDA path uses int8 and needs an RTX 20-series or newer; older cards fall back to CPU and are too slow to use | | Editors | The official Tabby plugins for VS Code and JetBrains | ghost text and the accept gesture are editor-specific and already solved | | Measurement | A local log of latency and acceptance | the only way to know whether this is a real replacement or an expensive hobby | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **An NVIDIA GPU with compute capability 7.0 or newer, or an Apple silicon Mac** · free if you already have suitable hardware; a suitable GPU otherwise starts in the high hundreds of USD, which is the figure the comparison in Phase 5 has to justify - Why: This is the prerequisite that decides whether the project is viable. Below it, Tabby falls back to CPU and completions arrive too late to be useful. - Get it: Check an existing machine first with nvidia-smi. An RTX 20-series or newer qualifies. Apple silicon uses the Metal path instead and works well for smaller models. - Verify: nvidia-smi reports compute capability 7.0 or higher, or you are on Apple silicon - [ ] **Docker with GPU passthrough, or a native Tabby build** · free - Why: The container image is the fastest route to a running server, but it needs the GPU visible inside the container. - Get it: Install Docker, then the NVIDIA container toolkit on Linux. On Apple silicon, use the native build rather than a container. - Verify: docker run --gpus all reports the GPU, or the native binary starts and reports the Metal device - [ ] **VS Code or a JetBrains IDE with the Tabby plugin** · free - Why: The plugin is what turns a completion endpoint into ghost text. Writing your own is a project of its own. - Get it: Install from your editor's plugin marketplace and point it at your server address. - Verify: The plugin's status indicator shows connected - [ ] **Baseline figures from the tool you are replacing** · free, but it must be done first - Why: Phase 5 compares against them, and once you have cancelled the subscription you cannot go back and measure. - Get it: Spend a morning with the paid tool, logging how often you accept a completion and roughly how fast they arrive. Record it before you start. - Verify: A written baseline exists with an acceptance rate and a latency impression - [ ] **Twenty gigabytes of free disk** · free - Why: Models and indexes are large, and a model download that fails halfway through a full disk wastes an evening. - Get it: Check free space before pulling a model. Larger models need considerably more. - Verify: df reports at least twenty gigabytes free ## Quick start ```sh nvidia-smi --query-gpu=name,compute_cap --format=csv ``` Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Copilot's latency at scale, which is a fleet of accelerators. - Native GitHub integration across pull requests and code review. - Model routing by task, done invisibly by the subscription. - Fine-tuning on your own codebase. - native GitHub/IDE integration - fast completions - model routing - code review/security features - managed billing - team controls If one of those is essential to you, that is the reason to keep paying for GitHub Copilot, and the README should say so rather than pretend. ===== BRIEF.md ===== # Build brief · GitHub Copilot The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me self-hosted inline code completion running on hardware you control to replace GitHub Copilot. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Rule zero Do not train a model and do not write a completion engine. Run Tabby, which is a self-hosted completion server with fill-in-the-middle support and official editor plugins. Your work is the deployment, the model choice, the repository indexing and an honest measurement of whether the completions are good enough to keep. Note the distinction that decides your stack: inline completion and chat are different jobs. Completion wants a small model trained for fill-in-the-middle and answering in well under a second. Chat and agent work wants a large model and can afford to think. Do not try to serve both from one model. ### Stack (fixed, do not substitute) - Completion server: Tabby, self-hosted · purpose-built for this, with fill-in-the-middle support, repository indexing and editor plugins already written - Completion model: A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware · these are trained to fill a gap between a prefix and a suffix, which is not what a chat model does - Hardware: An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal · Tabby's CUDA path uses int8 and needs an RTX 20-series or newer; older cards fall back to CPU and are too slow to use - Editors: The official Tabby plugins for VS Code and JetBrains · ghost text and the accept gesture are editor-specific and already solved - Measurement: A local log of latency and acceptance · the only way to know whether this is a real replacement or an expensive hobby ### Data model (create this before Phase 1) - This is a deployment, so the model that matters is your operational state, not a schema. - server · the Tabby instance, its bound address, its model and its device - index · which repositories are indexed, when, and how large the index is - completions(t, latency_ms, accepted, model, language, prefix_len) · your own log, because acceptance rate is the only honest quality measure - baseline · the latency and acceptance figures from the subscription you are replacing, recorded before you cancel it ### Phase 1 · Hardware truth and a first completion Build: Check the GPU first, because it decides whether this project is viable. Run Tabby with a small completion model, connect the VS Code plugin, and get ghost text to appear. Then measure the round trip before doing anything else. Trap: Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. Done when: Ghost text appears in VS Code from your own server. Median completion latency is measured and written down. If that median is above roughly half a second, you have learned this hardware is not sufficient, which is a legitimate and useful outcome of this phase. Do not build yet: No indexing, no JetBrains, no measurement dashboard. One completion and one honest number. ### Phase 2 · Choosing a model by measurement Build: Try two or three completion models at different sizes. For each, record median latency and how often you accept the suggestion across a real morning of work. Pick on the combination, not on the benchmark. Trap: A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. Done when: Two or more models have recorded latency and acceptance figures from real work rather than synthetic prompts. The chosen model is the one with the best acceptance rate, not the largest that runs. The reasoning is written down. Do not build yet: No repository context yet, so completions are still local to the open file. ### Phase 3 · Repository context Build: Index your repositories so the server can retrieve relevant context. Exclude generated directories, vendored dependencies and anything containing credentials. Re-index on a schedule and confirm that a symbol defined in another file influences a completion. Trap: Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. Done when: A completion in one file correctly uses a function signature defined in a different file in the same repository. The index excludes generated and vendored directories, verified by its size and content. Adding a new file and re-indexing makes its symbols available. Do not build yet: No team deployment yet. ### Phase 4 · Availability and the offline case Build: Run the server as a managed service that starts on boot. Confirm the editor degrades cleanly when the server is unavailable rather than blocking typing. Decide whether it listens beyond localhost, and if so put authentication in front of it. Trap: A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. Done when: The server starts automatically after a reboot. With the server stopped, typing in the editor is unaffected apart from the absence of suggestions, with no freeze and no error popup on every keystroke. The listening address is confirmed by inspection, and if it is not localhost, an unauthenticated request is refused. Do not build yet: Team use is the product phase. ### Phase 5 · Was it worth it Build: Compare against the baseline you recorded: acceptance rate, median latency, hardware cost including electricity, and the hours you spent. Decide deliberately whether to keep this or go back, and write the decision down either way. Trap: Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. Done when: A written comparison covering acceptance rate, median latency and total cost including the hardware. The decision to keep or abandon is recorded with its reasoning. If the answer is that the subscription was better, that is a successful outcome of this phase rather than a failure. Do not build yet: Team deployment only if you decided to keep it. ### Phase 6 · Serving a team Build: Put the server behind TLS with authentication. Give each person a token. Watch GPU saturation, because completion latency collapses when several people type at once. Write down what is logged and who can see it. Trap: Completion requests contain the code around the cursor, which means the server sees your colleagues' work in progress. Decide and publish the retention policy before anyone connects, not after someone asks. Done when: Each user authenticates with their own token and a revoked token stops working immediately. Under concurrent load, latency is measured and a saturation point is documented. The retention policy is written and matches what the server actually stores. Do not build yet: Nothing after this. ### Out of scope (and why) - Copilot's completion latency at global scale, which comes from a fleet of accelerators you are not going to match with one card. - The native GitHub integration: pull request summaries, code review and the surfaces that only exist because GitHub owns both ends. - Model routing across a family of models by task, which the subscription does invisibly. - Training or fine-tuning a model on your own code, which is a separate project with a different budget. ### README must contain - The GPU requirement, specifically compute capability 7.0 or newer for the CUDA path - That completion and chat are different jobs served by different models, and which one this serves - The chosen model and the latency and acceptance figures that justified it - What the index excludes and how to confirm no credentials are in it - What request content the server stores, for how long, and who can read it ===== AGENTS.md ===== # Agent instructions · GitHub Copilot indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Tabby, self-hosted, A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware, An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal, The official Tabby plugins for VS Code and JetBrains, A local log of latency and acceptance. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. - A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. - Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. - A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. - Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. ===== BUILD_PLAN.md ===== # Build plan · GitHub Copilot A Tabby server on your own machine or a GPU box, serving fill-in-the-middle completions to VS Code and JetBrains through official plugins, indexing your repositories for context, with latency measured rather than assumed and an acceptance rate you can compare against the subscription you left. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · Hardware truth and a first completion A completion appears in your editor, and you know whether your hardware can serve them fast enough to be useful. ### Steps 1. Establish what your hardware can do Check the GPU model and its compute capability, or confirm Apple silicon. Write the answer down before installing anything, because it constrains every later choice. ```sh nvidia-smi --query-gpu=name,compute_cap --format=csv ``` 2. Run Tabby with a small model Start with the smallest completion model that fits comfortably. A model that barely fits will swap and be slower than a smaller one that does not. ```sh docker run -it --gpus all -p 8080:8080 -v $HOME/.tabby:/data tabbyml/tabby serve --model StarCoder2-3B --device cuda ``` 3. Connect the editor and time it Install the Tabby VS Code plugin, point it at your server, and record the time from keystroke to ghost text over twenty completions. Files: `notes/latency.md` ### Done when - [ ] Ghost text appears in VS Code from your own server - [ ] The GPU compute capability is recorded and meets the floor, or the CPU fallback has been measured - [ ] Median completion latency over twenty samples is written down - [ ] Stopping the server produces a clear failure in the editor rather than a hang ### Watch out - Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. ## Phase 2 · Choosing a model by measurement You picked the model on evidence rather than on parameter count. ### Steps 1. Log every completion and its fate Record latency, language and whether you accepted it. The plugin can be configured to log, or you can wrap the server endpoint. Files: `scripts/log_completions.py` 2. Test each model over real work A morning each, on code you were writing anyway. Synthetic prompts will mislead you because they lack the surrounding file. 3. Write down the decision Model, latency, acceptance and the reason. In three months you will not remember why, and you will be tempted to re-test. Files: `docs/model-choice.md` ### Done when - [ ] At least two models have real latency and acceptance figures - [ ] The acceptance rate is computed from logged events, not estimated - [ ] The chosen model is justified in writing - [ ] Median latency for the chosen model is under half a second ### Watch out - A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. ## Phase 3 · Repository context Completions know about the rest of your codebase, not just the open file. ### Steps 1. Register repositories and set exclusions Add each repository to the server configuration with an exclusion list. Start from .gitignore and add credential paths. Files: `~/.tabby/config.toml` 2. Schedule re-indexing A periodic job. An index that reflects last month's code is worse than useless because it confidently suggests names you have since renamed. 3. Prove cross-file context works Define a distinctively named function in one file and start calling it in another. If the completion knows the signature, indexing is doing something. ### Done when - [ ] A completion uses a signature defined in another file - [ ] The index excludes generated and vendored directories - [ ] Re-indexing picks up a newly added file - [ ] No credential file is present in the index ### Watch out - Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. ## Phase 4 · Availability and the offline case The server is there when you start work, and the editor is usable when it is not. ### Steps 1. Run it as a service A systemd unit, a launchd agent or a restart policy on the container. Confirm by rebooting rather than by reading the configuration. ```sh systemctl --user enable --now tabby ``` 2. Verify graceful degradation Stop the server and work for ten minutes. Anything worse than a missing suggestion is a bug worth fixing before you rely on this. 3. Check what it is listening on Inspect the bound address. If it is not loopback, add a token and verify an unauthenticated request is refused. ```sh ss -tlnp | grep 8080 ``` ### Done when - [ ] The server comes back automatically after a reboot - [ ] Typing is unaffected while the server is stopped - [ ] The listening address is confirmed by inspection - [ ] If exposed beyond localhost, an unauthenticated request is refused ### Watch out - A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. ## Phase 5 · Was it worth it You can answer the question with numbers instead of a feeling. ### Steps 1. Compute acceptance from your logs Accepted completions over offered completions, by language. Aggregate hides that it may be excellent for one language and useless for another. Files: `scripts/report.py` 2. Cost it honestly Hardware amortised, electricity, and your setup time at whatever you value it. Compare with the annual subscription. Files: `docs/comparison.md` 3. Write the decision down Including the case where you go back. A documented negative result is worth more than a quiet retreat. Files: `docs/comparison.md` ### Done when - [ ] Acceptance rate is reported per language, not only in aggregate - [ ] The cost comparison includes hardware and electricity - [ ] The decision and its reasoning are written down - [ ] The baseline figures were captured before cancelling anything ### Watch out - Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. ## Not in this build - Copilot's latency at scale, which is a fleet of accelerators. - Native GitHub integration across pull requests and code review. - Model routing by task, done invisibly by the subscription. - Fine-tuning on your own codebase. ## After v1, if you want it - A separate chat and agent setup, which wants a different model entirely - Per-language acceptance tracking to find where it genuinely helps - Sharing one server across a small team, once the saturation point is known ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. Bind address. Keep it on loopback unless you have deliberately added authentication. TABBY_HOST=127.0.0.1 # Required. The port the completion server listens on. TABBY_PORT=8080 # Required. The completion model. Chosen by the measurement in Phase 2, not by parameter count. TABBY_MODEL=StarCoder2-3B # Required. cuda, metal or cpu. The cpu value is a diagnostic, not a working configuration. TABBY_DEVICE=cuda # Optional · secret. Product phase only. Required the moment the server listens on anything but loopback. TABBY_TOKEN=replace-with-a-random-token # Required. Your own latency and acceptance log. This is what makes Phase 5 possible. COMPLETION_LOG_PATH=~/.local/share/tabby/completions.sqlite
You are building a lean indie version of GitHub Copilot. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # GitHub Copilot · indie build A Tabby server on your own machine or a GPU box, serving fill-in-the-middle completions to VS Code and JetBrains through official plugins, indexing your repositories for context, with latency measured rather than assumed and an acceptance rate you can compare against the subscription you left. Estimated effort: **weekend**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Completion server | Tabby, self-hosted | purpose-built for this, with fill-in-the-middle support, repository indexing and editor plugins already written | | Completion model | A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware | these are trained to fill a gap between a prefix and a suffix, which is not what a chat model does | | Hardware | An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal | Tabby's CUDA path uses int8 and needs an RTX 20-series or newer; older cards fall back to CPU and are too slow to use | | Editors | The official Tabby plugins for VS Code and JetBrains | ghost text and the accept gesture are editor-specific and already solved | | Measurement | A local log of latency and acceptance | the only way to know whether this is a real replacement or an expensive hobby | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **An NVIDIA GPU with compute capability 7.0 or newer, or an Apple silicon Mac** · free if you already have suitable hardware; a suitable GPU otherwise starts in the high hundreds of USD, which is the figure the comparison in Phase 5 has to justify - Why: This is the prerequisite that decides whether the project is viable. Below it, Tabby falls back to CPU and completions arrive too late to be useful. - Get it: Check an existing machine first with nvidia-smi. An RTX 20-series or newer qualifies. Apple silicon uses the Metal path instead and works well for smaller models. - Verify: nvidia-smi reports compute capability 7.0 or higher, or you are on Apple silicon - [ ] **Docker with GPU passthrough, or a native Tabby build** · free - Why: The container image is the fastest route to a running server, but it needs the GPU visible inside the container. - Get it: Install Docker, then the NVIDIA container toolkit on Linux. On Apple silicon, use the native build rather than a container. - Verify: docker run --gpus all reports the GPU, or the native binary starts and reports the Metal device - [ ] **VS Code or a JetBrains IDE with the Tabby plugin** · free - Why: The plugin is what turns a completion endpoint into ghost text. Writing your own is a project of its own. - Get it: Install from your editor's plugin marketplace and point it at your server address. - Verify: The plugin's status indicator shows connected - [ ] **Baseline figures from the tool you are replacing** · free, but it must be done first - Why: Phase 5 compares against them, and once you have cancelled the subscription you cannot go back and measure. - Get it: Spend a morning with the paid tool, logging how often you accept a completion and roughly how fast they arrive. Record it before you start. - Verify: A written baseline exists with an acceptance rate and a latency impression - [ ] **Twenty gigabytes of free disk** · free - Why: Models and indexes are large, and a model download that fails halfway through a full disk wastes an evening. - Get it: Check free space before pulling a model. Larger models need considerably more. - Verify: df reports at least twenty gigabytes free ## Quick start ```sh nvidia-smi --query-gpu=name,compute_cap --format=csv ``` Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Copilot's latency at scale, which is a fleet of accelerators. - Native GitHub integration across pull requests and code review. - Model routing by task, done invisibly by the subscription. - Fine-tuning on your own codebase. - native GitHub/IDE integration - fast completions - model routing - code review/security features - managed billing - team controls If one of those is essential to you, that is the reason to keep paying for GitHub Copilot, and the README should say so rather than pretend. ===== BRIEF.md ===== # Build brief · GitHub Copilot The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me self-hosted inline code completion running on hardware you control to replace GitHub Copilot. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Rule zero Do not train a model and do not write a completion engine. Run Tabby, which is a self-hosted completion server with fill-in-the-middle support and official editor plugins. Your work is the deployment, the model choice, the repository indexing and an honest measurement of whether the completions are good enough to keep. Note the distinction that decides your stack: inline completion and chat are different jobs. Completion wants a small model trained for fill-in-the-middle and answering in well under a second. Chat and agent work wants a large model and can afford to think. Do not try to serve both from one model. ### Stack (fixed, do not substitute) - Completion server: Tabby, self-hosted · purpose-built for this, with fill-in-the-middle support, repository indexing and editor plugins already written - Completion model: A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware · these are trained to fill a gap between a prefix and a suffix, which is not what a chat model does - Hardware: An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal · Tabby's CUDA path uses int8 and needs an RTX 20-series or newer; older cards fall back to CPU and are too slow to use - Editors: The official Tabby plugins for VS Code and JetBrains · ghost text and the accept gesture are editor-specific and already solved - Measurement: A local log of latency and acceptance · the only way to know whether this is a real replacement or an expensive hobby ### Data model (create this before Phase 1) - This is a deployment, so the model that matters is your operational state, not a schema. - server · the Tabby instance, its bound address, its model and its device - index · which repositories are indexed, when, and how large the index is - completions(t, latency_ms, accepted, model, language, prefix_len) · your own log, because acceptance rate is the only honest quality measure - baseline · the latency and acceptance figures from the subscription you are replacing, recorded before you cancel it ### Phase 1 · Hardware truth and a first completion Build: Check the GPU first, because it decides whether this project is viable. Run Tabby with a small completion model, connect the VS Code plugin, and get ghost text to appear. Then measure the round trip before doing anything else. Trap: Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. Done when: Ghost text appears in VS Code from your own server. Median completion latency is measured and written down. If that median is above roughly half a second, you have learned this hardware is not sufficient, which is a legitimate and useful outcome of this phase. Do not build yet: No indexing, no JetBrains, no measurement dashboard. One completion and one honest number. ### Phase 2 · Choosing a model by measurement Build: Try two or three completion models at different sizes. For each, record median latency and how often you accept the suggestion across a real morning of work. Pick on the combination, not on the benchmark. Trap: A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. Done when: Two or more models have recorded latency and acceptance figures from real work rather than synthetic prompts. The chosen model is the one with the best acceptance rate, not the largest that runs. The reasoning is written down. Do not build yet: No repository context yet, so completions are still local to the open file. ### Phase 3 · Repository context Build: Index your repositories so the server can retrieve relevant context. Exclude generated directories, vendored dependencies and anything containing credentials. Re-index on a schedule and confirm that a symbol defined in another file influences a completion. Trap: Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. Done when: A completion in one file correctly uses a function signature defined in a different file in the same repository. The index excludes generated and vendored directories, verified by its size and content. Adding a new file and re-indexing makes its symbols available. Do not build yet: No team deployment yet. ### Phase 4 · Availability and the offline case Build: Run the server as a managed service that starts on boot. Confirm the editor degrades cleanly when the server is unavailable rather than blocking typing. Decide whether it listens beyond localhost, and if so put authentication in front of it. Trap: A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. Done when: The server starts automatically after a reboot. With the server stopped, typing in the editor is unaffected apart from the absence of suggestions, with no freeze and no error popup on every keystroke. The listening address is confirmed by inspection, and if it is not localhost, an unauthenticated request is refused. Do not build yet: Team use is the product phase. ### Phase 5 · Was it worth it Build: Compare against the baseline you recorded: acceptance rate, median latency, hardware cost including electricity, and the hours you spent. Decide deliberately whether to keep this or go back, and write the decision down either way. Trap: Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. Done when: A written comparison covering acceptance rate, median latency and total cost including the hardware. The decision to keep or abandon is recorded with its reasoning. If the answer is that the subscription was better, that is a successful outcome of this phase rather than a failure. Do not build yet: Team deployment only if you decided to keep it. ### Phase 6 · Serving a team Build: Put the server behind TLS with authentication. Give each person a token. Watch GPU saturation, because completion latency collapses when several people type at once. Write down what is logged and who can see it. Trap: Completion requests contain the code around the cursor, which means the server sees your colleagues' work in progress. Decide and publish the retention policy before anyone connects, not after someone asks. Done when: Each user authenticates with their own token and a revoked token stops working immediately. Under concurrent load, latency is measured and a saturation point is documented. The retention policy is written and matches what the server actually stores. Do not build yet: Nothing after this. ### Out of scope (and why) - Copilot's completion latency at global scale, which comes from a fleet of accelerators you are not going to match with one card. - The native GitHub integration: pull request summaries, code review and the surfaces that only exist because GitHub owns both ends. - Model routing across a family of models by task, which the subscription does invisibly. - Training or fine-tuning a model on your own code, which is a separate project with a different budget. ### README must contain - The GPU requirement, specifically compute capability 7.0 or newer for the CUDA path - That completion and chat are different jobs served by different models, and which one this serves - The chosen model and the latency and acceptance figures that justified it - What the index excludes and how to confirm no credentials are in it - What request content the server stores, for how long, and who can read it ===== AGENTS.md ===== # Agent instructions · GitHub Copilot indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Tabby, self-hosted, A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware, An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal, The official Tabby plugins for VS Code and JetBrains, A local log of latency and acceptance. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. - A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. - Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. - A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. - Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. ===== BUILD_PLAN.md ===== # Build plan · GitHub Copilot A Tabby server on your own machine or a GPU box, serving fill-in-the-middle completions to VS Code and JetBrains through official plugins, indexing your repositories for context, with latency measured rather than assumed and an acceptance rate you can compare against the subscription you left. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · Hardware truth and a first completion A completion appears in your editor, and you know whether your hardware can serve them fast enough to be useful. ### Steps 1. Establish what your hardware can do Check the GPU model and its compute capability, or confirm Apple silicon. Write the answer down before installing anything, because it constrains every later choice. ```sh nvidia-smi --query-gpu=name,compute_cap --format=csv ``` 2. Run Tabby with a small model Start with the smallest completion model that fits comfortably. A model that barely fits will swap and be slower than a smaller one that does not. ```sh docker run -it --gpus all -p 8080:8080 -v $HOME/.tabby:/data tabbyml/tabby serve --model StarCoder2-3B --device cuda ``` 3. Connect the editor and time it Install the Tabby VS Code plugin, point it at your server, and record the time from keystroke to ghost text over twenty completions. Files: `notes/latency.md` ### Done when - [ ] Ghost text appears in VS Code from your own server - [ ] The GPU compute capability is recorded and meets the floor, or the CPU fallback has been measured - [ ] Median completion latency over twenty samples is written down - [ ] Stopping the server produces a clear failure in the editor rather than a hang ### Watch out - Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. ## Phase 2 · Choosing a model by measurement You picked the model on evidence rather than on parameter count. ### Steps 1. Log every completion and its fate Record latency, language and whether you accepted it. The plugin can be configured to log, or you can wrap the server endpoint. Files: `scripts/log_completions.py` 2. Test each model over real work A morning each, on code you were writing anyway. Synthetic prompts will mislead you because they lack the surrounding file. 3. Write down the decision Model, latency, acceptance and the reason. In three months you will not remember why, and you will be tempted to re-test. Files: `docs/model-choice.md` ### Done when - [ ] At least two models have real latency and acceptance figures - [ ] The acceptance rate is computed from logged events, not estimated - [ ] The chosen model is justified in writing - [ ] Median latency for the chosen model is under half a second ### Watch out - A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. ## Phase 3 · Repository context Completions know about the rest of your codebase, not just the open file. ### Steps 1. Register repositories and set exclusions Add each repository to the server configuration with an exclusion list. Start from .gitignore and add credential paths. Files: `~/.tabby/config.toml` 2. Schedule re-indexing A periodic job. An index that reflects last month's code is worse than useless because it confidently suggests names you have since renamed. 3. Prove cross-file context works Define a distinctively named function in one file and start calling it in another. If the completion knows the signature, indexing is doing something. ### Done when - [ ] A completion uses a signature defined in another file - [ ] The index excludes generated and vendored directories - [ ] Re-indexing picks up a newly added file - [ ] No credential file is present in the index ### Watch out - Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. ## Phase 4 · Availability and the offline case The server is there when you start work, and the editor is usable when it is not. ### Steps 1. Run it as a service A systemd unit, a launchd agent or a restart policy on the container. Confirm by rebooting rather than by reading the configuration. ```sh systemctl --user enable --now tabby ``` 2. Verify graceful degradation Stop the server and work for ten minutes. Anything worse than a missing suggestion is a bug worth fixing before you rely on this. 3. Check what it is listening on Inspect the bound address. If it is not loopback, add a token and verify an unauthenticated request is refused. ```sh ss -tlnp | grep 8080 ``` ### Done when - [ ] The server comes back automatically after a reboot - [ ] Typing is unaffected while the server is stopped - [ ] The listening address is confirmed by inspection - [ ] If exposed beyond localhost, an unauthenticated request is refused ### Watch out - A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. ## Phase 5 · Was it worth it You can answer the question with numbers instead of a feeling. ### Steps 1. Compute acceptance from your logs Accepted completions over offered completions, by language. Aggregate hides that it may be excellent for one language and useless for another. Files: `scripts/report.py` 2. Cost it honestly Hardware amortised, electricity, and your setup time at whatever you value it. Compare with the annual subscription. Files: `docs/comparison.md` 3. Write the decision down Including the case where you go back. A documented negative result is worth more than a quiet retreat. Files: `docs/comparison.md` ### Done when - [ ] Acceptance rate is reported per language, not only in aggregate - [ ] The cost comparison includes hardware and electricity - [ ] The decision and its reasoning are written down - [ ] The baseline figures were captured before cancelling anything ### Watch out - Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. ## Not in this build - Copilot's latency at scale, which is a fleet of accelerators. - Native GitHub integration across pull requests and code review. - Model routing by task, done invisibly by the subscription. - Fine-tuning on your own codebase. ## After v1, if you want it - A separate chat and agent setup, which wants a different model entirely - Per-language acceptance tracking to find where it genuinely helps - Sharing one server across a small team, once the saturation point is known ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. Bind address. Keep it on loopback unless you have deliberately added authentication. TABBY_HOST=127.0.0.1 # Required. The port the completion server listens on. TABBY_PORT=8080 # Required. The completion model. Chosen by the measurement in Phase 2, not by parameter count. TABBY_MODEL=StarCoder2-3B # Required. cuda, metal or cpu. The cpu value is a diagnostic, not a working configuration. TABBY_DEVICE=cuda # Optional · secret. Product phase only. Required the moment the server listens on anything but loopback. TABBY_TOKEN=replace-with-a-random-token # Required. Your own latency and acceptance log. This is what makes Phase 5 possible. COMPLETION_LOG_PATH=~/.local/share/tabby/completions.sqlite
You are building a production product version of GitHub Copilot. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== PRODUCT.md ===== # GitHub Copilot · product brief ## Problem You can use open-source editor agents and local/API models, but Copilot's value is editor integration, model routing, GitHub context, completions, and managed usage. ## Product outcome A completion server on hardware you own, serving your editors at a measured latency, indexing only code you wrote, with an acceptance rate you can compare against the subscription and a documented decision about whether it was worth it. ## Target user A builder who needs a maintainable product foundation, not a one-off demo. ## Required capabilities - VS Code/JetBrains extension - LLM API or local model - repo indexing - optional GitHub token ## Explicit non-goals for v1 - Copilot's latency at scale, which is a fleet of accelerators. - Native GitHub integration across pull requests and code review. - Model routing by task, done invisibly by the subscription. - Fine-tuning on your own codebase. - native GitHub/IDE integration - fast completions - model routing - code review/security features - managed billing - team controls ## Success criteria - Median completion latency is under half a second on the chosen model - The index contains no credential file, verified by inspection - The server is confirmed to bind only where intended - A revoked token is proved to stop working - The retention policy is published before anyone else connects ===== BRIEF.md ===== # Build brief · GitHub Copilot The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me self-hosted inline code completion running on hardware you control to replace GitHub Copilot. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Rule zero Do not train a model and do not write a completion engine. Run Tabby, which is a self-hosted completion server with fill-in-the-middle support and official editor plugins. Your work is the deployment, the model choice, the repository indexing and an honest measurement of whether the completions are good enough to keep. Note the distinction that decides your stack: inline completion and chat are different jobs. Completion wants a small model trained for fill-in-the-middle and answering in well under a second. Chat and agent work wants a large model and can afford to think. Do not try to serve both from one model. ### Stack (fixed, do not substitute) - Completion server: Tabby, self-hosted · purpose-built for this, with fill-in-the-middle support, repository indexing and editor plugins already written - Completion model: A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware · these are trained to fill a gap between a prefix and a suffix, which is not what a chat model does - Hardware: An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal · Tabby's CUDA path uses int8 and needs an RTX 20-series or newer; older cards fall back to CPU and are too slow to use - Editors: The official Tabby plugins for VS Code and JetBrains · ghost text and the accept gesture are editor-specific and already solved - Measurement: A local log of latency and acceptance · the only way to know whether this is a real replacement or an expensive hobby ### Data model (create this before Phase 1) - This is a deployment, so the model that matters is your operational state, not a schema. - server · the Tabby instance, its bound address, its model and its device - index · which repositories are indexed, when, and how large the index is - completions(t, latency_ms, accepted, model, language, prefix_len) · your own log, because acceptance rate is the only honest quality measure - baseline · the latency and acceptance figures from the subscription you are replacing, recorded before you cancel it ### Phase 1 · Hardware truth and a first completion Build: Check the GPU first, because it decides whether this project is viable. Run Tabby with a small completion model, connect the VS Code plugin, and get ghost text to appear. Then measure the round trip before doing anything else. Trap: Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. Done when: Ghost text appears in VS Code from your own server. Median completion latency is measured and written down. If that median is above roughly half a second, you have learned this hardware is not sufficient, which is a legitimate and useful outcome of this phase. Do not build yet: No indexing, no JetBrains, no measurement dashboard. One completion and one honest number. ### Phase 2 · Choosing a model by measurement Build: Try two or three completion models at different sizes. For each, record median latency and how often you accept the suggestion across a real morning of work. Pick on the combination, not on the benchmark. Trap: A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. Done when: Two or more models have recorded latency and acceptance figures from real work rather than synthetic prompts. The chosen model is the one with the best acceptance rate, not the largest that runs. The reasoning is written down. Do not build yet: No repository context yet, so completions are still local to the open file. ### Phase 3 · Repository context Build: Index your repositories so the server can retrieve relevant context. Exclude generated directories, vendored dependencies and anything containing credentials. Re-index on a schedule and confirm that a symbol defined in another file influences a completion. Trap: Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. Done when: A completion in one file correctly uses a function signature defined in a different file in the same repository. The index excludes generated and vendored directories, verified by its size and content. Adding a new file and re-indexing makes its symbols available. Do not build yet: No team deployment yet. ### Phase 4 · Availability and the offline case Build: Run the server as a managed service that starts on boot. Confirm the editor degrades cleanly when the server is unavailable rather than blocking typing. Decide whether it listens beyond localhost, and if so put authentication in front of it. Trap: A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. Done when: The server starts automatically after a reboot. With the server stopped, typing in the editor is unaffected apart from the absence of suggestions, with no freeze and no error popup on every keystroke. The listening address is confirmed by inspection, and if it is not localhost, an unauthenticated request is refused. Do not build yet: Team use is the product phase. ### Phase 5 · Was it worth it Build: Compare against the baseline you recorded: acceptance rate, median latency, hardware cost including electricity, and the hours you spent. Decide deliberately whether to keep this or go back, and write the decision down either way. Trap: Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. Done when: A written comparison covering acceptance rate, median latency and total cost including the hardware. The decision to keep or abandon is recorded with its reasoning. If the answer is that the subscription was better, that is a successful outcome of this phase rather than a failure. Do not build yet: Team deployment only if you decided to keep it. ### Phase 6 · Serving a team Build: Put the server behind TLS with authentication. Give each person a token. Watch GPU saturation, because completion latency collapses when several people type at once. Write down what is logged and who can see it. Trap: Completion requests contain the code around the cursor, which means the server sees your colleagues' work in progress. Decide and publish the retention policy before anyone connects, not after someone asks. Done when: Each user authenticates with their own token and a revoked token stops working immediately. Under concurrent load, latency is measured and a saturation point is documented. The retention policy is written and matches what the server actually stores. Do not build yet: Nothing after this. ### Out of scope (and why) - Copilot's completion latency at global scale, which comes from a fleet of accelerators you are not going to match with one card. - The native GitHub integration: pull request summaries, code review and the surfaces that only exist because GitHub owns both ends. - Model routing across a family of models by task, which the subscription does invisibly. - Training or fine-tuning a model on your own code, which is a separate project with a different budget. ### README must contain - The GPU requirement, specifically compute capability 7.0 or newer for the CUDA path - That completion and chat are different jobs served by different models, and which one this serves - The chosen model and the latency and acceptance figures that justified it - What the index excludes and how to confirm no credentials are in it - What request content the server stores, for how long, and who can read it ===== ARCHITECTURE.md ===== # Architecture · GitHub Copilot ## Stack | Part | Choice | Why | | --- | --- | --- | | Completion server | Tabby, self-hosted | purpose-built for this, with fill-in-the-middle support, repository indexing and editor plugins already written | | Completion model | A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware | these are trained to fill a gap between a prefix and a suffix, which is not what a chat model does | | Hardware | An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal | Tabby's CUDA path uses int8 and needs an RTX 20-series or newer; older cards fall back to CPU and are too slow to use | | Editors | The official Tabby plugins for VS Code and JetBrains | ghost text and the accept gesture are editor-specific and already solved | | Measurement | A local log of latency and acceptance | the only way to know whether this is a real replacement or an expensive hobby | ## Modules Each module has one owner concern and a documented way to replace it. | Module | Owns | How to replace it | | --- | --- | --- | | Server | Model loading, inference and the completion endpoint. | Tabby is the deployment. If you replace it, the editor plugins go too, which is most of the value. | | Model | Completion quality and latency. | Swapping models is a configuration change and a restart, which is exactly why Phase 2 measures rather than guesses. | | Index | Repository context. | The exclusion list matters more than the indexer. Revisit it whenever a repository grows a new generated directory. | | Editors | Ghost text and the accept gesture. | Official plugins per editor. Writing your own is the one part of this stack that is genuinely not worth it. | | Measurement | Latency and acceptance logging. | Yours entirely, and the only reason you can answer whether this works. | ## Configuration Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists. - `TABBY_HOST` · required · Bind address. Keep it on loopback unless you have deliberately added authentication. - `TABBY_PORT` · required · The port the completion server listens on. - `TABBY_MODEL` · required · The completion model. Chosen by the measurement in Phase 2, not by parameter count. - `TABBY_DEVICE` · required · cuda, metal or cpu. The cpu value is a diagnostic, not a working configuration. - `TABBY_TOKEN` · optional, secret · Product phase only. Required the moment the server listens on anything but loopback. - `COMPLETION_LOG_PATH` · required · Your own latency and acceptance log. This is what makes Phase 5 possible. ## Production baseline - Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts. - Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path. ## Decision records For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it. ===== AGENTS.md ===== # Agent instructions · GitHub Copilot product build - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: Tabby, self-hosted, A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware, An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal, The official Tabby plugins for VS Code and JetBrains, A local log of latency and acceptance. - Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit. - Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a check pass. - Put every external service behind an interface with a deterministic fake for tests. - Add migrations and rollback or recovery notes for every persistent data change. - Log useful operational context without credentials, tokens, passwords or personal data. - Update documentation and run every check before completing a milestone. ## Known traps - Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. - A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. - Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. - A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. - Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. - Completion requests contain the code around the cursor, which means the server sees your colleagues' work in progress. Decide and publish the retention policy before anyone connects, not after someone asks. ===== MILESTONES.md ===== # Delivery milestones · GitHub Copilot Estimated effort: **weekend** for the indie phases; the production-only milestones add the trust and operability layer. ## M1 · Hardware truth and a first completion A completion appears in your editor, and you know whether your hardware can serve them fast enough to be useful. ### Steps 1. Establish what your hardware can do Check the GPU model and its compute capability, or confirm Apple silicon. Write the answer down before installing anything, because it constrains every later choice. ```sh nvidia-smi --query-gpu=name,compute_cap --format=csv ``` 2. Run Tabby with a small model Start with the smallest completion model that fits comfortably. A model that barely fits will swap and be slower than a smaller one that does not. ```sh docker run -it --gpus all -p 8080:8080 -v $HOME/.tabby:/data tabbyml/tabby serve --model StarCoder2-3B --device cuda ``` 3. Connect the editor and time it Install the Tabby VS Code plugin, point it at your server, and record the time from keystroke to ghost text over twenty completions. Files: `notes/latency.md` ### Done when - [ ] Ghost text appears in VS Code from your own server - [ ] The GPU compute capability is recorded and meets the floor, or the CPU fallback has been measured - [ ] Median completion latency over twenty samples is written down - [ ] Stopping the server produces a clear failure in the editor rather than a hang ### Watch out - Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. ## M2 · Choosing a model by measurement You picked the model on evidence rather than on parameter count. ### Steps 1. Log every completion and its fate Record latency, language and whether you accepted it. The plugin can be configured to log, or you can wrap the server endpoint. Files: `scripts/log_completions.py` 2. Test each model over real work A morning each, on code you were writing anyway. Synthetic prompts will mislead you because they lack the surrounding file. 3. Write down the decision Model, latency, acceptance and the reason. In three months you will not remember why, and you will be tempted to re-test. Files: `docs/model-choice.md` ### Done when - [ ] At least two models have real latency and acceptance figures - [ ] The acceptance rate is computed from logged events, not estimated - [ ] The chosen model is justified in writing - [ ] Median latency for the chosen model is under half a second ### Watch out - A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. ## M3 · Repository context Completions know about the rest of your codebase, not just the open file. ### Steps 1. Register repositories and set exclusions Add each repository to the server configuration with an exclusion list. Start from .gitignore and add credential paths. Files: `~/.tabby/config.toml` 2. Schedule re-indexing A periodic job. An index that reflects last month's code is worse than useless because it confidently suggests names you have since renamed. 3. Prove cross-file context works Define a distinctively named function in one file and start calling it in another. If the completion knows the signature, indexing is doing something. ### Done when - [ ] A completion uses a signature defined in another file - [ ] The index excludes generated and vendored directories - [ ] Re-indexing picks up a newly added file - [ ] No credential file is present in the index ### Watch out - Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. ## M4 · Availability and the offline case The server is there when you start work, and the editor is usable when it is not. ### Steps 1. Run it as a service A systemd unit, a launchd agent or a restart policy on the container. Confirm by rebooting rather than by reading the configuration. ```sh systemctl --user enable --now tabby ``` 2. Verify graceful degradation Stop the server and work for ten minutes. Anything worse than a missing suggestion is a bug worth fixing before you rely on this. 3. Check what it is listening on Inspect the bound address. If it is not loopback, add a token and verify an unauthenticated request is refused. ```sh ss -tlnp | grep 8080 ``` ### Done when - [ ] The server comes back automatically after a reboot - [ ] Typing is unaffected while the server is stopped - [ ] The listening address is confirmed by inspection - [ ] If exposed beyond localhost, an unauthenticated request is refused ### Watch out - A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. ## M5 · Was it worth it You can answer the question with numbers instead of a feeling. ### Steps 1. Compute acceptance from your logs Accepted completions over offered completions, by language. Aggregate hides that it may be excellent for one language and useless for another. Files: `scripts/report.py` 2. Cost it honestly Hardware amortised, electricity, and your setup time at whatever you value it. Compare with the annual subscription. Files: `docs/comparison.md` 3. Write the decision down Including the case where you go back. A documented negative result is worth more than a quiet retreat. Files: `docs/comparison.md` ### Done when - [ ] Acceptance rate is reported per language, not only in aggregate - [ ] The cost comparison includes hardware and electricity - [ ] The decision and its reasoning are written down - [ ] The baseline figures were captured before cancelling anything ### Watch out - Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. ## M6 · Serving a team (production only) Colleagues can use it without you handing out a bare port. ### Steps 1. Add TLS and per-user tokens A reverse proxy for certificates and the server's own token support for identity. Test revocation, not just issuance. Files: `Caddyfile` 2. Load test for saturation Simulate concurrent completion requests and find where latency crosses the half second threshold. That number is your user limit. Files: `scripts/loadtest.py` 3. Publish the retention policy What request content is stored, for how long, and who can read it. One paragraph, agreed before rollout. Files: `docs/retention.md` ### Done when - [ ] A revoked token stops working immediately - [ ] The concurrent user limit is measured and documented - [ ] TLS is in place and plain HTTP is refused - [ ] The retention policy matches what the server actually stores ### Watch out - Completion requests contain the code around the cursor, which means the server sees your colleagues' work in progress. Decide and publish the retention policy before anyone connects, not after someone asks. ===== OPERATIONS.md ===== # Operations · GitHub Copilot ## Backup The model files are re-downloadable and the index is rebuildable, so the only thing worth backing up is your configuration and the completion log that supports the comparison. ## Restore Reinstall, restore the configuration, re-download the model and re-index. Time this once so you know whether a failed disk costs you an hour or a day. Do a restore drill before the first real user, and write the date here when it passes. ## Monitoring GPU memory and utilisation, completion latency percentiles rather than the mean, and index freshness. The ninety-fifth percentile is what people notice; the median looks fine while the experience is bad. ## Incident checklist If latency degrades, check GPU saturation and index size first, in that order. If completions become wrong rather than slow, the index is probably stale and pointing at renamed symbols. 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified backup when needed. 5. Document the root cause, the remediation and the regression test. ## Release gate - [ ] Median completion latency is under half a second on the chosen model - [ ] The index contains no credential file, verified by inspection - [ ] The server is confirmed to bind only where intended - [ ] A revoked token is proved to stop working - [ ] The retention policy is published before anyone else connects ## Launch constraint Do not market omitted GitHub Copilot capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered. ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. Bind address. Keep it on loopback unless you have deliberately added authentication. TABBY_HOST=127.0.0.1 # Required. The port the completion server listens on. TABBY_PORT=8080 # Required. The completion model. Chosen by the measurement in Phase 2, not by parameter count. TABBY_MODEL=StarCoder2-3B # Required. cuda, metal or cpu. The cpu value is a diagnostic, not a working configuration. TABBY_DEVICE=cuda # Optional · secret. Product phase only. Required the moment the server listens on anything but loopback. TABBY_TOKEN=replace-with-a-random-token # Required. Your own latency and acceptance log. This is what makes Phase 5 possible. COMPLETION_LOG_PATH=~/.local/share/tabby/completions.sqlite
# GitHub Copilot · indie build A Tabby server on your own machine or a GPU box, serving fill-in-the-middle completions to VS Code and JetBrains through official plugins, indexing your repositories for context, with latency measured rather than assumed and an acceptance rate you can compare against the subscription you left. Estimated effort: **weekend**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Completion server | Tabby, self-hosted | purpose-built for this, with fill-in-the-middle support, repository indexing and editor plugins already written | | Completion model | A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware | these are trained to fill a gap between a prefix and a suffix, which is not what a chat model does | | Hardware | An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal | Tabby's CUDA path uses int8 and needs an RTX 20-series or newer; older cards fall back to CPU and are too slow to use | | Editors | The official Tabby plugins for VS Code and JetBrains | ghost text and the accept gesture are editor-specific and already solved | | Measurement | A local log of latency and acceptance | the only way to know whether this is a real replacement or an expensive hobby | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **An NVIDIA GPU with compute capability 7.0 or newer, or an Apple silicon Mac** · free if you already have suitable hardware; a suitable GPU otherwise starts in the high hundreds of USD, which is the figure the comparison in Phase 5 has to justify - Why: This is the prerequisite that decides whether the project is viable. Below it, Tabby falls back to CPU and completions arrive too late to be useful. - Get it: Check an existing machine first with nvidia-smi. An RTX 20-series or newer qualifies. Apple silicon uses the Metal path instead and works well for smaller models. - Verify: nvidia-smi reports compute capability 7.0 or higher, or you are on Apple silicon - [ ] **Docker with GPU passthrough, or a native Tabby build** · free - Why: The container image is the fastest route to a running server, but it needs the GPU visible inside the container. - Get it: Install Docker, then the NVIDIA container toolkit on Linux. On Apple silicon, use the native build rather than a container. - Verify: docker run --gpus all reports the GPU, or the native binary starts and reports the Metal device - [ ] **VS Code or a JetBrains IDE with the Tabby plugin** · free - Why: The plugin is what turns a completion endpoint into ghost text. Writing your own is a project of its own. - Get it: Install from your editor's plugin marketplace and point it at your server address. - Verify: The plugin's status indicator shows connected - [ ] **Baseline figures from the tool you are replacing** · free, but it must be done first - Why: Phase 5 compares against them, and once you have cancelled the subscription you cannot go back and measure. - Get it: Spend a morning with the paid tool, logging how often you accept a completion and roughly how fast they arrive. Record it before you start. - Verify: A written baseline exists with an acceptance rate and a latency impression - [ ] **Twenty gigabytes of free disk** · free - Why: Models and indexes are large, and a model download that fails halfway through a full disk wastes an evening. - Get it: Check free space before pulling a model. Larger models need considerably more. - Verify: df reports at least twenty gigabytes free ## Quick start ```sh nvidia-smi --query-gpu=name,compute_cap --format=csv ``` Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Copilot's latency at scale, which is a fleet of accelerators. - Native GitHub integration across pull requests and code review. - Model routing by task, done invisibly by the subscription. - Fine-tuning on your own codebase. - native GitHub/IDE integration - fast completions - model routing - code review/security features - managed billing - team controls If one of those is essential to you, that is the reason to keep paying for GitHub Copilot, and the README should say so rather than pretend.
# Build brief · GitHub Copilot The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me self-hosted inline code completion running on hardware you control to replace GitHub Copilot. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Rule zero Do not train a model and do not write a completion engine. Run Tabby, which is a self-hosted completion server with fill-in-the-middle support and official editor plugins. Your work is the deployment, the model choice, the repository indexing and an honest measurement of whether the completions are good enough to keep. Note the distinction that decides your stack: inline completion and chat are different jobs. Completion wants a small model trained for fill-in-the-middle and answering in well under a second. Chat and agent work wants a large model and can afford to think. Do not try to serve both from one model. ### Stack (fixed, do not substitute) - Completion server: Tabby, self-hosted · purpose-built for this, with fill-in-the-middle support, repository indexing and editor plugins already written - Completion model: A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware · these are trained to fill a gap between a prefix and a suffix, which is not what a chat model does - Hardware: An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal · Tabby's CUDA path uses int8 and needs an RTX 20-series or newer; older cards fall back to CPU and are too slow to use - Editors: The official Tabby plugins for VS Code and JetBrains · ghost text and the accept gesture are editor-specific and already solved - Measurement: A local log of latency and acceptance · the only way to know whether this is a real replacement or an expensive hobby ### Data model (create this before Phase 1) - This is a deployment, so the model that matters is your operational state, not a schema. - server · the Tabby instance, its bound address, its model and its device - index · which repositories are indexed, when, and how large the index is - completions(t, latency_ms, accepted, model, language, prefix_len) · your own log, because acceptance rate is the only honest quality measure - baseline · the latency and acceptance figures from the subscription you are replacing, recorded before you cancel it ### Phase 1 · Hardware truth and a first completion Build: Check the GPU first, because it decides whether this project is viable. Run Tabby with a small completion model, connect the VS Code plugin, and get ghost text to appear. Then measure the round trip before doing anything else. Trap: Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. Done when: Ghost text appears in VS Code from your own server. Median completion latency is measured and written down. If that median is above roughly half a second, you have learned this hardware is not sufficient, which is a legitimate and useful outcome of this phase. Do not build yet: No indexing, no JetBrains, no measurement dashboard. One completion and one honest number. ### Phase 2 · Choosing a model by measurement Build: Try two or three completion models at different sizes. For each, record median latency and how often you accept the suggestion across a real morning of work. Pick on the combination, not on the benchmark. Trap: A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. Done when: Two or more models have recorded latency and acceptance figures from real work rather than synthetic prompts. The chosen model is the one with the best acceptance rate, not the largest that runs. The reasoning is written down. Do not build yet: No repository context yet, so completions are still local to the open file. ### Phase 3 · Repository context Build: Index your repositories so the server can retrieve relevant context. Exclude generated directories, vendored dependencies and anything containing credentials. Re-index on a schedule and confirm that a symbol defined in another file influences a completion. Trap: Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. Done when: A completion in one file correctly uses a function signature defined in a different file in the same repository. The index excludes generated and vendored directories, verified by its size and content. Adding a new file and re-indexing makes its symbols available. Do not build yet: No team deployment yet. ### Phase 4 · Availability and the offline case Build: Run the server as a managed service that starts on boot. Confirm the editor degrades cleanly when the server is unavailable rather than blocking typing. Decide whether it listens beyond localhost, and if so put authentication in front of it. Trap: A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. Done when: The server starts automatically after a reboot. With the server stopped, typing in the editor is unaffected apart from the absence of suggestions, with no freeze and no error popup on every keystroke. The listening address is confirmed by inspection, and if it is not localhost, an unauthenticated request is refused. Do not build yet: Team use is the product phase. ### Phase 5 · Was it worth it Build: Compare against the baseline you recorded: acceptance rate, median latency, hardware cost including electricity, and the hours you spent. Decide deliberately whether to keep this or go back, and write the decision down either way. Trap: Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. Done when: A written comparison covering acceptance rate, median latency and total cost including the hardware. The decision to keep or abandon is recorded with its reasoning. If the answer is that the subscription was better, that is a successful outcome of this phase rather than a failure. Do not build yet: Team deployment only if you decided to keep it. ### Phase 6 · Serving a team Build: Put the server behind TLS with authentication. Give each person a token. Watch GPU saturation, because completion latency collapses when several people type at once. Write down what is logged and who can see it. Trap: Completion requests contain the code around the cursor, which means the server sees your colleagues' work in progress. Decide and publish the retention policy before anyone connects, not after someone asks. Done when: Each user authenticates with their own token and a revoked token stops working immediately. Under concurrent load, latency is measured and a saturation point is documented. The retention policy is written and matches what the server actually stores. Do not build yet: Nothing after this. ### Out of scope (and why) - Copilot's completion latency at global scale, which comes from a fleet of accelerators you are not going to match with one card. - The native GitHub integration: pull request summaries, code review and the surfaces that only exist because GitHub owns both ends. - Model routing across a family of models by task, which the subscription does invisibly. - Training or fine-tuning a model on your own code, which is a separate project with a different budget. ### README must contain - The GPU requirement, specifically compute capability 7.0 or newer for the CUDA path - That completion and chat are different jobs served by different models, and which one this serves - The chosen model and the latency and acceptance figures that justified it - What the index excludes and how to confirm no credentials are in it - What request content the server stores, for how long, and who can read it
# Agent instructions · GitHub Copilot indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Tabby, self-hosted, A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware, An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal, The official Tabby plugins for VS Code and JetBrains, A local log of latency and acceptance. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. - A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. - Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. - A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. - Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt.
# Build plan · GitHub Copilot A Tabby server on your own machine or a GPU box, serving fill-in-the-middle completions to VS Code and JetBrains through official plugins, indexing your repositories for context, with latency measured rather than assumed and an acceptance rate you can compare against the subscription you left. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · Hardware truth and a first completion A completion appears in your editor, and you know whether your hardware can serve them fast enough to be useful. ### Steps 1. Establish what your hardware can do Check the GPU model and its compute capability, or confirm Apple silicon. Write the answer down before installing anything, because it constrains every later choice. ```sh nvidia-smi --query-gpu=name,compute_cap --format=csv ``` 2. Run Tabby with a small model Start with the smallest completion model that fits comfortably. A model that barely fits will swap and be slower than a smaller one that does not. ```sh docker run -it --gpus all -p 8080:8080 -v $HOME/.tabby:/data tabbyml/tabby serve --model StarCoder2-3B --device cuda ``` 3. Connect the editor and time it Install the Tabby VS Code plugin, point it at your server, and record the time from keystroke to ghost text over twenty completions. Files: `notes/latency.md` ### Done when - [ ] Ghost text appears in VS Code from your own server - [ ] The GPU compute capability is recorded and meets the floor, or the CPU fallback has been measured - [ ] Median completion latency over twenty samples is written down - [ ] Stopping the server produces a clear failure in the editor rather than a hang ### Watch out - Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. ## Phase 2 · Choosing a model by measurement You picked the model on evidence rather than on parameter count. ### Steps 1. Log every completion and its fate Record latency, language and whether you accepted it. The plugin can be configured to log, or you can wrap the server endpoint. Files: `scripts/log_completions.py` 2. Test each model over real work A morning each, on code you were writing anyway. Synthetic prompts will mislead you because they lack the surrounding file. 3. Write down the decision Model, latency, acceptance and the reason. In three months you will not remember why, and you will be tempted to re-test. Files: `docs/model-choice.md` ### Done when - [ ] At least two models have real latency and acceptance figures - [ ] The acceptance rate is computed from logged events, not estimated - [ ] The chosen model is justified in writing - [ ] Median latency for the chosen model is under half a second ### Watch out - A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. ## Phase 3 · Repository context Completions know about the rest of your codebase, not just the open file. ### Steps 1. Register repositories and set exclusions Add each repository to the server configuration with an exclusion list. Start from .gitignore and add credential paths. Files: `~/.tabby/config.toml` 2. Schedule re-indexing A periodic job. An index that reflects last month's code is worse than useless because it confidently suggests names you have since renamed. 3. Prove cross-file context works Define a distinctively named function in one file and start calling it in another. If the completion knows the signature, indexing is doing something. ### Done when - [ ] A completion uses a signature defined in another file - [ ] The index excludes generated and vendored directories - [ ] Re-indexing picks up a newly added file - [ ] No credential file is present in the index ### Watch out - Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. ## Phase 4 · Availability and the offline case The server is there when you start work, and the editor is usable when it is not. ### Steps 1. Run it as a service A systemd unit, a launchd agent or a restart policy on the container. Confirm by rebooting rather than by reading the configuration. ```sh systemctl --user enable --now tabby ``` 2. Verify graceful degradation Stop the server and work for ten minutes. Anything worse than a missing suggestion is a bug worth fixing before you rely on this. 3. Check what it is listening on Inspect the bound address. If it is not loopback, add a token and verify an unauthenticated request is refused. ```sh ss -tlnp | grep 8080 ``` ### Done when - [ ] The server comes back automatically after a reboot - [ ] Typing is unaffected while the server is stopped - [ ] The listening address is confirmed by inspection - [ ] If exposed beyond localhost, an unauthenticated request is refused ### Watch out - A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. ## Phase 5 · Was it worth it You can answer the question with numbers instead of a feeling. ### Steps 1. Compute acceptance from your logs Accepted completions over offered completions, by language. Aggregate hides that it may be excellent for one language and useless for another. Files: `scripts/report.py` 2. Cost it honestly Hardware amortised, electricity, and your setup time at whatever you value it. Compare with the annual subscription. Files: `docs/comparison.md` 3. Write the decision down Including the case where you go back. A documented negative result is worth more than a quiet retreat. Files: `docs/comparison.md` ### Done when - [ ] Acceptance rate is reported per language, not only in aggregate - [ ] The cost comparison includes hardware and electricity - [ ] The decision and its reasoning are written down - [ ] The baseline figures were captured before cancelling anything ### Watch out - Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. ## Not in this build - Copilot's latency at scale, which is a fleet of accelerators. - Native GitHub integration across pull requests and code review. - Model routing by task, done invisibly by the subscription. - Fine-tuning on your own codebase. ## After v1, if you want it - A separate chat and agent setup, which wants a different model entirely - Per-language acceptance tracking to find where it genuinely helps - Sharing one server across a small team, once the saturation point is known
# Copy to .env and fill in. Never commit .env; this file documents it. # Required. Bind address. Keep it on loopback unless you have deliberately added authentication. TABBY_HOST=127.0.0.1 # Required. The port the completion server listens on. TABBY_PORT=8080 # Required. The completion model. Chosen by the measurement in Phase 2, not by parameter count. TABBY_MODEL=StarCoder2-3B # Required. cuda, metal or cpu. The cpu value is a diagnostic, not a working configuration. TABBY_DEVICE=cuda # Optional · secret. Product phase only. Required the moment the server listens on anything but loopback. TABBY_TOKEN=replace-with-a-random-token # Required. Your own latency and acceptance log. This is what makes Phase 5 possible. COMPLETION_LOG_PATH=~/.local/share/tabby/completions.sqlite
# GitHub Copilot · product brief ## Problem You can use open-source editor agents and local/API models, but Copilot's value is editor integration, model routing, GitHub context, completions, and managed usage. ## Product outcome A completion server on hardware you own, serving your editors at a measured latency, indexing only code you wrote, with an acceptance rate you can compare against the subscription and a documented decision about whether it was worth it. ## Target user A builder who needs a maintainable product foundation, not a one-off demo. ## Required capabilities - VS Code/JetBrains extension - LLM API or local model - repo indexing - optional GitHub token ## Explicit non-goals for v1 - Copilot's latency at scale, which is a fleet of accelerators. - Native GitHub integration across pull requests and code review. - Model routing by task, done invisibly by the subscription. - Fine-tuning on your own codebase. - native GitHub/IDE integration - fast completions - model routing - code review/security features - managed billing - team controls ## Success criteria - Median completion latency is under half a second on the chosen model - The index contains no credential file, verified by inspection - The server is confirmed to bind only where intended - A revoked token is proved to stop working - The retention policy is published before anyone else connects
# Build brief · GitHub Copilot The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me self-hosted inline code completion running on hardware you control to replace GitHub Copilot. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Rule zero Do not train a model and do not write a completion engine. Run Tabby, which is a self-hosted completion server with fill-in-the-middle support and official editor plugins. Your work is the deployment, the model choice, the repository indexing and an honest measurement of whether the completions are good enough to keep. Note the distinction that decides your stack: inline completion and chat are different jobs. Completion wants a small model trained for fill-in-the-middle and answering in well under a second. Chat and agent work wants a large model and can afford to think. Do not try to serve both from one model. ### Stack (fixed, do not substitute) - Completion server: Tabby, self-hosted · purpose-built for this, with fill-in-the-middle support, repository indexing and editor plugins already written - Completion model: A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware · these are trained to fill a gap between a prefix and a suffix, which is not what a chat model does - Hardware: An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal · Tabby's CUDA path uses int8 and needs an RTX 20-series or newer; older cards fall back to CPU and are too slow to use - Editors: The official Tabby plugins for VS Code and JetBrains · ghost text and the accept gesture are editor-specific and already solved - Measurement: A local log of latency and acceptance · the only way to know whether this is a real replacement or an expensive hobby ### Data model (create this before Phase 1) - This is a deployment, so the model that matters is your operational state, not a schema. - server · the Tabby instance, its bound address, its model and its device - index · which repositories are indexed, when, and how large the index is - completions(t, latency_ms, accepted, model, language, prefix_len) · your own log, because acceptance rate is the only honest quality measure - baseline · the latency and acceptance figures from the subscription you are replacing, recorded before you cancel it ### Phase 1 · Hardware truth and a first completion Build: Check the GPU first, because it decides whether this project is viable. Run Tabby with a small completion model, connect the VS Code plugin, and get ghost text to appear. Then measure the round trip before doing anything else. Trap: Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. Done when: Ghost text appears in VS Code from your own server. Median completion latency is measured and written down. If that median is above roughly half a second, you have learned this hardware is not sufficient, which is a legitimate and useful outcome of this phase. Do not build yet: No indexing, no JetBrains, no measurement dashboard. One completion and one honest number. ### Phase 2 · Choosing a model by measurement Build: Try two or three completion models at different sizes. For each, record median latency and how often you accept the suggestion across a real morning of work. Pick on the combination, not on the benchmark. Trap: A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. Done when: Two or more models have recorded latency and acceptance figures from real work rather than synthetic prompts. The chosen model is the one with the best acceptance rate, not the largest that runs. The reasoning is written down. Do not build yet: No repository context yet, so completions are still local to the open file. ### Phase 3 · Repository context Build: Index your repositories so the server can retrieve relevant context. Exclude generated directories, vendored dependencies and anything containing credentials. Re-index on a schedule and confirm that a symbol defined in another file influences a completion. Trap: Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. Done when: A completion in one file correctly uses a function signature defined in a different file in the same repository. The index excludes generated and vendored directories, verified by its size and content. Adding a new file and re-indexing makes its symbols available. Do not build yet: No team deployment yet. ### Phase 4 · Availability and the offline case Build: Run the server as a managed service that starts on boot. Confirm the editor degrades cleanly when the server is unavailable rather than blocking typing. Decide whether it listens beyond localhost, and if so put authentication in front of it. Trap: A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. Done when: The server starts automatically after a reboot. With the server stopped, typing in the editor is unaffected apart from the absence of suggestions, with no freeze and no error popup on every keystroke. The listening address is confirmed by inspection, and if it is not localhost, an unauthenticated request is refused. Do not build yet: Team use is the product phase. ### Phase 5 · Was it worth it Build: Compare against the baseline you recorded: acceptance rate, median latency, hardware cost including electricity, and the hours you spent. Decide deliberately whether to keep this or go back, and write the decision down either way. Trap: Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. Done when: A written comparison covering acceptance rate, median latency and total cost including the hardware. The decision to keep or abandon is recorded with its reasoning. If the answer is that the subscription was better, that is a successful outcome of this phase rather than a failure. Do not build yet: Team deployment only if you decided to keep it. ### Phase 6 · Serving a team Build: Put the server behind TLS with authentication. Give each person a token. Watch GPU saturation, because completion latency collapses when several people type at once. Write down what is logged and who can see it. Trap: Completion requests contain the code around the cursor, which means the server sees your colleagues' work in progress. Decide and publish the retention policy before anyone connects, not after someone asks. Done when: Each user authenticates with their own token and a revoked token stops working immediately. Under concurrent load, latency is measured and a saturation point is documented. The retention policy is written and matches what the server actually stores. Do not build yet: Nothing after this. ### Out of scope (and why) - Copilot's completion latency at global scale, which comes from a fleet of accelerators you are not going to match with one card. - The native GitHub integration: pull request summaries, code review and the surfaces that only exist because GitHub owns both ends. - Model routing across a family of models by task, which the subscription does invisibly. - Training or fine-tuning a model on your own code, which is a separate project with a different budget. ### README must contain - The GPU requirement, specifically compute capability 7.0 or newer for the CUDA path - That completion and chat are different jobs served by different models, and which one this serves - The chosen model and the latency and acceptance figures that justified it - What the index excludes and how to confirm no credentials are in it - What request content the server stores, for how long, and who can read it
# Architecture · GitHub Copilot ## Stack | Part | Choice | Why | | --- | --- | --- | | Completion server | Tabby, self-hosted | purpose-built for this, with fill-in-the-middle support, repository indexing and editor plugins already written | | Completion model | A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware | these are trained to fill a gap between a prefix and a suffix, which is not what a chat model does | | Hardware | An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal | Tabby's CUDA path uses int8 and needs an RTX 20-series or newer; older cards fall back to CPU and are too slow to use | | Editors | The official Tabby plugins for VS Code and JetBrains | ghost text and the accept gesture are editor-specific and already solved | | Measurement | A local log of latency and acceptance | the only way to know whether this is a real replacement or an expensive hobby | ## Modules Each module has one owner concern and a documented way to replace it. | Module | Owns | How to replace it | | --- | --- | --- | | Server | Model loading, inference and the completion endpoint. | Tabby is the deployment. If you replace it, the editor plugins go too, which is most of the value. | | Model | Completion quality and latency. | Swapping models is a configuration change and a restart, which is exactly why Phase 2 measures rather than guesses. | | Index | Repository context. | The exclusion list matters more than the indexer. Revisit it whenever a repository grows a new generated directory. | | Editors | Ghost text and the accept gesture. | Official plugins per editor. Writing your own is the one part of this stack that is genuinely not worth it. | | Measurement | Latency and acceptance logging. | Yours entirely, and the only reason you can answer whether this works. | ## Configuration Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists. - `TABBY_HOST` · required · Bind address. Keep it on loopback unless you have deliberately added authentication. - `TABBY_PORT` · required · The port the completion server listens on. - `TABBY_MODEL` · required · The completion model. Chosen by the measurement in Phase 2, not by parameter count. - `TABBY_DEVICE` · required · cuda, metal or cpu. The cpu value is a diagnostic, not a working configuration. - `TABBY_TOKEN` · optional, secret · Product phase only. Required the moment the server listens on anything but loopback. - `COMPLETION_LOG_PATH` · required · Your own latency and acceptance log. This is what makes Phase 5 possible. ## Production baseline - Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts. - Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path. ## Decision records For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it.
# Agent instructions · GitHub Copilot product build - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: Tabby, self-hosted, A code-completion model such as StarCoder2 or DeepSeek-Coder, sized to your hardware, An NVIDIA GPU with compute capability 7.0 or newer, or Apple silicon with Metal, The official Tabby plugins for VS Code and JetBrains, A local log of latency and acceptance. - Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit. - Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a check pass. - Put every external service behind an interface with a deterministic fake for tests. - Add migrations and rollback or recovery notes for every persistent data change. - Log useful operational context without credentials, tokens, passwords or personal data. - Update documentation and run every check before completing a milestone. ## Known traps - Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. - A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. - Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. - A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. - Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. - Completion requests contain the code around the cursor, which means the server sees your colleagues' work in progress. Decide and publish the retention policy before anyone connects, not after someone asks.
# Delivery milestones · GitHub Copilot Estimated effort: **weekend** for the indie phases; the production-only milestones add the trust and operability layer. ## M1 · Hardware truth and a first completion A completion appears in your editor, and you know whether your hardware can serve them fast enough to be useful. ### Steps 1. Establish what your hardware can do Check the GPU model and its compute capability, or confirm Apple silicon. Write the answer down before installing anything, because it constrains every later choice. ```sh nvidia-smi --query-gpu=name,compute_cap --format=csv ``` 2. Run Tabby with a small model Start with the smallest completion model that fits comfortably. A model that barely fits will swap and be slower than a smaller one that does not. ```sh docker run -it --gpus all -p 8080:8080 -v $HOME/.tabby:/data tabbyml/tabby serve --model StarCoder2-3B --device cuda ``` 3. Connect the editor and time it Install the Tabby VS Code plugin, point it at your server, and record the time from keystroke to ghost text over twenty completions. Files: `notes/latency.md` ### Done when - [ ] Ghost text appears in VS Code from your own server - [ ] The GPU compute capability is recorded and meets the floor, or the CPU fallback has been measured - [ ] Median completion latency over twenty samples is written down - [ ] Stopping the server produces a clear failure in the editor rather than a hang ### Watch out - Tabby's CUDA path defaults to int8 and requires compute capability 7.0 or higher, meaning an RTX 20-series card or newer. On anything older it falls back to CPU, where completions arrive after you have already typed the line, which is the same as having none. Establish this before you spend a weekend on it. ## M2 · Choosing a model by measurement You picked the model on evidence rather than on parameter count. ### Steps 1. Log every completion and its fate Record latency, language and whether you accepted it. The plugin can be configured to log, or you can wrap the server endpoint. Files: `scripts/log_completions.py` 2. Test each model over real work A morning each, on code you were writing anyway. Synthetic prompts will mislead you because they lack the surrounding file. 3. Write down the decision Model, latency, acceptance and the reason. In three months you will not remember why, and you will be tempted to re-test. Files: `docs/model-choice.md` ### Done when - [ ] At least two models have real latency and acceptance figures - [ ] The acceptance rate is computed from logged events, not estimated - [ ] The chosen model is justified in writing - [ ] Median latency for the chosen model is under half a second ### Watch out - A larger model produces better completions and worse latency, and past roughly half a second the completion arrives after you have typed the line yourself, so its quality stops mattering. Acceptance rate captures this trade-off and a benchmark score does not. ## M3 · Repository context Completions know about the rest of your codebase, not just the open file. ### Steps 1. Register repositories and set exclusions Add each repository to the server configuration with an exclusion list. Start from .gitignore and add credential paths. Files: `~/.tabby/config.toml` 2. Schedule re-indexing A periodic job. An index that reflects last month's code is worse than useless because it confidently suggests names you have since renamed. 3. Prove cross-file context works Define a distinctively named function in one file and start calling it in another. If the completion knows the signature, indexing is doing something. ### Done when - [ ] A completion uses a signature defined in another file - [ ] The index excludes generated and vendored directories - [ ] Re-indexing picks up a newly added file - [ ] No credential file is present in the index ### Watch out - Indexing node_modules or a build directory buries genuine context under generated code and makes both indexing and retrieval slower. Exclude aggressively; the index should cover code you wrote. ## M4 · Availability and the offline case The server is there when you start work, and the editor is usable when it is not. ### Steps 1. Run it as a service A systemd unit, a launchd agent or a restart policy on the container. Confirm by rebooting rather than by reading the configuration. ```sh systemctl --user enable --now tabby ``` 2. Verify graceful degradation Stop the server and work for ten minutes. Anything worse than a missing suggestion is a bug worth fixing before you rely on this. 3. Check what it is listening on Inspect the bound address. If it is not loopback, add a token and verify an unauthenticated request is refused. ```sh ss -tlnp | grep 8080 ``` ### Done when - [ ] The server comes back automatically after a reboot - [ ] Typing is unaffected while the server is stopped - [ ] The listening address is confirmed by inspection - [ ] If exposed beyond localhost, an unauthenticated request is refused ### Watch out - A completion server bound to all interfaces with no authentication is a free GPU for anyone on the network. Bind to localhost unless you have deliberately added a token, and check what it is actually listening on rather than what you intended. ## M5 · Was it worth it You can answer the question with numbers instead of a feeling. ### Steps 1. Compute acceptance from your logs Accepted completions over offered completions, by language. Aggregate hides that it may be excellent for one language and useless for another. Files: `scripts/report.py` 2. Cost it honestly Hardware amortised, electricity, and your setup time at whatever you value it. Compare with the annual subscription. Files: `docs/comparison.md` 3. Write the decision down Including the case where you go back. A documented negative result is worth more than a quiet retreat. Files: `docs/comparison.md` ### Done when - [ ] Acceptance rate is reported per language, not only in aggregate - [ ] The cost comparison includes hardware and electricity - [ ] The decision and its reasoning are written down - [ ] The baseline figures were captured before cancelling anything ### Watch out - Sunk cost makes this comparison hard to do honestly after a weekend of setup. Record the baseline numbers from the paid tool before you cancel it, because afterwards you will only have a memory of how good it felt. ## M6 · Serving a team (production only) Colleagues can use it without you handing out a bare port. ### Steps 1. Add TLS and per-user tokens A reverse proxy for certificates and the server's own token support for identity. Test revocation, not just issuance. Files: `Caddyfile` 2. Load test for saturation Simulate concurrent completion requests and find where latency crosses the half second threshold. That number is your user limit. Files: `scripts/loadtest.py` 3. Publish the retention policy What request content is stored, for how long, and who can read it. One paragraph, agreed before rollout. Files: `docs/retention.md` ### Done when - [ ] A revoked token stops working immediately - [ ] The concurrent user limit is measured and documented - [ ] TLS is in place and plain HTTP is refused - [ ] The retention policy matches what the server actually stores ### Watch out - Completion requests contain the code around the cursor, which means the server sees your colleagues' work in progress. Decide and publish the retention policy before anyone connects, not after someone asks.
# Operations · GitHub Copilot ## Backup The model files are re-downloadable and the index is rebuildable, so the only thing worth backing up is your configuration and the completion log that supports the comparison. ## Restore Reinstall, restore the configuration, re-download the model and re-index. Time this once so you know whether a failed disk costs you an hour or a day. Do a restore drill before the first real user, and write the date here when it passes. ## Monitoring GPU memory and utilisation, completion latency percentiles rather than the mean, and index freshness. The ninety-fifth percentile is what people notice; the median looks fine while the experience is bad. ## Incident checklist If latency degrades, check GPU saturation and index size first, in that order. If completions become wrong rather than slow, the index is probably stale and pointing at renamed symbols. 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified backup when needed. 5. Document the root cause, the remediation and the regression test. ## Release gate - [ ] Median completion latency is under half a second on the chosen model - [ ] The index contains no credential file, verified by inspection - [ ] The server is confirmed to bind only where intended - [ ] A revoked token is proved to stop working - [ ] The retention policy is published before anyone else connects ## Launch constraint Do not market omitted GitHub Copilot capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered.
# Copy to .env and fill in. Never commit .env; this file documents it. # Required. Bind address. Keep it on loopback unless you have deliberately added authentication. TABBY_HOST=127.0.0.1 # Required. The port the completion server listens on. TABBY_PORT=8080 # Required. The completion model. Chosen by the measurement in Phase 2, not by parameter count. TABBY_MODEL=StarCoder2-3B # Required. cuda, metal or cpu. The cpu value is a diagnostic, not a working configuration. TABBY_DEVICE=cuda # Optional · secret. Product phase only. Required the moment the server listens on anything but loopback. TABBY_TOKEN=replace-with-a-random-token # Required. Your own latency and acceptance log. This is what makes Phase 5 possible. COMPLETION_LOG_PATH=~/.local/share/tabby/completions.sqlite
$ choose a build depth, inspect the files, then open the complete pack in your agent
They pay because low-latency completion and repo-aware coding are available in their editor without setup.
xnative GitHub/IDE integration
xfast completions
xmodel routing
xcode review/security features
xmanaged billing
xteam controls
Don't feel like building it? These folks already made it free.
all 5 free alternatives to GitHub Copilot →· no votes, no pay-to-list · just what's real
GitHub Copilot pricing
| plan | monthly | annual (per mo) | what you get |
|---|---|---|---|
| free | $0/user | $0/user | 2,000 code completions/month; AI-credit allowance exists but its numeric amount is not publicly stated; automatic model selection only. |
| student | $0/user | $0/user | Unlimited code completions; AI-credit allowance exists but its numeric amount is not publicly stated. |
| pro | $10/user | — | 1,500 AI credits/month: 1,000 base plus 500 Flex; unlimited code completions. |
| pro+ | $39/user | — | 7,000 AI credits/month: 3,900 base plus 3,100 Flex; unlimited code completions. |
| max | $100/user | — | 20,000 AI credits/month: 10,000 base plus 10,000 Flex; unlimited code completions. |
| business | $19/user | — | Standard allowance is 1,900 AI credits/user/month; temporary June-August 2026 promotion raises it to 3,000 through August 31, 2026. |
| enterprise | $39/user | — | Standard allowance is 3,900 AI credits/user/month; temporary June-August 2026 promotion raises it to 7,000 through August 31, 2026. |
free tier2,000 code completions/month; AI-credit quantity is not publicly stated; automatic model selection only
billingnew individual subscriptions are monthly only; legacy annual Pro/Pro+ subscriptions remain on the old request model until renewal
hidden costsExtra AI credits cost $0.01 each and unused monthly credits do not roll over; Copilot code review can also consume separately billed GitHub Actions minutes.
verified 2026-08-14 · source ↗
Vibecode GitHub Copilot
Kinda. The core of GitHub Copilot is buildable in a weekend with the prompt on this page, but there are real gaps: native GitHub/IDE integration, fast completions. Read the honest list above before committing.
How much does GitHub Copilot cost?
GitHub Copilot costs about $10/month (Pro, checked 2026-07-30), which is $120 per year.
What do I lose by replacing GitHub Copilot?
Honestly: native GitHub/IDE integration; fast completions; model routing; code review/security features; managed billing; team controls. If any of those are load-bearing for you, keep paying.
Is there an open-source alternative to GitHub Copilot?
Yes: OpenCode (A fast local coding agent with no loyalty to any model vendor.) Zed (A fast open editor with completions, chat and agents built in; model usage is separate.) Cline (A code agent in your editor; the model bill is still yours.) All 5 curated free alternatives are at vibecodeit.com/github-copilot/alternatives. The prompt is for when you want it exactly your way.