codex-devtools 0.1.1 → 0.1.3

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
@@ -1,117 +1,124 @@
1
- # codex-devtools
1
+ <p align="center">
2
+ <img src="resources/logo.png" width="120" alt="codex-devtools logo" />
3
+ </p>
2
4
 
3
- Desktop app for inspecting Codex session data.
5
+ <h1 align="center">codex-devtools</h1>
4
6
 
5
- ## Prerequisites
7
+ <p align="center">
8
+ Desktop inspector for <a href="https://github.com/openai/codex">Codex</a> session data.
9
+ <br />
10
+ Browse conversations, search messages, and analyze agent activity across sessions.
11
+ </p>
6
12
 
7
- - Node.js 20+ (Node 24 works)
8
- - `pnpm` 10 (via Corepack recommended)
13
+ <p align="center">
14
+ <a href="https://www.npmjs.com/package/codex-devtools"><img src="https://img.shields.io/npm/v/codex-devtools" alt="npm version" /></a>
15
+ <a href="https://github.com/gulivan/codex-devtools/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/codex-devtools" alt="license" /></a>
16
+ </p>
9
17
 
10
- ## Build and run
18
+ ---
11
19
 
12
- ```bash
13
- cd /Users/ivan/git/codex-devtools
14
- corepack enable
15
- pnpm install
16
- pnpm approve-builds
17
- ```
20
+ ## Quick start
18
21
 
19
- In `pnpm approve-builds`, approve:
20
-
21
- - `electron`
22
- - `esbuild`
23
-
24
- Then start the desktop app in development mode:
22
+ > Requires **Node.js 20+** and **pnpm 10** (Corepack recommended).
25
23
 
26
24
  ```bash
27
- pnpm dev
25
+ git clone https://github.com/gulivan/codex-devtools.git
26
+ cd codex-devtools
27
+ corepack enable
28
+ pnpm install
29
+ pnpm approve-builds # approve electron and esbuild
30
+ pnpm dev # launch Electron app in dev mode
28
31
  ```
29
32
 
30
- ## Production build
33
+ Or run instantly via npm without cloning:
31
34
 
32
35
  ```bash
33
- pnpm build
36
+ npx codex-devtools
37
+ # or
38
+ bunx codex-devtools
34
39
  ```
35
40
 
36
- Build artifacts are generated in:
41
+ This starts a standalone HTTP server at `http://localhost:3456`.
37
42
 
38
- - `dist-electron`
39
- - `out/renderer`
43
+ ## Standalone mode
40
44
 
41
- Create desktop installers/packages locally:
45
+ Run as an HTTP server without Electron:
42
46
 
43
47
  ```bash
44
- pnpm dist
48
+ pnpm standalone
45
49
  ```
46
50
 
47
- Platform-specific package commands:
48
-
49
- - `pnpm dist:mac` (macOS: `.dmg`, `.zip`)
50
- - `pnpm dist:win` (Windows: NSIS installer)
51
- - `pnpm dist:linux` (Linux: AppImage, `.deb`, `.rpm`)
52
-
53
- ## Standalone mode
51
+ Opens at `http://localhost:3456` by default.
54
52
 
55
- Run as an HTTP server (without launching Electron):
53
+ ## Production build
56
54
 
57
55
  ```bash
58
- pnpm standalone
56
+ pnpm build # compile renderer + main/preload
57
+ pnpm dist # create installers for all platforms
59
58
  ```
60
59
 
61
- Default URL:
60
+ Platform-specific:
61
+
62
+ | Command | Output |
63
+ |---------|--------|
64
+ | `pnpm dist:mac` | `.dmg`, `.zip` |
65
+ | `pnpm dist:win` | NSIS installer |
66
+ | `pnpm dist:linux` | AppImage, `.deb`, `.rpm` |
62
67
 
63
- - `http://localhost:3456`
68
+ Build artifacts land in `release/`.
64
69
 
65
70
  ## Environment variables
66
71
 
67
- - `CODEX_SESSIONS_PATH`: path to Codex sessions directory (default: `~/.codex/sessions`)
68
- - `HOST`: standalone server host (default: `0.0.0.0`)
69
- - `PORT`: standalone server port (default: `3456`)
72
+ | Variable | Default | Description |
73
+ |----------|---------|-------------|
74
+ | `CODEX_SESSIONS_PATH` | `~/.codex/sessions` | Path to Codex sessions directory |
75
+ | `HOST` | `0.0.0.0` | Standalone server host |
76
+ | `PORT` | `3456` | Standalone server port |
70
77
 
71
78
  ## Scripts
72
79
 
