惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Visual Studio Blog
IT之家
IT之家
博客园 - 聂微东
The Cloudflare Blog
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
S
SegmentFault 最新的问题
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
H
Help Net Security
博客园 - 叶小钗
V
V2EX
WordPress大学
WordPress大学
J
Java Code Geeks
Hugging Face - Blog
Hugging Face - Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园_首页
C
Check Point Blog
B
Blog
D
DataBreaches.Net
美团技术团队
罗磊的独立博客

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
feat(plugin-sdk): add typed presentation command actions ...
steipete · 2026-06-01 · via Recent Commits to openclaw:main
11

import crypto from "node:crypto";

22

import { resolveAgentDir, resolveSessionAgentIds } from "openclaw/plugin-sdk/agent-runtime";

3-

import type { MessagePresentation } from "openclaw/plugin-sdk/interactive-runtime";

43

import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";

54

import type { PluginCommandContext, PluginCommandResult } from "openclaw/plugin-sdk/plugin-entry";

65

import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";

@@ -40,6 +39,10 @@ import {

4039

handleCodexPluginsSubcommand,

4140

type CodexPluginsManagementIO,

4241

} from "./command-plugins-management.js";

42+

import {

43+

buildCodexCommandPickerPresentation,

44+

type CodexCommandPickerButton,

45+

} from "./command-presentation.js";

4346

import {

4447

codexControlRequest,

4548

readCodexStatusProbes,

@@ -241,30 +244,12 @@ export function resetCodexDiagnosticsFeedbackStateForTests(): void {

241244

pendingCodexDiagnosticsConfirmationTokensByScope.clear();

242245

}

243246244-

type CodexPickerButton = { label: string; command: string };

245-246-

function buildPickerPresentation(title: string, prompt: string, buttons: CodexPickerButton[]) {

247-

return {

248-

title,

249-

blocks: [

250-

{ type: "text", text: prompt },

251-

{

252-

type: "buttons",

253-

buttons: buttons.map((button) => ({

254-

label: button.label,

255-

value: button.command,

256-

})),

257-

},

258-

],

259-

} satisfies MessagePresentation;

260-

}

261-262247

/**

263-

* No-arg `/codex` picker. Core owns the native command tree; channels render

264-

* the portable buttons as inline controls when their transport can.

248+

* No-arg `/codex` picker. Codex owns the command tree; channels render the

249+

* portable command actions as inline controls when their transport can.

265250

*/

266251

function buildCodexSubcommandPickerReply(): PluginCommandResult {

267-

const verbs: CodexPickerButton[] = [

252+

const verbs: CodexCommandPickerButton[] = [

268253

{ label: "plugins", command: "/codex plugins menu" },

269254

{ label: "permissions", command: "/codex permissions menu" },

270255

{ label: "fast", command: "/codex fast menu" },

@@ -287,14 +272,18 @@ function buildCodexSubcommandPickerReply(): PluginCommandResult {

287272288273

return {

289274

text: fallbackTextLines.join("\n"),

290-

presentation: buildPickerPresentation("Codex commands", "Pick a Codex subcommand:", verbs),

275+

presentation: buildCodexCommandPickerPresentation(

276+

"Codex commands",

277+

"Pick a Codex subcommand:",

278+

verbs,

279+

),

291280

};

292281

}

293282294283

/** Sub-picker for `/codex fast menu` (on / off / status). */

295284

function buildCodexFastMenuReply(): PluginCommandResult {

296285

const modes = ["on", "off", "status"] as const;

297-

const buttons: CodexPickerButton[] = [

286+

const buttons: CodexCommandPickerButton[] = [

298287

...modes.map((mode) => ({ label: mode, command: `/codex fast ${mode}` })),

299288

{ label: "back", command: "/codex" },

300289

];

@@ -307,14 +296,18 @@ function buildCodexFastMenuReply(): PluginCommandResult {

307296

];

308297

return {

309298

text: fallbackTextLines.join("\n"),

310-

presentation: buildPickerPresentation("Codex fast mode", "Pick a Codex fast mode:", buttons),

299+

presentation: buildCodexCommandPickerPresentation(

300+

"Codex fast mode",

301+

"Pick a Codex fast mode:",

302+

buttons,

303+

),

311304

};

312305

}

313306314307

/** Sub-picker for `/codex permissions menu` (default / yolo / status). */

315308

function buildCodexPermissionsMenuReply(): PluginCommandResult {

316309

const modes = ["default", "yolo", "status"] as const;

317-

const buttons: CodexPickerButton[] = [

310+

const buttons: CodexCommandPickerButton[] = [

318311

...modes.map((mode) => ({ label: mode, command: `/codex permissions ${mode}` })),

319312

{ label: "back", command: "/codex" },

320313

];

@@ -327,7 +320,7 @@ function buildCodexPermissionsMenuReply(): PluginCommandResult {

327320

];

328321

return {

329322

text: fallbackTextLines.join("\n"),

330-

presentation: buildPickerPresentation(

323+

presentation: buildCodexCommandPickerPresentation(

331324

"Codex permissions",

332325

"Pick a Codex permissions mode:",

333326

buttons,

@@ -338,7 +331,7 @@ function buildCodexPermissionsMenuReply(): PluginCommandResult {

338331

/** Sub-picker for `/codex computer-use menu` (status / install). */

339332

function buildCodexComputerUseMenuReply(): PluginCommandResult {

340333

const actions = ["status", "install"] as const;

341-

const buttons: CodexPickerButton[] = [

334+

const buttons: CodexCommandPickerButton[] = [

342335

...actions.map((action) => ({

343336

label: action,

344337

command: `/codex computer-use ${action}`,

@@ -356,7 +349,7 @@ function buildCodexComputerUseMenuReply(): PluginCommandResult {

356349

];

357350

return {

358351

text: fallbackTextLines.join("\n"),

359-

presentation: buildPickerPresentation(

352+

presentation: buildCodexCommandPickerPresentation(

360353

"Codex computer-use",

361354

"Pick a Codex computer-use action:",

362355

buttons,

@@ -1149,8 +1142,18 @@ async function requestCodexDiagnosticsFeedbackApproval(

11491142

{

11501143

type: "buttons",

11511144

buttons: [

1152-

{ label: "Send diagnostics", value: confirmCommand, style: "danger" },

1153-

{ label: "Cancel", value: cancelCommand, style: "secondary" },

1145+

{

1146+

label: "Send diagnostics",

1147+

action: { type: "command", command: confirmCommand },

1148+

value: confirmCommand,

1149+

style: "danger",

1150+

},

1151+

{

1152+

label: "Cancel",

1153+

action: { type: "command", command: cancelCommand },

1154+

value: cancelCommand,

1155+

style: "secondary",

1156+

},

11541157

],

11551158

},

11561159

],