copilot-reverse 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +149 -15
- package/dist/cli/index.js +17 -3
- package/dist/shared/creds.js +5 -1
- package/dist/tui/assistant/on-chat.js +9 -2
- package/dist/tui/slash/commands.js +2 -0
- package/dist/worker/errors.js +4 -0
- package/package.json +1 -2
- package/GUIDE.md +0 -142
package/README.md
CHANGED
|
@@ -1,37 +1,166 @@
|
|
|
1
1
|
# copilot-reverse
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
built-in assistant.
|
|
3
|
+
**Use the GitHub Copilot subscription you already pay for as a local Claude Code / Codex backend.**
|
|
4
|
+
No new API keys. No per-token bills. One terminal app.
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
```
|
|
7
|
+
┌─────────────┐ ┌───────────────────┐ ┌─────────────┐
|
|
8
|
+
│ Claude Code │ ─────▶ │ copilot-reverse │ ─────▶ │ Copilot │
|
|
9
|
+
│ / Codex │ local │ (your machine) │ proxy │ (your sub) │
|
|
10
|
+
└─────────────┘ └───────────────────┘ └─────────────┘
|
|
11
|
+
```
|
|
8
12
|
|
|
9
13
|
> **Disclaimer:** The GitHub Copilot integration uses community-documented,
|
|
10
14
|
> unofficial endpoints, for use with your own Copilot subscription only. It may
|
|
11
15
|
> break if GitHub changes these endpoints.
|
|
12
16
|
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 60-second start
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx copilot-reverse
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
1. It asks you to log in to GitHub (device code — paste a code in your browser). One time only.
|
|
26
|
+
2. The terminal app launches. You'll see a prompt and a status bar.
|
|
27
|
+
3. In the app, type:
|
|
28
|
+
```
|
|
29
|
+
/setup-claude
|
|
30
|
+
```
|
|
31
|
+
Pick a model (e.g. **claude-opus-4.8 (1M)**), choose **global**, done.
|
|
32
|
+
4. Open a **new** terminal and run `claude`. It's now talking to Copilot through copilot-reverse. 🎉
|
|
33
|
+
|
|
34
|
+
That's it. Codex users: run `/setup-codex` instead.
|
|
35
|
+
|
|
36
|
+
Here's the app itself — a prompt, a live status bar, and slash-command autocomplete:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
✳ copilot-reverse worker: ready
|
|
40
|
+
|
|
41
|
+
Type a message to chat with the assistant, or /help for commands.
|
|
42
|
+
╭─────────────────────────────────────────────────────────────────────────────────────╮
|
|
43
|
+
│ › /setup │
|
|
44
|
+
╰─────────────────────────────────────────────────────────────────────────────────────╯
|
|
45
|
+
❯ /setup-claude print Claude Code config
|
|
46
|
+
/setup-codex print Codex/OpenAI config
|
|
47
|
+
/setup-status show configured endpoints
|
|
48
|
+
↑↓ navigate · tab complete · enter run
|
|
49
|
+
model claude-opus-4.8 · daemon ready · claude u:✓ p:○ codex u:✓ p:○ · /help
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## What can I do in the app?
|
|
55
|
+
|
|
56
|
+
Just **talk to it** — it understands plain English and will do the work for you:
|
|
57
|
+
|
|
58
|
+
> *"list models"* → shows every model + its context window
|
|
59
|
+
> *"set up claude"* → configures Claude Code
|
|
60
|
+
> *"is the worker healthy?"* → runs a health check
|
|
61
|
+
> *"why did my last request fail?"* → shows the error
|
|
62
|
+
|
|
63
|
+
Prefer commands? Type `/` to see them all. The essentials:
|
|
64
|
+
|
|
65
|
+
| Command | What it does |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `/setup-claude` · `/setup-codex` | Point Claude Code / Codex at copilot-reverse |
|
|
68
|
+
| `/model` | Switch the chat model (1M-context models marked) |
|
|
69
|
+
| `/status` · `/doctor` | Is everything healthy? |
|
|
70
|
+
| `/logs` · `/metrics` | What ran, what failed, and why |
|
|
71
|
+
| `/dashboard` | Open a live web dashboard in your browser |
|
|
72
|
+
| `/report` | File a pre-filled bug report (diagnostics only — no prompts) |
|
|
73
|
+
| `/reset-claude` · `/reset-codex` | Undo setup, restore original config |
|
|
74
|
+
| `/login` · `/logout` | Sign in to GitHub (device-code) · sign out (remove token) |
|
|
75
|
+
| `/help` · `/quit` | List commands · exit |
|
|
76
|
+
|
|
77
|
+
### The live dashboard
|
|
78
|
+
|
|
79
|
+
`/dashboard` opens a self-refreshing web view of everything happening through the proxy — worker
|
|
80
|
+
health, request volume, and (most useful) recent **errors with their real messages**:
|
|
81
|
+
|
|
13
82
|

