Skip to content

Commit 5388154

Browse files
chore: initial public TrimControl snapshot
0 parents  commit 5388154

51 files changed

Lines changed: 7409 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Bug Report
2+
description: Report a TrimControl bug
3+
title: "[Bug]: "
4+
labels:
5+
- bug
6+
body:
7+
- type: textarea
8+
id: summary
9+
attributes:
10+
label: Summary
11+
description: What happened?
12+
validations:
13+
required: true
14+
- type: input
15+
id: macos-version
16+
attributes:
17+
label: macOS Version
18+
placeholder: "14.6"
19+
validations:
20+
required: true
21+
- type: input
22+
id: trimcontrol-version
23+
attributes:
24+
label: TrimControl Version
25+
placeholder: "0.1.0"
26+
validations:
27+
required: true
28+
- type: input
29+
id: terminal-backend
30+
attributes:
31+
label: Terminal Backend
32+
placeholder: "Apple Terminal, iTerm2, Ghostty, WezTerm, Alacritty, or Custom Command"
33+
- type: textarea
34+
id: steps
35+
attributes:
36+
label: Steps To Reproduce
37+
description: Include the file extension involved, but do not include private file contents.
38+
validations:
39+
required: true
40+
- type: textarea
41+
id: expected
42+
attributes:
43+
label: Expected Behavior
44+
- type: textarea
45+
id: actual
46+
attributes:
47+
label: Actual Behavior

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
blank_issues_enabled: true
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Feature Request
2+
description: Suggest an improvement for TrimControl
3+
title: "[Feature]: "
4+
labels:
5+
- enhancement
6+
body:
7+
- type: textarea
8+
id: problem
9+
attributes:
10+
label: Problem
11+
description: What workflow should TrimControl support better?
12+
validations:
13+
required: true
14+
- type: textarea
15+
id: proposal
16+
attributes:
17+
label: Proposed Solution
18+
description: What would you like to happen?
19+
validations:
20+
required: true
21+
- type: textarea
22+
id: alternatives
23+
attributes:
24+
label: Alternatives Considered
25+
- type: dropdown
26+
id: area
27+
attributes:
28+
label: Area
29+
options:
30+
- Finder defaults
31+
- Default Openers
32+
- Terminal backends
33+
- Packaging or installation
34+
- User interface
35+
- Documentation

