Skip to content

feat(codex): add native Lumen plugin package - #184

Open
aeneasr wants to merge 6 commits into
mainfrom
aeneasr/fix-codex-lumen-path
Open

feat(codex): add native Lumen plugin package#184
aeneasr wants to merge 6 commits into
mainfrom
aeneasr/fix-codex-lumen-path

Conversation

@aeneasr

@aeneasr aeneasr commented Aug 7, 2026

Copy link
Copy Markdown
Member

Adds an isolated native Codex/Agent Plugins package with local marketplace metadata, MCP manifests, copied skills, and cross-platform launchers.

Updates launchers to honor PLUGIN_ROOT and store downloaded binaries in writable PLUGIN_DATA, with release metadata parity and platform tests. Refreshes Codex installation and migration docs, and adds a Linux Codex plugin install smoke test to CI.

Tests: make test; bash scripts/test_run.sh; make lint.

Summary by CodeRabbit

  • New Features

    • Added native Codex marketplace installation for the Lumen plugin.
    • Added cross-platform launchers that automatically download and manage the required Lumen binary.
    • Added Codex skills for diagnosing setup and refreshing search indexes.
    • Added native MCP configuration and plugin metadata.
  • Bug Fixes

    • Improved embedding-service health checks and model availability reporting.
    • Improved index status reporting and recovery after incomplete or failed indexing.
  • Documentation

    • Updated Codex installation, migration, update, verification, and uninstall guidance.
  • Tests

    • Added validation for plugin installations, packaged assets, and cross-platform releases.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 896ae99a-ee7d-4f5c-a330-7f9c7bf3d8bd

📥 Commits

Reviewing files that changed from the base of the PR and between c1fa452 and 68ed997.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/ci.yml

📝 Walkthrough

Walkthrough

The repository now distributes Lumen through a native Codex marketplace plugin. It adds plugin metadata, MCP configuration, skills, cross-platform launchers, writable binary storage, index health handling, installation checks, release validation, and updated documentation.

Changes

Codex plugin distribution

