mirror of
https://github.com/maxgoedjen/secretive.git
synced 2025-12-14 21:10:56 +00:00
update name to be cursor internal
This commit is contained in:
parent
303c5fc2a1
commit
625a605cc7
28
.github/workflows/nightly.yml
vendored
28
.github/workflows/nightly.yml
vendored
@ -58,7 +58,7 @@ jobs:
|
|||||||
CLI_BINARY="Sources/Packages/.build/release/SecretiveCLI"
|
CLI_BINARY="Sources/Packages/.build/release/SecretiveCLI"
|
||||||
ENTITLEMENTS="Sources/Packages/Sources/SecretiveCLI/SecretiveCLI.entitlements"
|
ENTITLEMENTS="Sources/Packages/Sources/SecretiveCLI/SecretiveCLI.entitlements"
|
||||||
IDENTITY=$(security find-identity -p codesigning -v 2>/dev/null | grep "Developer ID Application" | head -n1 | awk -F'"' '{print $2}')
|
IDENTITY=$(security find-identity -p codesigning -v 2>/dev/null | grep "Developer ID Application" | head -n1 | awk -F'"' '{print $2}')
|
||||||
codesign --force --options runtime --sign "$IDENTITY" --identifier "com.maxgoedjen.Secretive.Host" --entitlements "$ENTITLEMENTS" "$CLI_BINARY"
|
codesign --force --options runtime --sign "$IDENTITY" --identifier "com.cursorinternal.Secretive.Host" --entitlements "$ENTITLEMENTS" "$CLI_BINARY"
|
||||||
- name: Prepare Artifact Folder
|
- name: Prepare Artifact Folder
|
||||||
run: |
|
run: |
|
||||||
mkdir -p Artifact/App
|
mkdir -p Artifact/App
|
||||||
@ -67,32 +67,32 @@ jobs:
|
|||||||
cp Sources/Packages/.build/release/SecretiveCLI Artifact/CLI/secretive
|
cp Sources/Packages/.build/release/SecretiveCLI Artifact/CLI/secretive
|
||||||
- name: Build Installer Package
|
- name: Build Installer Package
|
||||||
run: |
|
run: |
|
||||||
pkgbuild --root Artifact/App --install-location /Applications --identifier com.maxgoedjen.Secretive.app --version 1.0 App.pkg
|
pkgbuild --root Artifact/App --install-location /Applications --identifier com.cursorinternal.Secretive.app --version 1.0 App.pkg
|
||||||
pkgbuild --root Artifact/CLI --install-location /usr/local/bin --identifier com.maxgoedjen.Secretive.cli --version 1.0 CLI.pkg
|
pkgbuild --root Artifact/CLI --install-location /usr/local/bin --identifier com.cursorinternal.Secretive.cli --version 1.0 CLI.pkg
|
||||||
cat > distribution.xml << 'EOF'
|
cat > distribution.xml << 'EOF'
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<installer-gui-script minSpecVersion="2">
|
<installer-gui-script minSpecVersion="2">
|
||||||
<title>Secretive</title>
|
<title>Secretive</title>
|
||||||
<organization>com.maxgoedjen</organization>
|
<organization>com.cursorinternal</organization>
|
||||||
<domains enable_localSystem="true"/>
|
<domains enable_localSystem="true"/>
|
||||||
<options customize="never" require-scripts="false" rootVolumeOnly="true"/>
|
<options customize="never" require-scripts="false" rootVolumeOnly="true"/>
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.app"/>
|
<pkg-ref id="com.cursorinternal.Secretive.app"/>
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.cli"/>
|
<pkg-ref id="com.cursorinternal.Secretive.cli"/>
|
||||||
<choices-outline>
|
<choices-outline>
|
||||||
<line choice="default">
|
<line choice="default">
|
||||||
<line choice="com.maxgoedjen.Secretive.app"/>
|
<line choice="com.cursorinternal.Secretive.app"/>
|
||||||
<line choice="com.maxgoedjen.Secretive.cli"/>
|
<line choice="com.cursorinternal.Secretive.cli"/>
|
||||||
</line>
|
</line>
|
||||||
</choices-outline>
|
</choices-outline>
|
||||||
<choice id="default"/>
|
<choice id="default"/>
|
||||||
<choice id="com.maxgoedjen.Secretive.app" visible="false">
|
<choice id="com.cursorinternal.Secretive.app" visible="false">
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.app"/>
|
<pkg-ref id="com.cursorinternal.Secretive.app"/>
|
||||||
</choice>
|
</choice>
|
||||||
<choice id="com.maxgoedjen.Secretive.cli" visible="false">
|
<choice id="com.cursorinternal.Secretive.cli" visible="false">
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.cli"/>
|
<pkg-ref id="com.cursorinternal.Secretive.cli"/>
|
||||||
</choice>
|
</choice>
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.app" version="1.0" onConclusion="none">App.pkg</pkg-ref>
|
<pkg-ref id="com.cursorinternal.Secretive.app" version="1.0" onConclusion="none">App.pkg</pkg-ref>
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.cli" version="1.0" onConclusion="none">CLI.pkg</pkg-ref>
|
<pkg-ref id="com.cursorinternal.Secretive.cli" version="1.0" onConclusion="none">CLI.pkg</pkg-ref>
|
||||||
</installer-gui-script>
|
</installer-gui-script>
|
||||||
EOF
|
EOF
|
||||||
productbuild --distribution distribution.xml --package-path . Secretive-unsigned.pkg
|
productbuild --distribution distribution.xml --package-path . Secretive-unsigned.pkg
|
||||||
|
|||||||
93
.github/workflows/oneoff.yml
vendored
93
.github/workflows/oneoff.yml
vendored
@ -22,7 +22,22 @@ jobs:
|
|||||||
AGENT_PROFILE_DATA: ${{ secrets.AGENT_PROFILE_DATA }}
|
AGENT_PROFILE_DATA: ${{ secrets.AGENT_PROFILE_DATA }}
|
||||||
APPLE_API_KEY_DATA: ${{ secrets.APPLE_API_KEY_DATA }}
|
APPLE_API_KEY_DATA: ${{ secrets.APPLE_API_KEY_DATA }}
|
||||||
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
|
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
|
||||||
run: ./.github/scripts/signing.sh
|
run: |
|
||||||
|
echo $SIGNING_DATA | base64 -d -o Signing.p12
|
||||||
|
security create-keychain -p ci ci.keychain
|
||||||
|
security default-keychain -s ci.keychain
|
||||||
|
security list-keychains -s ci.keychain
|
||||||
|
security import ./Signing.p12 -k ci.keychain -P $SIGNING_PASSWORD -A
|
||||||
|
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k ci ci.keychain
|
||||||
|
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
|
||||||
|
echo $HOST_PROFILE_DATA | base64 -d -o Host.provisionprofile
|
||||||
|
HOST_UUID=$(grep UUID -A1 -a Host.provisionprofile | grep -io "[-A-F0-9]\{36\}")
|
||||||
|
cp Host.provisionprofile ~/Library/MobileDevice/Provisioning\ Profiles/$HOST_UUID.provisionprofile
|
||||||
|
echo $AGENT_PROFILE_DATA | base64 -d -o Agent.provisionprofile
|
||||||
|
AGENT_UUID=$(grep UUID -A1 -a Agent.provisionprofile | grep -io "[-A-F0-9]\{36\}")
|
||||||
|
cp Agent.provisionprofile ~/Library/MobileDevice/Provisioning\ Profiles/$AGENT_UUID.provisionprofile
|
||||||
|
mkdir ~/.private_keys
|
||||||
|
echo -n "$APPLE_API_KEY_DATA" > ~/.private_keys/AuthKey_$APPLE_API_KEY_ID.p8
|
||||||
- name: Set Environment
|
- name: Set Environment
|
||||||
run: sudo xcrun xcode-select -s /Applications/Xcode_26.1.app
|
run: sudo xcrun xcode-select -s /Applications/Xcode_26.1.app
|
||||||
- name: Update Build Number
|
- name: Update Build Number
|
||||||
@ -33,32 +48,70 @@ jobs:
|
|||||||
sed -i '' -e "s/GITHUB_CI_VERSION/0.0.0_oneoff-$DATE/g" Sources/Config/Config.xcconfig
|
sed -i '' -e "s/GITHUB_CI_VERSION/0.0.0_oneoff-$DATE/g" Sources/Config/Config.xcconfig
|
||||||
sed -i '' -e "s/GITHUB_BUILD_NUMBER/1.$RUN_ID/g" Sources/Config/Config.xcconfig
|
sed -i '' -e "s/GITHUB_BUILD_NUMBER/1.$RUN_ID/g" Sources/Config/Config.xcconfig
|
||||||
sed -i '' -e "s/GITHUB_BUILD_URL/https:\/\/github.com\/maxgoedjen\/secretive\/actions\/runs\/$RUN_ID/g" Sources/Config/Config.xcconfig
|
sed -i '' -e "s/GITHUB_BUILD_URL/https:\/\/github.com\/maxgoedjen\/secretive\/actions\/runs\/$RUN_ID/g" Sources/Config/Config.xcconfig
|
||||||
- name: Build
|
- name: Build App
|
||||||
run: xcrun xcodebuild -project Sources/Secretive.xcodeproj -scheme Secretive -configuration Release -archivePath Archive.xcarchive archive
|
run: xcrun xcodebuild -project Sources/Secretive.xcodeproj -scheme Secretive -configuration Release -archivePath Archive.xcarchive archive
|
||||||
- name: Move to Artifact Folder
|
- name: Build CLI
|
||||||
run: mkdir Artifact; cp -r Archive.xcarchive/Products/Applications/Secretive.app Artifact
|
run: swift build -c release --product SecretiveCLI --package-path Sources/Packages
|
||||||
- name: Upload App to Artifacts
|
- name: Codesign CLI
|
||||||
id: upload
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: Secretive
|
|
||||||
path: Artifact
|
|
||||||
- name: Download Zipped Artifact
|
|
||||||
id: download
|
|
||||||
env:
|
|
||||||
ZIP_ID: ${{ steps.upload.outputs.artifact-id }}
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
run: |
|
||||||
curl -L -H "Authorization: Bearer $GITHUB_TOKEN" -L \
|
CLI_BINARY="Sources/Packages/.build/release/SecretiveCLI"
|
||||||
https://api.github.com/repos/maxgoedjen/secretive/actions/artifacts/$ZIP_ID/zip > Secretive.zip
|
ENTITLEMENTS="Sources/Packages/Sources/SecretiveCLI/SecretiveCLI.entitlements"
|
||||||
|
IDENTITY=$(security find-identity -p codesigning -v 2>/dev/null | grep "Developer ID Application" | head -n1 | awk -F'"' '{print $2}')
|
||||||
|
codesign --force --options runtime --sign "$IDENTITY" --identifier "com.cursorinternal.Secretive.Host" --entitlements "$ENTITLEMENTS" "$CLI_BINARY"
|
||||||
|
- name: Prepare Artifact Folder
|
||||||
|
run: |
|
||||||
|
mkdir -p Artifact/App
|
||||||
|
mkdir -p Artifact/CLI
|
||||||
|
cp -r Archive.xcarchive/Products/Applications/Secretive.app Artifact/App/
|
||||||
|
cp Sources/Packages/.build/release/SecretiveCLI Artifact/CLI/secretive
|
||||||
|
- name: Build Installer Package
|
||||||
|
run: |
|
||||||
|
pkgbuild --root Artifact/App --install-location /Applications --identifier com.cursorinternal.Secretive.app --version 1.0 App.pkg
|
||||||
|
pkgbuild --root Artifact/CLI --install-location /usr/local/bin --identifier com.cursorinternal.Secretive.cli --version 1.0 CLI.pkg
|
||||||
|
cat > distribution.xml << 'EOF'
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<installer-gui-script minSpecVersion="2">
|
||||||
|
<title>Secretive</title>
|
||||||
|
<organization>com.cursorinternal</organization>
|
||||||
|
<domains enable_localSystem="true"/>
|
||||||
|
<options customize="never" require-scripts="false" rootVolumeOnly="true"/>
|
||||||
|
<pkg-ref id="com.cursorinternal.Secretive.app"/>
|
||||||
|
<pkg-ref id="com.cursorinternal.Secretive.cli"/>
|
||||||
|
<choices-outline>
|
||||||
|
<line choice="default">
|
||||||
|
<line choice="com.cursorinternal.Secretive.app"/>
|
||||||
|
<line choice="com.cursorinternal.Secretive.cli"/>
|
||||||
|
</line>
|
||||||
|
</choices-outline>
|
||||||
|
<choice id="default"/>
|
||||||
|
<choice id="com.cursorinternal.Secretive.app" visible="false">
|
||||||
|
<pkg-ref id="com.cursorinternal.Secretive.app"/>
|
||||||
|
</choice>
|
||||||
|
<choice id="com.cursorinternal.Secretive.cli" visible="false">
|
||||||
|
<pkg-ref id="com.cursorinternal.Secretive.cli"/>
|
||||||
|
</choice>
|
||||||
|
<pkg-ref id="com.cursorinternal.Secretive.app" version="1.0" onConclusion="none">App.pkg</pkg-ref>
|
||||||
|
<pkg-ref id="com.cursorinternal.Secretive.cli" version="1.0" onConclusion="none">CLI.pkg</pkg-ref>
|
||||||
|
</installer-gui-script>
|
||||||
|
EOF
|
||||||
|
productbuild --distribution distribution.xml --package-path . Secretive-unsigned.pkg
|
||||||
|
INSTALLER_IDENTITY=$(security find-identity -p basic -v 2>/dev/null | grep "Developer ID Installer" | head -n1 | awk -F'"' '{print $2}')
|
||||||
|
productsign --sign "$INSTALLER_IDENTITY" Secretive-unsigned.pkg Secretive.pkg
|
||||||
- name: Notarize
|
- name: Notarize
|
||||||
env:
|
env:
|
||||||
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
|
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
|
||||||
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
|
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
|
||||||
run: xcrun notarytool submit --key ~/.private_keys/AuthKey_$APPLE_API_KEY_ID.p8 --key-id $APPLE_API_KEY_ID --issuer $APPLE_API_ISSUER Secretive.zip
|
run: |
|
||||||
|
xcrun notarytool submit --key ~/.private_keys/AuthKey_$APPLE_API_KEY_ID.p8 --key-id $APPLE_API_KEY_ID --issuer $APPLE_API_ISSUER --wait Secretive.pkg
|
||||||
|
xcrun stapler staple Secretive.pkg
|
||||||
|
- name: Upload Installer to Artifacts
|
||||||
|
id: upload
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: Secretive.pkg
|
||||||
|
path: Secretive.pkg
|
||||||
- name: Attest
|
- name: Attest
|
||||||
id: attest
|
id: attest
|
||||||
uses: actions/attest-build-provenance@v2
|
uses: actions/attest-build-provenance@v2
|
||||||
with:
|
with:
|
||||||
subject-name: "Secretive.zip"
|
subject-path: "Secretive.pkg"
|
||||||
subject-digest: sha256:${{ steps.upload.outputs.artifact-digest }}
|
|
||||||
|
|||||||
28
.github/workflows/release.yml
vendored
28
.github/workflows/release.yml
vendored
@ -96,7 +96,7 @@ jobs:
|
|||||||
CLI_BINARY="Sources/Packages/.build/release/SecretiveCLI"
|
CLI_BINARY="Sources/Packages/.build/release/SecretiveCLI"
|
||||||
ENTITLEMENTS="Sources/Packages/Sources/SecretiveCLI/SecretiveCLI.entitlements"
|
ENTITLEMENTS="Sources/Packages/Sources/SecretiveCLI/SecretiveCLI.entitlements"
|
||||||
IDENTITY=$(security find-identity -p codesigning -v 2>/dev/null | grep "Developer ID Application" | head -n1 | awk -F'"' '{print $2}')
|
IDENTITY=$(security find-identity -p codesigning -v 2>/dev/null | grep "Developer ID Application" | head -n1 | awk -F'"' '{print $2}')
|
||||||
codesign --force --options runtime --sign "$IDENTITY" --identifier "com.maxgoedjen.Secretive.Host" --entitlements "$ENTITLEMENTS" "$CLI_BINARY"
|
codesign --force --options runtime --sign "$IDENTITY" --identifier "com.cursorinternal.Secretive.Host" --entitlements "$ENTITLEMENTS" "$CLI_BINARY"
|
||||||
- name: Prepare Artifact Folder
|
- name: Prepare Artifact Folder
|
||||||
run: |
|
run: |
|
||||||
mkdir -p Artifact/App
|
mkdir -p Artifact/App
|
||||||
@ -105,32 +105,32 @@ jobs:
|
|||||||
cp Sources/Packages/.build/release/SecretiveCLI Artifact/CLI/secretive
|
cp Sources/Packages/.build/release/SecretiveCLI Artifact/CLI/secretive
|
||||||
- name: Build Installer Package
|
- name: Build Installer Package
|
||||||
run: |
|
run: |
|
||||||
pkgbuild --root Artifact/App --install-location /Applications --identifier com.maxgoedjen.Secretive.app --version 1.0 App.pkg
|
pkgbuild --root Artifact/App --install-location /Applications --identifier com.cursorinternal.Secretive.app --version 1.0 App.pkg
|
||||||
pkgbuild --root Artifact/CLI --install-location /usr/local/bin --identifier com.maxgoedjen.Secretive.cli --version 1.0 CLI.pkg
|
pkgbuild --root Artifact/CLI --install-location /usr/local/bin --identifier com.cursorinternal.Secretive.cli --version 1.0 CLI.pkg
|
||||||
cat > distribution.xml << 'EOF'
|
cat > distribution.xml << 'EOF'
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<installer-gui-script minSpecVersion="2">
|
<installer-gui-script minSpecVersion="2">
|
||||||
<title>Secretive</title>
|
<title>Secretive</title>
|
||||||
<organization>com.maxgoedjen</organization>
|
<organization>com.cursorinternal</organization>
|
||||||
<domains enable_localSystem="true"/>
|
<domains enable_localSystem="true"/>
|
||||||
<options customize="never" require-scripts="false" rootVolumeOnly="true"/>
|
<options customize="never" require-scripts="false" rootVolumeOnly="true"/>
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.app"/>
|
<pkg-ref id="com.cursorinternal.Secretive.app"/>
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.cli"/>
|
<pkg-ref id="com.cursorinternal.Secretive.cli"/>
|
||||||
<choices-outline>
|
<choices-outline>
|
||||||
<line choice="default">
|
<line choice="default">
|
||||||
<line choice="com.maxgoedjen.Secretive.app"/>
|
<line choice="com.cursorinternal.Secretive.app"/>
|
||||||
<line choice="com.maxgoedjen.Secretive.cli"/>
|
<line choice="com.cursorinternal.Secretive.cli"/>
|
||||||
</line>
|
</line>
|
||||||
</choices-outline>
|
</choices-outline>
|
||||||
<choice id="default"/>
|
<choice id="default"/>
|
||||||
<choice id="com.maxgoedjen.Secretive.app" visible="false">
|
<choice id="com.cursorinternal.Secretive.app" visible="false">
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.app"/>
|
<pkg-ref id="com.cursorinternal.Secretive.app"/>
|
||||||
</choice>
|
</choice>
|
||||||
<choice id="com.maxgoedjen.Secretive.cli" visible="false">
|
<choice id="com.cursorinternal.Secretive.cli" visible="false">
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.cli"/>
|
<pkg-ref id="com.cursorinternal.Secretive.cli"/>
|
||||||
</choice>
|
</choice>
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.app" version="1.0" onConclusion="none">App.pkg</pkg-ref>
|
<pkg-ref id="com.cursorinternal.Secretive.app" version="1.0" onConclusion="none">App.pkg</pkg-ref>
|
||||||
<pkg-ref id="com.maxgoedjen.Secretive.cli" version="1.0" onConclusion="none">CLI.pkg</pkg-ref>
|
<pkg-ref id="com.cursorinternal.Secretive.cli" version="1.0" onConclusion="none">CLI.pkg</pkg-ref>
|
||||||
</installer-gui-script>
|
</installer-gui-script>
|
||||||
EOF
|
EOF
|
||||||
productbuild --distribution distribution.xml --package-path . Secretive-unsigned.pkg
|
productbuild --distribution distribution.xml --package-path . Secretive-unsigned.pkg
|
||||||
|
|||||||
2
FAQ.md
2
FAQ.md
@ -54,7 +54,7 @@ Secretive checks in with GitHub's releases API to check if there's a new version
|
|||||||
|
|
||||||
### How do I uninstall Secretive?
|
### How do I uninstall Secretive?
|
||||||
|
|
||||||
Drag Secretive.app to the trash and remove `~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent`. `SecretAgent` may continue running until you quit it or reboot.
|
Drag Secretive.app to the trash and remove `~/Library/Containers/com.cursorinternal.Secretive.SecretAgent`. `SecretAgent` may continue running until you quit it or reboot.
|
||||||
|
|
||||||
### I have a security issue
|
### I have a security issue
|
||||||
|
|
||||||
|
|||||||
72
Makefile
72
Makefile
@ -1,5 +1,11 @@
|
|||||||
# Creates a dev package containing the Secretive app and CLI
|
# Creates a dev package containing the Secretive app and CLI
|
||||||
# Usage: make
|
# Usage:
|
||||||
|
# make - Build unsigned (no keychain/Secure Enclave access)
|
||||||
|
# make SIGN=1 TEAM=XXXXXX - Build with development signing (enables keychain access)
|
||||||
|
#
|
||||||
|
# To find your team ID, run:
|
||||||
|
# security find-identity -v -p codesigning
|
||||||
|
# Look for "Apple Development: Your Name (TEAMID)" - the TEAMID is in parentheses at the end
|
||||||
|
|
||||||
PROJECT_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
|
PROJECT_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||||
BUILD_DIR := $(PROJECT_DIR)/build
|
BUILD_DIR := $(PROJECT_DIR)/build
|
||||||
@ -16,26 +22,51 @@ FINAL_PKG := $(BUILD_DIR)/Secretive-dev-unsigned.pkg
|
|||||||
|
|
||||||
XCODEBUILD := xcodebuild -project $(PROJECT_DIR)/Sources/Secretive.xcodeproj
|
XCODEBUILD := xcodebuild -project $(PROJECT_DIR)/Sources/Secretive.xcodeproj
|
||||||
|
|
||||||
|
# Signing configuration
|
||||||
|
# SIGN_IDENTITY can be set to a specific identity, otherwise defaults to "Apple Development"
|
||||||
|
SIGN_IDENTITY ?= Apple Development
|
||||||
|
|
||||||
|
ifdef SIGN
|
||||||
|
CODE_SIGN_ARGS := CODE_SIGNING_ALLOWED=YES CODE_SIGNING_REQUIRED=YES CODE_SIGN_STYLE=Automatic
|
||||||
|
ifdef TEAM
|
||||||
|
CODE_SIGN_ARGS += DEVELOPMENT_TEAM=$(TEAM)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
CODE_SIGN_ARGS := CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY=""
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
all: $(FINAL_PKG)
|
all: $(FINAL_PKG)
|
||||||
@echo "Built: $(FINAL_PKG)"
|
@echo "Built: $(FINAL_PKG)"
|
||||||
|
|
||||||
|
# Validate TEAM is set when SIGN is enabled
|
||||||
|
ifdef SIGN
|
||||||
|
ifndef TEAM
|
||||||
|
$(error SIGN=1 requires TEAM=<your-team-id>. Find it with: security find-identity -v -p codesigning)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
$(ARCHIVE):
|
$(ARCHIVE):
|
||||||
@mkdir -p $(BUILD_DIR)
|
@mkdir -p $(BUILD_DIR)
|
||||||
$(XCODEBUILD) -scheme Secretive -configuration Release CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY="" -archivePath $(ARCHIVE) archive
|
$(XCODEBUILD) -scheme Secretive -configuration Release $(CODE_SIGN_ARGS) -archivePath $(ARCHIVE) archive
|
||||||
|
|
||||||
$(APP_BUNDLE): $(ARCHIVE)
|
$(APP_BUNDLE): $(ARCHIVE)
|
||||||
@rm -rf $(APP_BUNDLE)
|
@rm -rf $(APP_BUNDLE)
|
||||||
cp -R $(ARCHIVE)/Products/Applications/Secretive.app $(APP_BUNDLE)
|
cp -R $(ARCHIVE)/Products/Applications/Secretive.app $(APP_BUNDLE)
|
||||||
|
|
||||||
|
CLI_ENTITLEMENTS_SRC := $(PROJECT_DIR)/Sources/Packages/Sources/SecretiveCLI/SecretiveCLI.entitlements
|
||||||
|
CLI_ENTITLEMENTS := $(BUILD_DIR)/SecretiveCLI.entitlements
|
||||||
|
|
||||||
$(CLI_BIN):
|
$(CLI_BIN):
|
||||||
@mkdir -p $(BUILD_DIR)
|
@mkdir -p $(BUILD_DIR)
|
||||||
cd $(PROJECT_DIR)/Sources/Packages && xcodebuild -scheme SecretiveCLI -configuration Release \
|
swift build -c release --product SecretiveCLI --package-path $(PROJECT_DIR)/Sources/Packages
|
||||||
-destination 'platform=macOS' CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY="" \
|
cp $(PROJECT_DIR)/Sources/Packages/.build/release/SecretiveCLI $(CLI_BIN)
|
||||||
SYMROOT=$(BUILD_DIR)/xcode-cli build
|
ifdef SIGN
|
||||||
cp $(BUILD_DIR)/xcode-cli/Release/SecretiveCLI $(CLI_BIN)
|
@echo "Signing CLI binary with team $(TEAM)..."
|
||||||
cp -R $(BUILD_DIR)/xcode-cli/Release/*.bundle $(BUILD_DIR)/ 2>/dev/null || true
|
@sed 's/$$(AppIdentifierPrefix)/$(TEAM)./g' $(CLI_ENTITLEMENTS_SRC) > $(CLI_ENTITLEMENTS)
|
||||||
|
codesign --force --sign "$(SIGN_IDENTITY)" --entitlements $(CLI_ENTITLEMENTS) $(CLI_BIN)
|
||||||
|
endif
|
||||||
|
|
||||||
$(APP_ROOT): $(APP_BUNDLE)
|
$(APP_ROOT): $(APP_BUNDLE)
|
||||||
@rm -rf $(APP_ROOT)
|
@rm -rf $(APP_ROOT)
|
||||||
@ -48,10 +79,10 @@ $(CLI_ROOT): $(CLI_BIN)
|
|||||||
cp $(CLI_BIN) $(CLI_ROOT)/secretive
|
cp $(CLI_BIN) $(CLI_ROOT)/secretive
|
||||||
|
|
||||||
$(APP_PKG): $(APP_ROOT)
|
$(APP_PKG): $(APP_ROOT)
|
||||||
pkgbuild --root $(APP_ROOT) --install-location /Applications --identifier com.maxgoedjen.Secretive.app --version 0.0.0-dev $(APP_PKG)
|
pkgbuild --root $(APP_ROOT) --install-location /Applications --identifier com.cursorinternal.Secretive.app --version 0.0.0-dev $(APP_PKG)
|
||||||
|
|
||||||
$(CLI_PKG): $(CLI_ROOT)
|
$(CLI_PKG): $(CLI_ROOT)
|
||||||
pkgbuild --root $(CLI_ROOT) --install-location /usr/local/bin --identifier com.maxgoedjen.Secretive.cli --version 0.0.0-dev $(CLI_PKG)
|
pkgbuild --root $(CLI_ROOT) --install-location /usr/local/bin --identifier com.cursorinternal.Secretive.cli --version 0.0.0-dev $(CLI_PKG)
|
||||||
|
|
||||||
$(DIST):
|
$(DIST):
|
||||||
@mkdir -p $(BUILD_DIR)
|
@mkdir -p $(BUILD_DIR)
|
||||||
@ -59,31 +90,32 @@ $(DIST):
|
|||||||
'<?xml version="1.0" encoding="utf-8"?>' \
|
'<?xml version="1.0" encoding="utf-8"?>' \
|
||||||
'<installer-gui-script minSpecVersion="2">' \
|
'<installer-gui-script minSpecVersion="2">' \
|
||||||
' <title>Secretive (Dev)</title>' \
|
' <title>Secretive (Dev)</title>' \
|
||||||
' <organization>com.maxgoedjen</organization>' \
|
' <organization>com.cursorinternal</organization>' \
|
||||||
' <domains enable_localSystem="true"/>' \
|
' <domains enable_localSystem="true"/>' \
|
||||||
' <options customize="never" require-scripts="false" rootVolumeOnly="true"/>' \
|
' <options customize="never" require-scripts="false" rootVolumeOnly="true"/>' \
|
||||||
' <pkg-ref id="com.maxgoedjen.Secretive.app"/>' \
|
' <pkg-ref id="com.cursorinternal.Secretive.app"/>' \
|
||||||
' <pkg-ref id="com.maxgoedjen.Secretive.cli"/>' \
|
' <pkg-ref id="com.cursorinternal.Secretive.cli"/>' \
|
||||||
' <choices-outline>' \
|
' <choices-outline>' \
|
||||||
' <line choice="default">' \
|
' <line choice="default">' \
|
||||||
' <line choice="com.maxgoedjen.Secretive.app"/>' \
|
' <line choice="com.cursorinternal.Secretive.app"/>' \
|
||||||
' <line choice="com.maxgoedjen.Secretive.cli"/>' \
|
' <line choice="com.cursorinternal.Secretive.cli"/>' \
|
||||||
' </line>' \
|
' </line>' \
|
||||||
' </choices-outline>' \
|
' </choices-outline>' \
|
||||||
' <choice id="default"/>' \
|
' <choice id="default"/>' \
|
||||||
' <choice id="com.maxgoedjen.Secretive.app" visible="false">' \
|
' <choice id="com.cursorinternal.Secretive.app" visible="false">' \
|
||||||
' <pkg-ref id="com.maxgoedjen.Secretive.app"/>' \
|
' <pkg-ref id="com.cursorinternal.Secretive.app"/>' \
|
||||||
' </choice>' \
|
' </choice>' \
|
||||||
' <choice id="com.maxgoedjen.Secretive.cli" visible="false">' \
|
' <choice id="com.cursorinternal.Secretive.cli" visible="false">' \
|
||||||
' <pkg-ref id="com.maxgoedjen.Secretive.cli"/>' \
|
' <pkg-ref id="com.cursorinternal.Secretive.cli"/>' \
|
||||||
' </choice>' \
|
' </choice>' \
|
||||||
' <pkg-ref id="com.maxgoedjen.Secretive.app" version="0.0.0-dev" onConclusion="none">App.pkg</pkg-ref>' \
|
' <pkg-ref id="com.cursorinternal.Secretive.app" version="0.0.0-dev" onConclusion="none">App.pkg</pkg-ref>' \
|
||||||
' <pkg-ref id="com.maxgoedjen.Secretive.cli" version="0.0.0-dev" onConclusion="none">CLI.pkg</pkg-ref>' \
|
' <pkg-ref id="com.cursorinternal.Secretive.cli" version="0.0.0-dev" onConclusion="none">CLI.pkg</pkg-ref>' \
|
||||||
'</installer-gui-script>' \
|
'</installer-gui-script>' \
|
||||||
> $(DIST)
|
> $(DIST)
|
||||||
|
|
||||||
$(FINAL_PKG): $(APP_PKG) $(CLI_PKG) $(DIST)
|
$(FINAL_PKG): $(APP_PKG) $(CLI_PKG) $(DIST)
|
||||||
productbuild --distribution $(DIST) --package-path $(BUILD_DIR) $(FINAL_PKG)
|
productbuild --distribution $(DIST) --package-path $(BUILD_DIR) $(FINAL_PKG)
|
||||||
|
@rm -rf $(ARCHIVE) $(APP_BUNDLE) $(APP_ROOT) $(APP_PKG) $(CLI_BIN) $(CLI_ROOT) $(CLI_PKG) $(DIST)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD_DIR)
|
rm -rf $(BUILD_DIR)
|
||||||
|
|||||||
@ -37,7 +37,7 @@ let package = Package(
|
|||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
name: "SecretKit",
|
name: "SecretKit",
|
||||||
dependencies: [],
|
dependencies: ["Localizations"],
|
||||||
resources: [localization],
|
resources: [localization],
|
||||||
swiftSettings: swiftSettings,
|
swiftSettings: swiftSettings,
|
||||||
),
|
),
|
||||||
@ -54,13 +54,13 @@ let package = Package(
|
|||||||
),
|
),
|
||||||
.target(
|
.target(
|
||||||
name: "SecureEnclaveSecretKit",
|
name: "SecureEnclaveSecretKit",
|
||||||
dependencies: ["SecretKit", "Localizations"],
|
dependencies: ["SecretKit"],
|
||||||
resources: [localization],
|
resources: [localization],
|
||||||
swiftSettings: swiftSettings,
|
swiftSettings: swiftSettings,
|
||||||
),
|
),
|
||||||
.target(
|
.target(
|
||||||
name: "SmartCardSecretKit",
|
name: "SmartCardSecretKit",
|
||||||
dependencies: ["SecretKit", "Localizations"],
|
dependencies: ["SecretKit"],
|
||||||
resources: [localization],
|
resources: [localization],
|
||||||
swiftSettings: swiftSettings,
|
swiftSettings: swiftSettings,
|
||||||
),
|
),
|
||||||
@ -97,12 +97,10 @@ let package = Package(
|
|||||||
.executableTarget(
|
.executableTarget(
|
||||||
name: "SecretiveCLI",
|
name: "SecretiveCLI",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"SecretAgentKit",
|
|
||||||
"SecureEnclaveSecretKit",
|
"SecureEnclaveSecretKit",
|
||||||
"SmartCardSecretKit",
|
"SmartCardSecretKit",
|
||||||
"SecretKit",
|
"SecretKit",
|
||||||
"Common",
|
"Common",
|
||||||
"Localizations",
|
|
||||||
],
|
],
|
||||||
exclude: ["Generated"],
|
exclude: ["Generated"],
|
||||||
swiftSettings: swiftSettings,
|
swiftSettings: swiftSettings,
|
||||||
|
|||||||
@ -47,7 +47,7 @@ import XPCWrappers
|
|||||||
|
|
||||||
/// Manually trigger an update check.
|
/// Manually trigger an update check.
|
||||||
public func checkForUpdates() async throws {
|
public func checkForUpdates() async throws {
|
||||||
let session = try await XPCTypedSession<[Release], Never>(serviceName: "com.maxgoedjen.Secretive.SecretiveUpdater")
|
let session = try await XPCTypedSession<[Release], Never>(serviceName: "com.cursorinternal.Secretive.SecretiveUpdater")
|
||||||
await evaluate(releases: try await session.send())
|
await evaluate(releases: try await session.send())
|
||||||
session.complete()
|
session.complete()
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ extension Updater {
|
|||||||
|
|
||||||
/// The user defaults used to store user ignore state.
|
/// The user defaults used to store user ignore state.
|
||||||
var defaults: UserDefaults {
|
var defaults: UserDefaults {
|
||||||
UserDefaults(suiteName: "com.maxgoedjen.Secretive.updater.ignorelist")!
|
UserDefaults(suiteName: "com.cursorinternal.Secretive.updater.ignorelist")!
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ public final class Agent: Sendable {
|
|||||||
private let publicKeyWriter = OpenSSHPublicKeyWriter()
|
private let publicKeyWriter = OpenSSHPublicKeyWriter()
|
||||||
private let signatureWriter = OpenSSHSignatureWriter()
|
private let signatureWriter = OpenSSHSignatureWriter()
|
||||||
private let certificateHandler = OpenSSHCertificateHandler()
|
private let certificateHandler = OpenSSHCertificateHandler()
|
||||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "Agent")
|
private let logger = Logger(subsystem: "com.cursorinternal.secretive.secretagent", category: "Agent")
|
||||||
|
|
||||||
/// Initializes an agent with a store list and a witness.
|
/// Initializes an agent with a store list and a witness.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import SecretKit
|
|||||||
public actor OpenSSHCertificateHandler: Sendable {
|
public actor OpenSSHCertificateHandler: Sendable {
|
||||||
|
|
||||||
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: URL.homeDirectory)
|
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: URL.homeDirectory)
|
||||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "OpenSSHCertificateHandler")
|
private let logger = Logger(subsystem: "com.cursorinternal.secretive.secretagent", category: "OpenSSHCertificateHandler")
|
||||||
private let writer = OpenSSHPublicKeyWriter()
|
private let writer = OpenSSHPublicKeyWriter()
|
||||||
private var keyBlobsAndNames: [AnySecret: (Data, Data)] = [:]
|
private var keyBlobsAndNames: [AnySecret: (Data, Data)] = [:]
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ public protocol SSHAgentInputParserProtocol {
|
|||||||
|
|
||||||
public struct SSHAgentInputParser: SSHAgentInputParserProtocol {
|
public struct SSHAgentInputParser: SSHAgentInputParserProtocol {
|
||||||
|
|
||||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "InputParser")
|
private let logger = Logger(subsystem: "com.cursorinternal.secretive.secretagent", category: "InputParser")
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ public struct SocketController {
|
|||||||
private let fileHandle: FileHandle
|
private let fileHandle: FileHandle
|
||||||
|
|
||||||
/// Logger for the socket controller.
|
/// Logger for the socket controller.
|
||||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "SocketController")
|
private let logger = Logger(subsystem: "com.cursorinternal.secretive.secretagent", category: "SocketController")
|
||||||
|
|
||||||
/// Tracer which determines who originates a socket connection.
|
/// Tracer which determines who originates a socket connection.
|
||||||
private let requestTracer = SigningRequestTracer()
|
private let requestTracer = SigningRequestTracer()
|
||||||
@ -74,7 +74,7 @@ extension SocketController {
|
|||||||
private let messagesContinuation: AsyncStream<Data>.Continuation
|
private let messagesContinuation: AsyncStream<Data>.Continuation
|
||||||
|
|
||||||
/// A logger for the session.
|
/// A logger for the session.
|
||||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "Session")
|
private let logger = Logger(subsystem: "com.cursorinternal.secretive.secretagent", category: "Session")
|
||||||
|
|
||||||
/// Initializes a new Session.
|
/// Initializes a new Session.
|
||||||
/// - Parameter fileHandle: The FileHandle used to communicate with the socket.
|
/// - Parameter fileHandle: The FileHandle used to communicate with the socket.
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
// Copyright Anysphere Inc.
|
||||||
|
// Re-exports Localizations module so dependent modules can access localization extensions.
|
||||||
|
@_exported import Localizations
|
||||||
@ -4,7 +4,7 @@ import OSLog
|
|||||||
/// Controller responsible for writing public keys to disk, so that they're easily accessible by scripts.
|
/// Controller responsible for writing public keys to disk, so that they're easily accessible by scripts.
|
||||||
public final class PublicKeyFileStoreController: Sendable {
|
public final class PublicKeyFileStoreController: Sendable {
|
||||||
|
|
||||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "PublicKeyFileStoreController")
|
private let logger = Logger(subsystem: "com.cursorinternal.secretive.secretagent", category: "PublicKeyFileStoreController")
|
||||||
private let directory: URL
|
private let directory: URL
|
||||||
private let keyWriter = OpenSSHPublicKeyWriter()
|
private let keyWriter = OpenSSHPublicKeyWriter()
|
||||||
|
|
||||||
|
|||||||
@ -96,8 +96,8 @@ public struct KeyAvailability: Sendable {
|
|||||||
extension NSNotification.Name {
|
extension NSNotification.Name {
|
||||||
|
|
||||||
// Distributed notification that keys were modified out of process (ie, that the management tool added/removed secrets)
|
// Distributed notification that keys were modified out of process (ie, that the management tool added/removed secrets)
|
||||||
public static let secretStoreUpdated = NSNotification.Name("com.maxgoedjen.Secretive.secretStore.updated")
|
public static let secretStoreUpdated = NSNotification.Name("com.cursorinternal.Secretive.secretStore.updated")
|
||||||
// Internal notification that keys were reloaded from the backing store.
|
// Internal notification that keys were reloaded from the backing store.
|
||||||
public static let secretStoreReloaded = NSNotification.Name("com.maxgoedjen.Secretive.secretStore.reloaded")
|
public static let secretStoreReloaded = NSNotification.Name("com.cursorinternal.Secretive.secretStore.reloaded")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
# Secretive CLI
|
# Secretive CLI
|
||||||
|
|
||||||
A command-line interface for Secretive that provides full key management and SSH agent functionality, sharing the same keychain and socket path as the GUI application.
|
A command-line interface companion for Secretive that provides key management capabilities, sharing the same keychain and socket path as the GUI application.
|
||||||
|
|
||||||
|
**Note:** The CLI is a helper tool for the main Secretive app. The SSH agent is managed by the Secretive GUI app - the CLI can check its status but does not run its own agent.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@ -37,7 +39,7 @@ The CLI uses the entitlements file at `SecretiveCLI.entitlements`:
|
|||||||
<true/>
|
<true/>
|
||||||
<key>keychain-access-groups</key>
|
<key>keychain-access-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>$(AppIdentifierPrefix)com.maxgoedjen.Secretive</string>
|
<string>$(AppIdentifierPrefix)com.cursorinternal.Secretive</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@ -51,41 +53,31 @@ Sign the CLI binary with:
|
|||||||
codesign --force \
|
codesign --force \
|
||||||
--sign "Developer ID Application: YOUR_TEAM_NAME" \
|
--sign "Developer ID Application: YOUR_TEAM_NAME" \
|
||||||
--options runtime \
|
--options runtime \
|
||||||
--identifier com.maxgoedjen.Secretive.Host \
|
--identifier com.cursorinternal.Secretive.Host \
|
||||||
--entitlements Sources/Packages/Sources/SecretiveCLI/SecretiveCLI.entitlements \
|
--entitlements Sources/Packages/Sources/SecretiveCLI/SecretiveCLI.entitlements \
|
||||||
Sources/Packages/.build/release/SecretiveCLI
|
Sources/Packages/.build/release/SecretiveCLI
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace `YOUR_TEAM_NAME` with your actual Developer ID or use your team's signing identity.
|
Replace `YOUR_TEAM_NAME` with your actual Developer ID or use your team's signing identity.
|
||||||
|
|
||||||
**Important:** The `--identifier` must be `com.maxgoedjen.Secretive.Host` to match the GUI app's bundle identifier, ensuring the CLI can access the same keychain items.
|
**Important:** The `--identifier` must be `com.cursorinternal.Secretive.Host` to match the GUI app's bundle identifier, ensuring the CLI can access the same keychain items.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Agent Management
|
### Agent Management
|
||||||
|
|
||||||
Install and manage the SSH agent as a launchd service:
|
Check and control Secretive's SSH agent:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install the agent as a launchd service
|
|
||||||
secretive agent install
|
|
||||||
|
|
||||||
# Start the agent
|
|
||||||
secretive agent start
|
|
||||||
|
|
||||||
# Check agent status
|
# Check agent status
|
||||||
secretive agent status
|
secretive agent status
|
||||||
|
|
||||||
# Stop the agent
|
# Start the agent (if not already running)
|
||||||
secretive agent stop
|
secretive agent start
|
||||||
|
|
||||||
# Uninstall the agent
|
|
||||||
secretive agent uninstall
|
|
||||||
|
|
||||||
# Run agent in foreground (for testing)
|
|
||||||
secretive agent run
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The SSH agent is bundled with the Secretive GUI app. The `start` command will locate and launch the agent from the installed Secretive.app.
|
||||||
|
|
||||||
### Key Management
|
### Key Management
|
||||||
|
|
||||||
Manage SSH keys stored in the Secure Enclave:
|
Manage SSH keys stored in the Secure Enclave:
|
||||||
@ -110,27 +102,27 @@ secretive key update "My Key Name"
|
|||||||
## Socket Path
|
## Socket Path
|
||||||
|
|
||||||
The CLI uses the same socket path as the GUI app:
|
The CLI uses the same socket path as the GUI app:
|
||||||
- Production: `~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh`
|
- Production: `~/Library/Containers/com.cursorinternal.Secretive.SecretAgent/Data/socket.ssh`
|
||||||
- Debug: `~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket-debug.ssh`
|
- Debug: `~/Library/Containers/com.cursorinternal.Secretive.SecretAgent/Data/socket-debug.ssh`
|
||||||
|
|
||||||
Set `SSH_AUTH_SOCK` to this path to use the agent:
|
Set `SSH_AUTH_SOCK` to this path to use the agent:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export SSH_AUTH_SOCK=~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh
|
export SSH_AUTH_SOCK=~/Library/Containers/com.cursorinternal.Secretive.SecretAgent/Data/socket.ssh
|
||||||
```
|
```
|
||||||
|
|
||||||
## Keychain Access
|
## Keychain Access
|
||||||
|
|
||||||
The CLI shares the same keychain access group as the GUI app (`com.maxgoedjen.Secretive`), allowing it to:
|
The CLI shares the same keychain access group as the GUI app (`com.cursorinternal.Secretive`), allowing it to:
|
||||||
- Access keys created by the GUI app
|
- Access keys created by the GUI app
|
||||||
- Create keys that are accessible by the GUI app
|
- Create keys that are accessible by the GUI app
|
||||||
- Use the same Secure Enclave storage
|
- Use the same Secure Enclave storage
|
||||||
|
|
||||||
This is achieved by signing the CLI with the same bundle identifier (`com.maxgoedjen.Secretive.Host`) and keychain access group entitlements.
|
This is achieved by signing the CLI with the same bundle identifier (`com.cursorinternal.Secretive.Host`) and keychain access group entitlements.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- The CLI uses the same `SecretStoreList` setup as the GUI app, including Secure Enclave and Smart Card stores
|
- The CLI uses the same `SecretStoreList` setup as the GUI app, including Secure Enclave and Smart Card stores
|
||||||
- Keys created via CLI will appear in the GUI app and vice versa
|
- Keys created via CLI will appear in the GUI app and vice versa
|
||||||
- The agent can be run either via launchd (recommended) or in foreground mode for testing
|
- The SSH agent runs as part of the Secretive GUI app - use the CLI's `agent status` command to check if it's running
|
||||||
- All key operations require appropriate authentication (Touch ID, Apple Watch, or password) as configured per key
|
- All key operations require appropriate authentication (Touch ID, Apple Watch, or password) as configured per key
|
||||||
|
|||||||
@ -6,8 +6,9 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>keychain-access-groups</key>
|
<key>keychain-access-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>$(AppIdentifierPrefix)com.maxgoedjen.Secretive</string>
|
<string>$(AppIdentifierPrefix)com.cursorinternal.Secretive</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Darwin
|
import AppKit
|
||||||
import SecretAgentKit
|
|
||||||
import SecretKit
|
import SecretKit
|
||||||
import SecureEnclaveSecretKit
|
import SecureEnclaveSecretKit
|
||||||
import SmartCardSecretKit
|
import SmartCardSecretKit
|
||||||
@ -9,7 +8,7 @@ import OSLog
|
|||||||
|
|
||||||
@main
|
@main
|
||||||
struct SecretiveCLI {
|
struct SecretiveCLI {
|
||||||
private static let logger = Logger(subsystem: "com.maxgoedjen.secretive.cli", category: "CLI")
|
private static let logger = Logger(subsystem: "com.cursorinternal.secretive.cli", category: "CLI")
|
||||||
|
|
||||||
static func main() async {
|
static func main() async {
|
||||||
let args = Array(CommandLine.arguments.dropFirst())
|
let args = Array(CommandLine.arguments.dropFirst())
|
||||||
@ -46,13 +45,8 @@ struct SecretiveCLI {
|
|||||||
Usage: secretive-cli <command> [options]
|
Usage: secretive-cli <command> [options]
|
||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
agent <subcommand> Manage SSH agent
|
agent status Check if Secretive's SSH agent is running
|
||||||
install Install agent as launchd service
|
agent start Start Secretive's SSH agent
|
||||||
uninstall Uninstall agent from launchd
|
|
||||||
start Start the agent service
|
|
||||||
stop Stop the agent service
|
|
||||||
status Check agent status
|
|
||||||
run Run agent in foreground (for testing)
|
|
||||||
|
|
||||||
key <subcommand> Manage SSH keys
|
key <subcommand> Manage SSH keys
|
||||||
generate [name] Generate a new key (default: "Secretive Key")
|
generate [name] Generate a new key (default: "Secretive Key")
|
||||||
@ -70,211 +64,109 @@ struct SecretiveCLI {
|
|||||||
|
|
||||||
extension SecretiveCLI {
|
extension SecretiveCLI {
|
||||||
|
|
||||||
|
private static let agentBundleID = "com.cursorinternal.Secretive.SecretAgent"
|
||||||
|
private static let secretiveBundleID = "com.cursorinternal.Secretive.Host"
|
||||||
|
|
||||||
static func handleAgentCommand(args: [String]) async throws {
|
static func handleAgentCommand(args: [String]) async throws {
|
||||||
guard let subcommand = args.first else {
|
guard let subcommand = args.first else {
|
||||||
print("Agent subcommand required: install, uninstall, start, stop, status, or run")
|
print("Agent subcommand required: status, start")
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch subcommand {
|
switch subcommand {
|
||||||
case "install":
|
|
||||||
try await installAgent()
|
|
||||||
case "uninstall":
|
|
||||||
try await uninstallAgent()
|
|
||||||
case "start":
|
|
||||||
try await startAgent()
|
|
||||||
case "stop":
|
|
||||||
try await stopAgent()
|
|
||||||
case "status":
|
case "status":
|
||||||
try await checkAgentStatus()
|
try await checkAgentStatus()
|
||||||
case "run":
|
case "start":
|
||||||
try await runAgent()
|
try await startAgent()
|
||||||
default:
|
default:
|
||||||
print("Unknown agent subcommand: \(subcommand)")
|
print("Unknown agent subcommand: \(subcommand)")
|
||||||
|
print("Available: status, start")
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func installAgent() async throws {
|
static func checkAgentStatus() async throws {
|
||||||
let plistPath = launchdPlistPath
|
// Check if the main Secretive app's SecretAgent is running
|
||||||
let plistDir = (plistPath as NSString).deletingLastPathComponent
|
let runningAgents = NSRunningApplication.runningApplications(withBundleIdentifier: agentBundleID)
|
||||||
|
|
||||||
// Create directory if needed
|
if let agent = runningAgents.first {
|
||||||
try FileManager.default.createDirectory(atPath: plistDir, withIntermediateDirectories: true)
|
print("Secretive agent is running")
|
||||||
|
if let url = agent.bundleURL {
|
||||||
// Get the CLI binary path
|
print(" Path: \(url.path)")
|
||||||
guard let cliPath = Bundle.main.executablePath else {
|
}
|
||||||
throw CLIError("Could not determine CLI binary path")
|
print(" PID: \(agent.processIdentifier)")
|
||||||
|
|
||||||
|
// Also check socket
|
||||||
|
let socketPath = URL.socketPath
|
||||||
|
if FileManager.default.fileExists(atPath: socketPath) {
|
||||||
|
print(" Socket: \(socketPath)")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print("Secretive agent is not running")
|
||||||
|
print("Run 'secretive agent start' to start it")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create plist content
|
|
||||||
let plist: [String: Any] = [
|
|
||||||
"Label": launchdServiceLabel,
|
|
||||||
"ProgramArguments": [cliPath, "agent", "run"],
|
|
||||||
"RunAtLoad": true,
|
|
||||||
"KeepAlive": true,
|
|
||||||
"StandardOutPath": "/dev/null",
|
|
||||||
"StandardErrorPath": "/dev/null",
|
|
||||||
"EnvironmentVariables": [
|
|
||||||
"SSH_AUTH_SOCK": socketPath
|
|
||||||
]
|
|
||||||
]
|
|
||||||
|
|
||||||
let plistData = try PropertyListSerialization.data(fromPropertyList: plist, format: .xml, options: 0)
|
|
||||||
try plistData.write(to: URL(fileURLWithPath: plistPath))
|
|
||||||
|
|
||||||
// Bootstrap the service
|
|
||||||
let process = Process()
|
|
||||||
process.executableURL = URL(fileURLWithPath: "/bin/launchctl")
|
|
||||||
process.arguments = ["bootstrap", "gui/\(getuid())", plistPath]
|
|
||||||
|
|
||||||
try process.run()
|
|
||||||
process.waitUntilExit()
|
|
||||||
|
|
||||||
if process.terminationStatus != 0 {
|
|
||||||
throw CLIError("Failed to install agent: launchctl bootstrap returned \(process.terminationStatus)")
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Agent installed successfully")
|
|
||||||
}
|
|
||||||
|
|
||||||
static func uninstallAgent() async throws {
|
|
||||||
let plistPath = launchdPlistPath
|
|
||||||
|
|
||||||
// Unbootstrap the service
|
|
||||||
let process = Process()
|
|
||||||
process.executableURL = URL(fileURLWithPath: "/bin/launchctl")
|
|
||||||
process.arguments = ["bootout", "gui/\(getuid())", launchdServiceLabel]
|
|
||||||
|
|
||||||
try process.run()
|
|
||||||
process.waitUntilExit()
|
|
||||||
|
|
||||||
// Remove plist file if it exists
|
|
||||||
if FileManager.default.fileExists(atPath: plistPath) {
|
|
||||||
try FileManager.default.removeItem(atPath: plistPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Agent uninstalled successfully")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static func startAgent() async throws {
|
static func startAgent() async throws {
|
||||||
let process = Process()
|
// Check if already running
|
||||||
process.executableURL = URL(fileURLWithPath: "/bin/launchctl")
|
let runningAgents = NSRunningApplication.runningApplications(withBundleIdentifier: agentBundleID)
|
||||||
process.arguments = ["kickstart", "gui/\(getuid())/\(launchdServiceLabel)"]
|
if !runningAgents.isEmpty {
|
||||||
|
print("Secretive agent is already running")
|
||||||
try process.run()
|
return
|
||||||
process.waitUntilExit()
|
|
||||||
|
|
||||||
if process.terminationStatus != 0 {
|
|
||||||
throw CLIError("Failed to start agent: launchctl kickstart returned \(process.terminationStatus)")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print("Agent started")
|
// Find the SecretAgent app inside the installed Secretive app
|
||||||
}
|
guard let agentURL = findSecretAgentApp() else {
|
||||||
|
throw CLIError("Could not find Secretive.app. Please ensure Secretive is installed in /Applications or ~/Applications.")
|
||||||
static func stopAgent() async throws {
|
}
|
||||||
let process = Process()
|
|
||||||
process.executableURL = URL(fileURLWithPath: "/bin/launchctl")
|
|
||||||
process.arguments = ["kill", "gui/\(getuid())/\(launchdServiceLabel)"]
|
|
||||||
|
|
||||||
try process.run()
|
print("Starting Secretive agent...")
|
||||||
process.waitUntilExit()
|
let config = NSWorkspace.OpenConfiguration()
|
||||||
|
config.activates = false
|
||||||
|
|
||||||
print("Agent stopped")
|
do {
|
||||||
}
|
try await NSWorkspace.shared.openApplication(at: agentURL, configuration: config)
|
||||||
|
// Give it a moment to start
|
||||||
static func checkAgentStatus() async throws {
|
try await Task.sleep(for: .seconds(1))
|
||||||
let process = Process()
|
|
||||||
process.executableURL = URL(fileURLWithPath: "/bin/launchctl")
|
// Verify it started
|
||||||
process.arguments = ["list", launchdServiceLabel]
|
let agents = NSRunningApplication.runningApplications(withBundleIdentifier: agentBundleID)
|
||||||
|
if !agents.isEmpty {
|
||||||
let pipe = Pipe()
|
print("Secretive agent started successfully")
|
||||||
process.standardOutput = pipe
|
} else {
|
||||||
|
print("Warning: Agent may not have started. Check Secretive.app for details.")
|
||||||
try process.run()
|
}
|
||||||
process.waitUntilExit()
|
} catch {
|
||||||
|
throw CLIError("Failed to start agent: \(error.localizedDescription)")
|
||||||
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
|
||||||
let output = String(data: data, encoding: .utf8) ?? ""
|
|
||||||
|
|
||||||
if process.terminationStatus == 0 && !output.isEmpty {
|
|
||||||
print("Agent is running")
|
|
||||||
print(output)
|
|
||||||
} else {
|
|
||||||
print("Agent is not running")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func runAgent() async throws {
|
private static func findSecretAgentApp() -> URL? {
|
||||||
logger.info("Starting SSH agent")
|
let fileManager = FileManager.default
|
||||||
|
|
||||||
// Set up store list
|
// Possible locations for Secretive.app
|
||||||
let storeList: SecretStoreList = await MainActor.run {
|
let searchPaths = [
|
||||||
let list = SecretStoreList()
|
"/Applications/Secretive.app",
|
||||||
let cryptoKit = SecureEnclave.Store()
|
"\(fileManager.homeDirectoryForCurrentUser.path)/Applications/Secretive.app"
|
||||||
let migrator = SecureEnclave.CryptoKitMigrator()
|
]
|
||||||
try? migrator.migrate(to: cryptoKit)
|
|
||||||
list.add(store: cryptoKit)
|
|
||||||
list.add(store: SmartCard.Store())
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create agent (no witness for CLI)
|
for path in searchPaths {
|
||||||
let agent = Agent(storeList: storeList, witness: nil)
|
let secretiveURL = URL(fileURLWithPath: path)
|
||||||
|
let agentURL = secretiveURL.appendingPathComponent("Contents/Library/LoginItems/SecretAgent.app")
|
||||||
// Set up socket controller
|
if fileManager.fileExists(atPath: agentURL.path) {
|
||||||
let socket = SocketController(path: socketPath)
|
return agentURL
|
||||||
|
|
||||||
// Set up input parser (use direct parser, not XPC)
|
|
||||||
let parser = SSHAgentInputParser()
|
|
||||||
|
|
||||||
logger.info("SSH agent listening on \(socketPath)")
|
|
||||||
print("SSH agent running on \(socketPath)")
|
|
||||||
print("Set SSH_AUTH_SOCK=\(socketPath) to use this agent")
|
|
||||||
|
|
||||||
func handleSession(_ session: SocketController.Session) async {
|
|
||||||
do {
|
|
||||||
for await message in session.messages {
|
|
||||||
let request = try parser.parse(data: message)
|
|
||||||
let response = await agent.handle(request: request, provenance: session.provenance)
|
|
||||||
try await MainActor.run {
|
|
||||||
try session.write(response)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
logger.error("Session error: \(error.localizedDescription)")
|
|
||||||
try? session.close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle sessions
|
// Also try to find via Launch Services
|
||||||
for await session in socket.sessions {
|
if let secretiveURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: secretiveBundleID) {
|
||||||
await handleSession(session)
|
let agentURL = secretiveURL.appendingPathComponent("Contents/Library/LoginItems/SecretAgent.app")
|
||||||
|
if fileManager.fileExists(atPath: agentURL.path) {
|
||||||
|
return agentURL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return nil
|
||||||
// MARK: - Agent Paths
|
|
||||||
|
|
||||||
static var socketPath: String {
|
|
||||||
// Use the same socket path as the GUI app
|
|
||||||
// This matches URL.socketPath from Common module, which constructs:
|
|
||||||
// ~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh
|
|
||||||
let home = FileManager.default.homeDirectoryForCurrentUser.path
|
|
||||||
let containerPath = "\(home)/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data"
|
|
||||||
#if DEBUG
|
|
||||||
return "\(containerPath)/socket-debug.ssh"
|
|
||||||
#else
|
|
||||||
return "\(containerPath)/socket.ssh"
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static var launchdServiceLabel: String {
|
|
||||||
"com.maxgoedjen.secretive.cli"
|
|
||||||
}
|
|
||||||
|
|
||||||
static var launchdPlistPath: String {
|
|
||||||
let home = FileManager.default.homeDirectoryForCurrentUser.path
|
|
||||||
return "\(home)/Library/LaunchAgents/\(launchdServiceLabel).plist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ extension SecureEnclave {
|
|||||||
|
|
||||||
public struct CryptoKitMigrator {
|
public struct CryptoKitMigrator {
|
||||||
|
|
||||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.migration", category: "CryptoKitMigrator")
|
private let logger = Logger(subsystem: "com.cursorinternal.secretive.migration", category: "CryptoKitMigrator")
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -287,7 +287,7 @@ extension SecureEnclave.Store {
|
|||||||
|
|
||||||
enum Constants {
|
enum Constants {
|
||||||
static let keyClass = kSecClassGenericPassword as String
|
static let keyClass = kSecClassGenericPassword as String
|
||||||
static let keyTag = Data("com.maxgoedjen.secretive.secureenclave.key".utf8)
|
static let keyTag = Data("com.cursorinternal.secretive.secureenclave.key".utf8)
|
||||||
static let notificationToken = UUID().uuidString
|
static let notificationToken = UUID().uuidString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -53,7 +53,7 @@ public final class XPCServiceDelegate: NSObject, NSXPCListenerDelegate {
|
|||||||
extension NSError {
|
extension NSError {
|
||||||
|
|
||||||
private enum Constants {
|
private enum Constants {
|
||||||
static let domain = "com.maxgoedjen.secretive.xpcwrappers"
|
static let domain = "com.cursorinternal.secretive.xpcwrappers"
|
||||||
static let code = -1
|
static let code = -1
|
||||||
static let dataKey = "underlying"
|
static let dataKey = "underlying"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
let path = URL.socketPath as String
|
let path = URL.socketPath as String
|
||||||
return SocketController(path: path)
|
return SocketController(path: path)
|
||||||
}()
|
}()
|
||||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "AppDelegate")
|
private let logger = Logger(subsystem: "com.cursorinternal.secretive.secretagent", category: "AppDelegate")
|
||||||
|
|
||||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||||
logger.debug("SecretAgent finished launching")
|
logger.debug("SecretAgent finished launching")
|
||||||
|
|||||||
@ -114,18 +114,18 @@ extension Notifier {
|
|||||||
enum Constants {
|
enum Constants {
|
||||||
|
|
||||||
// Update notifications
|
// Update notifications
|
||||||
static let updateCategoryIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.update"
|
static let updateCategoryIdentitifier = "com.cursorinternal.Secretive.SecretAgent.update"
|
||||||
static let criticalUpdateCategoryIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.update.critical"
|
static let criticalUpdateCategoryIdentitifier = "com.cursorinternal.Secretive.SecretAgent.update.critical"
|
||||||
static let updateActionIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.update.updateaction"
|
static let updateActionIdentitifier = "com.cursorinternal.Secretive.SecretAgent.update.updateaction"
|
||||||
static let ignoreActionIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.update.ignoreaction"
|
static let ignoreActionIdentitifier = "com.cursorinternal.Secretive.SecretAgent.update.ignoreaction"
|
||||||
|
|
||||||
// Authorization persistence notificatoins
|
// Authorization persistence notificatoins
|
||||||
static let persistAuthenticationCategoryIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.persistauthentication"
|
static let persistAuthenticationCategoryIdentitifier = "com.cursorinternal.Secretive.SecretAgent.persistauthentication"
|
||||||
static let doNotPersistActionIdentitifier = "com.maxgoedjen.Secretive.SecretAgent.persistauthentication.donotpersist"
|
static let doNotPersistActionIdentitifier = "com.cursorinternal.Secretive.SecretAgent.persistauthentication.donotpersist"
|
||||||
static let persistForActionIdentitifierPrefix = "com.maxgoedjen.Secretive.SecretAgent.persistauthentication.persist."
|
static let persistForActionIdentitifierPrefix = "com.cursorinternal.Secretive.SecretAgent.persistauthentication.persist."
|
||||||
|
|
||||||
static let persistSecretIDKey = "com.maxgoedjen.Secretive.SecretAgent.persistauthentication.secretidkey"
|
static let persistSecretIDKey = "com.cursorinternal.Secretive.SecretAgent.persistauthentication.secretidkey"
|
||||||
static let persistStoreIDKey = "com.maxgoedjen.Secretive.SecretAgent.persistauthentication.storeidkey"
|
static let persistStoreIDKey = "com.cursorinternal.Secretive.SecretAgent.persistauthentication.storeidkey"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>keychain-access-groups</key>
|
<key>keychain-access-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>$(AppIdentifierPrefix)com.maxgoedjen.Secretive</string>
|
<string>$(AppIdentifierPrefix)com.cursorinternal.Secretive</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@ -7,12 +7,12 @@ import OSLog
|
|||||||
/// Delegates all agent input parsing to an XPC service which wraps OpenSSH
|
/// Delegates all agent input parsing to an XPC service which wraps OpenSSH
|
||||||
public final class XPCAgentInputParser: SSHAgentInputParserProtocol {
|
public final class XPCAgentInputParser: SSHAgentInputParserProtocol {
|
||||||
|
|
||||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "XPCAgentInputParser")
|
private let logger = Logger(subsystem: "com.cursorinternal.secretive.secretagent", category: "XPCAgentInputParser")
|
||||||
private let session: XPCTypedSession<SSHAgent.Request, SSHAgentInputParser.AgentParsingError>
|
private let session: XPCTypedSession<SSHAgent.Request, SSHAgentInputParser.AgentParsingError>
|
||||||
|
|
||||||
public init() async throws {
|
public init() async throws {
|
||||||
logger.debug("Creating XPCAgentInputParser")
|
logger.debug("Creating XPCAgentInputParser")
|
||||||
session = try await XPCTypedSession(serviceName: "com.maxgoedjen.Secretive.SecretAgentInputParser", warmup: true)
|
session = try await XPCTypedSession(serviceName: "com.cursorinternal.Secretive.SecretAgentInputParser", warmup: true)
|
||||||
logger.debug("XPCAgentInputParser is warmed up.")
|
logger.debug("XPCAgentInputParser is warmed up.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import SecretAgentKit
|
|||||||
|
|
||||||
final class SecretAgentInputParser: NSObject, XPCProtocol {
|
final class SecretAgentInputParser: NSObject, XPCProtocol {
|
||||||
|
|
||||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.SecretAgentInputParser", category: "SecretAgentInputParser")
|
private let logger = Logger(subsystem: "com.cursorinternal.secretive.SecretAgentInputParser", category: "SecretAgentInputParser")
|
||||||
|
|
||||||
func process(_ data: Data) async throws -> SSHAgent.Request {
|
func process(_ data: Data) async throws -> SSHAgent.Request {
|
||||||
let parser = SSHAgentInputParser()
|
let parser = SSHAgentInputParser()
|
||||||
|
|||||||
@ -960,7 +960,7 @@
|
|||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1;
|
MARKETING_VERSION = 1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.Host;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
};
|
};
|
||||||
@ -1000,7 +1000,7 @@
|
|||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1;
|
MARKETING_VERSION = 1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.Host;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "Secretive - Host";
|
PROVISIONING_PROFILE_SPECIFIER = "Secretive - Host";
|
||||||
};
|
};
|
||||||
@ -1036,7 +1036,7 @@
|
|||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretiveUpdater;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.SecretiveUpdater;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
REGISTER_APP_GROUPS = YES;
|
REGISTER_APP_GROUPS = YES;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
@ -1076,7 +1076,7 @@
|
|||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretiveUpdater;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.SecretiveUpdater;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
REGISTER_APP_GROUPS = YES;
|
REGISTER_APP_GROUPS = YES;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
@ -1118,7 +1118,7 @@
|
|||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretiveUpdater;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.SecretiveUpdater;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
REGISTER_APP_GROUPS = YES;
|
REGISTER_APP_GROUPS = YES;
|
||||||
@ -1150,7 +1150,7 @@
|
|||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgentInputParser;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.SecretAgentInputParser;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
REGISTER_APP_GROUPS = YES;
|
REGISTER_APP_GROUPS = YES;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
@ -1180,7 +1180,7 @@
|
|||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgentInputParser;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.SecretAgentInputParser;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
REGISTER_APP_GROUPS = YES;
|
REGISTER_APP_GROUPS = YES;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
@ -1212,7 +1212,7 @@
|
|||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgentInputParser;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.SecretAgentInputParser;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
REGISTER_APP_GROUPS = YES;
|
REGISTER_APP_GROUPS = YES;
|
||||||
@ -1333,7 +1333,7 @@
|
|||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1;
|
MARKETING_VERSION = 1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.Host;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.Host;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
};
|
};
|
||||||
name = Test;
|
name = Test;
|
||||||
@ -1366,7 +1366,7 @@
|
|||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1;
|
MARKETING_VERSION = 1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.SecretAgent;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
};
|
};
|
||||||
name = Test;
|
name = Test;
|
||||||
@ -1401,7 +1401,7 @@
|
|||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1;
|
MARKETING_VERSION = 1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.SecretAgent;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
@ -1437,7 +1437,7 @@
|
|||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = 1;
|
MARKETING_VERSION = 1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretAgent;
|
PRODUCT_BUNDLE_IDENTIFIER = com.cursorinternal.Secretive.SecretAgent;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "Secretive - Secret Agent";
|
PROVISIONING_PROFILE_SPECIFIER = "Secretive - Secret Agent";
|
||||||
};
|
};
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import Common
|
|||||||
|
|
||||||
var running: Bool = false
|
var running: Bool = false
|
||||||
var process: NSRunningApplication? = nil
|
var process: NSRunningApplication? = nil
|
||||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive", category: "LaunchAgentController")
|
private let logger = Logger(subsystem: "com.cursorinternal.secretive", category: "LaunchAgentController")
|
||||||
private let service = SMAppService.loginItem(identifier: Bundle.agentBundleID)
|
private let service = SMAppService.loginItem(identifier: Bundle.agentBundleID)
|
||||||
|
|
||||||
nonisolated init() {
|
nonisolated init() {
|
||||||
|
|||||||
@ -37,8 +37,8 @@ import AppKit
|
|||||||
extension JustUpdatedChecker {
|
extension JustUpdatedChecker {
|
||||||
|
|
||||||
enum Constants {
|
enum Constants {
|
||||||
static let previousVersionUserDefaultsKey = "com.maxgoedjen.Secretive.lastBuild"
|
static let previousVersionUserDefaultsKey = "com.cursorinternal.Secretive.lastBuild"
|
||||||
static let previousOSVersionUserDefaultsKey = "com.maxgoedjen.Secretive.lastOS"
|
static let previousOSVersionUserDefaultsKey = "com.cursorinternal.Secretive.lastOS"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>keychain-access-groups</key>
|
<key>keychain-access-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>$(AppIdentifierPrefix)com.maxgoedjen.Secretive</string>
|
<string>$(AppIdentifierPrefix)com.cursorinternal.Secretive</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user