Skip to content

Add portable Codex hooks#7

Closed
ariobarin wants to merge 13 commits into
mainfrom
codex/portable-hooks
Closed

Add portable Codex hooks#7
ariobarin wants to merge 13 commits into
mainfrom
codex/portable-hooks

Conversation

@ariobarin

Copy link
Copy Markdown
Owner

Carries global Codex hooks through the portable install path so they can be reviewed and moved between machines.

@ariobarin ariobarin force-pushed the codex/portable-hooks branch from 2ac7d3f to a2cfd69 Compare June 16, 2026 15:18
@ariobarin

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a2cfd6908a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex/hooks.json Outdated
Comment on lines +9 to +10
"command": "python3 ~/.codex/hooks/portable_guard.py",
"commandWindows": "python -c \"import os, runpy; runpy.run_path(os.path.join(os.environ['USERPROFILE'], '.codex', 'hooks', 'portable_guard.py'), run_name='__main__')\"",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Resolve hooks from the installed Codex home

When scripts/install.ps1 -CodexHome <path> -Apply is used, the map in Get-PortableFileMap copies both hooks.json and hooks/ into that custom home, but this command still executes the guard from ~/.codex (and the Windows override uses %USERPROFILE%\.codex). That makes a custom-home install run a missing or stale guard rather than the script it just installed, so the new hooks lose their protection outside the default profile.

Useful? React with 👍 / 👎.

