-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add GitHub icon next to CTA buttons for increased trust (TOU-1) #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| https://apple.stackexchange.com/questions/470569/how-to-fix-regular-blackout-of-touch-bar |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| <plist version="1.0"> | ||
| <dict> | ||
| <!-- App Store Sandbox Required --> | ||
| <key>com.apple.security.app-sandbox</key> | ||
| <true/> | ||
|
|
||
| <!-- Hardened Runtime --> | ||
| <key>com.apple.security.cs.allow-unsigned-executable-memory</key> | ||
| <false/> | ||
|
|
||
| <!-- Allow AppleScript for Touch Bar control --> | ||
| <key>com.apple.security.automation.apple-events</key> | ||
| <true/> | ||
|
|
||
| <!-- Temporary exception for System Events access --> | ||
| <key>com.apple.security.temporary-exception.apple-events</key> | ||
| <array> | ||
| <string>com.apple.systemevents</string> | ||
| </array> | ||
|
|
||
| <!-- User-selected file access (for future features) --> | ||
| <key>com.apple.security.files.user-selected.read-only</key> | ||
| <true/> | ||
|
|
||
| <!-- Network access for update checks (App Store handles this) --> | ||
| <key>com.apple.security.network.client</key> | ||
| <false/> | ||
|
|
||
| <!-- Accessibility for Touch Bar interaction --> | ||
| <key>com.apple.security.device.usb</key> | ||
| <false/> | ||
| </dict> | ||
| </plist> | ||
|
Comment on lines
+1
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainApp Store viability risk: killing Apple processes may be rejected under sandbox. Even with sandbox + AE, an MAS app that terminates Apple system components (e.g., TouchBarServer) is likely to be rejected. Consider Developer ID + notarization distribution instead of MAS for this utility. 🌐 Web query: 💡 Result: Short answers:
Sources:
If you want, I can quote the exact entitlement keys you'd need for a specific capability or suggest an App-Store-acceptable design to achieve your goal (e.g., scripted activation, Apple Events with scripting-targets, or a user-approved helper). App Store rejection risk — MAS sandboxed apps cannot terminate Apple system processes Temporary-exception entitlements can be declared in App Store Connect and justified, but they do not grant a sandboxed MAS app permission to kill or manipulate Apple system daemons (e.g., TouchBarServer); attempting this will very likely cause App Store rejection. File: App/Resources/TouchBarFixAppStore.entitlements. Fix: remove/avoid any process‑termination behavior or switch to Developer ID + notarization; if you must remain on MAS, redesign to use App‑Store‑acceptable patterns (Apple Events scripting targets, limited automation, or an approved helper/XPC approach). 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| # Development Session Handover | ||
|
|
||
| **Project:** touchbarfix | ||
| **Session Date:** 2025-09-15 16:56:59 | ||
| **Branch:** feature/tou-1-github-icon-trust | ||
| **Project Type:** nodejs | ||
|
|
||
| ## Session Summary | ||
|
|
||
| This document provides a comprehensive handover of the development session, including changes made, current status, and next steps. | ||
|
|
||
| ## Changes Made | ||
|
|
||
| ### Files Modified | ||
|
|
||
|
|
||
| ### Pull Request | ||
| Preparing PR... | ||
|
|
||
| ## Current Status | ||
|
|
||
| ### Project Structure | ||
| ``` | ||
| ./APP-STORE-SUBMISSION-GUIDE.md | ||
| ./App/DEVELOPMENT.md | ||
| ./App/README.md | ||
| ./CLAUDE-MEMORY-SOLUTION.md | ||
| ./CLEAN-REDDIT-POST.md | ||
| ./LINEAR-INTEGRATION-GUIDE.md | ||
| ./NEW-SESSION-QUICK-START.md | ||
| ./QUICK-UAT-GUIDE.md | ||
| ./SESSION-STARTUP-CHECKLIST.md | ||
| ./TOUCHBARFIX-DESIGN-SYSTEM.md | ||
| ./UNIFIED-BRAND-LAUNCH-PACKAGE.md | ||
| ./brand-implementation-plan.md | ||
| ./design/image-generation-prompts.md | ||
| ./linear-bridge.js | ||
| ./vercel.json | ||
| ``` | ||
|
|
||
| ### Key Documentation | ||
| - ./App/README.md | ||
| - ./n8n-automation/README.md | ||
| - ./README.md | ||
| - ./components/README.md | ||
| - ./.github/README.md | ||
|
|
||
| ## Repository Information | ||
|
|
||
| - **Repository URL:** https://github.com/ProduktEntdecker/touchbarfix.git | ||
| - **Current Branch:** feature/tou-1-github-icon-trust | ||
| - **Last Commit:** 0cdfdf9 - fix: improve accessibility and analytics for GitHub icon links (Dr. Florian Steiner, 10 minutes ago) | ||
|
|
||
| ## Open TODOs | ||
|
|
||
| - [1;33m🔍 Extracting TODOs from codebase...[0m | ||
| - [0;35m📝 Found TODOs:[0m | ||
| - api/capture-email.js:136: // Store email securely (TODO: Implement Vercel KV or PostgreSQL) | ||
| - api/capture-email.js:147: // TODO: Replace with actual persistent storage | ||
| - node_modules/@octokit/core/dist-src/index.js:136: // TODO: type `octokit.auth` based on passed options.authStrategy | ||
| - node_modules/@octokit/openapi-types/types.d.ts:9180: * If the authenticated user is an organization owner or a team maintainer, they can remove any repositories from the team. To remove a repository from a team as an organization member, the authenticated user must have admin access to the repository and must be able to see the team. NOTE: This does not delete the repository, it just removes it from the team. | ||
| - node_modules/@octokit/openapi-types/types.d.ts:106680: /** @description Login for the user that this issue should be assigned to. _NOTE: Only users with push access can set the assignee for new issues. The assignee is silently dropped otherwise. **This field is closing down.**_ */ | ||
| - node_modules/@octokit/openapi-types/types.d.ts:106683: /** @description Labels to associate with this issue. _NOTE: Only users with push access can set labels for new issues. Labels are silently dropped otherwise._ */ | ||
| - node_modules/@octokit/openapi-types/types.d.ts:106695: /** @description Logins for Users to assign to this issue. _NOTE: Only users with push access can set assignees for new issues. Assignees are silently dropped otherwise._ */ | ||
| - node_modules/@octokit/openapi-types/types.d.ts:106698: * @description The name of the issue type to associate with this issue. _NOTE: Only users with push access can set the type for new issues. The type is silently dropped otherwise._ | ||
| - node_modules/@octokit/openapi-types/types.d.ts:107144: /** @description Usernames of people to assign this issue to. _NOTE: Only users with push access can add assignees to an issue. Assignees are silently ignored otherwise._ */ | ||
| - node_modules/@octokit/openapi-types/types.d.ts:107173: /** @description Usernames of assignees to remove from an issue. _NOTE: Only users with push access can remove assignees from an issue. Assignees are silently ignored otherwise._ */ | ||
| - node_modules/@octokit/openapi-types/types.d.ts:113970: * If the authenticated user is an organization owner or a team maintainer, they can remove any repositories from the team. To remove a repository from a team as an organization member, the authenticated user must have admin access to the repository and must be able to see the team. NOTE: This does not delete the repository, it just removes it from the team. | ||
| - Binary file tailwindcss-macos-arm64 matches | ||
| - api/capture-email.js:136: // Store email securely (TODO: Implement Vercel KV or PostgreSQL) | ||
| - api/capture-email.js:147: // TODO: Replace with actual persistent storage | ||
| - node_modules/@octokit/core/dist-src/index.js:136: // TODO: type `octokit.auth` based on passed options.authStrategy | ||
| - node_modules/@octokit/openapi-types/types.d.ts:9180: * If the authenticated user is an organization owner or a team maintainer, they can remove any repositories from the team. To remove a repository from a team as an organization member, the authenticated user must have admin access to the repository and must be able to see the team. NOTE: This does not delete the repository, it just removes it from the team. | ||
| - node_modules/@octokit/openapi-types/types.d.ts:106680: /** @description Login for the user that this issue should be assigned to. _NOTE: Only users with push access can set the assignee for new issues. The assignee is silently dropped otherwise. **This field is closing down.**_ */ | ||
| - node_modules/@octokit/openapi-types/types.d.ts:106683: /** @description Labels to associate with this issue. _NOTE: Only users with push access can set labels for new issues. Labels are silently dropped otherwise._ */ | ||
| - ... and 6 more TODOs found in codebase | ||
|
|
||
| ## Development Environment | ||
|
|
||
| ### Prerequisites | ||
| - Node.js 18+ | ||
| - npm or yarn | ||
| - Dependencies: `npm install` | ||
|
|
||
| ### Quick Start | ||
| ```bash | ||
| # Check package.json or project documentation | ||
| # for specific startup commands | ||
| ``` | ||
|
|
||
| ## Next Steps | ||
|
|
||
| ### Immediate Actions Needed | ||
| - [ ] [1;33m🔍 Extracting TODOs from codebase...[0m | ||
| - [ ] [0;35m📝 Found TODOs:[0m | ||
| - [ ] api/capture-email.js:136: // Store email securely (TODO: Implement Vercel KV or PostgreSQL) | ||
| - [ ] api/capture-email.js:147: // TODO: Replace with actual persistent storage | ||
| - [ ] node_modules/@octokit/core/dist-src/index.js:136: // TODO: type `octokit.auth` based on passed options.authStrategy | ||
|
|
||
| ### Future Enhancements | ||
| - [ ] Code review and optimization | ||
| - [ ] Performance testing | ||
| - [ ] Documentation improvements | ||
| - [ ] Security audit | ||
|
|
||
| ## Notes | ||
|
|
||
| - This handover was generated automatically on 2025-09-15 16:56:59 | ||
| - All changes have been committed and pushed to the repository | ||
| - Review the pull request for detailed change information | ||
| - Contact the previous developer for any clarifications | ||
|
|
||
| --- | ||
|
|
||
| *Generated by Claude Code wrap-up script* |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,94 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/bin/bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Build script for App Store version of TouchBarFix | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # This creates a sandboxed version compatible with App Store requirements | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -e | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "🏗️ Building TouchBarFix for App Store..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Colors for output | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| RED='\033[0;31m' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| GREEN='\033[0;32m' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| YELLOW='\033[1;33m' | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| NC='\033[0m' # No Color | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Navigate to App directory | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| cd App | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Clean previous builds | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "🧹 Cleaning previous builds..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| rm -rf .build | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| rm -rf TouchBarFix.app | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Use App Store compatible manager | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "📝 Switching to App Store compatible code..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f Sources/TouchBarManager.swift ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| mv Sources/TouchBarManager.swift Sources/TouchBarManager.original.swift | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| cp Sources/TouchBarManagerAppStore.swift Sources/TouchBarManager.swift | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+24
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid leaving the repo in a swapped state; restore on exit. If the script aborts, Apply: echo "📝 Switching to App Store compatible code..."
+orig_swapped=0
if [ -f Sources/TouchBarManager.swift ]; then
mv Sources/TouchBarManager.swift Sources/TouchBarManager.original.swift
+ orig_swapped=1
fi
cp Sources/TouchBarManagerAppStore.swift Sources/TouchBarManager.swift
+
+# Always restore original on exit
+cleanup() {
+ if [ "${orig_swapped}" = "1" ] && [ -f Sources/TouchBarManager.original.swift ]; then
+ mv Sources/TouchBarManager.original.swift Sources/TouchBarManager.swift
+ fi
+}
+trap cleanup EXIT INT TERM🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Build the app | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "🔨 Building App Store version..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| swift build -c release --arch arm64 --arch x86_64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Create app bundle | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "📦 Creating app bundle..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| mkdir -p TouchBarFix.app/Contents/MacOS | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| mkdir -p TouchBarFix.app/Contents/Resources | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Copy executable | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| cp .build/apple/Products/Release/TouchBarFix TouchBarFix.app/Contents/MacOS/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Copy Info.plist | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| cp Resources/Info.plist TouchBarFix.app/Contents/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Copy icon | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f ../Assets/AppIcon.icns ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| cp ../Assets/AppIcon.icns TouchBarFix.app/Contents/Resources/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Use App Store entitlements | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| cp Resources/TouchBarFixAppStore.entitlements TouchBarFix.app/Contents/Resources/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Sign the app with App Store certificate | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "🔏 Signing for App Store..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| IDENTITY="Developer ID Application: FLORIAN MICHAEL STEINER (D3SM7HA325)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # For App Store, we need to use "3rd Party Mac Developer Application" certificate | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check if App Store certificate exists | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if security find-identity -v -p codesigning | grep -q "3rd Party Mac Developer Application"; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| IDENTITY=$(security find-identity -v -p codesigning | grep "3rd Party Mac Developer Application" | head -1 | awk '{print $2}') | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Using App Store certificate: $IDENTITY" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo -e "${YELLOW}⚠️ Warning: No App Store certificate found. Using Developer ID for testing.${NC}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "To submit to App Store, you need a '3rd Party Mac Developer Application' certificate." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+56
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don’t commit a personal signing identity; make it configurable. Use env var with a sensible auto-detect fallback; avoid leaking real name/Team ID into the repo. Apply: -IDENTITY="Developer ID Application: FLORIAN MICHAEL STEINER (D3SM7HA325)"
+IDENTITY="${SIGN_IDENTITY:-}"
+
+# Prefer “3rd Party Mac Developer Application” for MAS; else fallback to Developer ID (testing only).
if security find-identity -v -p codesigning | grep -q "3rd Party Mac Developer Application"; then
- IDENTITY=$(security find-identity -v -p codesigning | grep "3rd Party Mac Developer Application" | head -1 | awk '{print $2}')
+ IDENTITY="${IDENTITY:-$(security find-identity -v -p codesigning | awk -F\" '/3rd Party Mac Developer Application/{print $2; exit}')}"
echo "Using App Store certificate: $IDENTITY"
else
- echo -e "${YELLOW}⚠️ Warning: No App Store certificate found. Using Developer ID for testing.${NC}"
+ echo -e "${YELLOW}⚠️ Warning: No App Store certificate found. Using Developer ID for testing.${NC}"
+ IDENTITY="${IDENTITY:-$(security find-identity -v -p codesigning | awk -F\" '/Developer ID Application/{print $2; exit}')}"
echo "To submit to App Store, you need a '3rd Party Mac Developer Application' certificate."
fi
+[ -n "${IDENTITY}" ] || { echo -e "${RED:-}❌ No signing identity found${NC:-}"; exit 1; }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| codesign --force --deep --sign "$IDENTITY" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| --entitlements Resources/TouchBarFixAppStore.entitlements \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| --options runtime \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| TouchBarFix.app | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Verify signature | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "✅ Verifying signature..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| codesign --verify --deep --strict --verbose=2 TouchBarFix.app | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check entitlements | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "🔍 Checking entitlements..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| codesign -d --entitlements - TouchBarFix.app | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Restore original manager file | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f Sources/TouchBarManager.original.swift ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| mv Sources/TouchBarManager.original.swift Sources/TouchBarManager.swift | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo -e "${GREEN}✅ App Store build complete!${NC}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Next steps:" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "1. Open TouchBarFix.app in Xcode" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "2. Select Product > Archive" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "3. Validate the archive" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "4. Upload to App Store Connect" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "App location: $(pwd)/TouchBarFix.app" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove temporary Apple Events exception (not allowed for Mac App Store).
com.apple.security.temporary-exception.apple-eventsis a temporary entitlement and generally rejected for MAS submissions. Keepcom.apple.security.automation.apple-eventsand explain usage via Info.plist description instead.Apply:
Outside this file, add to Info.plist:
🤖 Prompt for AI Agents