Add read-only runtime inventory settings (#130)

* add gated codex goals support

* sync README SDK versions

* bump claude agent sdk

* add codex goals settings toggle

* reuse status dashboard message and simplify settings actions

* refine settings page UX

* fix settings nav hash routing

* add dashboard UX verification

* refine dashboard settings and inbox UX

* remove inbox top-level navigation

* remove dashboard health top-level navigation

* fix: allow runtime image attachment paths

* feat: configure attachment allowlist dirs

* fix: clean duplicate dashboard status messages

* fix: poll dashboard duplicate cleanup between status updates

* fix: delete dashboard duplicates on create

* Refine settings IA with tabbed sections

* Add read-only runtime inventory settings
This commit is contained in:
Eyejoker
2026-05-04 02:13:42 +09:00
committed by GitHub
parent c7d4bf82d7
commit 2da6052eff
11 changed files with 890 additions and 1 deletions

View File

@@ -11,6 +11,7 @@ import type {
FastModeSnapshot,
ModelConfigSnapshot,
} from './settings-store.js';
import type { RuntimeInventorySnapshot } from './runtime-inventory.js';
import type { MoaSettingsSnapshot } from './settings-store-moa.js';
function jsonResponse(value: unknown, init?: ResponseInit): Response {
@@ -44,6 +45,88 @@ const modelConfig: ModelConfigSnapshot = {
const fastMode: FastModeSnapshot = { codex: true, claude: false };
const codexFeatures: CodexFeatureSnapshot = { goals: false };
const runtimeInventory: RuntimeInventorySnapshot = {
generatedAt: '2026-05-04T00:00:00.000Z',
projectRoot: '/repo',
dataDir: '/repo/data',
service: {
id: 'codex-main',
sessionScope: 'codex-main',
agentType: 'codex',
},
codex: {
configFiles: [
{
label: 'Codex config.toml',
path: '/home/.codex/config.toml',
exists: true,
},
],
skillDirs: [
{
label: 'Codex user skills',
path: '/home/.agents/skills',
exists: true,
count: 1,
skills: [
{
name: 'agent-browser',
description: 'Browser automation',
path: '/home/.agents/skills/agent-browser',
},
],
},
],
mcp: {
configPath: {
label: 'Codex config.toml',
path: '/home/.codex/config.toml',
exists: true,
},
ejclawConfigured: true,
serverCount: 1,
},
},
claude: {
configFiles: [
{
label: 'Claude settings.json',
path: '/home/.claude/settings.json',
exists: true,
},
],
skillDirs: [],
mcp: {
configPath: {
label: 'Claude settings.json',
path: '/home/.claude/settings.json',
exists: true,
},
ejclawConfigured: false,
serverCount: 0,
},
},
ejclaw: {
runnerSkillDir: {
label: 'EJClaw runner skills',
path: '/repo/runners/skills',
exists: true,
count: 1,
skills: [
{
name: 'agent-browser',
description: 'Browser automation',
path: '/repo/runners/skills/agent-browser',
},
],
},
mcpServer: {
label: 'EJClaw IPC MCP server',
path: '/repo/runners/agent-runner/dist/ipc-mcp-stdio.js',
exists: true,
},
},
};
const moaSettings: MoaSettingsSnapshot = {
enabled: true,
@@ -113,6 +196,7 @@ function makeDeps(
getFastMode: () => fastMode,
getModelConfig: () => modelConfig,
getMoaSettings: () => moaSettings,
getRuntimeInventory: () => runtimeInventory,
listClaudeAccounts: () => [makeClaudeAccount()],
listCodexAccounts: () => [makeCodexAccount()],
refreshAllCodexAccounts: async () => ({ refreshed: [1], failed: [] }),
@@ -159,6 +243,14 @@ describe('web dashboard settings routes', () => {
expect(mode?.status).toBe(200);
await expect(mode?.json()).resolves.toEqual(fastMode);
const inventory = await route('/api/settings/runtime-inventory');
expect(inventory?.status).toBe(200);
await expect(inventory?.json()).resolves.toMatchObject({
service: { id: 'codex-main', agentType: 'codex' },
codex: { mcp: { ejclawConfigured: true } },
ejclaw: { runnerSkillDir: { count: 1 } },
});
const features = await route('/api/settings/codex-features');
expect(features?.status).toBe(200);
await expect(features?.json()).resolves.toEqual(codexFeatures);