|
|
14
83
|
|
|
15
|
-
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Connect your own tools
|
|
87
|
+
|
|
88
|
+
Already have something that speaks OpenAI or Anthropic? Point it here:
|
|
89
|
+
|
|
90
|
+
- **OpenAI-compatible:** `http://127.0.0.1:7891/v1`
|
|
91
|
+
- **Anthropic-compatible:** `http://127.0.0.1:7891`
|
|
92
|
+
|
|
93
|
+
Any API key value works locally (it's your machine). Example:
|
|
16
94
|
|
|
17
95
|
```bash
|
|
18
|
-
|
|
96
|
+
export ANTHROPIC_BASE_URL=http://127.0.0.1:7891
|
|
97
|
+
export ANTHROPIC_API_KEY=local
|
|
98
|
+
claude
|
|
19
99
|
```
|
|
20
100
|
|
|
21
|
-
|
|
22
|
-
just talk to the assistant in natural language.
|
|
101
|
+
---
|
|
23
102
|
|
|
24
|
-
|
|
25
|
-
- OpenAI: `http://127.0.0.1:7891/v1`
|
|
26
|
-
- Anthropic: `http://127.0.0.1:7891`
|
|
103
|
+
## The status bar, decoded
|
|
27
104
|
|
|
28
|
-
|
|
105
|
+
The bottom line of the app tells you everything at a glance:
|
|
29
106
|
|
|
30
|
-
|
|
107
|
+
```text
|
|
108
|
+
model claude-opus-4.8 · daemon ready · claude u:✓ p:○ codex u:○ p:○ · /help
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- **worker / daemon** — green `ready` means the proxy is up and self-healing.
|
|
112
|
+
- **claude u:✓ p:○** — Claude Code is configured at the **u**ser (global) level, not in this **p**roject. Read live from your real config files.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Troubleshooting
|
|
117
|
+
|
|
118
|
+
**"context 100%" or `/compact` fails in Claude Code**
|
|
119
|
+
Re-run `/setup-claude` and pick a **1M** model (e.g. `claude-opus-4.8 (1M)`). copilot-reverse writes
|
|
120
|
+
the right context-window hint so the client stops assuming a small window. Then restart Claude Code.
|
|
121
|
+
|
|
122
|
+
**"GitHub login expired"**
|
|
123
|
+
Your Copilot session lapsed. You don't need to restart anything — when a chat fails, copilot-reverse
|
|
124
|
+
detects it and tells you right there:
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
assistant error: 401 authentication_error: GitHub login expired
|
|
128
|
+
↳ your GitHub login looks expired — run /login to sign in again
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Just type **`/login`**, complete the device-code prompt, and you're back — the worker reloads the new
|
|
132
|
+
token automatically. (Switching accounts? `/logout` first, then `/login`.)
|
|
133
|
+
|
|
134
|
+
**A request failed and I don't know why**
|
|
135
|
+
Type `/logs` (or ask *"why did that fail?"*). Every failure is captured with its real upstream
|
|
136
|
+
message. Still stuck? `/report` opens a pre-filled GitHub issue with diagnostics — **never** your
|
|
137
|
+
prompt content.
|
|
138
|
+
|
|
139
|
+
**Want to undo everything**
|
|
140
|
+
`/reset-claude` and `/reset-codex` remove exactly the keys copilot-reverse added and leave the rest
|
|
141
|
+
of your config untouched.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Good to know
|
|
146
|
+
|
|
147
|
+
- **Your data stays local.** The app proxies between your editor and Copilot on `127.0.0.1`. Your
|
|
148
|
+
GitHub token lives only in `~/.copilot-reverse/creds.json` on your own disk.
|
|
149
|
+
- **It heals itself.** If the proxy crashes, the supervisor restarts it with backoff and records why.
|
|
150
|
+
- **Unofficial endpoints.** This uses community-documented Copilot endpoints with *your own*
|
|
151
|
+
subscription. It may break if GitHub changes them — that's the trade-off for not needing extra keys.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Architecture
|
|
156
|
+
|
|
157
|
+
Three processes, one terminal app:
|
|
158
|
+
|
|
159
|
+
- **TUI** (Ink) — the `copilot-reverse` process: REPL + slash commands + a claude-agent-sdk
|
|
31
160
|
assistant (which dogfoods copilot-reverse's own Anthropic endpoint).
|
|
32
161
|
- **Supervisor** (:7890) — control API + SQLite + self-healing worker supervision.
|
|
33
|
-
- **Worker** (:7891) — OpenAI `/v1/chat/completions` + Anthropic `/v1/messages`
|
|
34
|
-
|
|
162
|
+
- **Worker** (:7891) — OpenAI `/v1/chat/completions` + Anthropic `/v1/messages` → Copilot,
|
|
163
|
+
with tool-use translation both ways.
|
|
35
164
|
|
|
36
165
|
## Development
|
|
37
166
|
|
|
@@ -58,3 +187,8 @@ re-run and update `e2e/RESULTS.md`.
|
|
|
58
187
|
`useInput` subscribes to stdin asynchronously after mount, so writes issued in
|
|
59
188
|
the same tick as `render()` are dropped. The delay lets the subscription
|
|
60
189
|
attach; assertions are otherwise unchanged.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
Questions or bugs? Use `/report` from inside the app, or open an issue on
|
|
194
|
+
[GitHub](https://github.com/wangcansunking/copilot-reverse). Happy hacking. 🚀
|
package/dist/cli/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { probeSupervisor } from "../daemon/lifecycle.js";
|
|
|
10
10
|
import { startSupervisor } from "../supervisor/index.js";
|
|
11
11
|
import { runAssistantTurn } from "../tui/assistant/runtime.js";
|
|
12
12
|
import { makeOnChat } from "../tui/assistant/on-chat.js";
|
|
13
|
-
import { readGhToken } from "../shared/creds.js";
|
|
13
|
+
import { readGhToken, clearGhToken } from "../shared/creds.js";
|
|
14
14
|
import { readClientSetup, writeClientSetup } from "../shared/client-setup.js";
|
|
15
15
|
import { readChatModel, writeChatModel } from "../shared/prefs.js";
|
|
16
16
|
import { CopilotTokenStore, isCopilotTokenValid } from "../providers/copilot/token.js";
|
|
@@ -66,9 +66,23 @@ async function launchTui() {
|
|
|
66
66
|
const registry = buildRegistry({ client, quit }, endpoint, {
|
|
67
67
|
dashboardUrl: `http://${cfg.bindHost}:${cfg.supervisorPort}/`,
|
|
68
68
|
reportRepo: cfg.reportRepo,
|
|
69
|
-
appVersion: "0.0.
|
|
69
|
+
appVersion: "0.0.2",
|
|
70
70
|
platform: `${process.platform} node-${process.version}`,
|
|
71
71
|
resetClient,
|
|
72
|
+
// Re-run device-code login, then restart the worker so it picks up the new token.
|
|
73
|
+
login: async () => {
|
|
74
|
+
const lines = [];
|
|
75
|
+
await runDeviceLogin(dataDir(), fetch, (m) => lines.push(m));
|
|
76
|
+
await client.restart().catch(() => { });
|
|
77
|
+
lines.push("worker restarting with the new token");
|
|
78
|
+
return lines;
|
|
79
|
+
},
|
|
80
|
+
// Clear the stored token and restart the worker (it will report unauthenticated until re-login).
|
|
81
|
+
logout: async () => {
|
|
82
|
+
clearGhToken(dataDir());
|
|
83
|
+
await client.restart().catch(() => { });
|
|
84
|
+
return ["signed out — GitHub token removed", "run /login to sign in again"];
|
|
85
|
+
},
|
|
72
86
|
});
|
|
73
87
|
// Filled in below once we have a token; the assistant prefers a model's real window over the default.
|
|
74
88
|
const modelLimits = {};
|
|
@@ -127,7 +141,7 @@ async function launchTui() {
|
|
|
127
141
|
}));
|
|
128
142
|
}
|
|
129
143
|
const program = new Command();
|
|
130
|
-
program.name("copilot-reverse").description("copilot-reverse: interactive Copilot proxy").version("0.0.
|
|
144
|
+
program.name("copilot-reverse").description("copilot-reverse: interactive Copilot proxy").version("0.0.2");
|
|
131
145
|
program.command("login").description("GitHub device-code login").action(() => runDeviceLogin(dataDir()));
|
|
132
146
|
program.action(() => { void launchTui(); });
|
|
133
147
|
program.parseAsync(process.argv);
|
package/dist/shared/creds.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
// M1: plaintext token in the data dir (0600). Encryption-at-rest is M2.
|
|
4
4
|
const file = (dir) => join(dir, "creds.json");
|
|
@@ -12,3 +12,7 @@ export function readGhToken(dir) {
|
|
|
12
12
|
return null;
|
|
13
13
|
return JSON.parse(readFileSync(file(dir), "utf8")).ghToken ?? null;
|
|
14
14
|
}
|
|
15
|
+
// Remove the stored token (logout). No-op if there's nothing to remove.
|
|
16
|
+
export function clearGhToken(dir) {
|
|
17
|
+
rmSync(file(dir), { force: true });
|
|
18
|
+
}
|
|
@@ -18,8 +18,15 @@ export function makeOnChat(cfg, runner, timeoutMs = DEFAULT_TURN_TIMEOUT_MS) {
|
|
|
18
18
|
print("⎿ interrupted");
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
print(
|
|
21
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
22
|
+
print(`assistant error: ${message}`);
|
|
23
|
+
// Detect an expired/revoked GitHub login anywhere in the error and steer the user to re-auth.
|
|
24
|
+
if (/login expired|authentication_error|unauthorized|\b401\b|\b403\b|token exchange failed/i.test(message)) {
|
|
25
|
+
print("\n ↳ your GitHub login looks expired — run /login to sign in again");
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
print("\n ↳ next: retry · /model to switch model · /doctor to check health · /report to file it");
|
|
29
|
+
}
|
|
23
30
|
}
|
|
24
31
|
};
|
|
25
32
|
}
|
|
@@ -42,6 +42,8 @@ export function buildRegistry(ctx, endpoint, opts = {}) {
|
|
|
42
42
|
reg.add({ name: "/setup-status", describe: "show configured endpoints", run: async () => [`OpenAI: http://${endpoint.host}:${endpoint.port}/v1`, `Anthropic: http://${endpoint.host}:${endpoint.port}`] });
|
|
43
43
|
reg.add({ name: "/reset-claude", describe: "restore Claude Code config (remove copilot-reverse's keys)", run: async () => opts.resetClient ? opts.resetClient("claude") : ["reset not available"] });
|
|
44
44
|
reg.add({ name: "/reset-codex", describe: "restore Codex/OpenAI config (remove copilot-reverse's keys)", run: async () => opts.resetClient ? opts.resetClient("codex") : ["reset not available"] });
|
|
45
|
+
reg.add({ name: "/login", describe: "sign in to GitHub (device-code)", run: async () => opts.login ? opts.login() : ["login not available"] });
|
|
46
|
+
reg.add({ name: "/logout", describe: "sign out — remove the stored GitHub token", run: async () => opts.logout ? opts.logout() : ["logout not available"] });
|
|
45
47
|
reg.add({ name: "/model", describe: "switch the chat model", run: async () => ["opening model picker…"] });
|
|
46
48
|
reg.add({ name: "/config", describe: "view & change configuration", run: async () => ["opening config panel…"] });
|
|
47
49
|
reg.add({ name: "/dashboard", describe: "open the web dashboard in your browser", run: async () => {
|
package/dist/worker/errors.js
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
// structured context-window-exceeded + model_not_supported guidance instead of a bare 400).
|
|
3
3
|
export function errorHint(message) {
|
|
4
4
|
const m = message.toLowerCase();
|
|
5
|
+
// An expired/revoked GitHub login — tell the user to re-authenticate from inside the app.
|
|
6
|
+
if (/login expired|authentication_error|token exchange failed|unauthorized|\b401\b|\b403\b/.test(m)) {
|
|
7
|
+
return "GitHub login expired — run /login to sign in again";
|
|
8
|
+
}
|
|
5
9
|
if (/context_length_exceeded|prompt is too long|maximum context|too many tokens|context window/.test(m)) {
|
|
6
10
|
return "context window exceeded — the conversation is too long; /compact or switch to a larger-context model";
|
|
7
11
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "copilot-reverse",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Interactive terminal app that exposes your GitHub Copilot subscription as local OpenAI- and Anthropic-compatible endpoints, with a self-healing daemon and a built-in assistant.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
"files": [
|
|
19
19
|
"dist",
|
|
20
20
|
"README.md",
|
|
21
|
-
"GUIDE.md",
|
|
22
21
|
"images"
|
|
23
22
|
],
|
|
24
23
|
"keywords": [
|
package/GUIDE.md
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
# copilot-reverse — User Guide
|
|
2
|
-
|
|
3
|
-
**Use the Copilot subscription you already pay for as a local Claude Code / Codex backend.**
|
|
4
|
-
No new API keys. No per-token bills. One terminal app.
|
|
5
|
-
|
|
6
|
-
```
|
|
7
|
-
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
|
|
8
|
-
│ Claude Code │ ─────▶ │ copilot-reverse │ ─────▶ │ Copilot │
|
|
9
|
-
│ / Codex │ local │ (your machine) │ proxy │ (your sub) │
|
|
10
|
-
└─────────────┘ └──────────────────┘ └─────────────┘
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 60-second start
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npx copilot-reverse
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
1. It asks you to log in to GitHub (device code — paste a code in your browser). One time only.
|
|
22
|
-
2. The terminal app launches. You'll see a prompt and a status bar.
|
|
23
|
-
3. In the app, type:
|
|
24
|
-
```
|
|
25
|
-
/setup-claude
|
|
26
|
-
```
|
|
27
|
-
Pick a model (e.g. **claude-opus-4.8 (1M)**), choose **global**, done.
|
|
28
|
-
4. Open a **new** terminal and run `claude`. It's now talking to Copilot through copilot-reverse. 🎉
|
|
29
|
-
|
|
30
|
-
That's it. Codex users: run `/setup-codex` instead.
|
|
31
|
-
|
|
32
|
-
Here's the app itself — a prompt, a live status bar, and slash-command autocomplete:
|
|
33
|
-
|
|
34
|
-
```text
|
|
35
|
-
✳ copilot-reverse worker: ready
|
|
36
|
-
|
|
37
|
-
Type a message to chat with the assistant, or /help for commands.
|
|
38
|
-
╭─────────────────────────────────────────────────────────────────────────────────────╮
|
|
39
|
-
│ › /setup │
|
|
40
|
-
╰─────────────────────────────────────────────────────────────────────────────────────╯
|
|
41
|
-
❯ /setup-claude print Claude Code config
|
|
42
|
-
/setup-codex print Codex/OpenAI config
|
|
43
|
-
/setup-status show configured endpoints
|
|
44
|
-
↑↓ navigate · tab complete · enter run
|
|
45
|
-
model claude-opus-4.8 · daemon ready · claude u:✓ p:○ codex u:✓ p:○ · /help
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## What can I do in the app?
|
|
51
|
-
|
|
52
|
-
Just **talk to it** — it understands plain English and will do the work for you:
|
|
53
|
-
|
|
54
|
-
> *"list models"* → shows every model + its context window
|
|
55
|
-
> *"set up claude"* → configures Claude Code
|
|
56
|
-
> *"is the worker healthy?"* → runs a health check
|
|
57
|
-
> *"why did my last request fail?"* → shows the error
|
|
58
|
-
|
|
59
|
-
Prefer commands? Type `/` to see them all. The essentials:
|
|
60
|
-
|
|
61
|
-
| Command | What it does |
|
|
62
|
-
|---|---|
|
|
63
|
-
| `/setup-claude` · `/setup-codex` | Point Claude Code / Codex at copilot-reverse |
|
|
64
|
-
| `/model` | Switch the chat model (1M-context models marked) |
|
|
65
|
-
| `/status` · `/doctor` | Is everything healthy? |
|
|
66
|
-
| `/logs` · `/metrics` | What ran, what failed, and why |
|
|
67
|
-
| `/dashboard` | Open a live web dashboard in your browser |
|
|
68
|
-
| `/report` | File a pre-filled bug report (diagnostics only — no prompts) |
|
|
69
|
-
| `/reset-claude` · `/reset-codex` | Undo setup, restore original config |
|
|
70
|
-
| `/help` · `/quit` | List commands · exit |
|
|
71
|
-
|
|
72
|
-
### The live dashboard
|
|
73
|
-
|
|
74
|
-
`/dashboard` opens a self-refreshing web view of everything happening through the proxy — worker
|
|
75
|
-
health, request volume, and (most useful) recent **errors with their real messages**:
|
|
76
|
-
|
|
77
|
-

|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## Connect your own tools
|
|
82
|
-
|
|
83
|
-
Already have something that speaks OpenAI or Anthropic? Point it here:
|
|
84
|
-
|
|
85
|
-
- **OpenAI-compatible:** `http://127.0.0.1:7891/v1`
|
|
86
|
-
- **Anthropic-compatible:** `http://127.0.0.1:7891`
|
|
87
|
-
|
|
88
|
-
Any API key value works locally (it's your machine). Example:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
export ANTHROPIC_BASE_URL=http://127.0.0.1:7891
|
|
92
|
-
export ANTHROPIC_API_KEY=local
|
|
93
|
-
claude
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## The status bar, decoded
|
|
99
|
-
|
|
100
|
-
The bottom line of the app (see the screenshot above) tells you everything at a glance:
|
|
101
|
-
|
|
102
|
-
```text
|
|
103
|
-
model claude-opus-4.8 · daemon ready · claude u:✓ p:○ codex u:○ p:○ · /help
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
- **worker / daemon** — green `ready` means the proxy is up and self-healing.
|
|
107
|
-
- **claude u:✓ p:○** — Claude Code is configured at the **u**ser (global) level, not in this **p**roject. Read live from your real config files.
|
|
108
|
-
|
|
109
|
-
---
|
|
110
|
-
|
|
111
|
-
## Troubleshooting
|
|
112
|
-
|
|
113
|
-
**"context 100%" or `/compact` fails in Claude Code**
|
|
114
|
-
Re-run `/setup-claude` and pick a **1M** model (e.g. `claude-opus-4.8 (1M)`). copilot-reverse writes
|
|
115
|
-
the right context-window hint so the client stops assuming a small window. Then restart Claude Code.
|
|
116
|
-
|
|
117
|
-
**"GitHub login expired"**
|
|
118
|
-
Your Copilot session lapsed. Restart copilot-reverse — it'll prompt you to log in again.
|
|
119
|
-
|
|
120
|
-
**A request failed and I don't know why**
|
|
121
|
-
Type `/logs` (or ask *"why did that fail?"*). Every failure is captured with its real upstream
|
|
122
|
-
message. Still stuck? `/report` opens a pre-filled GitHub issue with diagnostics — **never** your
|
|
123
|
-
prompt content.
|
|
124
|
-
|
|
125
|
-
**Want to undo everything**
|
|
126
|
-
`/reset-claude` and `/reset-codex` remove exactly the keys copilot-reverse added and leave the rest
|
|
127
|
-
of your config untouched.
|
|
128
|
-
|
|
129
|
-
---
|
|
130
|
-
|
|
131
|
-
## Good to know
|
|
132
|
-
|
|
133
|
-
- **Your data stays local.** The app proxies between your editor and Copilot on `127.0.0.1`. Your
|
|
134
|
-
GitHub token lives only in `~/.copilot-reverse/creds.json` on your own disk.
|
|
135
|
-
- **It heals itself.** If the proxy crashes, the supervisor restarts it with backoff and records why.
|
|
136
|
-
- **Unofficial endpoints.** This uses community-documented Copilot endpoints with *your own*
|
|
137
|
-
subscription. It may break if GitHub changes them — that's the trade-off for not needing extra keys.
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
Questions or bugs? Use `/report` from inside the app, or open an issue on
|
|
142
|
-
[GitHub](https://github.com/wangcansunking/copilot-reverse). Happy hacking. 🚀
|