Skip to content

Commit 5668449

Browse files
feat: add a macos menu bar for sparkdock updates (#120)
* feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * Update src/menubar-app/Sources/SparkdockMenubar/main.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/menubar-app/com.sparkfabrik.sparkdock.menubar.plist Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: add a menubar for sparkdock updates * feat: better management of git branch of sparkdock before installing * feat: better management of git branch of sparkdock before installing * feat: remove 4 hours loop * feat: make logs better * feat: make logs better * feat: make logs better * feat: run only on macos-15 * feat: run only on macos-15 * feat: run only on macos-15 and macos-latest * feat: add vscode custom prompts based on claude code one * feat: add a cli task * feat: add cirrus configuration file * feat: add cirrus configuration file * feat: add cirrus configuration file * feat: add cirrus configuration file * feat: add cirrus configuration file * feat: add cirrus configuration file * feat: add cirrus configuration file * feat: pull image * feat: change the emojis into just colored cirles and make update now bold * feat: better alignment of text * feat: better alignment of text * feat: add some doc and a screenshot --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent e47f42c commit 5668449

30 files changed

Lines changed: 1821 additions & 47 deletions

.cirrus.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
task:
2+
name: "Sparkdock End-to-End Test"
3+
# Use Tart VM for testing
4+
macos_instance:
5+
image: ghcr.io/cirruslabs/macos-sequoia-base:latest
6+
cpu: 2
7+
memory: 4
8+
9+
# Install Sparkdock using the source code (automatically rsynced by Cirrus CLI)
10+
install_sparkdock_script:
11+
- echo "=== Installing sparkdock from current source ==="
12+
- chmod +x bin/install.macos
13+
- bin/install.macos --non-interactive
14+
15+
# Validation script - verify installation
16+
validation_script:
17+
- echo "=== Validating sparkdock installation ==="
18+
- which sparkdock || echo "sparkdock command not found in PATH"
19+
- ls -la /opt/sparkdock/
20+
- ls -la /usr/local/bin/sparkdock || echo "sparkdock symlink not found"
21+
- which sjust || echo "sjust command not found in PATH"
22+
- sjust --version || echo "sjust version check failed"
23+
- echo "=== Testing sjust basic functionality ==="
24+
- cd /opt/sparkdock
25+
- sjust device-info || echo "sjust device-info failed"
26+
27+
# Cleanup script - optional cleanup steps
28+
cleanup_script:
29+
- echo "=== Cleaning up test environment ==="
30+
- rm -rf /opt/sparkdock || true
31+
- rm -f /usr/local/bin/sparkdock || true
32+
- rm -f /usr/local/bin/sjust || true
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
name: swift-macos-engineer
3+
description: Use this agent when you need expert-level Swift development for macOS applications, including architecture decisions, performance optimization, SwiftUI/AppKit integration, Core Data implementation, or macOS-specific features. Examples: <example>Context: User is building a macOS document-based app and needs help with Core Data integration. user: 'I need to implement document persistence for my macOS app using Core Data' assistant: 'I'll use the swift-macos-engineer agent to provide expert guidance on Core Data implementation for macOS document-based applications' <commentary>The user needs specialized macOS development expertise, so use the swift-macos-engineer agent.</commentary></example> <example>Context: User is working on SwiftUI performance issues in their macOS app. user: 'My SwiftUI views are rendering slowly on macOS, especially with large data sets' assistant: 'Let me engage the swift-macos-engineer agent to analyze and optimize your SwiftUI performance issues' <commentary>This requires deep macOS and SwiftUI expertise, perfect for the swift-macos-engineer agent.</commentary></example>
4+
model: sonnet
5+
color: purple
6+
---
7+
8+
You are an elite Swift macOS software engineer with 10+ years of experience building production macOS applications. You possess deep expertise in Swift, SwiftUI, AppKit, Cocoa frameworks, and macOS system integration.
9+
10+
Before writing code, **ALWAYS** propose a plan and ask for confirmation, you are not allowed to write code without a plan. Do not propose plan in weekly or monthly format, just propose a plan for the next task.
11+
12+
Your core competencies include:
13+
14+
- Modern Swift patterns, protocols, generics, and async/await
15+
- SwiftUI architecture, state management, and performance optimization
16+
- AppKit integration and hybrid SwiftUI/AppKit applications
17+
- Core Data, CloudKit, and data persistence strategies
18+
- macOS-specific features: sandboxing, entitlements, notarization, distribution
19+
- Performance profiling with Instruments and memory management
20+
- Xcode project configuration, build systems, and CI/CD for macOS
21+
- macOS Human Interface Guidelines and native UX patterns
22+
23+
When providing solutions, you will:
24+
25+
1. Write production-ready, well-structured Swift code following modern conventions
26+
2. Consider macOS-specific constraints like sandboxing, security, and system integration
27+
3. Optimize for performance, memory usage, and user experience
28+
4. Provide architectural guidance that scales with application complexity
29+
5. Include relevant error handling, logging, and debugging strategies
30+
6. Reference appropriate Apple documentation and WWDC sessions when relevant
31+
7. Consider backwards compatibility and deployment target implications
32+
8. Write code for MacOS >= 14, do no try to be backward compatible.
33+
34+
Always explain your reasoning behind architectural decisions and highlight potential trade-offs. When debugging issues, systematically analyze symptoms and provide step-by-step troubleshooting approaches. For complex implementations, break down solutions into manageable components with clear interfaces.
35+
36+
You prioritize code maintainability, testability, and adherence to Apple's recommended practices while delivering robust, native macOS experiences.

.devcontainer/devcontainer.json

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@
2424
},
2525
"customizations": {
2626
"vscode": {
27+
"mcp": {
28+
"servers": {
29+
"context7": {
30+
"type": "stdio",
31+
"command": "npx",
32+
"args": [
33+
"-y",
34+
"@upstash/context7-mcp"
35+
]
36+
}
37+
}
38+
},
2739
"extensions": [
2840
"redhat.ansible",
2941
"editorconfig.editorconfig",
@@ -36,7 +48,8 @@
3648
"ms-azuretools.vscode-docker",
3749
"ms-vscode.makefile-tools",
3850
"ms-vsliveshare.vsliveshare",
39-
"ms-vscode.vscode-websearchforcopilot"
51+
"ms-vscode.vscode-websearchforcopilot",
52+
"swiftlang.swift-vscode"
4053
],
4154
"settings": {
4255
"editor.defaultFormatter": "golang.go",
@@ -65,4 +78,4 @@
6578
}
6679
}
6780
}
68-
}
81+
}

