Lunavect

Connecting Claude Code and Codex

Connect either provider or both in Settings → Connections. Lunavect checks each provider separately: finding the client, confirming sign-in, configuring local events and receiving fresh usage data are different steps.

Requirements

The guide reuses an existing installation and sign-in. If a step is already complete, it moves to the next one.

Connect a provider

  1. Open Connect Claude or Connect Codex.
  2. If the client is missing, review the official installer source and choose the installation step. It runs in Terminal. Simply opening the guide does not install anything.
  3. If sign-in is needed, start the official client’s login flow. Complete it in Terminal or your browser, then return to Lunavect. Authentication stays with that client.
  4. Review the local changes and enable limits and sessions. Lunavect adds its event handlers; Claude also gets a status-line command. Existing unrelated handlers are preserved and configuration is backed up.
  5. For newly installed Codex handlers, open /hooks in Codex and approve the Lunavect commands when requested. A configuration file alone does not prove that events have arrived.
  6. Follow any remaining diagnostic action. Claude may need its first /usage launch completed. Run a task to check session events and compare available quotas with the official client.

The guide checks progress while open. If an external window was closed or setup did not finish, retry the incomplete step. It does not need to replace a working sign-in or reinstall existing handlers just because a quota request failed.

Where the data comes from

Provider Usage limits Session state and titles
Claude Code The official CLI’s /usage output and rate_limits delivered to the status-line command Local lifecycle hooks, available client session information and title metadata
Codex account/rateLimits/read through the local Codex app-server Available runtime state, lifecycle hooks and local session metadata; log-based fallback where needed

/usage shows resets truncated to the minute: “Resets Sep 27 at 11:59pm” for a reset at 00:00:00. Lunavect stores the end of the shown minute, so a window is not shown as reset and its return is not announced before the reset has certainly happened; the same reset from the status line gives the same time. Resets shown as a date only (“Sep 28”), relative (“in 2h 15m”), as “today/tomorrow at …”, in 24-hour time or with an abbreviated zone (“CEST”) are read the same way, to the end of the shown day or unit and never later than the window’s length from the reading. A time in a repeated daylight-saving hour is read as its later occurrence; a time in a skipped hour is rejected. A status-line window at 0 % without a reset time has not started yet and is shown like the same /usage block; a used window without a reset time is treated as absent. The other window is kept either way.

Claude status-line quotas have a receipt time but no server observation timestamp. They remain marked as saved observations; recent /usage results take precedence. Recognized repeated status-line payloads do not advance their receipt time, and a lower value for the same limit window from another session (an idle session’s older response, re-sent when Claude re-runs its status line) does not replace a newer observation.

When limits are refreshed

A Claude /usage probe starts Claude Code for a few seconds, and a Codex request starts its app-server, so Lunavect asks only when the window state calls for it. A five-minute timer only evaluates this policy:

State Shown Automatic request
Current value Remaining percentage and countdown; * after 15 minutes After 15 minutes while sessions are active (an event within the last hour), otherwise after an hour
0 % remaining, reset ahead 0% and the countdown, without * A manual reset in the Claude or Codex app can lift it early. Codex: hourly and after session activity. Claude: only after a response its limit did not refuse, at most hourly, since each probe is a short session other clients may list. The other window’s passed reset brings no request of its own
Reset passed, no newer data A dash and “Reset at HH:MM, waiting for the new window’s first data” One request at the latest passed reset plus a grace (30 s after the end of the minute /usage showed; 5 s for exact status-line and Codex times); an answer that still shows the passed reset is repeated with the backoff
Window not started (0 % used, no reset) 100 % and “Starts with the first request” After session activity, otherwise hourly
Codex with unlimited credits and no window ∞ and “No limits” Hourly
Last request failed, or an answer without any known window Last value with * and the specific reason, or a dash Backs off 5, 10, 20, 40, then 60 minutes; “limit reached” waits for the earliest known reset, or an hour and a response its limit did not refuse

