codex-plus-patcher 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +12 -1
  2. package/package.json +5 -2
  3. package/src/cli.js +97 -0
  4. package/src/patches/26.616.41845-4198.js +2 -0
  5. package/src/patches/26.616.51431-4212.js +2 -0
  6. package/src/patches/26.616.71553-4265.js +6 -0
  7. package/src/patches/26.616.81150-4306.js +7 -0
  8. package/src/patches/lib/common-patches.js +175 -58
  9. package/src/patches/lib/hooks/about.js +7 -0
  10. package/src/patches/lib/hooks/diagnostics.js +7 -0
  11. package/src/patches/lib/hooks/mermaid.js +7 -0
  12. package/src/patches/lib/hooks/message-composer.js +7 -0
  13. package/src/patches/lib/hooks/native-main.js +7 -0
  14. package/src/patches/lib/hooks/project-selector.js +12 -0
  15. package/src/patches/lib/hooks/review.js +7 -0
  16. package/src/patches/lib/hooks/settings-commands.js +12 -0
  17. package/src/patches/lib/hooks/sidebar.js +12 -0
  18. package/src/patches/lib/hooks/thread-header.js +7 -0
  19. package/src/patches/lib/hooks/worker.js +7 -0
  20. package/src/patches/lib/project-selector-shortcut-patch.js +55 -0
  21. package/src/runtime/api/about.js +16 -0
  22. package/src/runtime/api/commands.js +85 -0
  23. package/src/runtime/api/composer.js +14 -0
  24. package/src/runtime/api/diagnostics.js +38 -0
  25. package/src/runtime/api/errors.js +20 -0
  26. package/src/runtime/api/index.js +79 -0
  27. package/src/runtime/api/mermaid.js +14 -0
  28. package/src/runtime/api/message.js +14 -0
  29. package/src/runtime/api/modules.js +57 -0
  30. package/src/runtime/api/native.js +14 -0
  31. package/src/runtime/api/patches.js +31 -0
  32. package/src/runtime/api/review.js +20 -0
  33. package/src/runtime/api/settings.js +76 -0
  34. package/src/runtime/api/sidebar.js +24 -0
  35. package/src/runtime/api/styles.js +28 -0
  36. package/src/runtime/api/threadHeader.js +41 -0
  37. package/src/runtime/assets.js +58 -13
  38. package/src/runtime/host/messageComposer.js +16 -0
  39. package/src/runtime/host/nativeMain.js +159 -0
  40. package/src/runtime/host/projectSelector.js +58 -0
  41. package/src/runtime/host/review.js +62 -0
  42. package/src/runtime/host/sidebar.js +21 -0
  43. package/src/runtime/host/threadHeader.js +9 -0
  44. package/src/runtime/{worker.js → host/worker.js} +7 -0
  45. package/src/runtime/plugins/devTools.js +33 -0
  46. package/src/runtime/plugins/projectPathHeader.js +116 -0
  47. package/src/runtime/plugins/projectSelectorShortcut.js +207 -0
  48. package/src/runtime/runtime.js +22 -355
package/README.md CHANGED
@@ -29,14 +29,18 @@ patches plus readable runtime plugins:
29
29
  - add diagnostic detail for selected app-shell errors
30
30
  - add user-message bubble color controls in Appearance settings
31
31
  - add adaptive project colors for sidebar projects, grouped threads, pinned threads, user-message accents, and the composer
32
+ - show the active project path in the thread header with a copy action
32
33
  - add the `Toggle sidebar blur` command palette entry to blur sidebar chat and project names for the current session
34
+ - add an `Open Developer Tools` panels command for opening the current Codex window's DevTools
35
+ - add the `Focus project selector` command and `CmdOrCtrl+.` shortcut for new-chat project selection
33
36
  - add a fullscreen Mermaid diagram viewer with zoom controls
34
37
 
35
38
  The generated app includes a readable Codex Plus runtime under
36
39
  `webview/assets/codex-plus/`. Versioned ASAR patches install the runtime,
37
40
  built-in plugins, and the small Codex core hooks those plugins use. See
38
41
  [Runtime Plugin Support](docs/plugin-support.md) for the currently supported
39
- plugin interfaces.
42
+ plugin interfaces and [Plugin Architecture](docs/plugin-architecture.md) for
43
+ the layer rules.
40
44
 
41
45
  ## How It Works
42
46
 
@@ -112,6 +116,13 @@ Print the machine-readable result:
112
116
  codex-plus-patcher apply --dry-run --json
