codex-devtools 0.1.9 → 0.1.11

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.
package/README.md CHANGED
@@ -50,6 +50,12 @@ bunx codex-devtools --web
50
50
 
51
51
  Standalone mode serves at `http://localhost:3456`.
52
52
 
53
+ To make web mode the default without flags:
54
+
55
+ ```bash
56
+ CODEX_DEVTOOLS_DEFAULT_MODE=web npx codex-devtools
57
+ ```
58
+
53
59
  ## Standalone mode
54
60
 
55
61
  Run as an HTTP server without Electron:
@@ -1,18 +1,58 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- const { existsSync } = require('node:fs');
5
- const { join } = require('node:path');
6
- const { spawn } = require('node:child_process');
4
+ const { copyFileSync, existsSync } = require('node:fs');
5
+ const { join, resolve } = require('node:path');
6
+ const { spawn, spawnSync } = require('node:child_process');
7
7
 
8
8
  const APP_ROOT = join(__dirname, '..');
9
9
  const ELECTRON_ENTRY = join(APP_ROOT, 'dist-electron', 'main', 'index.cjs');
10
10
  const STANDALONE_ENTRY = join(APP_ROOT, 'dist-electron', 'main', 'standalone.cjs');
11
+ const APP_DISPLAY_NAME = 'codex-devtools';
12
+ const APP_BUNDLE_ID = 'com.codex.devtools.dev';
11
13
 
12
14
  function hasArg(flag) {
13
15
  return process.argv.includes(flag);
14
16
  }
15
17
 
