856
const declined = state.declinedToolCalls.delete(entry.toolCallId);
857
if (params.item.type === 'commandExecution') {
858
>
const success = params.item.status === 'completed' && (params.item.exitCode === 0 || params.item.exitCode === null);
codexMapAppServerEvents.ts
859
>
const output = params.item.aggregatedOutput ?? entry.output;
860
>
const command = unwrapShellInvocation(params.item.command ?? '');
861
>
const exit = params.item.exitCode;
862
>
const pastTense = success
863
? `Ran \`${command}\``
864
: exit !== null
865
? `Ran \`${command}\` (exit ${exit})`
866
: `Ran \`${command}\` (failed)`;
868
>
{
869
>
type: ActionType.ChatToolCallComplete,
870
>
turnId: entry.turnId,
871
>
toolCallId: entry.toolCallId,
872
>
result: {
873
>
success,
874
>
pastTenseMessage: pastTense,
875
>
content: output
876
? [{ type: ToolResultContentType.Text, text: output }]
877
: undefined,
879
message: exit !== null ? `Exit code ${exit}` : 'Command failed',
880
...(declined ? { code: 'denied' } : {}),
881
},
883
>
},
884
>
];
885
>
// A successful command that produced NO output may be a sandbox
886
>
// pre-flight that Codex will immediately re-run under an approval prompt
887
>
// (same command, new item). Defer its completion so the re-run can reuse
888
>
// this box; if no re-run arrives, it is flushed on the next item or at
889
>
// turn end (see mapItemStarted / mapTurnCompleted).
890
>
if (success && !output && !declined) {
891
const flushed = flushPendingPreflight(state);
892
state.pendingPreflight = { toolCallId: entry.toolCallId, turnId: entry.turnId, command, completion };