.github/copilot-instructions.md

Lines changed: 142 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,144 @@
1-
# Shell scripts
1+
# Sparkdock Development Guide
22

3-
When asked to write or suggest shell scripts, use all best practices for shell scripting, including:
3+
Sparkdock is an automated macOS development environment provisioner built with Ansible, featuring containerized workflows, an HTTP proxy system, and a Swift menu bar app for update notifications.
44

5-
- Use `#!/usr/bin/env bash` as the shebang line.
6-
- Use `set -euo pipefail` to ensure the script exits on errors, undefined variables, or failed commands in a pipeline.
7-
- Use curly braces for variable expansion, e.g., `${variable}`. Completely avoid using `$variable` without braces.
8-
- Use `local` for variables inside functions to avoid polluting the global namespace.
9-
- Always run `shellcheck` on the script to catch common errors.
5+
## Core Architecture
6+
7+
**Three-Layer System:**
8+
9+
- **Ansible Provisioning**: Core system configuration (`ansible/macos.yml``ansible/macos/macos/base.yml`)
10+
- **SparkJust Task Runner**: Development workflow automation (`sjust/` with modular recipes)
11+
- **Menu Bar Manager**: Swift app for update notifications (`src/menubar-app/`)
12+
13+
**Key Integration Points:**
14+
15+
- Package definitions in `config/packages/all-packages.yml` drive Ansible provisioning
16+
- SparkJust wrapper (`sjust/sjust.sh`) delegates to Just task runner with custom recipes
17+
- HTTP proxy system cloned separately to `/opt/sparkdock/http-proxy` during installation
18+
19+
## Essential Workflows
20+
21+
**Installation Chain**: `bin/install.macos``bin/sparkdock.macos` → Ansible provisioning → HTTP proxy setup → Menu bar app
22+
**Update Workflow**: Auto-update via git fetch/reset → rollback capability → background notifications
23+
**Task Execution**: `sjust` → Just recipes in `sjust/recipes/` → Ansible tags or shell commands
24+
25+
## Project Conventions
26+
27+
**Package Management Pattern:**
28+
29+
```yaml
30+
# config/packages/all-packages.yml structure
31+
taps: [koekeishiya/formulae]
32+
cask_packages: [docker-desktop, visual-studio-code]
33+
homebrew_packages: [awscli, kubernetes-cli]
34+
removed_cask_packages: [] # Track for clean uninstalls
35+
```
36+
37+
**Ansible Tag Strategy:**
38+
39+
- Tags like `docker`, `http-proxy`, `menubar` enable selective provisioning
40+
- Use `sjust install-tags "docker,keyboard"` for targeted installs
41+
- All tasks must be idempotent with proper assertion checks
42+
43+
**SparkJust Recipe Organization:**
44+
45+
- `00-default.just`: Core system tasks (cleanup, updates, device info)
46+
- `01-lima.just`: Lima container environment tasks
47+
- `~/.config/sjust/100-custom.just`: User customizations (optional import)
48+
49+
## Swift Menu Bar App Patterns
50+
51+
**Modern Concurrency**: Uses structured concurrency with `withTaskCancellationHandler` for process timeout
52+
**Event-Driven Updates**: Triggers on network changes and system wake (no polling)
53+
**Resource Fallbacks**: Custom logo → SF Symbols, JSON config → minimal menu
54+
**Integration**: Installed via Ansible `menubar` tag, auto-starts via LaunchAgent
55+
56+
Example structured concurrency pattern:
57+
58+
```swift
59+
let result = await withTaskCancellationHandler(
60+
operation: { try await withTimeout(seconds: 30) { /* async work */ } },
61+
onCancel: { process.terminate() }
62+
)
63+
```
64+
65+
## Shell Script Standards
66+
67+
All shell scripts must follow these patterns:
68+
69+
- Use `#!/usr/bin/env bash` shebang line
70+
- Include `set -euo pipefail` for strict error handling
71+
- Use `${variable}` syntax with braces (never `$variable`)
72+
- Use `local` for function variables to avoid namespace pollution
73+
- Pass `shellcheck` validation before committing
74+
- When implementing commands, when things exist, do not use `else` branches unless necessary, for example:
75+
76+
Prefer to do this:
77+
78+
```bash
79+
#!/usr/bin/env bash
80+
if ! tart list | grep -q "sparkdock-test"; then
81+
tart clone {{IMAGE}} sparkdock-test
82+
echo "✅ VM 'sparkdock-test' created successfully"
83+
fi
84+
```
85+
Instead of this:
86+
87+
Do not do this:
88+
89+
```bash
90+
#!/usr/bin/env bash
91+
if ! tart list | grep -q "sparkdock-test"; then
92+
tart clone {{IMAGE}} sparkdock-test
93+
echo "✅ VM 'sparkdock-test' created successfully"
94+
else
95+
echo "VM 'sparkdock-test' already exists"
96+
fi
97+
````
98+
99+
Instead of this:
100+
101+
```bash
102+
if ! command -v cirrus >/dev/null 2>&1; then
103+
echo "Installing Cirrus CLI via Homebrew..."
104+
brew install cirruslabs/cli/cirrus
105+
else
106+
echo "Cirrus CLI is already installed"
107+
fi
108+
```
109+
110+
Do this:
111+
112+
```bash
113+
if ! command -v cirrus >/dev/null 2>&1; then
114+
echo "Installing Cirrus CLI via Homebrew..."
115+
brew install cirruslabs/cli/cirrus
116+
fi
117+
```
118+
119+
**Critical: No Trailing Whitespace**
120+
121+
- Git warns about trailing whitespace in commits
122+
- Clean up before staging changes across ALL file types
123+
- Use editor whitespace visualization to identify issues
124+
125+
## HTTP Proxy Integration
126+
127+
**Architecture**: Separate repository cloned to `/opt/sparkdock/http-proxy`
128+
**DNS Resolution**: `.loc` domains automatically resolved via DNS resolver configuration
129+
**SSL Certificates**: mkcert integration for local HTTPS development
130+
**Management**: `spark-http-proxy start/stop/status` commands
131+
132+
## Build and Test Patterns
133+
134+
**Ansible**: `make run-ansible-macos TAGS="docker,http-proxy"` for targeted provisioning
135+
**Swift App**: `cd src/menubar-app && make build/test/install` for menu bar development
136+
**System Updates**: `sjust upgrade-system` for Homebrew maintenance
137+
**Debugging**: Use `sjust device-info` for system diagnostics
138+
139+
## Git Workflow Specifics
140+
141+
**Default Branch**: `master` (project-specific, not `main`)
142+
**Update Safety**: Automatic stashing of local changes during updates
143+
**Lock File**: `/tmp/sparkdock.lock` prevents concurrent updates
144+
**Rollback**: Built-in rollback on failed updates using stored commit hashes
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
mode: "agent"
3+
model: Claude Sonnet 4
4+
tools:
5+
[
6+
"codebase",
7+
"context7",
8+
"usages",
9+
"vscodeAPI",
10+
"think",
11+
"problems",
12+
"changes",
13+
"testFailure",
14+
"terminalSelection",
15+
"terminalLastCommand",
16+
"openSimpleBrowser",
17+
"fetch",
18+
"findTestFiles",
19+
"searchResults",
20+
"githubRepo",
21+
"extensions",
22+
"editFiles",
23+
"runNotebooks",
24+
"search",
25+
"new",
26+
"runCommands",
27+
"runTasks",
28+
]
29+
description: "Elite Swift macOS engineer with access to latest Swift documentation via Context7 and project-specific expertise"
30+
---
31+
32+
# Swift macOS Engineer - VS Code Enhanced
33+
34+
## Core Identity
35+
36+
You are an elite Swift macOS software engineer. For comprehensive expertise and guidelines, reference: #file:../../.claude/agents/swift-macos-engineer.md
37+
38+
## VS Code-Specific Enhancements
39+
40+
### Context7 Integration
41+
42+
**ALWAYS** use Context7 for Swift API questions:
43+
44+
- Add `use context7` to Swift-related queries
45+
- Library: `https://context7.com/swiftlang/swift`
46+
- Gets real-time, current Swift documentation
47+
48+
### VS Code Workflow
49+
50+
1. **Start with Context7**: "How do I use Swift's new AsyncSequence? use context7"
51+
2. **Reference project file**: Check #file:../../.claude/agents/swift-macos-engineer.md for detailed patterns
52+
3. **Use VS Code tools**: Leverage codebase search, file editing, terminal commands
53+
4. **Verify with latest docs**: Context7 ensures API accuracy
54+
55+
### Integration Examples
56+
57+
**API Research:**
58+
59+
```
60+
Show me SwiftUI's new navigation patterns. use context7
61+
```
62+
63+
**Architecture + Current APIs:**
64+
65+
```
66+
Design a document-based app following #file:../../.claude/agents/swift-macos-engineer.md patterns.
67+
Use latest SwiftUI APIs. use context7
68+
```
69+
70+
**Debugging with Tools:**
71+
72+
```
73+
Analyze this performance issue using VS Code tools and latest Swift best practices. use context7
74+
```

.github/workflows/test-ansible-playbook.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ jobs:
1414
runs-on: ${{ matrix.os }}
1515
strategy:
1616
matrix:
17-
os: [macos-14, macos-15, macos-latest]
18-
fail-fast: false
17+
os: [macos-15, macos-latest]
1918
env:
2019
TERM: xterm-256color
2120
SHELL: /bin/zsh

0 commit comments

Comments
 (0)