.github/workflows/release.yml

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
---
2+
name: Release
3+
4+
on:
5+
push:
6+
tags:
7+
- "v*"
8+
workflow_dispatch:
9+
inputs:
10+
version:
11+
description: "Release version without the leading v, for example 0.1.0"
12+
required: true
13+
type: string
14+
15+
permissions:
16+
contents: write
17+
18+
concurrency:
19+
group: release-${{ github.ref }}
20+
cancel-in-progress: false
21+
22+
jobs:
23+
dmg-and-homebrew:
24+
name: Build DMG and update Homebrew tap
25+
runs-on: macos-26
26+
27+
env:
28+
TRIMCONTROL_SIGN_IDENTITY: ${{ vars.TRIMCONTROL_SIGN_IDENTITY }}
29+
TRIMCONTROL_REQUIRE_SIGN_IDENTITY: "1"
30+
HOMEBREW_TAP_REPOSITORY: ${{ vars.HOMEBREW_TAP_REPOSITORY }}
31+
32+
steps:
33+
- name: Check out source
34+
uses: actions/checkout@v6
35+
with:
36+
fetch-depth: 0
37+
38+
- name: Resolve release version
39+
run: |
40+
set -euo pipefail
41+
42+
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
43+
tag="${GITHUB_REF_NAME}"
44+
version="${tag#v}"
45+
else
46+
version="${{ inputs.version }}"
47+
tag="v${version#v}"
48+
version="${version#v}"
49+
fi
50+
51+
if [[ -z "$version" || "$version" == "$tag" ]]; then
52+
echo "Could not resolve release version from $tag" >&2
53+
exit 1
54+
fi
55+
56+
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
57+
echo "Release version must be stable semantic version like 0.1.0." >&2
58+
exit 1
59+
fi
60+
61+
if [[ "$tag" != "v$version" ]]; then
62+
echo "Release tag must be v$version." >&2
63+
exit 1
64+
fi
65+
66+
echo "VERSION=$version" >> "$GITHUB_ENV"
67+
echo "TAG=$tag" >> "$GITHUB_ENV"
68+
echo "TRIMCONTROL_VERSION=$version" >> "$GITHUB_ENV"
69+
echo "TRIMCONTROL_BUILD_NUMBER=${GITHUB_RUN_NUMBER}" >> "$GITHUB_ENV"
70+
71+
- name: Import Developer ID certificate
72+
env:
73+
APPLE_CERTIFICATE_P12: ${{ secrets.APPLE_CERTIFICATE_P12 }}
74+
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
75+
run: script/import_codesign_certificate.sh
76+
77+
- name: Test
78+
run: swift test
79+
80+
- name: Build signed DMG
81+
run: script/package_dmg.sh --version "$VERSION" --arch arm64
82+
83+
- name: Prepare App Store Connect key
84+
env:
85+
APP_STORE_CONNECT_PRIVATE_KEY: ${{ secrets.APP_STORE_CONNECT_PRIVATE_KEY }}
86+
APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }}
87+
run: |
88+
set -euo pipefail
89+
: "${APP_STORE_CONNECT_PRIVATE_KEY:?Set APP_STORE_CONNECT_PRIVATE_KEY secret.}"
90+
: "${APP_STORE_CONNECT_KEY_ID:?Set APP_STORE_CONNECT_KEY_ID secret.}"
91+
92+
key_path="$RUNNER_TEMP/AuthKey_${APP_STORE_CONNECT_KEY_ID}.p8"
93+
printf '%s' "$APP_STORE_CONNECT_PRIVATE_KEY" > "$key_path"
94+
chmod 600 "$key_path"
95+
echo "APP_STORE_CONNECT_KEY_PATH=$key_path" >> "$GITHUB_ENV"
96+
97+
- name: Notarize DMG
98+
env:
99+
APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }}
100+
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
101+
run: script/notarize_dmg.sh "dist/release/TrimControl-$VERSION-arm64.dmg"
102+
103+
- name: Publish GitHub release
104+
env:
105+
GH_TOKEN: ${{ github.token }}
106+
run: |
107+
set -euo pipefail
108+
109+
dmg="dist/release/TrimControl-$VERSION-arm64.dmg"
110+
sha_file="$dmg.sha256"
111+
112+
if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then
113+
target_args=(--verify-tag)
114+
else
115+
target_args=(--target "$GITHUB_SHA")
116+
fi
117+
118+
gh release create "$TAG" \
119+
"$dmg#TrimControl $VERSION arm64 DMG" \
120+
"$sha_file#TrimControl $VERSION arm64 SHA-256" \
121+
--title "TrimControl $VERSION" \
122+
--generate-notes \
123+
"${target_args[@]}"
124+
125+
- name: Update Homebrew tap
126+
env:
127+
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
128+
run: |
129+
set -euo pipefail
130+
131+
: "${HOMEBREW_TAP_TOKEN:?Set HOMEBREW_TAP_TOKEN with push access to the tap repo.}"
132+
133+
tap_repo="${HOMEBREW_TAP_REPOSITORY:-subdepthtech/homebrew-trimcontrol}"
134+
tap_path="$RUNNER_TEMP/homebrew-tap"
135+
dmg="dist/release/TrimControl-$VERSION-arm64.dmg"
136+
sha256="$(shasum --algorithm 256 "$dmg" | awk '{print $1}')"
137+
download_url="https://github.com/${GITHUB_REPOSITORY}/releases/download/${TAG}/TrimControl-${VERSION}-arm64.dmg"
138+
139+
GH_TOKEN="$HOMEBREW_TAP_TOKEN" gh repo view "$tap_repo" --json nameWithOwner >/dev/null
140+
141+
auth_header="$(printf 'x-access-token:%s' "$HOMEBREW_TAP_TOKEN" | base64 | tr -d '\n')"
142+
git -c "http.https://github.com/.extraheader=AUTHORIZATION: basic ${auth_header}" \
143+
clone "https://github.com/${tap_repo}.git" "$tap_path"
144+
git -C "$tap_path" config \
145+
http.https://github.com/.extraheader \
146+
"AUTHORIZATION: basic ${auth_header}"
147+
148+
TAP_PATH="$tap_path" \
149+
VERSION="$VERSION" \
150+
SHA256="$sha256" \
151+
DOWNLOAD_URL="$download_url" \
152+
script/update_homebrew_cask.sh
153+
154+
brew style "$tap_path/Casks/trimcontrol.rb"
155+
156+
git -C "$tap_path" config user.name "github-actions[bot]"
157+
git -C "$tap_path" config user.email "41898282+github-actions[bot]@users.noreply.github.com"
158+
git -C "$tap_path" add Casks/trimcontrol.rb
159+
160+
if git -C "$tap_path" diff --cached --quiet; then
161+
echo "Homebrew cask already up to date."
162+
exit 0
163+
fi
164+
165+
git -C "$tap_path" commit -m "trimcontrol: update to $VERSION"
166+
git -C "$tap_path" push
167+
168+
- name: Clean up signing material
169+
if: always()
170+
run: |
171+
set -euo pipefail
172+
173+
if [[ -n "${APP_STORE_CONNECT_KEY_PATH:-}" ]]; then
174+
rm -f "$APP_STORE_CONNECT_KEY_PATH"
175+
fi
176+
177+
if [[ -n "${TRIMCONTROL_SIGNING_KEYCHAIN_PATH:-}" ]]; then
178+
security delete-keychain "$TRIMCONTROL_SIGNING_KEYCHAIN_PATH" >/dev/null 2>&1 || true
179+
rm -f "$TRIMCONTROL_SIGNING_KEYCHAIN_PATH"
180+
fi

