mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 17:30:31 +00:00
231 lines
7.2 KiB
TypeScript
231 lines
7.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { type ConfigReadResult, runtimeConfigSnapshotFromAppServerConfig } from "../../../../src/app-server/protocol/runtime-config";
|
|
import type { ModelMetadata } from "../../../../src/domain/catalog/metadata";
|
|
import type { RuntimeConfigSnapshot } from "../../../../src/domain/runtime/config";
|
|
import { createChatPanelRuntimeProjection } from "../../../../src/features/chat/panel/runtime-status-projection";
|
|
import { chatStateFixture, chatStateWith } from "../support/state";
|
|
|
|
describe("createChatPanelRuntimeProjection", () => {
|
|
it("builds slash-command runtime details from chat state", () => {
|
|
let state = chatStateFixture();
|
|
state = chatStateWith(state, { activeThread: { id: "thread-1" } });
|
|
state = chatStateWith(state, {
|
|
connection: {
|
|
runtimeConfig: runtimeConfigFixture({
|
|
model: "gpt-5.5",
|
|
model_provider: "openai",
|
|
model_reasoning_effort: "high",
|
|
service_tier: "fast",
|
|
}),
|
|
},
|
|
});
|
|
state = chatStateWith(state, { connection: { availableModels: [modelFixture("gpt-5.5")] } });
|
|
const projection = createChatPanelRuntimeProjection({
|
|
state: () => state,
|
|
connected: () => true,
|
|
configuredCommand: () => "codex",
|
|
vaultPath: () => "/vault",
|
|
nowMs: () => 0,
|
|
});
|
|
|
|
expect(projection.statusDetails()).toEqual([
|
|
{
|
|
auditFacts: [
|
|
{ key: "Thread", value: "thread-1" },
|
|
{ key: "Context", value: "0 tokens. No turns in this thread yet." },
|
|
{ key: "Usage Limits", value: "not available" },
|
|
],
|
|
},
|
|
]);
|
|
expect(projection.modelStatusDetails()).toEqual([
|
|
{
|
|
auditFacts: [
|
|
{ key: "Model", value: "gpt-5.5" },
|
|
{ key: "Override", value: "(none)" },
|
|
{ key: "Provider", value: "openai" },
|
|
{ key: "Effort", value: "high" },
|
|
{ key: "Mode", value: "Default" },
|
|
{ key: "Service tier", value: "fast" },
|
|
],
|
|
},
|
|
]);
|
|
expect(projection.effortStatusDetails()).toEqual([
|
|
{
|
|
auditFacts: [
|
|
{ key: "Effort", value: "high" },
|
|
{ key: "Override", value: "(none)" },
|
|
{ key: "Supported", value: "high" },
|
|
],
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("builds slash-command permission details from chat state", () => {
|
|
const state = chatStateWith(chatStateFixture(), {
|
|
activeThread: { id: "thread-1" },
|
|
runtime: {
|
|
active: {
|
|
activePermissionProfile: { id: "workspace-write", extends: null },
|
|
sandboxPolicy: {
|
|
type: "workspaceWrite",
|
|
writableRoots: ["/vault/Notes"],
|
|
networkAccess: false,
|
|
excludeTmpdirEnvVar: false,
|
|
excludeSlashTmp: false,
|
|
},
|
|
approvalPolicy: "on-request",
|
|
approvalsReviewer: "auto_review",
|
|
},
|
|
},
|
|
});
|
|
const projection = createChatPanelRuntimeProjection({
|
|
state: () => state,
|
|
connected: () => true,
|
|
configuredCommand: () => "codex",
|
|
vaultPath: () => "/vault",
|
|
nowMs: () => 0,
|
|
});
|
|
|
|
expect(projection.permissionDetails()).toEqual([
|
|
{
|
|
title: "Permissions",
|
|
auditFacts: [
|
|
{ key: "Profile", value: "workspace-write" },
|
|
{ key: "Sandbox", value: "workspace-write" },
|
|
{ key: "Codex network", value: "blocked" },
|
|
{ key: "Extra writable roots", value: "Vault/Notes" },
|
|
],
|
|
},
|
|
{
|
|
title: "Approvals",
|
|
auditFacts: [
|
|
{ key: "Approval policy", value: "on-request" },
|
|
{ key: "Auto review", value: "on" },
|
|
],
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("keeps pending approval reviewer out of diagnostic permission details", () => {
|
|
const state = chatStateWith(chatStateFixture(), {
|
|
activeThread: { id: "thread-1" },
|
|
connection: {
|
|
runtimeConfig: runtimeConfigFixture({
|
|
approvals_reviewer: "user",
|
|
approval_policy: "on-request",
|
|
}),
|
|
},
|
|
runtime: {
|
|
pending: {
|
|
approvalsReviewer: { kind: "set", value: "auto_review" },
|
|
},
|
|
},
|
|
});
|
|
const projection = createChatPanelRuntimeProjection({
|
|
state: () => state,
|
|
connected: () => true,
|
|
configuredCommand: () => "codex",
|
|
vaultPath: () => "/vault",
|
|
nowMs: () => 0,
|
|
});
|
|
|
|
expect(projection.permissionDetails()).toEqual([
|
|
{
|
|
title: "Permissions",
|
|
auditFacts: [
|
|
{ key: "Profile", value: "(not reported)" },
|
|
{ key: "Sandbox", value: "(not reported)" },
|
|
{ key: "Codex network", value: "(not reported)" },
|
|
{ key: "Extra writable roots", value: "(not reported)" },
|
|
],
|
|
},
|
|
{
|
|
title: "Approvals",
|
|
auditFacts: [
|
|
{ key: "Approval policy", value: "on-request" },
|
|
{ key: "Auto review", value: "off" },
|
|
],
|
|
},
|
|
]);
|
|
});
|
|
|
|
it("shows pending permission profile reservations in an empty panel", () => {
|
|
const state = chatStateWith(chatStateFixture(), {
|
|
runtime: {
|
|
pending: {
|
|
permissionProfile: { kind: "set", value: ":workspace" },
|
|
},
|
|
},
|
|
});
|
|
const projection = createChatPanelRuntimeProjection({
|
|
state: () => state,
|
|
connected: () => true,
|
|
configuredCommand: () => "codex",
|
|
vaultPath: () => "/vault",
|
|
nowMs: () => 0,
|
|
});
|
|
|
|
expect(projection.permissionDetails()[0]?.auditFacts).toEqual([
|
|
{ key: "Profile", value: ":workspace" },
|
|
{ key: "Sandbox", value: "(not reported)" },
|
|
{ key: "Codex network", value: "(not reported)" },
|
|
{ key: "Extra writable roots", value: "(not reported)" },
|
|
]);
|
|
});
|
|
|
|
it("does not report legacy sandbox details for configured permission profiles in an empty panel", () => {
|
|
const state = chatStateWith(chatStateFixture(), {
|
|
connection: {
|
|
runtimeConfig: runtimeConfigFixture({
|
|
default_permissions: "DevProfile",
|
|
sandbox_mode: "workspace-write",
|
|
sandbox_workspace_write: {
|
|
writable_roots: ["/vault"],
|
|
network_access: false,
|
|
exclude_tmpdir_env_var: false,
|
|
exclude_slash_tmp: false,
|
|
},
|
|
}),
|
|
},
|
|
});
|
|
const projection = createChatPanelRuntimeProjection({
|
|
state: () => state,
|
|
connected: () => true,
|
|
configuredCommand: () => "codex",
|
|
vaultPath: () => "/vault",
|
|
nowMs: () => 0,
|
|
});
|
|
|
|
expect(projection.permissionDetails()[0]?.auditFacts).toEqual([
|
|
{ key: "Profile", value: "DevProfile" },
|
|
{ key: "Sandbox", value: "(not reported)" },
|
|
{ key: "Codex network", value: "(not reported)" },
|
|
{ key: "Extra writable roots", value: "(not reported)" },
|
|
]);
|
|
});
|
|
});
|
|
|
|
function runtimeConfigFixture(config: Record<string, unknown>): RuntimeConfigSnapshot {
|
|
return runtimeConfigSnapshotFromAppServerConfig({
|
|
config: config as ConfigReadResult["config"],
|
|
origins: {},
|
|
layers: null,
|
|
});
|
|
}
|
|
|
|
function modelFixture(model: string): ModelMetadata {
|
|
return {
|
|
id: model,
|
|
model,
|
|
displayName: model,
|
|
description: "",
|
|
hidden: false,
|
|
supportedReasoningEfforts: ["high"],
|
|
defaultReasoningEffort: "high",
|
|
inputModalities: [],
|
|
serviceTiers: [],
|
|
defaultServiceTier: null,
|
|
isDefault: true,
|
|
};
|
|
}
|