fix(add-statusbar): derive log path from binary location, fix SKILL.md
- statusbar.swift: derive project root from binary location instead of
hardcoding ~/Documents/Projects/nanoclaw
- SKILL.md: remove references to non-existent apply-skill.ts, compile
directly from skill directory using ${CLAUDE_SKILL_DIR}
- SKILL.md: add xattr -cr step for Gatekeeper on macOS Sequoia+
- Remove unused manifest.yaml
Co-Authored-By: tomermesser <tomeaces@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,12 @@
|
|||||||
---
|
---
|
||||||
name: add-statusbar
|
name: add-statusbar
|
||||||
description: Add a macOS menu bar status indicator for NanoClaw. Shows a ⚡ icon with a green/red dot indicating whether NanoClaw is running, with Start, Stop, and Restart controls. macOS only.
|
description: Add a macOS menu bar status indicator for NanoClaw. Shows a bolt icon with a green/red dot indicating whether NanoClaw is running, with Start, Stop, and Restart controls. macOS only.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Add macOS Menu Bar Status Indicator
|
# Add macOS Menu Bar Status Indicator
|
||||||
|
|
||||||
Adds a persistent menu bar icon that shows NanoClaw's running status and lets the user start, stop, or restart the service — similar to how Docker Desktop appears in the menu bar.
|
Adds a persistent menu bar icon that shows NanoClaw's running status and lets the user
|
||||||
|
start, stop, or restart the service — similar to how Docker Desktop appears in the menu bar.
|
||||||
|
|
||||||
**macOS only.** Requires Xcode Command Line Tools (`swiftc`).
|
**macOS only.** Requires Xcode Command Line Tools (`swiftc`).
|
||||||
|
|
||||||
@@ -39,45 +40,38 @@ If not found, tell the user:
|
|||||||
launchctl list | grep com.nanoclaw.statusbar
|
launchctl list | grep com.nanoclaw.statusbar
|
||||||
```
|
```
|
||||||
|
|
||||||
If it returns a PID (not `-`), tell the user it's already installed and skip to Phase 4 (Verify).
|
If it returns a PID (not `-`), tell the user it's already installed and skip to Phase 3 (Verify).
|
||||||
|
|
||||||
## Phase 2: Apply Code Changes
|
## Phase 2: Compile and Install
|
||||||
|
|
||||||
### Initialize skills system (if needed)
|
|
||||||
|
|
||||||
If `.nanoclaw/` directory doesn't exist yet:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx tsx scripts/apply-skill.ts --init
|
|
||||||
```
|
|
||||||
|
|
||||||
### Apply the skill
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx tsx scripts/apply-skill.ts .claude/skills/add-statusbar
|
|
||||||
```
|
|
||||||
|
|
||||||
This copies `src/statusbar.swift` into the project and records the application in `.nanoclaw/state.yaml`.
|
|
||||||
|
|
||||||
## Phase 3: Compile and Install
|
|
||||||
|
|
||||||
### Compile the Swift binary
|
### Compile the Swift binary
|
||||||
|
|
||||||
|
The source lives in the skill directory. Compile it into `dist/`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
swiftc -O -o dist/statusbar src/statusbar.swift
|
mkdir -p dist
|
||||||
|
swiftc -O -o dist/statusbar "${CLAUDE_SKILL_DIR}/add/src/statusbar.swift"
|
||||||
```
|
```
|
||||||
|
|
||||||
This produces a small (~55KB) native binary at `dist/statusbar`.
|
This produces a small native binary at `dist/statusbar`.
|
||||||
|
|
||||||
|
On macOS Sequoia or later, clear the quarantine attribute so the binary can run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
xattr -cr dist/statusbar
|
||||||
|
```
|
||||||
|
|
||||||
### Create the launchd plist
|
### Create the launchd plist
|
||||||
|
|
||||||
Determine the absolute project root:
|
Determine the absolute project root and home directory:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pwd
|
pwd
|
||||||
|
echo $HOME
|
||||||
```
|
```
|
||||||
|
|
||||||
Create `~/Library/LaunchAgents/com.nanoclaw.statusbar.plist`, substituting the actual values for `{PROJECT_ROOT}` and `{HOME}`:
|
Create `~/Library/LaunchAgents/com.nanoclaw.statusbar.plist`, substituting the actual values
|
||||||
|
for `{PROJECT_ROOT}` and `{HOME}`:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
@@ -113,7 +107,7 @@ Create `~/Library/LaunchAgents/com.nanoclaw.statusbar.plist`, substituting the a
|
|||||||
launchctl load ~/Library/LaunchAgents/com.nanoclaw.statusbar.plist
|
launchctl load ~/Library/LaunchAgents/com.nanoclaw.statusbar.plist
|
||||||
```
|
```
|
||||||
|
|
||||||
## Phase 4: Verify
|
## Phase 3: Verify
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
launchctl list | grep com.nanoclaw.statusbar
|
launchctl list | grep com.nanoclaw.statusbar
|
||||||
@@ -123,7 +117,7 @@ The first column should show a PID (not `-`).
|
|||||||
|
|
||||||
Tell the user:
|
Tell the user:
|
||||||
|
|
||||||
> The ⚡ icon should now appear in your macOS menu bar. Click it to see NanoClaw's status and control the service.
|
> The bolt icon should now appear in your macOS menu bar. Click it to see NanoClaw's status and control the service.
|
||||||
>
|
>
|
||||||
> - **Green dot** — NanoClaw is running
|
> - **Green dot** — NanoClaw is running
|
||||||
> - **Red dot** — NanoClaw is stopped
|
> - **Red dot** — NanoClaw is stopped
|
||||||
@@ -136,5 +130,4 @@ Tell the user:
|
|||||||
launchctl unload ~/Library/LaunchAgents/com.nanoclaw.statusbar.plist
|
launchctl unload ~/Library/LaunchAgents/com.nanoclaw.statusbar.plist
|
||||||
rm ~/Library/LaunchAgents/com.nanoclaw.statusbar.plist
|
rm ~/Library/LaunchAgents/com.nanoclaw.statusbar.plist
|
||||||
rm dist/statusbar
|
rm dist/statusbar
|
||||||
rm src/statusbar.swift
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ class StatusBarController: NSObject {
|
|||||||
|
|
||||||
private let plistPath = "\(NSHomeDirectory())/Library/LaunchAgents/com.nanoclaw.plist"
|
private let plistPath = "\(NSHomeDirectory())/Library/LaunchAgents/com.nanoclaw.plist"
|
||||||
|
|
||||||
|
/// Derive the NanoClaw project root from the binary location.
|
||||||
|
/// The binary is compiled to {project}/dist/statusbar, so the parent of
|
||||||
|
/// the parent directory is the project root.
|
||||||
|
private static let projectRoot: String = {
|
||||||
|
let binary = URL(fileURLWithPath: CommandLine.arguments[0]).resolvingSymlinksInPath()
|
||||||
|
return binary.deletingLastPathComponent().deletingLastPathComponent().path
|
||||||
|
}()
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
super.init()
|
super.init()
|
||||||
setupStatusItem()
|
setupStatusItem()
|
||||||
@@ -108,7 +116,7 @@ class StatusBarController: NSObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc private func viewLogs() {
|
@objc private func viewLogs() {
|
||||||
let logPath = "\(NSHomeDirectory())/Documents/Projects/nanoclaw/logs/nanoclaw.log"
|
let logPath = "\(StatusBarController.projectRoot)/logs/nanoclaw.log"
|
||||||
NSWorkspace.shared.open(URL(fileURLWithPath: logPath))
|
NSWorkspace.shared.open(URL(fileURLWithPath: logPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
skill: statusbar
|
|
||||||
version: 1.0.0
|
|
||||||
description: "macOS menu bar status indicator — shows NanoClaw running state with start/stop/restart controls"
|
|
||||||
core_version: 0.1.0
|
|
||||||
adds:
|
|
||||||
- src/statusbar.swift
|
|
||||||
modifies: []
|
|
||||||
structured: {}
|
|
||||||
conflicts: []
|
|
||||||
depends: []
|
|
||||||
Reference in New Issue
Block a user