Skip to content

feat: add named color profile launchers - #34

Open
thomast8 wants to merge 2 commits into
Ducksss:mainfrom
thomast8:agent/named-color-launchers
Open

feat: add named color profile launchers#34
thomast8 wants to merge 2 commits into
Ducksss:mainfrom
thomast8:agent/named-color-launchers

Conversation

@thomast8

@thomast8 thomast8 commented Jul 20, 2026

Copy link
Copy Markdown

Summary

  • Add launcher create, list, path, and remove for managed macOS profile launchers.
  • Support custom display names and a fixed eight-color palette, deriving each icon locally from the installed ChatGPT artwork.
  • Keep the original signed ChatGPT bundle untouched; each generated app is a small wrapper around codex-profile app <profile>.
  • Add lifecycle, collision, cleanup, JSON, completion, documentation, and structured-data coverage.

Testing

  • make check
  • Live macOS smoke test against the installed signed ChatGPT app:
    • created green Main and blue Personal launchers
    • verified their distinct names and colors in Finder
    • invoked both launchers through macOS Computer Use / LaunchServices
    • verified the named profile process used its profile-specific Electron directory
    • verified the installed ChatGPT bundle aggregate SHA-256 was identical before and after
    • verified codesign --verify --deep --strict still passed

Scope and compatibility

  • Affected scope: named Desktop profile launch ergonomics only. The generated launcher delegates to the existing app behavior.
  • Compatibility impact: additive command surface; no version bump. Existing profiles and app launches are unchanged. The active ChatGPT process intentionally retains its native name and icon.
  • Platform: launcher creation is macOS-only and uses standard macOS tools (sips, qlmanage, and iconutil). Inspection and removal remain scriptable.

Checklist

  • I ran make check; if the environment lacks ShellCheck, I ran make test and documented the missing lint result instead.
  • I did not add code that reads, copies, prints, parses, uploads, compares, or migrates auth tokens or ChatGPT cookies.
  • Desktop changes preserve the stock app default session and use the original signed app bundle.
  • I did not claim that CLI and Desktop account equality can be inspected or verified.
  • I updated documentation for user-facing behavior changes.

Summary by CodeRabbit

  • New Features

    • Added macOS profile launchers with custom names and supported icon colors.
    • Added commands to create, list, inspect, and remove launchers.
    • Launchers preserve the installed ChatGPT app and existing profile data.
    • Added configurable launcher installation location.
  • Documentation

    • Updated the README, website, changelog, and extended documentation with launcher usage, options, limitations, and platform requirements.
  • Tests

    • Added coverage for launcher creation, replacement, validation, cleanup, and profile-data preservation.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds macOS-only managed launchers for individual profiles, including generated tinted icons, lifecycle commands, shell completions, isolated tests, configuration overrides, and documentation updates.

Changes

Managed macOS launchers

Layer / File(s) Summary
Launcher runtime and command dispatch
bin/codex-profile
Adds launcher configuration, bundle identifiers, metadata handling, icon rendering, wrapper app generation, create/list/path/remove handlers, JSON support, and command dispatch.
Launcher behavior validation
test/cli/launcher-test.sh, test/lib/cli-fixtures.sh
Tests deterministic creation, idempotency, forced replacement, validation, collision handling, cleanup, removal, and profile-data preservation.
Shell completion integration
bin/codex-profile, test/cli/shell-test.sh
Adds Bash, Zsh, and Fish completion entries for launcher commands, options, profiles, and colors, with matching assertions.
Launcher documentation and release notes
README.md, docs/llms.txt, docs/index.html, CHANGELOG.md
Documents launcher commands, configuration, behavior, macOS support, examples, FAQs, and the unreleased feature.

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

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant command_launcher
  participant launcher_render_icon
  participant launcher_build_bundle
  participant codex_profile_app
  User->>command_launcher: launcher create profile
  command_launcher->>launcher_render_icon: render tinted icon
  launcher_render_icon->>launcher_build_bundle: provide icon resource
  launcher_build_bundle->>codex_profile_app: route launch to app profile
Loading

Suggested reviewers: ducksss

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding named, color-capable profile launchers.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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

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.

@thomast8
thomast8 marked this pull request as ready for review July 21, 2026 12:10

