mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-04 22:49:41 +02:00
fix(cli-registry): toggling a CLI off in Settings never hid it anywhere else
window.__codemanCliAvailable — the flag isCliAvailable() reads client-side to gate the welcome-screen buttons, the Run-menu dropdown and the mobile overview — was built purely from each CLI's own installed-on-PATH resolver (isClaudeAvailable() etc.), with no reference to the registry's `enabled` flag at all. So disabling a CLI via the new Settings UI (or a hand-edited clis.json) updated the settings row and nothing else: every launch surface kept offering it, both live and after a full page reload, since even a fresh render never consulted the registry. Fixed in two places: - server.ts: after building `available`, intersect the nine real SessionMode ids against `enabledClis()`. git/cloudflared (utility binaries, not CLI registry entries) and deepseekBinary (a secondary installed-only flag for the "add a profile" affordance) are deliberately left alone. - settings-ui.js: `toggleCliEnabled()` now patches `window.__codemanCliAvailable` in place and refreshes the welcome screen, the mobile overview and an already-open Run menu, mirroring the existing `installDeepSeekProfile()` pattern for the same "injected once, needs an explicit patch" reason — without this half, the server-side fix alone still left every surface stale until the next reload. New test in test/render-index-html.test.ts: an installed-but-disabled CLI (codex, forced via clis.json + reloadCliRegistry()) reads as unavailable, while an installed-and-enabled one (claude) is unaffected by the override. Verified on the Debian devbox (codeman-devbox, real tmux — this sandbox has none and WebServer's constructor hard-requires it): typecheck clean, the new test passes (17/17 in render-index-html.test.ts), the CLI-registry suites pass (86/86), and the full CI gate is green (415 test files, 7855 tests, 0 failures). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N6eadpRyqpA9PD3i139cSD
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
db4557d94b
commit
0c77dd0a18
@@ -23,8 +23,11 @@ import { isDeepSeekAvailable, isDeepSeekRunnable } from '../src/utils/deepseek-c
|
||||
import { isOmpAvailable } from '../src/utils/omp-cli-resolver.js';
|
||||
import { isCloudflaredAvailable } from '../src/utils/cloudflared-resolver.js';
|
||||
import { isGitAvailable } from '../src/git-clone.js';
|
||||
import { enabledClis } from '../src/config/cli-registry/registry.js';
|
||||
import { enabledClis, reloadCliRegistry } from '../src/config/cli-registry/registry.js';
|
||||
import { STOCK_CLIS } from '../src/config/cli-registry/stock.js';
|
||||
import { dataPath } from '../src/config/instance.js';
|
||||
import { mkdirSync, writeFileSync } from 'node:fs';
|
||||
import { dirname } from 'node:path';
|
||||
|
||||
// renderIndexHtml probes the real PATH for every CLI, which would make the
|
||||
// assertions below depend on whatever happens to be installed on the machine
|
||||
@@ -197,6 +200,31 @@ describe('WebServer.renderIndexHtml', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('reads as unavailable for a CLI disabled via the registry, even though it is installed', async () => {
|
||||
// The bug this guards: a CLI toggled off in Settings (docs/cli-enable-disable-plan.md)
|
||||
// still offered itself in the welcome screen / Run menu / mobile overview, because
|
||||
// window.__codemanCliAvailable was built purely from each resolver's own PATH probe —
|
||||
// it never consulted the registry's `enabled` flag at all. Installed AND enabled must
|
||||
// both hold for `isCliAvailable()` (the client-side gate every one of those surfaces
|
||||
// reads) to read true.
|
||||
vi.mocked(isCodexAvailable).mockReturnValue(true);
|
||||
vi.mocked(isClaudeAvailable).mockReturnValue(true);
|
||||
const path = dataPath('clis.json');
|
||||
mkdirSync(dirname(path), { recursive: true });
|
||||
writeFileSync(path, JSON.stringify({ clis: { codex: { enabled: false } } }, null, 2), { mode: 0o600 });
|
||||
reloadCliRegistry();
|
||||
try {
|
||||
const { server } = makeServer({});
|
||||
const html = await render(server);
|
||||
const flags = JSON.parse(html.match(/window\.__codemanCliAvailable=(\{.*?\});/)![1]);
|
||||
expect(flags.codex).toBe(false); // installed, but disabled in the registry
|
||||
expect(flags.claude).toBe(true); // installed and enabled — unaffected by codex's override
|
||||
} finally {
|
||||
writeFileSync(path, JSON.stringify({ clis: {} }, null, 2), { mode: 0o600 });
|
||||
reloadCliRegistry();
|
||||
}
|
||||
});
|
||||
|
||||
it('reports which run modes the custom-model Run-menu picker may generate an entry for', async () => {
|
||||
// Read generically off the CLI registry's own capabilities, not a hardcoded id
|
||||
// list — antigravity (`unsupported`) and shell (`kind !== 'agent'`) must be
|
||||
|
||||
Reference in New Issue
Block a user