copilot-reverse 0.5.5 → 0.6.0

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.
@@ -0,0 +1,52 @@
1
+ export const APP_CHANGES = [
2
+ {
3
+ "version": "0.5.5",
4
+ "date": "2026-06-29",
5
+ "summary": "ci: gate PRs on a changeset. A pull request with no file in `.changes/` now fails the `changeset` check, so merges can't silently skip the release (the v0.5.3 freeze). Docs/test-only PRs opt out with a `no-changeset` label."
6
+ },
7
+ {
8
+ "version": "0.5.4",
9
+ "date": "2026-06-29",
10
+ "summary": "fix(worker): stop the empty-tool-call loop (\"call: call: call:…\") that froze sessions. Inline-XML blocks that recover no tool are now passed through verbatim instead of silently swallowed; nameless `function_call` items on the /responses path are dropped instead of streamed as a blank `call:`; and the runaway deadline now covers tool-call streams, not just text — a model looping on tool calls is cut cleanly instead of relaying forever."
11
+ },
12
+ {
13
+ "version": "0.5.3",
14
+ "date": "2026-06-29",
15
+ "summary": "Fix inline tool-call XML (`<invoke name=…>`) leaking as literal text instead of running. The extractor that recovers these blocks only ran on the chat path when the request declared tools, and never on the Codex `/responses` path. It now runs always-on across both streaming and non-stream paths, so a follow-up turn or a `/responses` model can no longer dump raw XML into the reply."
16
+ },
17
+ {
18
+ "version": "0.5.2",
19
+ "date": "2026-06-29",
20
+ "summary": "Fix the daemon going permanently dead during dogfooding. The worker had no `unhandledRejection` handler, so a stray floating rejection silently killed it (exit 1, empty stderr) on Node ≥15; once that happened 5×/60s the supervisor marked it `unhealthy` and gave up forever, leaving a running daemon with a dead worker. The worker now handles `unhandledRejection`, writes the cause to stderr *before* the IPC report (so crashes are no longer blind), the supervisor persists each crash to `crash.log`, and `unhealthy` now recovers: after a 30s cooldown it resets the window and tries again instead of staying down."
21
+ },
22
+ {
23
+ "version": "0.5.1",
24
+ "date": "2026-06-28",
25
+ "summary": "Fix the app dropping back to the shell during concurrent use. The TUI and supervisor share one process, but several synchronous throw sites had no handler — most importantly an SSE write to a client socket that died between broadcasts (likely with multiple clients connected), which crashed the whole process. Each broadcast listener is now isolated and a dead SSE connection is dropped instead of retried; `readGhToken` returns null on a corrupt/locked read instead of throwing on the heartbeat tick; and a process-level backstop logs any remaining stray throw/rejection to `~/.copilot-reverse/crash.log` and keeps the TUI alive."
26
+ },
27
+ {
28
+ "version": "0.5.0",
29
+ "date": "2026-06-28",
30
+ "summary": "Add a GitHub-token heartbeat: the supervisor now re-checks every ~60s whether the stored GitHub login still works, and the TUI footer shows a live `github ✓` / `✗ /login` badge — so an expired or revoked login surfaces within ~60s instead of only on the next failed request or a manual `/status`. A transient network/rate-limit hiccup is distinguished from a real auth failure, so the badge never flips on a single blip."
31
+ },
32
+ {
33
+ "version": "0.4.0",
34
+ "date": "2026-06-26",
35
+ "summary": "Codex `/responses` support, web search via Microsoft Web IQ, and a tool-call recovery fix:"
36
+ },
37
+ {
38
+ "version": "0.3.0",
39
+ "date": "2026-06-26",
40
+ "summary": "Restore `web_search` and `web_fetch` for Claude Code through the gateway: the worker now runs these tools internally against Microsoft Web IQ in a transparent agentic loop, and a new `/web-search-support` command stores the WebIQ API key."
41
+ },
42
+ {
43
+ "version": "0.2.1",
44
+ "date": "2026-06-25",
45
+ "summary": "Fix `/login` hanging with no output: the device-code prompt is now shown immediately while authorization is pending, instead of being buffered behind the blocking token poll."
46
+ },
47
+ {
48
+ "version": "0.2.0",
49
+ "date": "2026-06-23",
50
+ "summary": "Recover tool calls that some models emit as inline XML text into structured tool calls, and add changeset-driven automatic versioning + npm publish on merge to master."
51
+ }
52
+ ];
package/dist/cli/index.js CHANGED
@@ -181,11 +181,12 @@ async function launchTui() {
181
181
  }