@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 `@bin/codex-profile`:
- Around line 1287-1294: Update the launcher list loop around
launcher_load_state and launcher_is_managed_for_profile so invalid or stale
state entries emit a warning and continue to the next profile instead of calling
die. Preserve healthy entries and ensure --json output remains valid by avoiding
error text on stdout and allowing the list operation to complete.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 98346ce4-faf2-4d06-b0c8-4b32900500d1

📥 Commits

Reviewing files that changed from the base of the PR and between b0df2dd and 141a500.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • README.md
  • bin/codex-profile
  • docs/index.html
  • docs/llms.txt
  • test/cli/launcher-test.sh
  • test/cli/shell-test.sh
  • test/lib/cli-fixtures.sh

Comment thread bin/codex-profile
Comment on lines +1287 to +1294
if [[ -d "$LAUNCHER_STATE_DIR" && ! -L "$LAUNCHER_STATE_DIR" ]]; then
for state_file in "$LAUNCHER_STATE_DIR"/*.state; do
[[ -f "$state_file" && ! -L "$state_file" ]] || continue
profile="${state_file##*/}"
profile="${profile%.state}"
launcher_load_state "$profile" || die "Invalid launcher state: $state_file"
launcher_is_managed_for_profile "$LAUNCHER_STATE_PATH" "$profile" ||
die "Managed launcher is missing or invalid: $LAUNCHER_STATE_PATH"

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

launcher list aborts on the first stale/invalid entry. If a managed .app is removed out-of-band, launcher_load_state/launcher_is_managed_for_profile fails and die kills the entire listing — so one broken launcher hides all healthy ones. In --json mode the opening [ and any earlier objects are already on stdout, so callers get truncated, unparseable JSON alongside the stderr error. Prefer skipping (and warning) so list stays usable and JSON stays well-formed.

🛠️ Skip invalid entries instead of aborting
-      launcher_load_state "$profile" || die "Invalid launcher state: $state_file"
-      launcher_is_managed_for_profile "$LAUNCHER_STATE_PATH" "$profile" ||
-        die "Managed launcher is missing or invalid: $LAUNCHER_STATE_PATH"
+      launcher_load_state "$profile" || {
+        printf 'warning: skipping invalid launcher state: %s\n' "$state_file" >&2
+        continue
+      }
+      launcher_is_managed_for_profile "$LAUNCHER_STATE_PATH" "$profile" || {
+        printf 'warning: skipping missing/invalid managed launcher: %s\n' "$LAUNCHER_STATE_PATH" >&2
+        continue
+      }
📝 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
if [[ -d "$LAUNCHER_STATE_DIR" && ! -L "$LAUNCHER_STATE_DIR" ]]; then
for state_file in "$LAUNCHER_STATE_DIR"/*.state; do
[[ -f "$state_file" && ! -L "$state_file" ]] || continue
profile="${state_file##*/}"
profile="${profile%.state}"
launcher_load_state "$profile" || die "Invalid launcher state: $state_file"
launcher_is_managed_for_profile "$LAUNCHER_STATE_PATH" "$profile" ||
die "Managed launcher is missing or invalid: $LAUNCHER_STATE_PATH"
if [[ -d "$LAUNCHER_STATE_DIR" && ! -L "$LAUNCHER_STATE_DIR" ]]; then
for state_file in "$LAUNCHER_STATE_DIR"/*.state; do
[[ -f "$state_file" && ! -L "$state_file" ]] || continue
profile="${state_file##*/}"
profile="${profile%.state}"
launcher_load_state "$profile" || {
printf 'warning: skipping invalid launcher state: %s\n' "$state_file" >&2
continue
}
launcher_is_managed_for_profile "$LAUNCHER_STATE_PATH" "$profile" || {
printf 'warning: skipping missing/invalid managed launcher: %s\n' "$LAUNCHER_STATE_PATH" >&2
continue
}
🤖 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 `@bin/codex-profile` around lines 1287 - 1294, Update the launcher list loop
around launcher_load_state and launcher_is_managed_for_profile so invalid or
stale state entries emit a warning and continue to the next profile instead of
calling die. Preserve healthy entries and ensure --json output remains valid by
avoiding error text on stdout and allowing the list operation to complete.

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