969b06253c
Part B: Model Pricing, Hook Configuration and CLAUDE_HOME move from Settings → Dashboard to the Claude Code tab's AgentHub sub-tab (ClaudeAgentHubSettings.tsx); CODEX_HOME is editable in Codex → AgentHub. A home that is or contains the OS home is refused (EBADHOME). Settings persistence: dashboard-saved settings go to ~/.config/agenthub/settings.env (AGENTHUB_SETTINGS_FILE), outside the plugin cache an update wipes. Load order: real env > the checkout's .env > that file. The first CLAUDE_HOME change pins DASHBOARD_DATA_DIR so the DB stays put. C1: codex-usage.js reads Codex rollout journals into sessions (new column tool) and token_usage, tracked per file in codex_rollouts; forks deduped by total vector, sub-agent threads folded into the root; pricing-sync also prices OpenAI models; PricingSettings with a vendor filter. C2: codex-hooks.js installs AgentHub's hooks into $CODEX_HOME/hooks.json on a click, through a stable forwarder; Codex trust is never written. The hook route creates tool='codex' sessions and folds sub-agent hooks into the root. D: antigravity-usage.js reads agy's per-conversation SQLite files (tokens from ModelUsageStats) into tool='antigravity' sessions; antigravity-hooks.js installs the named hook `agenthub` (PreInvocation, PostToolUse, Stop — never PreToolUse) into ~/.gemini/config/hooks.json; Settings → Antigravity tab; Gemini pricing. Whole-change review fixes: sameOriginGuard on both home PUTs, routers.missing on a CLAUDE_HOME change, reset-pricing scope, GET /api/sessions?tool=, clear-data covering the new tables, Codex child-thread events moving no status, hooks owning status only while current, EFOREIGN for a forwarder that is not ours, agy quiet window and turn rules, AGENTHUB_SETTINGS_FILE honoured from .env. Docs, OpenAPI and the CLAUDE.md marker updated. Server 2141, client 779.
30 lines
994 B
TypeScript
30 lines
994 B
TypeScript
/**
|
|
* @file SessionToolBadge.test.tsx
|
|
* @description The session tool chip: nothing for a Claude Code session (so
|
|
* every hook row renders as before), the tool's name for a Codex one.
|
|
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
|
*/
|
|
|
|
import { render, screen } from "@testing-library/react";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import { SessionToolBadge } from "../SessionToolBadge";
|
|
|
|
vi.mock("../../lib/api", () => ({ api: { aiTools: { list: () => new Promise(() => {}) } } }));
|
|
|
|
describe("SessionToolBadge", () => {
|
|
it("renders nothing for a Claude or unset tool", () => {
|
|
const { container } = render(
|
|
<>
|
|
<SessionToolBadge tool="claude" />
|
|
<SessionToolBadge tool={undefined} />
|
|
</>
|
|
);
|
|
expect(container).toBeEmptyDOMElement();
|
|
});
|
|
|
|
it("names a Codex session's tool", () => {
|
|
render(<SessionToolBadge tool="codex" />);
|
|
expect(screen.getByText("Codex")).toHaveAttribute("title", "Recorded by Codex");
|
|
});
|
|
});
|