73
- - `pnpm dev`: start Electron app in dev mode
74
- - `pnpm build`: build renderer + Electron main/preload
75
- - `pnpm dist`: build macOS + Windows + Linux packages
76
- - `pnpm dist:mac`: build macOS packages
77
- - `pnpm dist:win`: build Windows installer
78
- - `pnpm dist:linux`: build Linux packages
79
- - `pnpm standalone`: build and run standalone HTTP server
80
- - `pnpm test`: run tests with Vitest
81
- - `pnpm lint`: run ESLint
82
- - `pnpm typecheck`: run TypeScript type checks
80
+ | Script | Description |
81
+ |--------|-------------|
82
+ | `pnpm dev` | Electron app in dev mode |
83
+ | `pnpm build` | Build renderer + Electron main/preload |
84
+ | `pnpm standalone` | Build and run standalone HTTP server |
85
+ | `pnpm dist` | Package for macOS + Windows + Linux |
86
+ | `pnpm dist:mac` | Package for macOS |
87
+ | `pnpm dist:win` | Package for Windows |
88
+ | `pnpm dist:linux` | Package for Linux |
89
+ | `pnpm test` | Run tests (Vitest) |
90
+ | `pnpm lint` | Run ESLint |
91
+ | `pnpm typecheck` | TypeScript type checks |
83
92
 
84
93
  ## CI/CD
85
94
 
86
- - `.github/workflows/ci.yml`: typecheck/lint/build/test on `main` and PRs.
87
- - `.github/workflows/release.yml`: cross-platform packaging on semver tags (`v*`) and manual dispatch.
88
- - `.github/workflows/npm-publish.yml`: npm publish on semver tags (`v*`) and manual dispatch.
89
-
90
- Required GitHub repository secret for npm publishing:
91
-
92
- - `NPM_TOKEN`: npm automation token (or granular token with publish + 2FA bypass).
93
-
94
- ## Versioning (SemVer)
95
+ | Workflow | Trigger | Action |
96
+ |----------|---------|--------|
97
+ | `ci.yml` | Push to `main`, PRs | Typecheck, lint, build, test |
98
+ | `release.yml` | Semver tags (`v*`), manual | Cross-platform packaging |
99
+ | `npm-publish.yml` | Semver tags (`v*`), manual | Publish to npm |
95
100
 
96
- Releases use semantic version tags:
101
+ Required secret: `NPM_TOKEN` (npm automation token with publish + 2FA bypass).
97
102
 
98
- - `vMAJOR.MINOR.PATCH` (example: `v0.1.1`)
99
- - optional pre-release/build metadata (`v1.2.3-beta.1`, `v1.2.3+build.4`)
100
-
101
- Tag and publish flow:
103
+ ## Releasing
102
104
 
103
105
  ```bash
104
- npm version patch
106
+ npm version patch # bumps version and creates git tag
105
107
  git push origin main --follow-tags
106
108
  ```
107
109
 
108
- `release.yml` and `npm-publish.yml` validate tag format and fail if the tag is not valid SemVer.
110
+ Tags must be valid semver (`vMAJOR.MINOR.PATCH`). Pre-release metadata supported (`v1.2.3-beta.1`).
109
111
 
110
112
  ## Troubleshooting
111
113
 
112
- If `pnpm dev` fails with `Electron failed to install correctly` or `Electron uninstall`:
114
+ **`Electron failed to install correctly`**
115
+
116
+ ```bash
117
+ pnpm approve-builds # approve electron and esbuild
118
+ pnpm install
119
+ pnpm dev
120
+ ```
121
+
122
+ ## License
113
123
 
114
- 1. Run `pnpm approve-builds`
115
- 2. Approve `electron` and `esbuild`
116
- 3. Run `pnpm install` again
117
- 4. Retry `pnpm dev`
124
+ [MIT](LICENSE)
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const { existsSync } = require('node:fs');
5
+ const { join } = require('node:path');
6
+
7
+ const standaloneEntrypoint = join(__dirname, '..', 'dist-electron', 'main', 'standalone.cjs');
8
+
9
+ if (!existsSync(standaloneEntrypoint)) {
10
+ console.error(
11
+ '[codex-devtools] Missing standalone bundle. Reinstall package or run a version that includes dist-electron output.',
12
+ );
13
+ process.exit(1);
14
+ }
15
+
16
+ const standaloneModule = require(standaloneEntrypoint);
17
+
18
+ if (typeof standaloneModule.startStandaloneCli !== 'function') {
19
+ console.error('[codex-devtools] Invalid standalone entrypoint: startStandaloneCli export not found.');
20
+ process.exit(1);
21
+ }
22
+
23
+ standaloneModule.startStandaloneCli();
@@ -187,7 +187,8 @@ const logger = CodexServiceContext.createLogger("Standalone");
187
187
  const __filename$1 = node_url.fileURLToPath(require("url").pathToFileURL(__filename).href);
188
188
  const __dirname$1 = path.dirname(__filename$1);
