1627 lines
45 KiB
JavaScript
1627 lines
45 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
import readline from "node:readline";
|
||
|
||
const rl = readline.createInterface({ input: process.stdin });
|
||
const received = [];
|
||
let injectedItems = [];
|
||
let extraSkillRoots = [];
|
||
let overloadedTurnStartEmitted = false;
|
||
let interruptibleTurn = null;
|
||
|
||
function send(message) {
|
||
process.stdout.write(`${JSON.stringify(message)}\n`);
|
||
}
|
||
|
||
rl.on("line", (line) => {
|
||
const message = JSON.parse(line);
|
||
received.push(message);
|
||
|
||
if (message.method === "initialize") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
userAgent: "boss-test-codex-app-server",
|
||
platformFamily: "mac",
|
||
platformOs: "darwin",
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "initialized") {
|
||
return;
|
||
}
|
||
|
||
if (message.method === "model/list") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
data: [
|
||
{
|
||
id: "gpt-5.4",
|
||
model: "gpt-5.4",
|
||
displayName: "GPT-5.4",
|
||
description: "Deep reasoning model",
|
||
hidden: false,
|
||
supportedReasoningEfforts: ["low", "medium", "high"],
|
||
defaultReasoningEffort: "medium",
|
||
inputModalities: ["text", "image"],
|
||
supportsPersonality: true,
|
||
serviceTiers: [{ id: "default", displayName: "Default" }],
|
||
defaultServiceTier: "default",
|
||
isDefault: true,
|
||
},
|
||
{
|
||
id: "gpt-5.4-mini",
|
||
model: "gpt-5.4-mini",
|
||
displayName: "GPT-5.4 mini",
|
||
description: "Fast response model",
|
||
hidden: false,
|
||
supportedReasoningEfforts: ["none", "low"],
|
||
defaultReasoningEffort: "none",
|
||
inputModalities: ["text"],
|
||
supportsPersonality: true,
|
||
serviceTiers: [],
|
||
defaultServiceTier: null,
|
||
isDefault: false,
|
||
},
|
||
],
|
||
nextCursor: null,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "modelProvider/capabilities/read") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
namespaceTools: true,
|
||
imageGeneration: true,
|
||
webSearch: true,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "skills/list") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
data: [
|
||
{
|
||
cwd: "/Users/kris/code/boss",
|
||
skills: [
|
||
{
|
||
name: "image2-ui-prototype",
|
||
description: "Generate high fidelity UI prototypes",
|
||
path: "/Users/kris/.codex/skills/image2-ui-prototype/SKILL.md",
|
||
scope: "user",
|
||
enabled: true,
|
||
},
|
||
],
|
||
errors: [],
|
||
},
|
||
],
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "skills/extraRoots/set") {
|
||
extraSkillRoots = message.params?.extraRoots ?? [];
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
status: "applied",
|
||
extraRoots: extraSkillRoots,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "hooks/list") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
data: [
|
||
{
|
||
cwd: "/Users/kris/code/boss",
|
||
hooks: [
|
||
{
|
||
key: "session-start-private-key-should-not-leak",
|
||
eventName: "SessionStart",
|
||
handlerType: "command",
|
||
matcher: null,
|
||
command: "echo token=sk-secret-should-not-leak",
|
||
timeoutSec: 30,
|
||
statusMessage: "private hook status should not leak",
|
||
sourcePath: "/Users/kris/code/boss/.codex/hooks/private-hook.toml",
|
||
source: "project",
|
||
pluginId: null,
|
||
displayOrder: 1,
|
||
enabled: true,
|
||
isManaged: true,
|
||
currentHash: "hash-secret-should-not-leak",
|
||
trustStatus: "trusted",
|
||
},
|
||
{
|
||
key: "pre-tool-private-key-should-not-leak",
|
||
eventName: "PreToolUse",
|
||
handlerType: "prompt",
|
||
matcher: "Bash",
|
||
command: null,
|
||
timeoutSec: 10,
|
||
statusMessage: "modified hook status should not leak",
|
||
sourcePath: "/Users/kris/.codex/hooks/private-user-hook.toml",
|
||
source: "user",
|
||
pluginId: "private-plugin-should-not-leak",
|
||
displayOrder: 2,
|
||
enabled: false,
|
||
isManaged: false,
|
||
currentHash: "modified-hash-secret-should-not-leak",
|
||
trustStatus: "modified",
|
||
},
|
||
],
|
||
warnings: ["private hook warning should not leak"],
|
||
errors: [
|
||
{
|
||
path: "/Users/kris/code/boss/.codex/hooks/broken-hook.toml",
|
||
message: "private hook error token=sk-secret-should-not-leak",
|
||
},
|
||
],
|
||
},
|
||
],
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "plugin/list") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
marketplaces: [
|
||
{
|
||
name: "local",
|
||
path: "/Users/kris/.codex/plugins/marketplace.json",
|
||
interface: null,
|
||
plugins: [
|
||
{
|
||
id: "github",
|
||
remotePluginId: null,
|
||
localVersion: "1.0.0",
|
||
name: "GitHub",
|
||
installed: true,
|
||
enabled: true,
|
||
keywords: ["repo"],
|
||
},
|
||
],
|
||
},
|
||
],
|
||
marketplaceLoadErrors: [],
|
||
featuredPluginIds: ["github"],
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "app/list") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
data: [
|
||
{
|
||
id: "canva",
|
||
name: "Canva",
|
||
description: "Design app",
|
||
isAccessible: true,
|
||
isEnabled: true,
|
||
pluginDisplayNames: ["Canva"],
|
||
},
|
||
],
|
||
nextCursor: null,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "experimentalFeature/list") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
data: [
|
||
{
|
||
name: "multi_agent",
|
||
stage: "stable",
|
||
displayName: "Multi agent",
|
||
description: "Allow spawned agents to coordinate work",
|
||
announcement: "internal token=sk-secret-should-not-leak",
|
||
enabled: true,
|
||
defaultEnabled: true,
|
||
},
|
||
{
|
||
name: "apps",
|
||
stage: "beta",
|
||
displayName: "Apps",
|
||
description: "Enable app connectors",
|
||
announcement: null,
|
||
enabled: false,
|
||
defaultEnabled: false,
|
||
},
|
||
],
|
||
nextCursor: null,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "collaborationMode/list") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
data: [
|
||
{
|
||
id: "solo",
|
||
name: "solo",
|
||
displayName: "Solo",
|
||
description: "Single-thread execution",
|
||
},
|
||
{
|
||
id: "plan",
|
||
name: "plan",
|
||
displayName: "Plan",
|
||
description: "Plan before coding",
|
||
},
|
||
],
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "permissionProfile/list") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
data: [
|
||
{
|
||
id: ":workspace",
|
||
description: "Workspace write",
|
||
filesystem: {
|
||
"/Users/kris/code/boss": "write",
|
||
},
|
||
},
|
||
{
|
||
id: ":read-only",
|
||
description: "Read-only",
|
||
},
|
||
],
|
||
nextCursor: null,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "mcpServerStatus/list") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
data: [
|
||
{
|
||
name: "github",
|
||
tools: {
|
||
"repos/list": { name: "repos/list", description: "List repositories" },
|
||
"issues/read": { name: "issues/read", description: "Read issues" },
|
||
},
|
||
resources: [
|
||
{
|
||
name: "private repo token=sk-secret-should-not-leak",
|
||
uri: "file:///Users/kris/.ssh/id_ed25519",
|
||
},
|
||
],
|
||
resourceTemplates: [],
|
||
authStatus: "oAuth",
|
||
},
|
||
{
|
||
name: "figma",
|
||
tools: {},
|
||
resources: [],
|
||
resourceTemplates: [],
|
||
authStatus: "notLoggedIn",
|
||
},
|
||
],
|
||
nextCursor: null,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "account/read") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
account: {
|
||
type: "chatgpt",
|
||
email: "private-user@example.com",
|
||
planType: "pro",
|
||
accessToken: "sk-secret-should-not-leak",
|
||
},
|
||
requiresOpenaiAuth: true,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "account/rateLimits/read") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
rateLimits: {
|
||
limitId: "codex",
|
||
limitName: "Primary Codex",
|
||
primary: { usedPercent: 25, windowDurationMins: 15, resetsAt: 1730947200 },
|
||
secondary: null,
|
||
rateLimitReachedType: null,
|
||
},
|
||
rateLimitsByLimitId: {
|
||
codex: {
|
||
limitId: "codex",
|
||
primary: { usedPercent: 25, windowDurationMins: 15, resetsAt: 1730947200 },
|
||
rateLimitReachedType: null,
|
||
},
|
||
codex_other: {
|
||
limitId: "codex_other",
|
||
limitName: "codex_other",
|
||
primary: { usedPercent: 42, windowDurationMins: 60, resetsAt: 1730950800 },
|
||
rateLimitReachedType: null,
|
||
},
|
||
},
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "config/read") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
config: {
|
||
api_key: "sk-secret-should-not-leak",
|
||
model: "gpt-5.4",
|
||
apps: {
|
||
_default: {
|
||
enabled: true,
|
||
destructive_enabled: false,
|
||
open_world_enabled: false,
|
||
},
|
||
google_drive: {
|
||
enabled: true,
|
||
destructive_enabled: false,
|
||
default_tools_approval_mode: "prompt",
|
||
},
|
||
secret_app: {
|
||
enabled: false,
|
||
token: "sk-secret-should-not-leak",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "configRequirements/read") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
managed: true,
|
||
requirements: [
|
||
{ keyPath: "apps._default.destructive_enabled", status: "blocked", sourcePath: "/Users/kris/.codex/config.toml" },
|
||
{ keyPath: "sandbox_mode", status: "ok" },
|
||
],
|
||
warnings: [{ message: "policy reads /Users/kris/.ssh/id_ed25519" }],
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "externalAgentConfig/detect") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
items: [
|
||
{
|
||
itemType: "AGENTS_MD",
|
||
description: "Import /Users/kris/code/boss/CLAUDE.md to /Users/kris/code/boss/AGENTS.md.",
|
||
cwd: "/Users/kris/code/boss",
|
||
},
|
||
{
|
||
itemType: "SKILLS",
|
||
description: "Copy skill folders from /Users/kris/.claude/skills to /Users/kris/.agents/skills.",
|
||
cwd: null,
|
||
},
|
||
{
|
||
itemType: "MCP_SERVER_CONFIG",
|
||
description: "Migrate server config with token sk-secret-should-not-leak",
|
||
cwd: "/Users/kris/code/boss",
|
||
},
|
||
],
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "thread/list") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
data: [
|
||
{
|
||
id: "thr-active",
|
||
name: "Boss App Server rollout",
|
||
sourceKind: "app",
|
||
archived: false,
|
||
updatedAt: "2026-06-03T08:20:00.000Z",
|
||
cwd: "/Users/kris/code/boss",
|
||
status: { type: "active", activeFlags: ["running"] },
|
||
turns: [{ userInput: "secret user text should not leak" }],
|
||
},
|
||
{
|
||
id: "thr-idle",
|
||
name: "AItoukui planning",
|
||
sourceKind: "cli",
|
||
archived: false,
|
||
updatedAt: "2026-06-03T07:00:00.000Z",
|
||
cwd: "/Users/kris/code/AItoukui",
|
||
status: { type: "idle" },
|
||
},
|
||
{
|
||
id: "thr-archived",
|
||
name: "Old private thread",
|
||
sourceKind: "app",
|
||
archived: true,
|
||
updatedAt: "2026-06-01T01:00:00.000Z",
|
||
cwd: "/Users/kris/private",
|
||
status: { type: "notLoaded" },
|
||
},
|
||
],
|
||
nextCursor: null,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "thread/loaded/list") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
threadIds: ["thr-active", "thr-idle"],
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "thread/turns/list") {
|
||
const threadId = message.params?.threadId;
|
||
if (threadId === "thr-active") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
data: [
|
||
{
|
||
id: "turn-active-2",
|
||
status: "running",
|
||
createdAt: "2026-06-03T08:18:00.000Z",
|
||
updatedAt: "2026-06-03T08:21:00.000Z",
|
||
userInput: "private active turn text should not leak",
|
||
items: [{ type: "message", content: "private item content should not leak" }],
|
||
},
|
||
{
|
||
id: "turn-active-1",
|
||
status: "completed",
|
||
createdAt: "2026-06-03T08:00:00.000Z",
|
||
updatedAt: "2026-06-03T08:10:00.000Z",
|
||
},
|
||
],
|
||
nextCursor: null,
|
||
backwardsCursor: null,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
if (threadId === "thr-idle") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
data: [
|
||
{
|
||
id: "turn-idle-1",
|
||
status: { type: "completed" },
|
||
createdAt: "2026-06-03T07:00:00.000Z",
|
||
updatedAt: "2026-06-03T07:30:00.000Z",
|
||
userInput: "private idle turn text should not leak",
|
||
},
|
||
],
|
||
nextCursor: null,
|
||
backwardsCursor: null,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
send({
|
||
id: message.id,
|
||
result: { data: [], nextCursor: null, backwardsCursor: null },
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "thread/resume") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
thread: {
|
||
id: message.params?.threadId ?? "thread-fixture",
|
||
name: "fixture thread",
|
||
},
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "thread/rollback") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
thread: {
|
||
id: message.params?.threadId,
|
||
name: "rollback fixture thread",
|
||
turns: [
|
||
{
|
||
id: "rollback-private-turn",
|
||
status: { type: "completed" },
|
||
userInput: "private rollback turn text should not leak",
|
||
},
|
||
],
|
||
rollbackApplied: {
|
||
numTurns: message.params?.numTurns,
|
||
},
|
||
},
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "thread/compact/start") {
|
||
send({
|
||
id: message.id,
|
||
result: {},
|
||
});
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "compact-turn-secret-should-not-leak",
|
||
item: {
|
||
type: "contextCompaction",
|
||
id: "context-compaction-secret-should-not-leak",
|
||
summary: "private compaction summary should not leak",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/compacted",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "compact-turn-secret-should-not-leak",
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "thread/read") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
thread: {
|
||
id: message.params?.threadId,
|
||
name: "源线程",
|
||
},
|
||
items: [
|
||
{
|
||
type: "message",
|
||
role: "assistant",
|
||
content: [
|
||
{
|
||
type: "output_text",
|
||
text: "源线程最近结论:优先使用 app-server 协议。",
|
||
},
|
||
],
|
||
},
|
||
],
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "thread/inject_items") {
|
||
injectedItems = message.params?.items ?? [];
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
injected: injectedItems.length,
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "thread/start") {
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
thread: {
|
||
id: "thread-started-fixture",
|
||
name: "new fixture thread",
|
||
},
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (message.method === "turn/start") {
|
||
if (
|
||
process.env.BOSS_CODEX_APP_SERVER_FIXTURE_OVERLOAD_ON_TURN_START === "1" &&
|
||
!overloadedTurnStartEmitted
|
||
) {
|
||
overloadedTurnStartEmitted = true;
|
||
send({
|
||
id: message.id,
|
||
error: {
|
||
code: -32001,
|
||
message: "Server overloaded; retry later.",
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
const text = message.params?.input?.find?.((item) => item?.type === "text")?.text ?? "";
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
turn: {
|
||
id: "turn-fixture",
|
||
threadId: message.params?.threadId,
|
||
},
|
||
},
|
||
});
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EXIT_AFTER_TURN_START === "1") {
|
||
process.exit(0);
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_WAIT_FOR_INTERRUPT === "1") {
|
||
interruptibleTurn = {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
};
|
||
return;
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_PROGRESS === "1") {
|
||
send({
|
||
method: "turn/plan/updated",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
plan: [
|
||
{ text: "读取 Codex 官方 app-server 协议", status: "completed" },
|
||
{ text: "执行 targeted/full test", status: "in_progress" },
|
||
],
|
||
},
|
||
});
|
||
send({
|
||
method: "turn/diff/updated",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
diff: {
|
||
changedFiles: 3,
|
||
additions: 181,
|
||
deletions: 52,
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "fileChange",
|
||
id: "file-change-1",
|
||
changes: [
|
||
{ path: "docs/protocol-snapshots/codex-app-server/codex-app-server-protocol-0.135.0.json" },
|
||
],
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/started",
|
||
params: {
|
||
thread: {
|
||
id: "subagent-thread",
|
||
source: {
|
||
subAgent: {
|
||
thread_spawn: {
|
||
agent_nickname: "Mendel",
|
||
agent_role: "explorer",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
});
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_GUARDIAN_EVENTS === "1") {
|
||
send({
|
||
id: "cmd-approval-1",
|
||
method: "item/commandExecution/requestApproval",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
itemId: "command-item-1",
|
||
startedAtMs: Date.now(),
|
||
reason: "需要确认命令执行",
|
||
command: "npm run build -- --token sk-secret-should-not-leak",
|
||
cwd: "/Users/kris/code/boss",
|
||
},
|
||
});
|
||
send({
|
||
method: "item/autoApprovalReview/started",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
reviewId: "review-1",
|
||
startedAtMs: Date.now(),
|
||
targetItemId: "command-item-1",
|
||
action: {
|
||
type: "command",
|
||
command: "npm run build -- --token sk-secret-should-not-leak",
|
||
cwd: "/Users/kris/code/boss",
|
||
},
|
||
review: {
|
||
status: "running",
|
||
riskLevel: "medium",
|
||
userAuthorization: null,
|
||
rationale: "contains a fake secret that must not be surfaced",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "guardianWarning",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
message: "检测到需要用户确认的命令执行。",
|
||
},
|
||
});
|
||
send({
|
||
method: "item/fileChange/patchUpdated",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
itemId: "file-change-item-1",
|
||
changes: [
|
||
{
|
||
path: "src/app/page.tsx",
|
||
kind: "update",
|
||
diff: "+ const secret = 'sk-secret-should-not-leak'",
|
||
},
|
||
{
|
||
path: "docs/architecture/codex_server_progress_card_cn.md",
|
||
kind: "add",
|
||
diff: "+ internal prompt should not leak",
|
||
},
|
||
],
|
||
},
|
||
});
|
||
send({
|
||
method: "item/autoApprovalReview/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
reviewId: "review-1",
|
||
startedAtMs: Date.now(),
|
||
completedAtMs: Date.now(),
|
||
targetItemId: "command-item-1",
|
||
decisionSource: "auto_review",
|
||
action: {
|
||
type: "command",
|
||
command: "npm run build -- --token sk-secret-should-not-leak",
|
||
cwd: "/Users/kris/code/boss",
|
||
},
|
||
review: {
|
||
status: "approved",
|
||
riskLevel: "medium",
|
||
userAuthorization: null,
|
||
rationale: "contains a fake secret that must not be surfaced",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "serverRequest/resolved",
|
||
params: {
|
||
requestId: "cmd-approval-1",
|
||
threadId: message.params?.threadId,
|
||
},
|
||
});
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_REALTIME_EVENTS === "1") {
|
||
send({
|
||
method: "thread/status/changed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
status: {
|
||
type: "active",
|
||
activeFlags: ["waitingOnApproval", "waitingOnUserInput"],
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/realtime/started",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
realtimeSessionId: "rt-session-1",
|
||
version: "v2",
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/realtime/sdp",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
sdp: "v=0 secret-sk-should-not-leak",
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/realtime/transcript/delta",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
role: "assistant",
|
||
delta: "正在分析 Codex ",
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/realtime/transcript/done",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
role: "assistant",
|
||
text: "正在分析 Codex App Server 实时事件。",
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/realtime/outputAudio/delta",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
audio: {
|
||
data: "audio-secret-payload",
|
||
sampleRate: 24000,
|
||
numChannels: 1,
|
||
samplesPerChannel: 480,
|
||
itemId: "audio-item-1",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/realtime/itemAdded",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
item: {
|
||
type: "message",
|
||
text: "raw realtime item should not be persisted",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/realtime/closed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
reason: "completed",
|
||
},
|
||
});
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_RUNTIME_STATUS === "1") {
|
||
send({
|
||
method: "model/rerouted",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
fromModel: "gpt-5.4-mini",
|
||
toModel: "gpt-5.4",
|
||
reason: "highRiskCyberActivity",
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/tokenUsage/updated",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
tokenUsage: {
|
||
total: {
|
||
totalTokens: 3000,
|
||
inputTokens: 2200,
|
||
cachedInputTokens: 300,
|
||
outputTokens: 650,
|
||
reasoningOutputTokens: 150,
|
||
},
|
||
last: {
|
||
totalTokens: 800,
|
||
inputTokens: 500,
|
||
cachedInputTokens: 120,
|
||
outputTokens: 260,
|
||
reasoningOutputTokens: 40,
|
||
},
|
||
modelContextWindow: 200000,
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "mcpServer/startupStatus/updated",
|
||
params: {
|
||
name: "github",
|
||
status: "failed",
|
||
error: "token=sk-secret-should-not-leak failed to start",
|
||
},
|
||
});
|
||
send({
|
||
method: "remoteControl/status/changed",
|
||
params: {
|
||
status: "connected",
|
||
serverName: "Mac Studio",
|
||
installationId: "install-secret-should-not-leak",
|
||
environmentId: "env-prod",
|
||
},
|
||
});
|
||
send({
|
||
method: "windowsSandbox/setupCompleted",
|
||
params: {
|
||
mode: "elevated",
|
||
success: false,
|
||
error: "token=sk-secret-should-not-leak failed in C:\\Users\\kris\\secret",
|
||
},
|
||
});
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_THREAD_CONFIG_EVENTS === "1") {
|
||
send({
|
||
method: "thread/goal/updated",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
goal: {
|
||
threadId: message.params?.threadId,
|
||
objective: "完成 App Server 线程目标同步",
|
||
status: "active",
|
||
tokenBudget: 120000,
|
||
tokensUsed: 4800,
|
||
timeUsedSeconds: 600,
|
||
createdAt: 1770000000,
|
||
updatedAt: 1770000300,
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/settings/updated",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
threadSettings: {
|
||
cwd: "/Users/kris/code/boss/secret-project",
|
||
approvalPolicy: "on-request",
|
||
approvalsReviewer: "user",
|
||
sandboxPolicy: {
|
||
type: "workspaceWrite",
|
||
writableRoots: ["/Users/kris/code/boss", "/Users/kris/.codex/memories"],
|
||
networkAccess: false,
|
||
excludeTmpdirEnvVar: false,
|
||
excludeSlashTmp: false,
|
||
},
|
||
activePermissionProfile: {
|
||
id: ":workspace",
|
||
extends: null,
|
||
},
|
||
model: "gpt-5.5",
|
||
modelProvider: "openai",
|
||
serviceTier: "fast",
|
||
effort: "low",
|
||
summary: "concise",
|
||
collaborationMode: {
|
||
mode: "plan",
|
||
settings: {
|
||
developer_instructions: "internal prompt should not leak",
|
||
model_instructions_file: "/Users/kris/.codex/secret-instructions.md",
|
||
},
|
||
},
|
||
personality: "pragmatic",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "thread/compacted",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
},
|
||
});
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_ACCOUNT_NOTICE_EVENTS === "1") {
|
||
send({
|
||
method: "account/updated",
|
||
params: {
|
||
authMode: "chatgpt",
|
||
planType: "team",
|
||
},
|
||
});
|
||
send({
|
||
method: "account/rateLimits/updated",
|
||
params: {
|
||
rateLimits: {
|
||
limitId: "codex",
|
||
limitName: "Codex",
|
||
primary: {
|
||
usedPercent: 88,
|
||
windowDurationMins: 180,
|
||
resetsAt: 1770003600,
|
||
},
|
||
secondary: null,
|
||
credits: {
|
||
hasCredits: true,
|
||
unlimited: false,
|
||
balance: "120.5",
|
||
},
|
||
planType: "team",
|
||
rateLimitReachedType: null,
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "model/verification",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
verifications: ["trustedAccessForCyber"],
|
||
},
|
||
});
|
||
send({
|
||
method: "warning",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
message: "模型切换提醒 token=sk-secret-should-not-leak",
|
||
},
|
||
});
|
||
send({
|
||
method: "configWarning",
|
||
params: {
|
||
summary: "项目配置已忽略",
|
||
details: "openai_base_url 不能放在项目配置里",
|
||
path: "/Users/kris/code/boss/.codex/config.toml",
|
||
},
|
||
});
|
||
send({
|
||
method: "deprecationNotice",
|
||
params: {
|
||
summary: "on-failure 已废弃",
|
||
details: "请改用 on-request",
|
||
},
|
||
});
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_COLLAB_EVENTS === "1") {
|
||
const useV2Collab = process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_COLLAB_EVENTS_V2 === "1";
|
||
send({
|
||
method: "item/started",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "collabToolCall",
|
||
id: "collab-call-1",
|
||
tool: "send_input",
|
||
status: "running",
|
||
senderThreadId: "thread-source-secret-should-not-leak",
|
||
...(useV2Collab
|
||
? {
|
||
receiverThreadIds: [
|
||
"thread-target-secret-should-not-leak",
|
||
"thread-target-2-secret-should-not-leak",
|
||
],
|
||
agentsStates: {
|
||
"thread-target-secret-should-not-leak": {
|
||
status: "running",
|
||
message: "private agent status message should not leak",
|
||
},
|
||
},
|
||
}
|
||
: {
|
||
receiverThreadId: "thread-target-secret-should-not-leak",
|
||
agentStatus: "running",
|
||
}),
|
||
prompt: "internal prompt token=sk-secret-should-not-leak",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "collabToolCall",
|
||
id: "collab-call-1",
|
||
tool: "send_input",
|
||
status: "completed",
|
||
senderThreadId: "thread-source-secret-should-not-leak",
|
||
...(useV2Collab
|
||
? {
|
||
receiverThreadIds: [
|
||
"thread-target-secret-should-not-leak",
|
||
"thread-target-2-secret-should-not-leak",
|
||
],
|
||
agentsStates: {
|
||
"thread-target-secret-should-not-leak": {
|
||
status: "completed",
|
||
message: "private agent completed message should not leak",
|
||
},
|
||
"thread-target-2-secret-should-not-leak": {
|
||
status: "errored",
|
||
message: "private agent error message should not leak",
|
||
},
|
||
},
|
||
}
|
||
: {
|
||
receiverThreadId: "thread-target-secret-should-not-leak",
|
||
agentStatus: "completed",
|
||
}),
|
||
prompt: "internal prompt token=sk-secret-should-not-leak",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "contextCompaction",
|
||
id: "context-compaction-secret-should-not-leak",
|
||
},
|
||
},
|
||
});
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_TOOL_ACTIVITY_EVENTS === "1") {
|
||
send({
|
||
method: "item/started",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "mcpToolCall",
|
||
id: "mcp-tool-secret-should-not-leak",
|
||
server: "github",
|
||
tool: "pull_request/list",
|
||
status: "running",
|
||
arguments: {
|
||
token: "sk-secret-should-not-leak",
|
||
},
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "mcpToolCall",
|
||
id: "mcp-tool-secret-should-not-leak",
|
||
server: "github",
|
||
tool: "pull_request/list",
|
||
status: "failed",
|
||
error: "token=sk-secret-should-not-leak failed",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "dynamicToolCall",
|
||
id: "dynamic-tool-secret-should-not-leak",
|
||
tool: "browser.open",
|
||
status: "completed",
|
||
success: true,
|
||
durationMs: 1234,
|
||
contentItems: [
|
||
{
|
||
text: "internal tool result token=sk-secret-should-not-leak",
|
||
},
|
||
],
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/started",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "webSearch",
|
||
id: "web-search-secret-should-not-leak",
|
||
query: "Codex App Server ThreadItem",
|
||
action: {
|
||
type: "openPage",
|
||
url: "https://example.com/private?token=sk-secret-should-not-leak",
|
||
},
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "imageView",
|
||
id: "image-view-secret-should-not-leak",
|
||
path: "/Users/kris/code/boss/private-screenshot.png",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/started",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "enteredReviewMode",
|
||
id: "review-mode-secret-should-not-leak",
|
||
review: {
|
||
status: "started",
|
||
prompt: "internal review prompt token=sk-secret-should-not-leak",
|
||
},
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "exitedReviewMode",
|
||
id: "review-mode-secret-should-not-leak",
|
||
review: {
|
||
status: "completed",
|
||
prompt: "internal review prompt token=sk-secret-should-not-leak",
|
||
},
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "commandExecution",
|
||
id: "command-secret-should-not-leak",
|
||
command: "cat /Users/kris/.ssh/id_rsa && echo sk-secret-should-not-leak",
|
||
cwd: "/Users/kris/code/boss",
|
||
status: "completed",
|
||
exitCode: 0,
|
||
aggregatedOutput: "private output token=sk-secret-should-not-leak",
|
||
durationMs: 2345,
|
||
},
|
||
},
|
||
});
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_IMAGE_GENERATION_EVENTS === "1") {
|
||
send({
|
||
method: "item/started",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "imageGeneration",
|
||
id: "image-generation-secret-should-not-leak",
|
||
status: "inProgress",
|
||
revisedPrompt: "internal prompt token=sk-secret-should-not-leak",
|
||
result: "data:image/png;base64,raw-secret-should-not-leak",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "imageGeneration",
|
||
id: "image-generation-secret-should-not-leak",
|
||
status: "completed",
|
||
revisedPrompt: "internal prompt token=sk-secret-should-not-leak",
|
||
result: "data:image/png;base64,raw-secret-should-not-leak",
|
||
savedPath: "/Users/kris/code/boss/outputs/generated-secret-image.png",
|
||
},
|
||
},
|
||
});
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_HOOK_EVENTS === "1") {
|
||
send({
|
||
method: "hook/started",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
run: {
|
||
id: "hook-secret-should-not-leak",
|
||
eventName: "postToolUse",
|
||
handlerType: "command",
|
||
executionMode: "async",
|
||
scope: "turn",
|
||
sourcePath: "/Users/kris/code/boss/.codex/hooks/private-hook.toml",
|
||
source: "project",
|
||
displayOrder: 1,
|
||
status: "running",
|
||
statusMessage: "running token=sk-secret-should-not-leak",
|
||
startedAt: Date.now(),
|
||
completedAt: null,
|
||
durationMs: null,
|
||
entries: [
|
||
{
|
||
kind: "context",
|
||
text: "internal hook output token=sk-secret-should-not-leak",
|
||
},
|
||
],
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "hook/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
run: {
|
||
id: "hook-secret-should-not-leak",
|
||
eventName: "postToolUse",
|
||
handlerType: "command",
|
||
executionMode: "async",
|
||
scope: "turn",
|
||
sourcePath: "/Users/kris/code/boss/.codex/hooks/private-hook.toml",
|
||
source: "project",
|
||
displayOrder: 1,
|
||
status: "completed",
|
||
statusMessage: "completed token=sk-secret-should-not-leak",
|
||
startedAt: Date.now() - 42,
|
||
completedAt: Date.now(),
|
||
durationMs: 42,
|
||
entries: [
|
||
{
|
||
kind: "feedback",
|
||
text: "private hook result token=sk-secret-should-not-leak",
|
||
},
|
||
],
|
||
},
|
||
},
|
||
});
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_REASONING_PLAN_EVENTS === "1") {
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "plan",
|
||
id: "plan-secret-should-not-leak",
|
||
text: "1. 回读官方 App Server item 协议\n2. 补充 reasoning summary 安全映射",
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/started",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "reasoning",
|
||
id: "reasoning-secret-should-not-leak",
|
||
summary: [
|
||
{
|
||
text: "正在判断哪些思考摘要可以展示。",
|
||
},
|
||
],
|
||
content: [
|
||
{
|
||
text: "raw hidden reasoning token=sk-secret-should-not-leak",
|
||
},
|
||
],
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
item: {
|
||
type: "reasoning",
|
||
id: "reasoning-secret-should-not-leak",
|
||
summary: ["确认只展示官方 summary,不展示 raw content。"],
|
||
content: [
|
||
{
|
||
text: "raw hidden chain of thought token=sk-secret-should-not-leak",
|
||
},
|
||
],
|
||
},
|
||
},
|
||
});
|
||
}
|
||
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_STREAM_DELTA_EVENTS === "1") {
|
||
send({
|
||
method: "item/plan/delta",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
itemId: "plan-delta-secret-should-not-leak",
|
||
delta: "secret plan delta should not leak",
|
||
},
|
||
});
|
||
send({
|
||
method: "item/reasoning/summaryPartAdded",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
itemId: "reasoning-delta-secret-should-not-leak",
|
||
summaryIndex: 0,
|
||
part: "secret reasoning summary part should not leak",
|
||
},
|
||
});
|
||
send({
|
||
method: "item/reasoning/summaryTextDelta",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
itemId: "reasoning-delta-secret-should-not-leak",
|
||
summaryIndex: 0,
|
||
delta: "secret reasoning summary delta should not leak",
|
||
},
|
||
});
|
||
send({
|
||
method: "item/reasoning/textDelta",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
itemId: "reasoning-delta-secret-should-not-leak",
|
||
delta: "secret raw reasoning delta should not leak",
|
||
},
|
||
});
|
||
send({
|
||
method: "item/mcpToolCall/progress",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
itemId: "mcp-progress-secret-should-not-leak",
|
||
message: "secret mcp progress should not leak",
|
||
},
|
||
});
|
||
send({
|
||
method: "item/commandExecution/outputDelta",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
itemId: "command-output-secret-should-not-leak",
|
||
stream: "stdout",
|
||
delta: "secret command output should not leak",
|
||
},
|
||
});
|
||
send({
|
||
method: "item/commandExecution/terminalInteraction",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
itemId: "terminal-interaction-secret-should-not-leak",
|
||
input: "secret terminal input should not leak",
|
||
},
|
||
});
|
||
send({
|
||
method: "item/fileChange/outputDelta",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
itemId: "file-output-secret-should-not-leak",
|
||
delta: "secret file output should not leak",
|
||
},
|
||
});
|
||
}
|
||
send({
|
||
method: "item/agentMessage/delta",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: "turn-fixture",
|
||
delta:
|
||
process.env.BOSS_CODEX_APP_SERVER_FIXTURE_INTER_THREAD === "1"
|
||
? `INTER_THREAD_INJECTED:${JSON.stringify(injectedItems)}`
|
||
: `APP_SERVER_REPLY:${text}`,
|
||
},
|
||
});
|
||
send({
|
||
method: "turn/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turn: {
|
||
id: "turn-fixture",
|
||
status: "completed",
|
||
},
|
||
},
|
||
});
|
||
process.stderr.write(`${JSON.stringify({ received })}\n`);
|
||
return;
|
||
}
|
||
|
||
if (message.method === "turn/interrupt") {
|
||
send({
|
||
id: message.id,
|
||
result: {},
|
||
});
|
||
send({
|
||
method: "turn/completed",
|
||
params: {
|
||
threadId: message.params?.threadId ?? interruptibleTurn?.threadId,
|
||
turn: {
|
||
id: message.params?.turnId ?? interruptibleTurn?.turnId,
|
||
status: "interrupted",
|
||
},
|
||
},
|
||
});
|
||
process.stderr.write(`${JSON.stringify({ received })}\n`);
|
||
return;
|
||
}
|
||
|
||
if (message.method === "turn/steer") {
|
||
const text = message.params?.input?.find?.((item) => item?.type === "text")?.text ?? "";
|
||
send({
|
||
id: message.id,
|
||
result: {
|
||
turn: {
|
||
id: message.params?.expectedTurnId,
|
||
threadId: message.params?.threadId,
|
||
},
|
||
},
|
||
});
|
||
send({
|
||
method: "item/agentMessage/delta",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turnId: message.params?.expectedTurnId,
|
||
delta:
|
||
process.env.BOSS_CODEX_APP_SERVER_FIXTURE_STEER === "1"
|
||
? `STEERED:${text}`
|
||
: `APP_SERVER_STEERED:${text}`,
|
||
},
|
||
});
|
||
send({
|
||
method: "turn/completed",
|
||
params: {
|
||
threadId: message.params?.threadId,
|
||
turn: {
|
||
id: message.params?.expectedTurnId,
|
||
status: "completed",
|
||
},
|
||
},
|
||
});
|
||
process.stderr.write(`${JSON.stringify({ received })}\n`);
|
||
return;
|
||
}
|
||
|
||
send({
|
||
id: message.id,
|
||
error: {
|
||
code: -32601,
|
||
message: `unknown method ${message.method}`,
|
||
},
|
||
});
|
||
});
|