Layer / File(s) Summary
Plugin contracts and packaged assets
.agents/plugins/marketplace.json, plugins/lumen/..., release-please-config.json, package.json, .gitignore
Added plugin manifests, MCP configurations, Doctor and Reindex skills, marketplace metadata, packaged launcher entries, and release-version synchronization.
Cross-platform launcher runtime
plugins/lumen/scripts/*, scripts/run*
Launchers now separate package and writable data roots, locate existing binaries, resolve versions from supported manifests, download missing platform binaries, and execute Lumen.
Index health and embedding probes
cmd/hook.go, cmd/stdio.go, internal/embedder/*, internal/index/*, internal/store/store.go
Added shared backend probing and indexing-error metadata. Hooks and failover now distinguish healthy, stale, incomplete, and unhealthy states.
Distribution and installation validation
.github/workflows/*, internal/release/*, scripts/test_*, scripts/testdata/*, scripts/verify_opencode_package.mjs
Added metadata checks, asset-parity checks, installation smoke tests, artifact tests, OpenCode package verification, and Linux, macOS, and Windows CI coverage.
Codex installation guidance
.codex/INSTALL.md, README.md, AGENTS.md, CLAUDE.md
Replaced manual Codex setup with marketplace installation, migration, verification, update, recovery, and removal instructions. Updated repository integration guidance.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Codex
  participant LumenLauncher
  participant PluginData
  participant GitHubReleases
  participant LumenBinary
  Codex->>LumenLauncher: invoke MCP command
  LumenLauncher->>PluginData: search for executable
  LumenLauncher->>GitHubReleases: download versioned or latest asset
  GitHubReleases-->>PluginData: return platform binary
  LumenLauncher->>LumenBinary: execute with forwarded arguments
Loading

Possibly related PRs

  • ory/lumen#159: Related launcher, MCP configuration, and installation test changes.
  • ory/lumen#132: Related embedding failover and health-probe changes.
  • ory/lumen#183: Related session-start hook and index-status changes.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: adding a native Lumen plugin package for Codex.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch aeneasr/fix-codex-lumen-path

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@aeneasr
aeneasr marked this pull request as ready for review August 7, 2026 21:27
@aeneasr
aeneasr force-pushed the aeneasr/fix-codex-lumen-path branch from 28491a4 to 5a59bbe Compare August 8, 2026 20:42

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/test_run.sh`:
- Around line 151-154: Update resolved_version_from_plugin_manifest so ver is
declared separately before assigning the command-substitution result. Keep the
existing version extraction and v prefix unchanged, ensuring the assignment’s
exit status is preserved.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7daeed30-b401-49ee-954f-37dc3e8665ce

📥 Commits

Reviewing files that changed from the base of the PR and between 8039636 and 5a59bbe.

📒 Files selected for processing (21)
  • .agents/plugins/marketplace.json
  • .codex/INSTALL.md
  • .github/workflows/ci.yml
  • .gitignore
  • AGENTS.md
  • CLAUDE.md
  • README.md
  • internal/release/metadata_test.go
  • plugins/lumen/.codex-plugin/plugin.json
  • plugins/lumen/.mcp.json
  • plugins/lumen/mcp.json
  • plugins/lumen/plugin.json
  • plugins/lumen/scripts/run
  • plugins/lumen/scripts/run.cmd
  • plugins/lumen/skills/doctor/SKILL.md
  • plugins/lumen/skills/reindex/SKILL.md
  • release-please-config.json
  • scripts/run
  • scripts/run.cmd
  • scripts/test_run.sh
  • scripts/test_run_windows.ps1

Comment thread scripts/test_run.sh
aeneasr and others added 3 commits August 8, 2026 22:48
Addresses ShellCheck SC2155 flagged in review: `local ver="$(...)"`
masks the command substitution's exit status.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The static workaround removes libpthread.dll.a, which is absent on the
current windows-latest image and makes setup-mingw fail before the build
step runs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 69-70: Add explicit read-only token permissions to both CI jobs:
set contents: read under semantic_e2e at .github/workflows/ci.yml lines 69-70
and under build at lines 141-148. No other job permissions need changing.

In @.github/workflows/release-please.yml:
- Around line 63-65: Update the actions/checkout step in the release workflow to
set persist-credentials to false alongside the existing ref configuration,
ensuring subsequent canary steps cannot access persisted GitHub token
credentials.

In `@cmd/hook_test.go`:
- Around line 387-394: Ensure the test store created in this setup is closed on
every exit path by immediately deferring s.Close() after store.New succeeds,
before calling SetMeta. Update the setup around store.New and SetMeta; preserve
the existing fatal error handling and avoid relying on a later explicit close.

In `@internal/embedder/failover.go`:
- Around line 236-244: Update the Embed request flow so the caller context is
passed through findNextHealthy to probeHealth, replacing probeHealth’s
context.Background() timeout base with that propagated context while retaining
the healthCheckTimeout deadline.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b5f9a609-42b9-4e4c-9bc3-75c162ffe3a3

📥 Commits

Reviewing files that changed from the base of the PR and between 5a59bbe and c1fa452.

📒 Files selected for processing (21)
  • .github/workflows/ci.yml
  • .github/workflows/release-please.yml
  • cmd/hook.go
  • cmd/hook_test.go
  • cmd/stdio.go
  • cmd/stdio_test.go
  • internal/embedder/failover.go
  • internal/embedder/failover_test.go
  • internal/embedder/health.go
  • internal/index/index.go
  • internal/index/index_test.go
  • internal/release/artifact_smoke_test.go
  • internal/store/store.go
  • package.json
  • plugins/lumen/scripts/run.cmd
  • plugins/lumen/skills/reindex/SKILL.md
  • scripts/run.cmd
  • scripts/test_agent_installations.sh
  • scripts/test_run.sh
  • scripts/testdata/mcp_smoke_client/main.go
  • scripts/verify_opencode_package.mjs
🚧 Files skipped from review as they are similar to previous changes (4)
  • plugins/lumen/skills/reindex/SKILL.md
  • plugins/lumen/scripts/run.cmd
  • scripts/run.cmd
  • scripts/test_run.sh

Comment thread .github/workflows/ci.yml
Comment on lines +69 to +70
semantic_e2e:
name: Semantic E2E

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Set explicit read-only permissions for CI jobs.

Both jobs use repository-default token permissions. The semantic E2E job installs and executes external CLI packages. The build job executes dependency and test code. A repository setting can grant these jobs write scopes.

  • .github/workflows/ci.yml#L69-L70: add permissions: contents: read to semantic_e2e.
  • .github/workflows/ci.yml#L141-L148: add permissions: contents: read to build.
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 69-139: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)

📍 Affects 1 file
  • .github/workflows/ci.yml#L69-L70 (this comment)
  • .github/workflows/ci.yml#L141-L148
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 69 - 70, Add explicit read-only token
permissions to both CI jobs: set contents: read under semantic_e2e at
.github/workflows/ci.yml lines 69-70 and under build at lines 141-148. No other
job permissions need changing.

Source: Linters/SAST tools

Comment on lines +63 to +65
- uses: actions/checkout@v4
with:
ref: ${{ needs.release-please.outputs.tag_name }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Disable persisted checkout credentials.

The canary executes repository code and a downloaded artifact after this checkout. actions/checkout persists the GitHub token in local Git configuration by default. Set persist-credentials: false because later steps do not need Git authentication.

Proposed fix
       - uses: actions/checkout@v4
         with:
           ref: ${{ needs.release-please.outputs.tag_name }}
+          persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
with:
ref: ${{ needs.release-please.outputs.tag_name }}
- uses: actions/checkout@v4
with:
ref: ${{ needs.release-please.outputs.tag_name }}
persist-credentials: false
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 63-65: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release-please.yml around lines 63 - 65, Update the
actions/checkout step in the release workflow to set persist-credentials to
false alongside the existing ref configuration, ensuring subsequent canary steps
cannot access persisted GitHub token credentials.

Source: Linters/SAST tools

Comment thread cmd/hook_test.go
Comment on lines +387 to +394
s, err := store.New(dbPath, cfg.ServerDims(0))
if err != nil {
t.Fatalf("store.New: %v", err)
}
if err := s.SetMeta(store.MetaLastIndexError, "embed batch: no models loaded"); err != nil {
t.Fatalf("SetMeta: %v", err)
}
_ = s.Close()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Close the test store on every exit path.

If s.SetMeta fails, Line 392 calls t.Fatalf before Line 394 closes s. This can retain database handles and file locks. Put this setup in a small closure and defer s.Close() immediately after store.New. As per coding guidelines, "Always defer cleanup for database, file, and other resource handles."

Proposed fix
-	s, err := store.New(dbPath, cfg.ServerDims(0))
-	if err != nil {
-		t.Fatalf("store.New: %v", err)
-	}
-	if err := s.SetMeta(store.MetaLastIndexError, "embed batch: no models loaded"); err != nil {
-		t.Fatalf("SetMeta: %v", err)
-	}
-	_ = s.Close()
+	func() {
+		s, err := store.New(dbPath, cfg.ServerDims(0))
+		if err != nil {
+			t.Fatalf("store.New: %v", err)
+		}
+		defer func() { _ = s.Close() }()
+
+		if err := s.SetMeta(store.MetaLastIndexError, "embed batch: no models loaded"); err != nil {
+			t.Fatalf("SetMeta: %v", err)
+		}
+	}()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
s, err := store.New(dbPath, cfg.ServerDims(0))
if err != nil {
t.Fatalf("store.New: %v", err)
}
if err := s.SetMeta(store.MetaLastIndexError, "embed batch: no models loaded"); err != nil {
t.Fatalf("SetMeta: %v", err)
}
_ = s.Close()
func() {
s, err := store.New(dbPath, cfg.ServerDims(0))
if err != nil {
t.Fatalf("store.New: %v", err)
}
defer func() { _ = s.Close() }()
if err := s.SetMeta(store.MetaLastIndexError, "embed batch: no models loaded"); err != nil {
t.Fatalf("SetMeta: %v", err)
}
}()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/hook_test.go` around lines 387 - 394, Ensure the test store created in
this setup is closed on every exit path by immediately deferring s.Close() after
store.New succeeds, before calling SetMeta. Update the setup around store.New
and SetMeta; preserve the existing fatal error handling and avoid relying on a
later explicit close.

Source: Coding guidelines

Comment on lines 236 to +244
func (f *FailoverEmbedder) probeHealth(i int) bool {
servers := f.cfg.Servers()
if i >= len(servers) {
return false
}
srv := servers[i]
endpoint := srv.Host + "/"
if srv.Backend == "lmstudio" {
endpoint = srv.Host + "/v1/models"
}
client := &http.Client{Timeout: healthCheckTimeout}
resp, err := client.Get(endpoint)
if err != nil {
ctx, cancel := context.WithTimeout(context.Background(), healthCheckTimeout)
defer cancel()
if err := ProbeServer(ctx, srv); err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline internal/embedder/failover.go --items all
rg -n -C 4 --type=go '\bprobeHealth\s*\(' internal/embedder

Repository: ory/lumen

Length of output: 3141


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '100,255p' internal/embedder/failover.go | cat -n

echo '--- ProbeServer definitions/usages ---'
rg -n -C 3 --type=go '\bProbeServer\s*\(' internal

Repository: ory/lumen

Length of output: 6982


Thread the embed request context into health probes.

Embed(ctx, ...) eventually calls findNextHealthy(active), but probeHealth(i) creates its timeout from context.Background() before calling ProbeServer. If the embedder request is canceled, this probe can still run for healthCheckTimeout; pass the caller context through findNextHealthy/probeHealth and derive the health-check timeout from it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/embedder/failover.go` around lines 236 - 244, Update the Embed
request flow so the caller context is passed through findNextHealthy to
probeHealth, replacing probeHealth’s context.Background() timeout base with that
propagated context while retaining the healthCheckTimeout deadline.

Source: Coding guidelines

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant