feat(ui): AI Tools modal, one-button lane tool picker, AgentHub settings in Overview, markdown preview

- AI Tools moves from a Settings section into a modal behind a button at the
  Settings tab bar's right edge (AiToolsModal, `actions` on PageTabs,
  /settings#ai-tools); rows get an enable switch, Default badge, and an
  Update button for every tool whose catalog names an updater (no version
  lookup on open); not-installed tools fold behind a disclosure, a finished
  job's log folds to one line; shared AiToolIcon
- codex updates through its own `codex update`, openclaw/hermes gain
  `update --yes`; update-all runs every installed updater and skips an npm
  one only when npm does not manage the binary
- Add-lane tool picker is one button showing the chosen tool that opens the
  enabled tools as buttons
- Claude Code / Codex AgentHub sub-tab folded into Overview (home editor,
  hooks, pricing); the path list drops CLAUDE_HOME/CODEX_HOME;
  HomeDirSetting shows the saved value only while the field differs
- Preview/Raw toggle for markdown files in the config FileViewer and the
  Changes panel's whole-file view (MarkdownPreview: react-markdown +
  remark-gfm, raw HTML never run, frontmatter as a code block)
- docs and the CLAUDE.md marker updated
This commit is contained in:
2026-10-01 10:11:43 +07:00
parent 058c574138
commit c5aba094bd
55 changed files with 2985 additions and 853 deletions
@@ -1,8 +1,9 @@
/**
* @file HomeDirSetting.tsx
* @description One editable home directory (CLAUDE_HOME in Claude Code →
* AgentHub, CODEX_HOME in Codex → AgentHub): a path field with Save, the
* server's refusal inline, the value in effect, and a warning when the real
* Overview, CODEX_HOME in Codex → Overview): a path field with Save, the
* server's refusal inline, the saved value while the field differs from it,
* and a warning when the real
* environment sets the variable (the environment wins at the next start, so a
* saved value would not survive a restart). The server validates and persists;
* this component only loads, submits and reports.
@@ -105,7 +106,8 @@ export function HomeDirSetting({ id, title, description, note, placeholder, load
</button>
</div>
{error && <p className="text-xs text-status-danger">{error}</p>}
{current && (
{/* The saved value, only while the field says something else. */}
{current && input !== current.value && (
<p className="text-xs text-fg-muted">
{t("homeDir.current")} <code className="text-fg-secondary">{current.value}</code>
</p>