18
+ function runCommand(command, args) {
19
+ const result = spawnSync(command, args, { stdio: 'ignore' });
20
+ return result.status === 0;
21
+ }
22
+
23
+ function patchMacElectronBundle(electronBinary) {
24
+ if (process.platform !== 'darwin') {
25
+ return;
26
+ }
27
+
28
+ try {
29
+ const appContents = resolve(electronBinary, '..', '..');
30
+ const plistPath = join(appContents, 'Info.plist');
31
+ const sourceIcon = join(APP_ROOT, 'resources', 'icon.icns');
32
+ const targetIcon = join(appContents, 'Resources', 'electron.icns');
33
+
34
+ if (!existsSync(plistPath)) {
35
+ return;
36
+ }
37
+
38
+ const replacements = [
39
+ ['CFBundleDisplayName', APP_DISPLAY_NAME],
40
+ ['CFBundleName', APP_DISPLAY_NAME],
41
+ ['CFBundleIdentifier', APP_BUNDLE_ID],
42
+ ];
43
+
44
+ for (const [key, value] of replacements) {
45
+ runCommand('plutil', ['-replace', key, '-string', value, plistPath]);
46
+ }
47
+
48
+ if (existsSync(sourceIcon)) {
49
+ copyFileSync(sourceIcon, targetIcon);
50
+ }
51
+ } catch {
52
+ // Best effort only; launch should continue even if patching fails.
53
+ }
54
+ }
55
+
16
56
  function runStandalone() {
17
57
  if (!existsSync(STANDALONE_ENTRY)) {
18
58
  console.error('[codex-devtools] Missing standalone bundle. Reinstall package and try again.');
@@ -47,10 +87,13 @@ function runDesktop() {
47
87
  process.exit(1);
48
88
  }
49
89
 
90
+ patchMacElectronBundle(electronBinary);
91
+
50
92
  const forwardedArgs = process.argv.slice(2).filter((arg) => arg !== '--desktop');
51
93
  const child = spawn(electronBinary, [APP_ROOT, ...forwardedArgs], {
52
94
  stdio: 'inherit',
53
95
  env: process.env,
96
+ argv0: APP_DISPLAY_NAME,
54
97
  });
55
98
 
56
99
  child.on('error', (error) => {
@@ -75,11 +118,18 @@ if (hasArg('--help') || hasArg('-h')) {
75
118
  console.log(' codex-devtools Launch Electron desktop app (default)');
76
119
  console.log(' codex-devtools --web Run standalone HTTP mode');
77
120
  console.log(' codex-devtools --desktop Force desktop mode');
121
+ console.log('');
122
+ console.log('Environment:');
123
+ console.log(' CODEX_DEVTOOLS_DEFAULT_MODE=web Use web mode by default');
78
124
  process.exit(0);
79
125
  }
80
126
 
81
127
  if (hasArg('--web') || hasArg('--standalone')) {
82
128
  runStandalone();
129
+ } else if (hasArg('--desktop')) {
130
+ runDesktop();
131
+ } else if ((process.env.CODEX_DEVTOOLS_DEFAULT_MODE || '').toLowerCase() === 'web') {
132
+ runStandalone();
83
133
  } else {
84
134
  runDesktop();
85
135
  }
@@ -240,6 +240,7 @@ function disposeServices() {
240
240
  }
241
241
  }
242
242
  electron.app.setName(APP_DISPLAY_NAME);
243
+ process.title = APP_DISPLAY_NAME;
243
244
  void electron.app.whenReady().then(() => {
244
245
  const iconPath = resolveAppIconPath();
245
246
  if (iconPath && process.platform === "darwin" && electron.app.dock) {
@@ -7142,6 +7142,7 @@ function resolveApi() {
7142
7142
  }
7143
7143
  return cachedHttpApi;
7144
7144
  }
7145
+ const isElectronMode = () => getWindowApi() !== null;
7145
7146
  const api = new Proxy({}, {
7146
7147
  get(_target, prop, receiver) {
7147
7148
  const impl = resolveApi();
@@ -7484,6 +7485,7 @@ function isCodexBootstrapMessage(content) {
7484
7485
  }
7485
7486
  const logger = createLogger("Store:sessionSlice");
7486
7487
  const PREVIEW_PREFETCH_LIMIT = 25;
7488
+ const DEFAULT_PREFETCH_PREVIEWS = isElectronMode();
7487
7489
  function normalizeFilePath(value) {
7488
7490
  return value.trim().replace(/\\/g, "/").replace(/\/+/g, "/");
7489
7491
  }
@@ -7527,7 +7529,7 @@ const createSessionSlice = (client2) => (set, get) => ({
7527
7529
  set({ sessions: [], activeSessionId: null });
7528
7530
  return;
7529
7531
  }
7530
- const shouldPrefetchPreviews = (_a = options == null ? void 0 : options.prefetchPreviews) != null ? _a : true;
7532
+ const shouldPrefetchPreviews = (_a = options == null ? void 0 : options.prefetchPreviews) != null ? _a : DEFAULT_PREFETCH_PREVIEWS;
7531
7533
  const isBackgroundRefresh = (_b = options == null ? void 0 : options.background) != null ? _b : false;
7532
7534
  if (!isBackgroundRefresh) {
7533
7535
  set({ sessionsLoading: true, sessionsError: null });
@@ -7734,7 +7736,7 @@ const createAppStore = (client2 = api) => create()((...args) => ({
7734
7736
  }));
7735
7737
  const useAppStore = createAppStore();
7736
7738
  const REFRESH_DEBOUNCE_MS = 120;
7737
- const FALLBACK_POLL_INTERVAL_MS = 15e3;
7739
+ const FALLBACK_POLL_INTERVAL_MS = 5e3;
7738
7740
  function initializeEventListeners(store = useAppStore, client2 = api) {
7739
7741
  let refreshTimer = null;
7740
7742
  let pollTimer = null;
@@ -7,7 +7,7 @@
7
7
  <link rel="icon" type="image/png" sizes="32x32" href="./assets/32x32-DQgygEFU.png" />
8
8
  <link rel="icon" type="image/png" sizes="16x16" href="./assets/16x16-B2_QkmoB.png" />
9
9
  <title>codex-devtools</title>
10
- <script type="module" crossorigin src="./assets/index-C1DUQHyp.js"></script>
10
+ <script type="module" crossorigin src="./assets/index-BEzdp8iI.js"></script>
11
11
  <link rel="stylesheet" crossorigin href="./assets/index-BTmVA30y.css">
12
12
  </head>
13
13
  <body>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "codex-devtools",
3
3
  "type": "module",
4
- "version": "0.1.9",
4
+ "version": "0.1.11",
5
5
  "description": "Desktop app for inspecting Codex session data",
6
6
  "license": "MIT",
7
7
  "author": {
@@ -24,6 +24,7 @@
24
24
  "bin/**",
25
25
  "dist-electron/**",
26
26
  "out/renderer/**",
27
+ "resources/**",
27
28
  "README.md"
28
29
  ],
29
30
  "scripts": {
File without changes
Binary file
Binary file
File without changes
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file