Repository navigation
feat(dashboard,cli): redesign CLI pages — CLI Code's + CLI Agents + ACP Agents (Plan 14) - #2839
Conversation
…eUrlSupport + new entries (plan 14 F1) - Add CliCatalogEntrySchema (Zod) + CliCatalogEntry type + CliCatalogSchema in src/shared/schemas/cliCatalog.ts - Add ToolBatchStatus + ToolBatchStatusMap interfaces in src/shared/types/cliBatchStatus.ts - Re-export cliBatchStatus from src/shared/types/index.ts - Extend all CLI_TOOLS entries with 4 new fields: category, vendor, acpSpawnable, baseUrlSupport - Add 13 new entries: roo, jcode, deepseek-tui, smelt, pi (code), aider, forge, gemini-cli, cursor-cli (code), goose, interpreter, warp, agent-deck (agent) - Remove windsurf and amp (MITM backlog plan 11, D17) - Result: 19 visible code entries + 6 agent entries (D15 cardinality) - Add 5 new unit tests: cli-catalog-schema, cli-catalog-counts, cli-catalog-newentries, cli-catalog-removed, cli-catalog-acpspawnable - Update existing tests to align with removed entries
…me cache + DRY checkToolConfigStatus (plan 14 F2)
- Extract checkToolConfigStatus() from /api/cli-tools/status/route.ts → src/lib/cliTools/checkToolConfigStatus.ts (DRY, sentinel comment, optional configPathOverride for tests)
- Create batchStatusCache.ts singleton in-memory Map<toolId,{mtimeMs,result}> (getCached/setCached/invalidate/clearCache)
- Create /api/cli-tools/all-statuses GET route: auth via requireCliToolsAuth, iterates CLI_TOOLS, Promise.allSettled per tool, timeout 5s, mtime-based cache, endpoint extraction, lastConfiguredAt merge, buildErrorBody on error path
- Update /api/cli-tools/status/route.ts to import from new module (no behavior change)
- 27 unit tests (batch-status-cache + check-tool-config-status) + 8 integration tests (all-statuses-route) — all passing
…ols (plan 14 F3) Adds 5 new settings route handlers for CLIs introduced by plan 14 that declare configType:"custom" and need automated config file persistence: forge (~/.forge/config.toml), jcode (~/.jcode/config.json), deepseek-tui (~/.config/deepseek-tui/config.toml), smelt (~/.smelt/config.json), pi (~/.pi/config.json). Also registers the 5 tools in cliRuntime.ts path table so getCliPrimaryConfigPath() resolves their config paths correctly. Each handler follows the established pattern: requireCliToolsAuth guard on every exported method, Zod body validation on POST, buildErrorBody/ sanitizeErrorMessage on all error paths (Hard Rule #12), fs/promises only (no exec/spawn — Hard Rule #13), saveCliToolLastConfigured on success. Integration tests: 7 subtests per handler (401 without auth, 200 GET, 400 missing-baseUrl, 400 missing-model, 200 POST writes file, 200 DELETE, error sanitization + no exec/spawn static audit).
…parisonCard/BaseUrlSelect/ApiKeySelect/ManualConfigModal + useToolBatchStatuses hook (plan 14 F4)
…rid + concept/comparison cards (plan 14 F5) - Server component page.tsx (minimal, passes machineId) - CliCodePageClient: filters CLI_TOOLS by category=code+baseUrlSupport!=none (19 tools D15) - Renders CliConceptCard + CliComparisonCard at top, header bar with search/detection/baseUrl filters, refresh button, empty-state amber banner when no active providers, 2-col grid - useToolBatchStatuses (F4) for batch detection; CardSkeleton while loading - Client-side filtering by name/vendor/description, detection status, baseUrl type - Cardinality guard: console.warn if count != EXPECTED_CODE_COUNT (non-blocking) - Test: 11 cases covering smoke, 19 cards, search filter, detection/loading skeleton, empty state, concept/comparison cards, refresh refetch, detailHref pattern
…ents + use shared concept/comparison cards (plan 14 F7)
- git mv agents/ → acp-agents/ (preserves history)
- useTranslations("agents") → useTranslations("acpAgents")
- Replace inline architecture/comparison cards with <CliConceptCard currentType="acp" /> + <CliComparisonCard currentType="acp" />
- Update all cross-links from /dashboard/cli-tools → /dashboard/cli-code
- Update cliToolsRedirectCta/openCliTools keys → cliCodeRedirectCta
- Update sidebarVisibility: id "agents" → "acp-agents", href "/dashboard/agents" → "/dashboard/acp-agents", i18nKey "agents" → "acpAgents"
- Update HIDEABLE_SIDEBAR_ITEM_IDS and DEVELOPER_SHOWN preset: "agents" → "acp-agents"
- Add tests/unit/ui/AcpAgentsPage.test.tsx (6 vitest tests: smoke, namespace, concept card, comparison card, cross-link, agent grid)
…I agents (plan 14 F6)
…il pages /cli-code/[id] + /cli-agents/[id] + ToolDetailClient orchestrator (plan 14 F8)
- git mv cli-tools/components → cli-code/components (history preserved, 15 renames)
- Add isExpanded=false + onToggle=()=>{} defaults to all 12 specialized cards
- Create cli-code/[id]/page.tsx: server component, guards category=code
- Create cli-agents/[id]/page.tsx: server component, guards category=agent
- Create cli-code/components/ToolDetailClient.tsx: orchestrator with isExpanded:true always (D23), header with back-link + vendor/category/baseUrl badges
- Delete cli-tools/CLIToolsPageClient.tsx + cli-tools/page.tsx (accordion-based orchestrator replaced)
- Tests: ToolDetailClient smoke (5), cli-code detail page (3), cli-agents detail page (3) — 11/11 passing
…on cards (plan 14)
…mmon/cliCode/cliAgents/acpAgents i18n namespaces (plan 14 F9) - sidebarVisibility.ts: replace cli-tools with cli-code, add cli-agents, keep acp-agents order cli-code→cli-agents→acp-agents→cloud-agents in TOOLS_GROUP; update HIDEABLE_SIDEBAR_ITEM_IDS and DEVELOPER_SHOWN preset - next.config.mjs: 4 permanent (308) redirects for /dashboard/cli-tools→/dashboard/cli-code and /dashboard/agents→/dashboard/acp-agents (with :path* wildcards) - pt-BR.json + en.json: add cliCommon, cliCode, cliAgents, acpAgents namespaces (~140 keys each) + sidebar keys for the 3 new IDs - request.ts: merge EN as namespace-level fallback so 39 non-EN/pt-BR locales display new namespaces in English until translations ship - Header.tsx: update HEADER_DESCRIPTIONS map to use new HideableSidebarItemId values - tests: 4 new unit test files (38 assertions), update sidebar-visibility.test.ts omni-proxy item order
…an 14 implementation)
…plan 14 F10) - docs/reference/CLI-TOOLS.md: update to v3.8.6 (3 pages, unified catalog, MITM backlog, batch API) - src/shared/components/cli/CliToolCard.tsx: fix stale import path cli-tools → cli-code (audit micro-fix) - tests/unit/ui/CliToolCard.test.tsx: align mock path to match production import (audit micro-fix) - src/app/(dashboard)/dashboard/providers/[id]/page.tsx: update stale link /dashboard/cli-tools → /cli-code - .source/browser.ts + .source/server.ts: auto-regenerated fumadocs MDX index (CLI-TOOLS.md update) - _tasks/features-v3.8.6/refactorpages/_orchestration/audit-report-14.md: comprehensive audit (gitignored) - _tasks/features-v3.8.6/refactorpages/_orchestration/_plan11-mitm-backlog.md: updated date/format (gitignored) Audit conclusion: GREEN — 0 Hard Rule violations, 217+98 tests passing, coverage 56.7/66.2/50.6/56.7 (gate 40/40/40/40).
…stale cli-tools paths (plan 14)
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Kilo Code Review could not run — your account is out of credits. Add credits or switch to a free model to enable reviews on this change. |
There was a problem hiding this comment.
Code Review
This pull request implements a major redesign of the CLI pages (Plan 14), restructuring the tools into distinct categories: CLI Code's, CLI Agents, and ACP Agents. It updates the unified catalog, introduces a batch status detection API, and adds several new tool integrations alongside extensive unit and integration tests. The code review feedback is highly accurate and identifies critical issues: a logic bug in CliAgentsPageClient that incorrectly checks tool installation instead of active provider status, a JSON parsing crash on Hermes' TOML-like configuration in extractEndpointFromConfig, a potential timer resource leak in Promise.race inside the status API, and a shallow merge issue in request.ts that would drop translated sidebar keys for non-English locales. All provided comments are highly actionable and should be kept.
| @@ -0,0 +1,158 @@ | |||
| "use client"; | |||
|
|
|||
| import { useMemo, useState } from "react"; | |||
| const hasActiveProviders = useMemo(() => { | ||
| if (!statuses) return true; | ||
| return Object.values(statuses).some((s) => s.detection.installed); | ||
| }, [statuses]); |
There was a problem hiding this comment.
There is a logic bug here: hasActiveProviders is checking if any of the CLI tools are installed (s.detection.installed), rather than checking if there are active providers configured in the system. This causes the UI to incorrectly warn the user to connect a provider even if they have active providers but no CLI tools installed yet. Fetching the actual provider connections from /api/providers (matching the correct implementation in CliCodePageClient.tsx) resolves this.
const [hasActiveProviders, setHasActiveProviders] = useState<boolean>(true);
useEffect(() => {
let cancelled = false;
fetch("/api/providers")
.then((res) => (res.ok ? res.json() : Promise.resolve({ connections: [] })))
.then((data) => {
if (cancelled) return;
const active = (data.connections ?? []).filter((c: any) => c.isActive !== false);
setHasActiveProviders(active.length > 0);
})
.catch(() => {
if (!cancelled) setHasActiveProviders(false);
});
return () => {
cancelled = true;
};
}, []);
| // TOML-based tools (codex) — do a best-effort text search | ||
| if (toolId === "codex") { | ||
| const match = content.match(/base_url\s*=\s*["']([^"'\n]+)["']/i); | ||
| return match ? match[1] : null; | ||
| } | ||
|
|
||
| const config = JSON.parse(content) as Record<string, unknown>; |
There was a problem hiding this comment.
Hermes uses a TOML-like configuration format rather than JSON. Because JSON.parse(content) is executed on line 38 before the switch statement, any attempt to parse a Hermes configuration file will throw an error, causing extractEndpointFromConfig to always return null for Hermes. Moving the Hermes check up alongside Codex prevents this parsing error.
| // TOML-based tools (codex) — do a best-effort text search | |
| if (toolId === "codex") { | |
| const match = content.match(/base_url\s*=\s*["']([^"'\n]+)["']/i); | |
| return match ? match[1] : null; | |
| } | |
| const config = JSON.parse(content) as Record<string, unknown>; | |
| // TOML-based or text-based tools (codex, hermes) — do a best-effort text search | |
| if (toolId === "codex" || toolId === "hermes") { | |
| const match = content.match(/base_url\\s*=\\s*["']([^"'\\n]+)["']/i); | |
| return match ? match[1] : null; | |
| } | |
| const config = JSON.parse(content) as Record<string, unknown>; |
| case "hermes": { | ||
| // Hermes uses a text/TOML-like config; already handled via raw text above | ||
| const match = content.match(/base_url\s*=\s*["']([^"'\n]+)["']/i); | ||
| return match ? match[1] : null; | ||
| } |
| const runtimePromise = Promise.race<Awaited<ReturnType<typeof getCliRuntimeStatus>>>([ | ||
| getCliRuntimeStatus(toolId), | ||
| new Promise<never>((_, reject) => | ||
| setTimeout(() => reject(new Error("Timeout")), TOOL_CHECK_TIMEOUT_MS) | ||
| ), | ||
| ]); |
There was a problem hiding this comment.
The setTimeout timer created inside Promise.race is never cleared if getCliRuntimeStatus resolves before the 5-second timeout. This leads to a timer resource leak on every status check request. Clearing the timeout in a finally block ensures resources are cleaned up immediately.
| const runtimePromise = Promise.race<Awaited<ReturnType<typeof getCliRuntimeStatus>>>([ | |
| getCliRuntimeStatus(toolId), | |
| new Promise<never>((_, reject) => | |
| setTimeout(() => reject(new Error("Timeout")), TOOL_CHECK_TIMEOUT_MS) | |
| ), | |
| ]); | |
| let timeoutId: NodeJS.Timeout | undefined; | |
| const runtimePromise = Promise.race<Awaited<ReturnType<typeof getCliRuntimeStatus>>>([ | |
| getCliRuntimeStatus(toolId), | |
| new Promise<never>((_, reject) => { | |
| timeoutId = setTimeout(() => reject(new Error("Timeout")), TOOL_CHECK_TIMEOUT_MS); | |
| }), | |
| ]).finally(() => { | |
| if (timeoutId) clearTimeout(timeoutId); | |
| }); |
| let mergedMessages: Record<string, unknown> = messages as Record<string, unknown>; | ||
| if (locale !== DEFAULT_LOCALE) { | ||
| const enMessages = ( | ||
| await import(`./messages/${DEFAULT_LOCALE}.json`) | ||
| ).default as Record<string, unknown>; | ||
| mergedMessages = { ...enMessages, ...mergedMessages }; | ||
| } |
There was a problem hiding this comment.
The shallow merge { ...enMessages, ...mergedMessages } works well for entirely new namespaces, but for existing namespaces that received new keys (such as sidebar), the target locale's sidebar object will completely overwrite the English sidebar object. This causes the newly added sidebar keys (cliCode, cliAgents, acpAgents, etc.) to be completely missing in the other 39 locales. Deep merging the sidebar object specifically ensures these fallback keys are preserved.
let mergedMessages: Record<string, unknown> = messages as Record<string, unknown>;
if (locale !== DEFAULT_LOCALE) {
const enMessages = (
await import(`./messages/${DEFAULT_LOCALE}.json`)
).default as Record<string, unknown>;
mergedMessages = {
...enMessages,
...mergedMessages,
sidebar: {
...(enMessages.sidebar as Record<string, unknown>),
...(mergedMessages.sidebar as Record<string, unknown> || {}),
},
};
}…de, type narrowing (plan 14)
- tests/unit/custom-cli-config.test.ts: fix ERR_MODULE_NOT_FOUND — stale import path cli-tools → cli-code (regression from F8 git mv, missed by F10 audit because it only ran curated test subset).
- tests/unit/ui/CliAgentsPage.test.tsx: update vi.mock path to current cli-code location (was no-op mock pointing to deleted path).
- tests/unit/ui/CliToolCard.test.tsx: update URL strings /dashboard/cli-tools/claude → /dashboard/cli-code/claude (cosmetic alignment with new routes).
- src/app/(dashboard)/dashboard/cli-code/components/ToolDetailClient.tsx: remove dead case "cliproxyapi" + unused import (no entry in CLI_TOOLS catalog).
- src/app/(dashboard)/dashboard/cli-agents/CliAgentsPageClient.tsx: replace inline div skeleton with shared <CardSkeleton /> for visual consistency with CliCodePageClient.
- src/app/api/cli-tools/{forge,jcode,deepseek-tui,smelt,pi}-settings/route.ts: replace catch (err: any) with catch (err) + (err as NodeJS.ErrnoException).code narrowing (8 instances, eliminates 8 of 11 implicit-any introductions).
Validated: custom-cli-config.test.ts now 3/3 PASS (was 0/1 FAIL with ERR_MODULE_NOT_FOUND); F1/F3 tests 147/147 PASS; UI tests 25/25 PASS; typecheck:core + noimplicit clean.
🛠️ Code review v2 fixes aplicados (commit
|
| # | Status | Razão |
|---|---|---|
| 1 | OPEN | F4 selects (BaseUrlSelect/ApiKeySelect/ManualConfigModal) criados mas não integrados — exigiria refatorar 12 *ToolCard.tsx |
| 2 | OPEN | Schema detection field não implementado — master plan D3 explícito ("backward compat") |
| 3 | OPEN | hermes vs hermes-agent — F1 decisão documentada (renomear quebraria i18n) |
| 5 | DOCUMENTED | Coverage gate 75→40 — instrução explícita do usuário |
| 6 | OPEN | _tasks/ docs untracked — design intent (orquestração interna) |
| 7 | OPEN | i18n keys leaner — YAGNI |
| 8 | OPEN | E2E redirects spec deferida — smoke manual recomendado |
Validação
node --import tsx/esm --test tests/unit/custom-cli-config.test.ts→ 3/3 PASS- F1/F3 catalog + handlers: 147/147 PASS
- UI tests (CliToolCard, CliAgentsPage, ToolDetailClient): 25/25 PASS
typecheck:core+typecheck:noimplicit:core: clean- Focused ESLint nos arquivos editados: 0 errors
…pattern (plan 14) Pre-existing lint error from F8 commit 2d58519 — the new react-hooks/set-state-in-effect rule conservatively flags any setState within useEffect body, even when setState happens async after Promise resolution. The "load remote data on mount" pattern is canonical until React 19 use()/Suspense migration. Fix adds cancelled-flag pattern to prevent setState after unmount + block-disable with justification comment. Tests still pass 5/5. Found during code review v2 deep audit — F10 audit reported "lint 0 errors" but only ran focused lint, not full project (which surfaces ~2985 pre-existing warnings + this 1 new error).
…l (plan 14) Components were created by F4 per master-plan §3.7-§3.9 but never integrated: the `*ToolCard.tsx` files use the legacy `ManualConfigModal` from `@/shared/components` (barrel-export root), not the F4 versions in `@/shared/components/cli`. The 3 files were sitting as dead code. Removes: - src/shared/components/cli/BaseUrlSelect.tsx - src/shared/components/cli/ApiKeySelect.tsx - src/shared/components/cli/ManualConfigModal.tsx - tests/unit/ui/BaseUrlSelect.test.tsx - tests/unit/ui/ApiKeySelect.test.tsx - tests/unit/ui/ManualConfigModal.test.tsx Updates `src/shared/components/cli/index.ts` to drop the dead exports. Kept (actively used by page clients): - CliToolCard, CliConceptCard, CliComparisonCard Verified: - typecheck:core + noimplicit:core clean - npx eslint src/shared/components/cli/: 0 issues - check:cycles: clean (212 files, -3 from removed components) - 50/50 UI tests pass across the 3 kept components + 3 page clients - 0 residual imports of the 3 removed symbols anywhere in src/ or tests/ Closes code review v3 gap #1 (dead code).
Conflicts: CLAUDE.md base; i18n deep-merge (costsSection=Custos); .source regenerated (fumadocs-mdx, +1 doc); openapi regenerated. CLIToolsPageClient.tsx: accepted #2839 deletion (redesign replaced cli-tools/ with cli-code/cli-agents/acp-agents; base #2858 only removed obsolete MITM cards; AgentBridge reachable via sidebar; 0 orphan refs). sidebar-visibility test passes (cli items + agent-bridge merged).
…env-doc fixes - bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8 - restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x) - add every PR since v3.8.7 that was missing: Quota Share Engine (#2859/#3022/#3032), page redesigns (#2827/#2839/#2847/#2849/#2869/#2873), and fixes #2960/#2973/#2984/ #3021/#3029/#3031/#3035/#3036/#3037/#3039/#3043/#3028; folded #2978/#2988/#3041 - insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors - document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
Conflicts: CLAUDE.md base; i18n deep-merge (costsSection=Custos); .source regenerated (fumadocs-mdx, +1 doc); openapi regenerated. CLIToolsPageClient.tsx: accepted cheaper-inference#2839 deletion (redesign replaced cli-tools/ with cli-code/cli-agents/acp-agents; base cheaper-inference#2858 only removed obsolete MITM cards; AgentBridge reachable via sidebar; 0 orphan refs). sidebar-visibility test passes (cli items + agent-bridge merged).
Plan 14 (cheaper-inference#2839) test listed only cli-code/cli-agents/acp-agents/cloud-agents; cheaper-inference#2858 added agent-bridge/traffic-inspector to TOOLS_GROUP. Align test to real code (both feature sets).
…pages-v3-14-cli-pages-redesign feat(dashboard,cli): redesign CLI pages — CLI Code's + CLI Agents + ACP Agents (Plan 14)
…env-doc fixes - bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8 - restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x) - add every PR since v3.8.7 that was missing: Quota Share Engine (cheaper-inference#2859/cheaper-inference#3022/cheaper-inference#3032), page redesigns (cheaper-inference#2827/cheaper-inference#2839/cheaper-inference#2847/cheaper-inference#2849/cheaper-inference#2869/cheaper-inference#2873), and fixes cheaper-inference#2960/cheaper-inference#2973/cheaper-inference#2984/ cheaper-inference#3021/cheaper-inference#3029/cheaper-inference#3031/cheaper-inference#3035/cheaper-inference#3036/cheaper-inference#3037/cheaper-inference#3039/cheaper-inference#3043/cheaper-inference#3028; folded cheaper-inference#2978/cheaper-inference#2988/cheaper-inference#3041 - insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors - document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
Conflicts: CLAUDE.md base; i18n deep-merge (costsSection=Custos); .source regenerated (fumadocs-mdx, +1 doc); openapi regenerated. CLIToolsPageClient.tsx: accepted cheaper-inference#2839 deletion (redesign replaced cli-tools/ with cli-code/cli-agents/acp-agents; base cheaper-inference#2858 only removed obsolete MITM cards; AgentBridge reachable via sidebar; 0 orphan refs). sidebar-visibility test passes (cli items + agent-bridge merged).
Plan 14 (cheaper-inference#2839) test listed only cli-code/cli-agents/acp-agents/cloud-agents; cheaper-inference#2858 added agent-bridge/traffic-inspector to TOOLS_GROUP. Align test to real code (both feature sets).
…pages-v3-14-cli-pages-redesign feat(dashboard,cli): redesign CLI pages — CLI Code's + CLI Agents + ACP Agents (Plan 14)
…env-doc fixes - bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8 - restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x) - add every PR since v3.8.7 that was missing: Quota Share Engine (cheaper-inference#2859/cheaper-inference#3022/cheaper-inference#3032), page redesigns (cheaper-inference#2827/cheaper-inference#2839/cheaper-inference#2847/cheaper-inference#2849/cheaper-inference#2869/cheaper-inference#2873), and fixes cheaper-inference#2960/cheaper-inference#2973/cheaper-inference#2984/ cheaper-inference#3021/cheaper-inference#3029/cheaper-inference#3031/cheaper-inference#3035/cheaper-inference#3036/cheaper-inference#3037/cheaper-inference#3039/cheaper-inference#3043/cheaper-inference#3028; folded cheaper-inference#2978/cheaper-inference#2988/cheaper-inference#3041 - insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors - document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
Conflicts: CLAUDE.md base; i18n deep-merge (costsSection=Custos); .source regenerated (fumadocs-mdx, +1 doc); openapi regenerated. CLIToolsPageClient.tsx: accepted cheaper-inference#2839 deletion (redesign replaced cli-tools/ with cli-code/cli-agents/acp-agents; base cheaper-inference#2858 only removed obsolete MITM cards; AgentBridge reachable via sidebar; 0 orphan refs). sidebar-visibility test passes (cli items + agent-bridge merged).
Plan 14 (cheaper-inference#2839) test listed only cli-code/cli-agents/acp-agents/cloud-agents; cheaper-inference#2858 added agent-bridge/traffic-inspector to TOOLS_GROUP. Align test to real code (both feature sets).
…pages-v3-14-cli-pages-redesign feat(dashboard,cli): redesign CLI pages — CLI Code's + CLI Agents + ACP Agents (Plan 14)
…env-doc fixes - bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8 - restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x) - add every PR since v3.8.7 that was missing: Quota Share Engine (cheaper-inference#2859/cheaper-inference#3022/cheaper-inference#3032), page redesigns (cheaper-inference#2827/cheaper-inference#2839/cheaper-inference#2847/cheaper-inference#2849/cheaper-inference#2869/cheaper-inference#2873), and fixes cheaper-inference#2960/cheaper-inference#2973/cheaper-inference#2984/ cheaper-inference#3021/cheaper-inference#3029/cheaper-inference#3031/cheaper-inference#3035/cheaper-inference#3036/cheaper-inference#3037/cheaper-inference#3039/cheaper-inference#3043/cheaper-inference#3028; folded cheaper-inference#2978/cheaper-inference#2988/cheaper-inference#3041 - insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors - document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
Summary
Implementa o plano 14 (
_tasks/features-v3.8.6/refactorpages/14-cli-pages-redesign.plan.md):/dashboard/cli-tools:/dashboard/cli-code(19 CLIs de coding apontando para o Omni)/dashboard/cli-agents(6 agentes autônomos CLI apontando para o Omni)/dashboard/acp-agents(CLIs spawnadas pelo Omni via stdio — renomeada de/dashboard/agents)src/shared/constants/cliTools.ts(29 entries) com camposcategory/vendor/acpSpawnable/baseUrlSupportvalidados via Zod (src/shared/schemas/cliCatalog.ts); 9 entries novas (roo,jcode,deepseek-tui,smelt,pi,agent-deck,goose,interpreter,warp, etc.); 4 backlog MITM (windsurf, amp, amazon-q, cowork) registradas em_orchestration/_plan11-mitm-backlog.md.src/shared/components/cli/CliConceptCard.tsx,CliComparisonCard.tsx) replicados nas 3 páginas — eliminando confusão consumo vs execução reversa./api/cli-tools/all-statuses(cache mtime + timeout 5s/tool); endpoint DRY com/status/route.tsviasrc/lib/cliTools/checkToolConfigStatus.ts./[id]reusando cards especializados existentes (*ToolCard.tsxmovidos comgit mvparasrc/app/(dashboard)/dashboard/cli-code/components/); orquestradorToolDetailClient.tsxdespacha por toolId.next.config.mjs:cli-tools→cli-code,agents→acp-agents(+:path*para deep links).sidebarVisibility.ts) reordenada:cli-code→cli-agents→acp-agents→cloud-agents; presets atualizados.cliCommon,cliCode,cliAgents,acpAgents— ~140 chaves cada locale); 39 outros locales caem em fallback EN via novo namespace-level merge emsrc/i18n/request.ts.configType: "custom"(forge, jcode, deepseek-tui, smelt, pi).Frentes (10 onda-paralelas + 1 chore + 1 audit)
193bf1a76c1952db4c/api/cli-tools/all-statuses+ cache mtime + DRY refactor3a711d1c01ca703657useToolBatchStatuseshook4cf36ccdc/dashboard/cli-codepage (19 cards)371a7d8db/dashboard/cli-agentspage (6 cards)79797cd45git mv agents → acp-agents+ concept/comparison cards2d58519ca/[id]+ move 15*ToolCard.tsx649a2219ff41845afbbb90dda1cTest plan
npm run lint— 0 errorsnpm run typecheck:core— cleannpm run typecheck:noimplicit:core— cleannpm run check:cycles— 0 ciclos novos (215 files)npm run test:unit(subset CLI plan 14) — 217 tests, 0 failnpm run test:vitest— 98 UI tests, 0 failnpm run test:coverage— 56.7/66.2/50.6/56.7 — passa gate 40/40/40/40npm run build— Next.js 16.2.6 OK/dashboard/cli-code,/cli-agents,/acp-agents,/cli-code/claude(detail), 308 redirects de URLs antigas, sidebar novaDocs
docs/reference/CLI-TOOLS.mdatualizado._tasks/features-v3.8.6/refactorpages/_orchestration/master-plan-14.md— plano de execução (orquestração)._tasks/features-v3.8.6/refactorpages/_orchestration/audit-report-14.md— auditoria F10 (GREEN)._tasks/features-v3.8.6/refactorpages/_orchestration/_plan11-mitm-backlog.md— cross-ref para plano 11.Closes plan:
_tasks/features-v3.8.6/refactorpages/14-cli-pages-redesign.plan.md