Skip to content

fix: let informational xcodebuild commands bypass xcsift - #82

Merged
alexey1312 merged 1 commit into
masterfrom
fix/issue-80-informational-commands
Aug 18, 2026
Merged

fix: let informational xcodebuild commands bypass xcsift#82
alexey1312 merged 1 commit into
masterfrom
fix/issue-80-informational-commands

Conversation

@alexey1312

Copy link
Copy Markdown
Collaborator

Closes #80.

The problem

The pre-tool hooks rewrote every command that starts with xcodebuild, so informational commands went through the build parser, which discarded the answer:

$ xcodebuild -version 2>&1 | xcsift -f toon
hint: build output ended without a success or failure marker (truncated or killed?)
status: incomplete
summary:
  errors: 0
  warnings: 0

The issue lists four commands. xcodebuild -showsdks, -showdestinations and swift build --show-bin-path failed the same way.

The fix belongs in the hook: the hook reads the command, but xcsift reads only the output. A passthrough mode inside xcsift would have to hold the raw input, which contradicts the bounded-memory streaming design from #79 and #81.

Changes

The hook condition is duplicated in three files that must agree — CursorTemplates.hookScript (written by install-cursor), plugins/cursor/hooks/pre-xcsift.sh, and plugins/claude-code/scripts/pre-xcsift.sh (installed by install-claude-code). All three get the same edit:

  • Informational commands pass through: -version, -usage, -help, -list, -showsdks, -showdestinations, -showTestPlans, -showBuildSettings(ForIndex), -find-executable, -find-library, -checkFirstLaunchStatus, -create-xcframework, --show-bin-path, --list-tests.
  • cd App && xcodebuild build now matches. The old pattern was anchored to the start of the line, so those build logs reached the agent raw.
  • The rewrite groups the command as { ... ; } 2>&1 | xcsift -f toon. The old code appended 2>&1 | to the end of the string, so xcodebuild build; swift test sent only the second half to xcsift.
  • Commands with their own pipe or file redirection pass through. xcodebuild build > log.txt previously left xcsift with empty input, which exits 64.
  • xcodebuild-foo build no longer matches. The old \b matched between d and -.

The Codex skill has no hook support, so SharedTemplates.skillMarkdown and both checked-in SKILL.md copies gain a "When Not to Use" section. PluginInstallation.md documents which commands the hooks rewrite.

The plugin version was 1.0.2 in marketplace.json, 1.0.3 in plugin.json and 1.0.3 in SKILL.md#60 bumped two of the three. All three now read 1.0.4, so installed plugins load the new script.

Tests

PluginFilesTests runs one table of 17 commands against all three hook copies and parses their real JSON replies, and compares the three version manifests. Running one table across every copy is what keeps them from drifting apart again.

Verified by mutation: removing the informational-command guard from one script fails the test on seven commands and names the file; reverting makes it pass. Reverting marketplace.json to 1.0.2 fails the version test.

swift test: 431 passed, 0 failures. swift format applied.

Result

$ echo '{"tool_input":{"command":"xcodebuild -version"}}' | ./plugins/cursor/hooks/pre-xcsift.sh
{"permission":"allow"}

$ echo '{"tool_input":{"command":"xcodebuild build"}}' | ./plugins/cursor/hooks/pre-xcsift.sh
{"permission":"allow","updated_input":{"command":"{ xcodebuild build ; } 2>&1 | xcsift -f toon"}}

The pre-tool hooks rewrote every command that starts with `xcodebuild`, so
`xcodebuild -version`, `-list -json`, `-showBuildSettings -json` and
`-showTestPlans -json` went through the build parser. The parser found no build
markers and reported `status: incomplete` with an empty summary, which discarded
the answer. `xcodebuild -showsdks` and `swift build --show-bin-path` failed the
same way.

The hook is the correct place for the fix: the hook reads the command, but
xcsift reads only the output.

Changes to the hook condition, applied to all three copies:

- Informational commands pass through untouched.
- The command matcher accepts a leading shell separator, so
  `cd App && xcodebuild build` is now piped through xcsift.
- The rewrite groups the command as `{ ... ; } 2>&1 | xcsift -f toon`. The
  previous code appended `2>&1 |` to the string, which sent only the last part
  of `xcodebuild build; swift test` to xcsift.
- Commands with their own pipe or file redirection pass through, because
  `xcodebuild build > log.txt` left xcsift with empty input.
- `xcodebuild-foo build` no longer matches.

Also synchronize the plugin version across marketplace.json, plugin.json and
SKILL.md, which drifted apart in #60, and raise it to 1.0.4 so installed plugins
load the new script.

`PluginFilesTests` runs one command table against all three hook copies and
compares the three version manifests, so a partial edit fails the tests.

Closes #80
@alexey1312
alexey1312 merged commit 822fc48 into master Aug 18, 2026
2 checks passed
@alexey1312
alexey1312 deleted the fix/issue-80-informational-commands branch August 18, 2026 06:10
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.

Allow raw output of non build/test commands

1 participant