182
182
  });
183
183
  const persistedModel = readChatModel(dataDir());
184
- // "What's new" banner: MAJOR changes only keyed by version so each release re-announces, shown
185
- // ~3 launches then quiet. Minor fixes/polish do NOT go here; reserve it for things worth noticing.
184
+ // "What's new" banner: IMPORTANT messages only (new capabilities, things worth noticing) NOT
185
+ // bug fixes. Keyed by version so each release re-announces, shown ~3 launches then quiet. The full
186
+ // list lives behind /changes; this is just a nudge.
186
187
  const CHANGE_ID = `v${APP_VERSION}`;
187
188
  const changeBanner = shouldShowChange(dataDir(), CHANGE_ID)
188
- ? { lines: ["• runaway streams now cut cleanly no more frozen 'code code code' sessions"] }
189
+ ? { lines: ["• type /changes to see what's new across recent releases"] }
189
190
  : undefined;
190
191
  // Startup overview. The token was already validated above (re-auth happens before we get here), so
191
192
  // GitHub is connected; web search readiness and configured clients are read from disk.
@@ -3,6 +3,7 @@ import { claudeCodeConfig, codexConfig } from "../setup/clients.js";
3
3
  import { aggregate, recentErrors } from "../panels/metrics-agg.js";
4
4
  import { openUrl as defaultOpenUrl } from "../../shared/open-url.js";
5
5
  import { buildIssueUrl, PLACEHOLDER_REPO } from "../report.js";
6
+ import { APP_CHANGES } from "../../changes.js";
6
7
  export function buildRegistry(ctx, endpoint, opts = {}) {
7
8
  const reg = new Registry(ctx);
8
9
  const openUrl = opts.openUrl ?? defaultOpenUrl;
@@ -68,6 +69,17 @@ export function buildRegistry(ctx, endpoint, opts = {}) {
68
69
  openUrl(url);
69
70
  return [`opening a pre-filled GitHub issue for ${repo} in your browser…`];
70
71
  } });
72
+ reg.add({ name: "/changes", describe: "what's new — recent releases", run: async () => {
73
+ if (!APP_CHANGES.length)
74
+ return ["no changelog bundled"];
75
+ const lines = APP_CHANGES.slice(0, 10).map((c) => {
76
+ const s = c.summary.length > 90 ? c.summary.slice(0, 87) + "…" : c.summary;
77
+ return `v${c.version} (${c.date}) — ${s}`;
78
+ });
79
+ const repo = opts.reportRepo && opts.reportRepo !== PLACEHOLDER_REPO ? opts.reportRepo : "wangcansunking/copilot-reverse";
80
+ lines.push("", `full changelog: https://github.com/${repo}/blob/master/CHANGELOG.md`);
81
+ return lines;
82
+ } });
71
83
  reg.add({ name: "/quit", describe: "exit copilot-reverse", run: async (_a, c) => { c.quit(); return ["bye"]; } });
72
84
  reg.add({ name: "/help", describe: "list commands", run: async () => reg.list().map((c) => `${c.name.padEnd(14)} ${c.describe}`) });
73
85
  return reg;
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // AUTO-GENERATED by scripts/gen-version.mjs from package.json — do not edit.
2
- export const APP_VERSION = "0.5.5";
2
+ export const APP_VERSION = "0.6.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "copilot-reverse",
3
- "version": "0.5.5",
3
+ "version": "0.6.0",
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",
@@ -32,7 +32,7 @@
32
32
  "llm"
33
33
  ],
34
34
  "scripts": {
35
- "prebuild": "node scripts/gen-version.mjs",
35
+ "prebuild": "node scripts/gen-version.mjs && node scripts/gen-changes.mjs",
36
36
  "build": "tsc -p tsconfig.json",
37
37
  "test": "vitest run",
38
38
  "test:coverage": "vitest run --coverage",