.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.DS_Store
2+
.build/
3+
.swiftpm/
4+
DerivedData/
5+
xcuserdata/
6+
*.xcuserstate
7+
*.xcworkspace/xcuserdata/
8+
*.xcodeproj/xcuserdata/
9+
*.xcodeproj/project.xcworkspace/xcuserdata/
10+
*.app.dSYM/
11+
*.dSYM/
12+
build/
13+
dist/
14+
*.log
15+
.claude/worktrees/
16+
videos/

Assets/TrimControlIcon.png

1.46 MB
Loading

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Changelog
2+
3+
All notable changes to TrimControl will be documented in this file.
4+
5+
## 0.1.0 - Unreleased
6+
7+
- Add a native macOS menu-bar utility for routing text, source, and config files from Finder into Neovim.
8+
- Add configurable terminal backends for Apple Terminal, iTerm2, Ghostty, WezTerm, Alacritty, and Custom Command.
9+
- Add Default Openers for companion files such as PDFs, images, media, archives, and office documents.
10+
- Add build, install, verification, DMG packaging, notarization, and Homebrew cask automation.

CONTRIBUTING.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Contributing
2+
3+
Thanks for helping improve TrimControl.
4+
5+
## Local Setup
6+
7+
TrimControl is a SwiftPM-based macOS app with no third-party Swift packages.
8+
9+
```sh
10+
swift test
11+
swift build
12+
script/build_app.sh
13+
script/verify_defaults.sh --app dist/TrimControl.app
14+
```
15+
16+
Use `TRIMCONTROL_SIGN_IDENTITY=-` for ad-hoc local signing. Do not run `script/install_app.sh` unless you intentionally want to replace the installed app and update LaunchServices defaults on your Mac.
17+
18+
## Pull Requests
19+
20+
- Keep changes small and focused.
21+
- Preserve the native macOS utility behavior.
22+
- Add or update tests for behavior changes.
23+
- Update docs when commands, release behavior, or user-visible workflows change.
24+
- Run `git diff --check` before opening a PR.
25+
26+
## LaunchServices Safety
27+
28+
LaunchServices defaults are host-local user state. Tests and scripts should avoid changing system defaults unless the command is explicitly named as an install or defaults operation.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 SubDepthTech
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Package.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// swift-tools-version: 5.9
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "TrimControl",
7+
platforms: [
8+
.macOS(.v14)
9+
],
10+
products: [
11+
.executable(name: "TrimControl", targets: ["TrimControl"]),
12+
.executable(name: "trimcontrol-tool", targets: ["TrimControlTool"]),
13+
],
14+
targets: [
15+
.target(
16+
name: "TrimControlCore"
17+
),
18+
.executableTarget(
19+
name: "TrimControl",
20+
dependencies: ["TrimControlCore"]
21+
),
22+
.executableTarget(
23+
name: "TrimControlTool",
24+
dependencies: ["TrimControlCore"]
25+
),
26+
.testTarget(
27+
name: "TrimControlCoreTests",
28+
dependencies: ["TrimControlCore"]
29+
),
30+
]
31+
)

0 commit comments

Comments
 (0)