A finished response reported by the lifecycle hooks triggers a request 90 seconds after the last event of a burst when the data is older than two minutes; hooks also run for Claude Desktop sessions. After wake Lunavect waits four seconds and asks only if the network is up. Wake and a restored connection restart the backoff after a network, timeout or loading failure; a workspace trust question, sign-in, API billing or unsupported screen keeps its backoff until you refresh. A timer, reset or session event that arrives while another refresh runs is evaluated after it. Refresh limits in the menu and the limits panel and Refresh data in Connections always ask, at most once per 30 seconds per provider. Refresh sessions in the session panel reads sessions only and never starts a quota probe.

Local catalog entries and titles are not evidence that a session is working. Fallback readers depend on client file formats, so a client update can affect detection. See sessions for state handling and navigation limits.

Local changes

Default client configuration files are ~/.claude/settings.json and ~/.codex/hooks.json. Lunavect respects CLAUDE_CONFIG_DIR and CODEX_HOME when set in the app’s environment. Advanced connection settings provide a manual Codex executable path when automatic discovery is insufficient.

Hooks invoke the bundled LunavectHook helper. It keeps session identity, project, client, state, tool name and timestamps, not the prompt or tool arguments. The Claude status-line handler stores quota values rather than the full input payload. A status line you had before keeps running with the same input and output; if it has not finished within 10 seconds, Lunavect stops it. Setup launchers contain commands and paths, not copied authentication tokens.

Helper path

Commands in client settings name a stable link, ~/Library/Application Support/Weekleft/bin/LunavectHook, not the app bundle. Every launch points that link at the running copy’s helper, so moving, renaming or updating Lunavect needs no change in settings.json or hooks.json. With two installed copies, the copy that ran last owns the link; Lunavect reports a second copy in /Applications or ~/Applications on the session panel. The clients run the command with /bin/sh; the path is single-quoted, so spaces and apostrophes are safe.

A downloaded app that macOS runs from a temporary App Translocation copy neither updates the link nor installs commands. The session panel and the setup guide ask you to move Lunavect to Applications and open it from there.

At launch Lunavect repairs only its own entries that name another path, including the absolute bundle path written by earlier versions, and shows a notice on the session panel. It never adds back an event handler you removed, never touches other handlers, and does not write while the client’s disableAllHooks is on or while the file cannot be read. Both the older absolute form and the link form count as connected and are removed on disconnect.

How settings files are written

Lunavect edits settings.json and hooks.json as JSON: it rereads the file, changes only its own entries, keeps a backup, writes a temporary file, flushes it to disk and renames it over the original, preserving the file’s mode and a link to it. The rewritten file uses sorted keys, two-space indentation and a final newline, so key order and spacing can change even though the values stay the same. A file with comments or trailing commas is reported as unreadable and never rewritten or backed up. Disconnecting restores the exact original bytes while Lunavect’s entries are the only change; if you created no file before connecting, the file stays after disconnecting, without Lunavect’s entries. Backups and the saved previous status line are private to your user (mode 0600); copies made by older versions are restricted at launch.

For all storage paths, backups, permissions and network behavior, see Privacy and permissions.

Troubleshooting

Disconnect

Disconnect a provider in Settings → Connections before removing Lunavect. This removes its event handlers and restores the saved previous Claude status line when applicable. Unrelated client settings and handlers remain in place.

If cleanup fails, the app reports the error; resolve it before deleting the app. Disconnecting does not sign you out of the official client, delete its conversations or erase Lunavect’s existing history. Removing only the app does not undo handler configuration. See uninstalling.

Interface references

These references describe the clients’ interfaces, not a certification or endorsement of Lunavect. Current installation and compatibility evidence is recorded in verification.

Sessions in editors

Lunavect 0.2.3 includes local companions for VS Code and JetBrains 2026.2. Install the companion from Settings → Connections → Sessions in editors to select the existing Claude or Codex terminal tab. See IDE session setup and compatibility, including the separate limits for provider panels and remote workspaces.