113
117
  ```
114
118
 
119
+ Inspect menu-related patch markers in a generated app:
120
+
121
+ ```bash
122
+ codex-plus-patcher menu-diagnostics \
123
+ --asar "~/Applications/Codex Plus.app/Contents/Resources/app.asar"
124
+ ```
125
+
115
126
  For local development of the CLI wrapper:
116
127
 
117
128
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-plus-patcher",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "description": "Patch queue tool for building a local Codex Plus.app from an installed Codex.app.",
6
6
  "repository": {
@@ -21,13 +21,16 @@
21
21
  ],
22
22
  "scripts": {
23
23
  "test": "node --test",
24
- "check": "node scripts/check-syntax.js"
24
+ "check": "node scripts/check-syntax.js",
25
+ "check:pr": "node scripts/safe-automerge-pr.js --check",
26
+ "pr:automerge": "node scripts/safe-automerge-pr.js"
25
27
  },
26
28
  "engines": {
27
29
  "node": ">=20"
28
30
  },
29
31
  "license": "Apache-2.0",
30
32
  "dependencies": {
33
+ "fzf": "0.5.2",
31
34
  "ora": "^9.4.0"
32
35
  }
33
36
  }
package/src/cli.js CHANGED
@@ -62,6 +62,7 @@ function helpText() {
62
62
  return `Usage:
63
63
  codex-plus-patcher
64
64
  codex-plus-patcher apply [options]
65
+ codex-plus-patcher menu-diagnostics --asar <path> [--json]
65
66
  codex-plus-patcher asar-list --asar <path> [--contains <text>] [--json]
66
67
  codex-plus-patcher asar-cat --asar <path> --file <asar-path> [--json]
67
68
 
@@ -156,6 +157,67 @@ function readAsarFile({ asar, file }) {
156
157
  return { asar, file, size, content };
157
158
  }
158
159
 
160
+ function readPackedEntry(archive, node) {
161
+ if (node.unpacked) return null;
162
+ const size = Number(node.size || 0);
163
+ const start = archive.dataStart + Number(node.offset || 0);
164
+ return archive.buffer.subarray(start, start + size).toString("utf8");
165
+ }
166
+
167
+ function menuDiagnostics({ asar }) {
168
+ if (!asar) throw new Error("--asar is required");
169
+ const archive = readAsar(asar);
170
+ const files = walkFiles(archive.header);
171
+ const commandId = "codexPlusOpenDevTools";
172
+ const menuTitle = "Open Developer Tools";
173
+ const commandMetadataFiles = [];
174
+ const nativeBridgeFiles = [];
175
+ const runtimePluginFiles = [];
176
+ const applicationMenuFiles = [];
177
+
178
+ for (const [file, node] of files) {
179
+ if (!file.endsWith(".js")) continue;
180
+ const content = readPackedEntry(archive, node);
181
+ if (content == null) continue;
182
+ const hasDevToolsCommand = content.includes(commandId);
183
+ const hasMenuTitle = content.includes(menuTitle);
184
+ const hasToggleBottomPanel = content.includes("Toggle Bottom Panel") || content.includes("toggleBottomPanel");
185
+ const hasPanelsGroup = content.includes("commandMenuGroupKey:`panels`") || content.includes('commandMenuGroupKey:"panels"');
186
+ const hasNativeBridge = content.includes("devtools/open") || content.includes("CPXOpenDevTools");
187
+ const hasRuntimePlugin = file.endsWith("/devTools.js") || content.includes('id: "devTools"');
188
+ const hasApplicationMenu = content.includes("Menu.setApplicationMenu") || content.includes("refreshApplicationMenu");
189
+
190
+ if (hasPanelsGroup || hasDevToolsCommand || file.includes("electron-menu-shortcuts")) {
191
+ commandMetadataFiles.push({
192
+ file,
193
+ hasDevToolsCommand,
194
+ hasMenuTitle,
195
+ hasToggleBottomPanel,
196
+ hasPanelsGroup,
197
+ });
198
+ }
199
+ if (hasNativeBridge) nativeBridgeFiles.push({ file, hasDevToolsOpenRequest: content.includes("devtools/open"), hasOpenDevToolsCall: content.includes("openDevTools") });
200
+ if (hasRuntimePlugin) runtimePluginFiles.push({ file, hasDevToolsCommand, hasDevToolsOpenRequest: content.includes("devtools/open") });
201
+ if (hasApplicationMenu) applicationMenuFiles.push({ file, hasDiagnosticsHook: content.includes("CPXLogMenuDiagnostics"), hasDevToolsCommand });
202
+ }
203
+
204
+ return {
205
+ asar,
206
+ commandId,
207
+ menuTitle,
208
+ commandMetadataFiles,
209
+ nativeBridgeFiles,
210
+ runtimePluginFiles,
211
+ applicationMenuFiles,
212
+ summary: {
213
+ commandMetadataFilesWithCommand: commandMetadataFiles.filter((entry) => entry.hasDevToolsCommand).map((entry) => entry.file),
214
+ nativeBridgeFilesWithRequest: nativeBridgeFiles.filter((entry) => entry.hasDevToolsOpenRequest).map((entry) => entry.file),
215
+ runtimePluginFilesWithCommand: runtimePluginFiles.filter((entry) => entry.hasDevToolsCommand).map((entry) => entry.file),
216
+ applicationMenuFilesWithDiagnostics: applicationMenuFiles.filter((entry) => entry.hasDiagnosticsHook).map((entry) => entry.file),
217
+ },
218
+ };
219
+ }
220
+
159
221
  function formatAsarListResult(result) {
160
222
  return result.files.length > 0 ? `${result.files.join("\n")}\n` : "";
161
223
  }
@@ -164,6 +226,34 @@ function formatAsarCatResult(result) {
164
226
  return result.content;
165
227
  }
166
228
 
229
+ function formatMenuDiagnosticsResult(result) {
230
+ const lines = [
231
+ `ASAR: ${result.asar}`,
232
+ `Command: ${result.commandId}`,
233
+ "",
234
+ "Command metadata bundles:",
235
+ ...result.commandMetadataFiles.map((entry) =>
236
+ `- ${entry.file}: command=${entry.hasDevToolsCommand ? "yes" : "no"}, title=${entry.hasMenuTitle ? "yes" : "no"}, bottomPanel=${entry.hasToggleBottomPanel ? "yes" : "no"}, panels=${entry.hasPanelsGroup ? "yes" : "no"}`,
237
+ ),
238
+ "",
239
+ "Native bridge bundles:",
240
+ ...result.nativeBridgeFiles.map((entry) =>
241
+ `- ${entry.file}: request=${entry.hasDevToolsOpenRequest ? "yes" : "no"}, openDevTools=${entry.hasOpenDevToolsCall ? "yes" : "no"}`,
242
+ ),
243
+ "",
244
+ "Runtime plugin bundles:",
245
+ ...result.runtimePluginFiles.map((entry) =>
246
+ `- ${entry.file}: command=${entry.hasDevToolsCommand ? "yes" : "no"}, request=${entry.hasDevToolsOpenRequest ? "yes" : "no"}`,
247
+ ),
248
+ "",
249
+ "Application menu bundles:",
250
+ ...result.applicationMenuFiles.map((entry) =>
251
+ `- ${entry.file}: diagnosticsHook=${entry.hasDiagnosticsHook ? "yes" : "no"}, command=${entry.hasDevToolsCommand ? "yes" : "no"}`,
252
+ ),
253
+ ];
254
+ return `${lines.join("\n")}\n`;
255
+ }
256
+
167
257
  function formatError(error, { debug = false } = {}) {
168
258
  if (debug || process.env.CODEX_PLUS_PATCHER_DEBUG === "1") return error.stack || error.message || String(error);
169
259
  return `Error: ${error.message || String(error)}`;
@@ -232,6 +322,11 @@ async function main() {
232
322
  process.stdout.write(args.json ? `${JSON.stringify(result, null, 2)}\n` : formatAsarCatResult(result));
233
323
  return;
234
324
  }
325
+ if (args.command === "menu-diagnostics") {
326
+ const result = menuDiagnostics(args);
327
+ process.stdout.write(args.json ? `${JSON.stringify(result, null, 2)}\n` : formatMenuDiagnosticsResult(result));
328
+ return;
329
+ }
235
330
  if (args.command !== "apply") throw new Error(`Unknown command: ${args.command}`);
236
331
 
237
332
  const patchSets = await loadPatchSets(args);
@@ -266,10 +361,12 @@ module.exports = {
266
361
  formatAsarCatResult,
267
362
  formatAsarListResult,
268
363
  formatError,
364
+ formatMenuDiagnosticsResult,
269
365
  formatResult,
270
366
  helpText,
271
367
  listAsarFiles,
272
368
  loadPatchSets,
369
+ menuDiagnostics,
273
370
  parseArgs,
274
371
  readAsarFile,
275
372
  requirePatchSetModule,
@@ -15,6 +15,8 @@ module.exports = buildCodexPlusPatchSet({
15
15
  "threadSidePanelTabs": "webview/assets/thread-side-panel-tabs-D0dd27Zf.js",
16
16
  "userMessageAttachments": "webview/assets/user-message-attachments-CgyXEK9U.js",
17
17
  "composer": "webview/assets/composer-CCuv6v-2.js",
18
+ "localActiveWorkspaceRootDropdown": "webview/assets/local-active-workspace-root-dropdown-ymhXI2RF.js",
19
+ "runCommand": "webview/assets/run-command-D6apgII3.js",
18
20
  "localTaskRow": "webview/assets/local-task-row-vTrSC6Rc.js",
19
21
  "keyboardShortcutsSearchInput": "webview/assets/keyboard-shortcuts-search-input-DjVpifwp.js",
20
22
  "src": "src-C7fSIbpz.js",
@@ -15,6 +15,8 @@ module.exports = buildCodexPlusPatchSet({
15
15
  "threadSidePanelTabs": "webview/assets/thread-side-panel-tabs-D0dd27Zf.js",
16
16
  "userMessageAttachments": "webview/assets/user-message-attachments-CgyXEK9U.js",
17
17
  "composer": "webview/assets/composer-CCuv6v-2.js",
18
+ "localActiveWorkspaceRootDropdown": "webview/assets/local-active-workspace-root-dropdown-ymhXI2RF.js",
19
+ "runCommand": "webview/assets/run-command-D6apgII3.js",
18
20
  "localTaskRow": "webview/assets/local-task-row-vTrSC6Rc.js",
19
21
  "keyboardShortcutsSearchInput": "webview/assets/keyboard-shortcuts-search-input-DjVpifwp.js",
20
22
  "src": "src-C7fSIbpz.js",
@@ -11,10 +11,16 @@ module.exports = buildCodexPlusPatchSet({
11
11
  "appShell": "webview/assets/app-shell-0b-x_r3Z.js",
12
12
  "errorBoundary": "webview/assets/error-boundary-BOla93vo.js",
13
13
  "generalSettings": "webview/assets/general-settings-U7DFIZBC.js",
14
+ "header": "webview/assets/header-DgzE38hF.js",
15
+ "threadPageHeader": "webview/assets/thread-page-header-D_hZ50OA.js",
16
+ "localConversationPage": "webview/assets/local-conversation-page-dVDt8SxG.js",
17
+ "threadContext": "webview/assets/thread-context-B0hBrRyZ.js",
14
18
  "sidebarProjectHoverCardSourceRows": "webview/assets/sidebar-project-hover-card-source-rows-DtE7St1r.js",
15
19
  "threadSidePanelTabs": "webview/assets/thread-side-panel-tabs-CLuB2SaS.js",
16
20
  "userMessageAttachments": "webview/assets/user-message-attachments-5G1ZKim-.js",
17
21
  "composer": "webview/assets/composer-DlMDPaCL.js",
22
+ "localActiveWorkspaceRootDropdown": "webview/assets/local-active-workspace-root-dropdown-B28GluSz.js",
23
+ "runCommand": "webview/assets/run-command-B0E8hx7Q.js",
18
24
  "localTaskRow": "webview/assets/local-task-row-CoPNn6SW.js",
19
25
  "mermaidDiagramShell": "webview/assets/mermaid-diagram-shell-BO-t9BGx.js",
20
26
  "keyboardShortcutsSearchInput": "webview/assets/keyboard-shortcuts-search-input-C1dmntOi.js",
@@ -7,14 +7,21 @@ module.exports = buildCodexPlusPatchSet({
7
7
  "asarSha256": "7f45c6a6bad9c6fabe2226e8f7e0aae3792eca8c59f24305b5f2996ee4b37e40",
8
8
  "files": {
9
9
  "main": ".vite/build/main-dSxbxAhH.js",
10
+ "electronCommandSource": ".vite/build/src-DBVh5FZA.js",
10
11
  "appMain": "webview/assets/app-main-Dldh3K_n.js",
11
12
  "appShell": "webview/assets/app-shell-0b-x_r3Z.js",
12
13
  "errorBoundary": "webview/assets/error-boundary-BOla93vo.js",
13
14
  "generalSettings": "webview/assets/general-settings-U7DFIZBC.js",
15
+ "header": "webview/assets/header-DgzE38hF.js",
16
+ "threadPageHeader": "webview/assets/thread-page-header-D_hZ50OA.js",
17
+ "localConversationPage": "webview/assets/local-conversation-page-dVDt8SxG.js",
18
+ "threadContext": "webview/assets/thread-context-B0hBrRyZ.js",
14
19
  "sidebarProjectHoverCardSourceRows": "webview/assets/sidebar-project-hover-card-source-rows-DtE7St1r.js",
15
20
  "threadSidePanelTabs": "webview/assets/thread-side-panel-tabs-CLuB2SaS.js",
16
21
  "userMessageAttachments": "webview/assets/user-message-attachments-5G1ZKim-.js",
17
22
  "composer": "webview/assets/composer-DlMDPaCL.js",
23
+ "localActiveWorkspaceRootDropdown": "webview/assets/local-active-workspace-root-dropdown-B28GluSz.js",
24
+ "runCommand": "webview/assets/run-command-B0E8hx7Q.js",
18
25
  "localTaskRow": "webview/assets/local-task-row-CoPNn6SW.js",
19
26
  "mermaidDiagramShell": "webview/assets/mermaid-diagram-shell-BO-t9BGx.js",
20
27
  "keyboardShortcutsSearchInput": "webview/assets/keyboard-shortcuts-search-input-C1dmntOi.js",