Wire diagnostics through the core chat command (#72936)

* feat: wire codex diagnostics feedback

* fix: harden codex diagnostics hints

* fix: neutralize codex diagnostics output

* fix: tighten codex diagnostics safeguards

* fix: bound codex diagnostics feedback output

* fix: tighten codex diagnostics throttling

* fix: confirm codex diagnostics uploads

* docs: clarify codex diagnostics add-on

* fix: route diagnostics through core command

* fix: tighten diagnostics authorization

* fix: pin diagnostics to bundled codex command

* fix: limit owner status in plugin commands

* fix: scope diagnostics confirmations

* fix: scope codex diagnostics cooldowns

* fix: harden codex diagnostics ownership scopes

* fix: harden diagnostics command trust and display

* fix: keep diagnostics command trust internal

* fix: clarify diagnostics exec boundary

* fix: consume codex diagnostics confirmations atomically

* test: include codex diagnostics binding metadata

* test: use string codex binding timestamps

* fix: keep reserved command trust host-only

* fix: harden diagnostics trust and resume hints

* wire diagnostics through exec approval

* fix: keep diagnostics tests aligned with bundled root trust

* fix telegram diagnostics owner auth

* route trajectory exports through exec approval

* fix trajectory exec command encoding

* fix telegram group owner auth

* fix export trajectory approval hardening

* fix pairing command owner bootstrap

* fix telegram owner exec approvals

* fix: make diagnostics approval flow pasteable

* fix: route native sensitive command followups

* fix: invoke diagnostics exports with current cli

* fix: refresh exec approval protocol models

* fix: list codex diagnostics from thread bindings

* fix: fold codex diagnostics into exec approval

* fix: preserve diagnostics approval line breaks

* docs: clarify diagnostics codex workflow
This commit is contained in:
pashpashpash
2026-04-28 15:40:37 -07:00
committed by GitHub
parent 7e41913a20
commit 6ce1058296
78 changed files with 5727 additions and 315 deletions

View File

@@ -7,6 +7,7 @@ const mocks = vi.hoisted(() => ({
healthCommand: vi.fn(),
sessionsCommand: vi.fn(),
sessionsCleanupCommand: vi.fn(),
exportTrajectoryCommand: vi.fn(),
tasksListCommand: vi.fn(),
tasksAuditCommand: vi.fn(),
tasksMaintenanceCommand: vi.fn(),
@@ -28,6 +29,7 @@ const statusCommand = mocks.statusCommand;
const healthCommand = mocks.healthCommand;
const sessionsCommand = mocks.sessionsCommand;
const sessionsCleanupCommand = mocks.sessionsCleanupCommand;
const exportTrajectoryCommand = mocks.exportTrajectoryCommand;
const tasksListCommand = mocks.tasksListCommand;
const tasksAuditCommand = mocks.tasksAuditCommand;
const tasksMaintenanceCommand = mocks.tasksMaintenanceCommand;
@@ -56,6 +58,10 @@ vi.mock("../../commands/sessions-cleanup.js", () => ({
sessionsCleanupCommand: mocks.sessionsCleanupCommand,
}));
vi.mock("../../commands/export-trajectory.js", () => ({
exportTrajectoryCommand: mocks.exportTrajectoryCommand,
}));
vi.mock("../../commands/tasks.js", () => ({
tasksListCommand: mocks.tasksListCommand,
tasksAuditCommand: mocks.tasksAuditCommand,
@@ -93,6 +99,7 @@ describe("registerStatusHealthSessionsCommands", () => {
healthCommand.mockResolvedValue(undefined);
sessionsCommand.mockResolvedValue(undefined);
sessionsCleanupCommand.mockResolvedValue(undefined);
exportTrajectoryCommand.mockResolvedValue(undefined);
tasksListCommand.mockResolvedValue(undefined);
tasksAuditCommand.mockResolvedValue(undefined);
tasksMaintenanceCommand.mockResolvedValue(undefined);
@@ -249,6 +256,51 @@ describe("registerStatusHealthSessionsCommands", () => {
);
});
it("runs sessions export-trajectory with owner-routable export options", async () => {
await runCli([
"sessions",
"--store",
"/tmp/sessions.json",
"export-trajectory",
"--session-key",
"agent:main:telegram:direct:owner",
"--workspace",
"/workspace",
"--output",
"bug-123",
"--json",
]);
expect(exportTrajectoryCommand).toHaveBeenCalledWith(
expect.objectContaining({
sessionKey: "agent:main:telegram:direct:owner",
output: "bug-123",
workspace: "/workspace",
store: "/tmp/sessions.json",
json: true,
}),
runtime,
);
});
it("forwards encoded sessions export-trajectory requests", async () => {
await runCli([
"sessions",
"export-trajectory",
"--request-json-base64",
"eyJzZXNzaW9uS2V5IjoiYWdlbnQ6bWFpbjp0ZWxlZ3JhbTpkaXJlY3Q6b3duZXIifQ",
"--json",
]);
expect(exportTrajectoryCommand).toHaveBeenCalledWith(
expect.objectContaining({
requestJsonBase64: "eyJzZXNzaW9uS2V5IjoiYWdlbnQ6bWFpbjp0ZWxlZ3JhbTpkaXJlY3Q6b3duZXIifQ",
json: true,
}),
runtime,
);
});
it("runs tasks list from the parent command", async () => {
await runCli(["tasks", "--json", "--runtime", "acp", "--status", "running"]);

View File

@@ -1,4 +1,5 @@
import type { Command } from "commander";
import { exportTrajectoryCommand } from "../../commands/export-trajectory.js";
import { flowsCancelCommand, flowsListCommand, flowsShowCommand } from "../../commands/flows.js";
import { healthCommand } from "../../commands/health.js";
import { sessionsCleanupCommand } from "../../commands/sessions-cleanup.js";
@@ -223,6 +224,40 @@ export function registerStatusHealthSessionsCommands(program: Command) {
});
});
sessionsCmd
.command("export-trajectory")
.description("Export a redacted trajectory bundle for a stored session")
.option("--session-key <key>", "Session key to export")
.option("--output <path>", "Output directory name inside .openclaw/trajectory-exports")
.option("--workspace <path>", "Workspace root for the export (default: current directory)")
.option("--store <path>", "Path to session store (default: resolved from session key)")
.option("--agent <id>", "Agent id for resolving the default session store")
.option("--request-json-base64 <payload>", "Base64url-encoded export request")
.option("--json", "Output JSON", false)
.action(async (opts, command) => {
const parentOpts = command.parent?.opts() as
| {
store?: string;
agent?: string;
json?: boolean;
}
| undefined;
await runCommandWithRuntime(defaultRuntime, async () => {
await exportTrajectoryCommand(
{
sessionKey: opts.sessionKey as string | undefined,
output: opts.output as string | undefined,
workspace: opts.workspace as string | undefined,
store: (opts.store as string | undefined) ?? parentOpts?.store,
agent: (opts.agent as string | undefined) ?? parentOpts?.agent,
requestJsonBase64: opts.requestJsonBase64 as string | undefined,
json: Boolean(opts.json || parentOpts?.json),
},
defaultRuntime,
);
});
});
const tasksCmd = program
.command("tasks")
.description("Inspect durable background tasks and TaskFlow state")