Comment on lines +15 to +17
PUBLIC_COMMAND_RE = re.compile(
r"\b(git\s+commit|git\s+tag|gh\s+pr\s+(create|edit)|gh\s+release)\b",
re.IGNORECASE,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Match git commands that use global options

Git's own usage allows global options before the subcommand (git [-C <path>] ... <command>, from git --help), but this regex only matches git followed immediately by commit or tag. Commands like git -C repo commit -m "<message with an em dash>" therefore pass through dash_guard even though they create public artifacts with Unicode dashes, which defeats the guard in the common git -C or git -c workflow.

Useful? React with 👍 / 👎.

@ariobarin

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cae356990d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex/skills/ui-ux-pro-max/SKILL.md Outdated
**Always start with `--design-system`** to get comprehensive recommendations with reasoning:

```bash
python3 skills/ui-ux-pro-max/scripts/search.py "<product_type> <industry> <keywords>" --design-system [-p "Project 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.

P2 Badge Use a runnable path for the bundled search script

These commands are shown as skills/ui-ux-pro-max/..., but after this portable repo installs the skill it lives under ~/.codex/skills/ui-ux-pro-max, and Codex runs from the target project cwd; there is normally no project-local skills/ directory, so the required Step 2 command fails before any search runs. Use the skill-local scripts/search.py path or an absolute Codex-home path in all examples.

Useful? React with 👍 / 👎.

project_name = design_system.get("project_name", "default")
project_slug = project_name.lower().replace(' ', '-')

design_system_dir = base_dir / "design-system" / project_slug

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep persisted retrieval paths under the project slug

Persisting always creates design-system/<project_slug>/..., but the generated MASTER/page files and the skill instructions direct agents to design-system/MASTER.md and design-system/pages/.... In any --persist -p run, those documented locations do not exist, so future sessions following the generated instructions miss the persisted rules and page overrides; either persist to the documented root or include the project slug in all retrieval guidance.

Useful? React with 👍 / 👎.

python search.py "<query>" --design-system [-p "Project Name"]
python search.py "<query>" --design-system --persist [-p "Project Name"] [--page "dashboard"]

Domains: style, prompt, color, chart, landing, product, ux, typography, google-fonts

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Remove or implement the advertised prompt domain

The CLI docs advertise prompt as a domain, but argparse restricts --domain to CSV_CONFIG.keys() and there is no prompt entry in core.py; running the documented --domain prompt "minimalism" exits with an invalid-choice error instead of returning CSS prompt keywords. Remove the advertised domain or add the missing CSV config.

Useful? React with 👍 / 👎.


# Print persistence confirmation
if args.persist:
project_slug = args.project_name.lower().replace(' ', '-') if args.project_name else "default"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Report the actual persisted slug when no project is named

When --persist is used without -p, generate_design_system names the project from the query and writes to a slug such as design-system/saas-dashboard/, but this confirmation prints design-system/default/; users following the success output will look in a non-existent directory. Derive the printed slug from the same project name used by persist_design_system.

Useful? React with 👍 / 👎.

@ariobarin ariobarin force-pushed the codex/portable-hooks branch from cae3569 to e411e43 Compare June 19, 2026 15:46
@ariobarin

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e411e437ac

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex/hooks/portable_guard.py Outdated

DASH_CHARS = chr(0x2013) + chr(0x2014)
PUBLIC_COMMAND_RE = re.compile(
r"\b(git\s+commit|git\s+tag|gh\s+pr\s+\S+|gh\s+release)\b",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Match git commands with global options

When the agent uses Git's documented global options before the subcommand, git --help shows git [-C <path>] [-c <name>=<value>] ... <command>, this regex does not match. A command such as git -C repo commit -m "bad U+2014 msg" therefore bypasses the PreToolUse dash guard and can publish the exact character the hook is meant to deny. Please allow optional Git global options before commit and tag.

Useful? React with 👍 / 👎.

@ariobarin

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 910cc232ae

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex/hooks/portable_guard.py Outdated

DASH_CHARS = chr(0x2013) + chr(0x2014)
PUBLIC_COMMAND_RE = re.compile(
r"\b(git\s+commit|git\s+tag|gh\s+pr\s+\S+|gh\s+release)\b",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle Git global options before guarded subcommands

When Codex runs a public artifact command with common Git global options, such as git -C /workspace/repo commit -m "x<U+2014>y" or git -c safe.directory=... tag ..., this regex does not match because it requires git to be followed immediately by commit or tag. Since the PreToolUse hook denies only after PUBLIC_COMMAND_RE.search(command), those commit and tag commands can still publish U+2013/U+2014 characters despite the guard's stated purpose.

Useful? React with 👍 / 👎.

Comment thread codex/hooks/portable_guard.py Outdated
Comment on lines +120 to +123
root = git_root(cwd)
if root is not None:
repos.append(root)
else:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Scan child repos even when cwd is a repo

If Codex is started from a directory that is itself a Git repo, this else prevents scanning any immediate child repositories. In a workspace where child repos are ignored by the parent, a dirty or unpushed child repo is silently omitted from the Stop continuation, contradicting the hook README's promise to report the current repo or immediate child repos before the final answer.

Useful? React with 👍 / 👎.

@ariobarin

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6050fffce4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex/hooks/portable_guard.py Outdated

DASH_CHARS = chr(0x2013) + chr(0x2014)
PUBLIC_COMMAND_RE = re.compile(
r"\b(git\s+commit|git\s+tag|gh(?:\s+(?:--repo|-R)\s+\S+)*\s+pr\s+\S+|gh\s+release)\b",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle git global options before public subcommands

When a Bash command uses Git global options before the subcommand, for example git -C ../repo commit -m 'bad \u2014 title', this regex does not match because it only accepts git\s+commit or git\s+tag immediately after git. I checked git -h, which allows global options before <command>, so multi-repo or out-of-tree workflows can still create commits and tags with U+2013/U+2014 text without the guard firing.

Useful? React with 👍 / 👎.

@ariobarin

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 13ade802d8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex/hooks/portable_guard.py Outdated
body = [line for line in lines[1:] if line.strip()]
header = lines[0]
has_ahead = "[ahead " in header or "ahead " in header
no_upstream = "..." not in header and not header.endswith("main") and not header.endswith("master")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid blocking clean branches without upstream

When a clean repo is on any local branch whose short status header has no upstream, for example ## topic, this sets no_upstream and the Stop hook returns decision: "block" even though there are no dirty files or known unpushed commits. I verified this by running the hook in a freshly committed temp repo on a topic branch with no upstream, which produced a required continuation saying no upstream shown; that makes normal final answers continue once and report spurious leftover state.

Useful? React with 👍 / 👎.

@ariobarin

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2f61c59ff0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex/hooks/portable_guard.py Outdated
body = [line for line in lines[1:] if line.strip()]
header = lines[0]
has_ahead = "[ahead " in header or "ahead " in header
no_upstream = "..." not in header and not header.endswith("main") and not header.endswith("master")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not block clean branches without upstream

When a repo is on a clean local branch that has no upstream, git status --short --branch produces only a header like ## work; this predicate makes repo_status_summary return no upstream shown even though there are no dirty files or proven unpushed commits. Because the Stop hook then emits decision: "block", every final answer in that normal local-branch setup gets forced into an extra continuation, which is noisier than the documented dirty or unpushed closeout behavior.

Useful? React with 👍 / 👎.

@ariobarin

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b4e2f3c515

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


body = [line for line in lines[1:] if line.strip()]
header = lines[0]
has_ahead = "[ahead " in header or "ahead " in header

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Detect unpushed commits without an upstream

For a clean branch that has local commits but no configured upstream, such as after git switch -c feature and a local commit before the first push, git status --short --branch only reports the branch name, so has_ahead stays false and this function returns None. The Stop hook then skips the continuation and fails to mention the unpushed-commit state it was added to catch; compare commits against remotes or explicitly handle branches with no upstream instead of only looking for [ahead ...].

Useful? React with 👍 / 👎.

@ariobarin

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 871257d224

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex/hooks/portable_guard.py Outdated
Comment on lines +177 to +178
has_no_upstream = "..." not in header
has_unpushed_no_upstream = has_no_upstream and head_missing_from_remotes(repo)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Report commits whose upstream branch is gone

When a branch tracks an upstream ref that has since been deleted, git status --short --branch reports a header like ## feature...origin/feature [gone], even if HEAD has local commits no current remote ref contains. Because this only calls head_missing_from_remotes() when the header lacks ..., those clean branches produce no Stop hook output, so the final answer omits the unpushed state this hook is meant to surface.

Useful? React with 👍 / 👎.

@ariobarin

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 51f006a8b8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ariobarin

Copy link
Copy Markdown
Owner Author

Superseded by split draft PRs #67, #68, #69, and #70.

@ariobarin ariobarin closed this Jun 30, 2026
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