189
189
  const createStandaloneServer = async (options = {}) => {
190
- const app = Fastify({ logger: true });
190
+ const enableHttpLogs = process.env.CODEX_DEVTOOLS_HTTP_LOGS === "1";
191
+ const app = Fastify({ logger: enableHttpLogs });
191
192
  const serviceContext = new CodexServiceContext.CodexServiceContext({
192
193
  sessionsPath: options.sessionsPath ?? process.env.CODEX_SESSIONS_PATH,
193
194
  configPath: options.configPath
@@ -7734,7 +7734,7 @@ const createAppStore = (client2 = api) => create()((...args) => ({
7734
7734
  }));
7735
7735
  const useAppStore = createAppStore();
7736
7736
  const REFRESH_DEBOUNCE_MS = 120;
7737
- const FALLBACK_POLL_INTERVAL_MS = 1500;
7737
+ const FALLBACK_POLL_INTERVAL_MS = 15e3;
7738
7738
  function initializeEventListeners(store = useAppStore, client2 = api) {
7739
7739
  let refreshTimer = null;
7740
7740
  let pollTimer = null;
@@ -7761,6 +7761,9 @@ function initializeEventListeners(store = useAppStore, client2 = api) {
7761
7761
  }, REFRESH_DEBOUNCE_MS);
7762
7762
  });
7763
7763
  const runFallbackRefresh = () => {
7764
+ if (typeof document !== "undefined" && document.visibilityState !== "visible") {
7765
+ return;
7766
+ }
7764
7767
  if (polling) {
7765
7768
  return;
7766
7769
  }
@@ -11564,6 +11567,7 @@ const DateGroupedSessions = () => {
11564
11567
  const {
11565
11568
  sessions,
11566
11569
  sessionsLoading,
11570
+ activeProjectCwd,
11567
11571
  activeSessionId,
11568
11572
  sessionPreviews,
11569
11573
  sessionUpdateBadges,
@@ -11572,6 +11576,7 @@ const DateGroupedSessions = () => {
11572
11576
  } = useAppStore((state) => ({
11573
11577
  sessions: state.sessions,
11574
11578
  sessionsLoading: state.sessionsLoading,
11579
+ activeProjectCwd: state.activeProjectCwd,
11575
11580
  activeSessionId: state.activeSessionId,
11576
11581
  sessionPreviews: state.sessionPreviews,
11577
11582
  sessionUpdateBadges: state.sessionUpdateBadges,
@@ -11594,7 +11599,7 @@ const DateGroupedSessions = () => {
11594
11599
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sidebar-loading", children: "Loading sessions..." });
11595
11600
  }
11596
11601
  if (groups.length === 0) {
11597
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sidebar-empty", children: "No sessions found for this project." });
11602
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sidebar-empty", children: activeProjectCwd ? "No sessions found for this project." : "Select a project to load sessions." });
11598
11603
  }
11599
11604
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "session-groups", children: groups.map((group) => /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "session-group", children: [
11600
11605
  /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "session-group-title", children: group.label }),
@@ -11679,6 +11684,11 @@ const Sidebar = () => {
11679
11684
  }
11680
11685
  )
11681
11686
  ] }),
11687
+ !projectsLoading && projects.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sidebar-empty", children: [
11688
+ "No projects discovered. Set ",
11689
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: "CODEX_SESSIONS_PATH" }),
11690
+ " and restart."
11691
+ ] }) : null,
11682
11692
  /* @__PURE__ */ jsxRuntimeExports.jsx(DateGroupedSessions, {})
11683
11693
  ] });
11684
11694
  };
@@ -555,6 +555,9 @@ video {
555
555
  max-width: 1536px;
556
556
  }
557
557
  }
558
+ .visible {
559
+ visibility: visible;
560
+ }
558
561
  .static {
559
562
  position: static;
560
563
  }
@@ -3,9 +3,12 @@
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="icon" type="image/png" sizes="256x256" href="./assets/256x256-DdIsGiwi.png" />
7
+ <link rel="icon" type="image/png" sizes="32x32" href="./assets/32x32-DQgygEFU.png" />
8
+ <link rel="icon" type="image/png" sizes="16x16" href="./assets/16x16-B2_QkmoB.png" />
6
9
  <title>codex-devtools</title>
7
- <script type="module" crossorigin src="./assets/index-CR8-JZrV.js"></script>
8
- <link rel="stylesheet" crossorigin href="./assets/index-r_pK0Xle.css">
10
+ <script type="module" crossorigin src="./assets/index-NyaijTgK.js"></script>
11
+ <link rel="stylesheet" crossorigin href="./assets/index-z5pXbBkY.css">
9
12
  </head>
10
13
  <body class="bg-slate-950 text-slate-100">
11
14
  <div id="root">
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "codex-devtools",
3
3
  "type": "module",
4
- "version": "0.1.1",
4
+ "version": "0.1.3",
5
5
  "description": "Desktop app for inspecting Codex session data",
6
6
  "license": "MIT",
7
7
  "author": {
@@ -17,7 +17,11 @@
17
17
  "url": "https://github.com/gulivan/codex-devtools/issues"
18
18
  },
19
19
  "main": "dist-electron/main/index.cjs",
20
+ "bin": {
21
+ "codex-devtools": "bin/codex-devtools.cjs"
22
+ },
20
23
  "files": [
24
+ "bin/**",
21
25
  "dist-electron/**",
22
26
  "out/renderer/**",
23
27
  "README.md"
@@ -85,7 +89,9 @@
85
89
  "extraMetadata": {
86
90
  "main": "dist-electron/main/index.cjs"
87
91
  },
92
+ "icon": "resources/icon.png",
88
93
  "mac": {
94
+ "icon": "resources/icon.icns",
89
95
  "category": "public.app-category.developer-tools",
90
96
  "target": [
91
97
  "dmg",