Stats
Actions
Tags
Help us improve
Share bugs, ideas, or general feedback.
From ios-from-web-guide
Runs Node.js hooks on tool events: before Edit/Read/Bash calls (can block), after a specific MCP edit tool, and on session/subagent start. Executes bash commands and may modify files.
4 events · 13 hooks
npx claudepluginhub j-morgan6/ios-from-web-guide --plugin ios-from-web-guideSafety signals detected in this hook configuration
Where this hook configuration is defined
Defined in hooks/hooks.json
Event handlers and matchers — expand Raw Configuration for the full JSON
BashINPUT=$(cat); CMD=$(printf '%s' "$INPUT" | python3 -c 'import json,sys; d=json.loads(sys.stdin.read()); print(d.get("tool_input",{}).get("command",""))' 2>/dev/null); if echo "$CMD" | grep -qE 'git[[:space:]]+push.*(-f|--force).*(main|master)'; then echo '🚫 Dangerous: force push to main/master rewrites shared history. Use --force-with-lease on a feature branch or push to a new branch.' && exit 2; fi; if echo "$CMD" | grep -qE 'xcrun[[:space:]]+simctl[[:space:]]+erase[[:space:]]+all'; then echo '⚠️ xcrun simctl erase all wipes ALL simulator state. Prefer erase <device-id> for a single device.' && exit 1; fi; exit 0INPUT=$(cat); CMD=$(printf '%s' "$INPUT" | python3 -c 'import json,sys; d=json.loads(sys.stdin.read()); print(d.get("tool_input",{}).get("command",""))' 2>/dev/null); if echo "$CMD" | grep -qE 'xcodebuild[[:space:]]+.*archive'; then bash "${CLAUDE_PLUGIN_ROOT}/scripts/validate_pre_archive.sh"; exit $?; fi; exit 0Write|Editbash "${CLAUDE_PLUGIN_ROOT}/scripts/hook-lint.sh" skill-reminderbash "${CLAUDE_PLUGIN_ROOT}/scripts/hook-lint.sh" userdefaults-tokenbash "${CLAUDE_PLUGIN_ROOT}/scripts/hook-lint.sh" navlink-plainbash "${CLAUDE_PLUGIN_ROOT}/scripts/hook-lint.sh" url-relativebash "${CLAUDE_PLUGIN_ROOT}/scripts/hook-lint.sh" dispatchqueue-mainactorbash "${CLAUDE_PLUGIN_ROOT}/scripts/hook-lint.sh" published-on-ios17bash "${CLAUDE_PLUGIN_ROOT}/scripts/hook-lint.sh" print-outside-testsbash "${CLAUDE_PLUGIN_ROOT}/scripts/hook-lint.sh" hashable-id-eqWrite|Editbash "${CLAUDE_PLUGIN_ROOT}/scripts/hook-lint.sh" post-write-viewsbash "${CLAUDE_PLUGIN_ROOT}/scripts/detect_project.sh" 2>/dev/null; exit 0printf '%s\n' '## iOS From Web Guide — Rules for Subagents
You are working in an iOS/SwiftUI project. Follow these rules strictly.
### SwiftUI Navigation
1. Use `.buttonStyle(.borderless)` on Buttons inside a NavigationLink, never `.plain`
2. Hoist `navigationDestination(for:)` to the root view that owns the NavigationStack
3. Prefer `NavigationLink(value:)` + `navigationDestination(for:)` over `NavigationLink(destination:)` (deprecated)
### State Management
1. Use `@Observable` (iOS 17+). Never `@Published`/`@ObservedObject`/`@StateObject`
2. Let Swift auto-synthesize Hashable. Never write a custom id-only `==` on a model struct
3. In Views, use `@State private var viewModel = FooViewModel()` for Observable classes
### API / Auth
1. Store tokens in Keychain (KeychainService). Never UserDefaults
2. Use snake_case on the wire — `.convertToSnakeCase` / `.convertFromSnakeCase` on JSONEncoder/Decoder
3. Always resolve relative paths via `.asBackendURL` — never `URL(string: relativePath)`
4. APIClient handles base URL internally; call sites pass relative paths
### Shipping
1. `CURRENT_PROJECT_VERSION` must strictly increment between TestFlight uploads
2. App icon must be RGB, no alpha channel
3. Every import of PhotosUI/AVFoundation/CoreLocation/ATT requires its Usage Description in Info.plist
4. Keep `DEVELOPMENT_TEAM` in project.yml, not Xcode (XcodeGen wipes Xcode-only edits)
### Layout
1. Use `.containerRelativeFrame(.horizontal, alignment: .leading)` to pin width in ScrollView. `.frame(maxWidth: .infinity)` accepts infinity but does not cap'; exit 0Share bugs, ideas, or general feedback.