Compare commits

..
1 Commits
Author SHA1 Message Date
tgrosinger 1b4bfa3e7e Waybar: add new memory widget 2026-09-15 13:38:26 -07:00
13 changed files with 49 additions and 167 deletions
-4
View File
@@ -6,10 +6,6 @@
# Python
*.pyc
# Secrets
home/.pi/agent/auth.json
# dev-tickets CLI dependencies, installed by install-packages.sh (npm ci)
home/.local/lib/dev-tickets/node_modules/
home/.agents/skills/synced
-58
View File
@@ -1,58 +0,0 @@
---
name: blender-local
description: Build, edit, and render 3D scenes with the locally installed Blender on this Mac. Use when the user requests Blender work or an editable Blender scene.
---
# Local Blender
## Installed application
The verified executable is `/Applications/Blender.app/Contents/MacOS/Blender` (plural `Applications`, not `/Application/Blender`). It reported Blender 5.1.2 during the September 2026 pelican project. Check the executable if the installation changes; use this local app for Blender requests.
## Working workflow
Write scene-building scripts in the task's `work/` directory. Execute `bpy` scripts with Blender's bundled Python, not an ordinary Python interpreter:
```sh
/Applications/Blender.app/Contents/MacOS/Blender --background --python work/scene.py
```
For ordinary Python helpers outside Blender, use `uv run`. Set absolute output paths in the Blender script, create the destination directory, and save both the editable `.blend` and rendered PNG to the task's deliverable directory.
To edit a saved scene, call `bpy.ops.wm.open_mainfile(filepath=...)` before making changes. Only clear all objects when intentionally building a new scene. Prefer reusable functions or loading the existing `.blend` over executing fragments sliced out of earlier scripts.
This finalization pattern worked with the installed version; choose image dimensions and samples for the task:
```python
scene = bpy.context.scene
scene.render.engine = 'CYCLES'
scene.cycles.samples = 64
scene.cycles.use_denoising = True
scene.render.resolution_x = 1600
scene.render.resolution_y = 1200
scene.render.resolution_percentage = 100
scene.view_settings.view_transform = 'AgX'
scene.render.image_settings.file_format = 'PNG'
scene.render.filepath = str(output_dir / 'scene.png')
bpy.ops.wm.save_as_mainfile(filepath=str(output_dir / 'scene.blend'))
bpy.ops.render.render(write_still=True)
```
Use roughly 32–48 samples for previews and 64–96 for a polished still with denoising as starting points. Do not assume GPU acceleration is configured. Saving before rendering preserves the scene if rendering fails.
## Execution and diagnosis
- The first sandboxed launch in this project exited with code 139 before running the script and wrote `blender.crash.txt` in the system temporary directory. A retry through the approved unsandboxed execution mechanism succeeded. Treat this as an observed environment issue, not proof that every crash needs escalation. On a similar startup failure, inspect the output and request the applicable execution permission; if a permitted retry still fails, investigate rather than repeatedly escalating.
- A USD `Arch_ValidateAssumptions` warning accompanied that startup failure; it did not establish the root cause.
- `Material.use_nodes` and `World.use_nodes` emitted deprecation warnings in 5.1.2 but worked. They are expected to change in Blender 6; verify the installed API when upgrading.
- Background rendering can produce little output for tens of seconds. If execution returns a session ID, poll that session until completion instead of launching duplicate renders. Confirm the exit status and saved files.
## Modeling and visual lessons
- Cylinders aligned with `direction.to_track_quat('Z', 'Y')`, beveled curves, UV spheres, and custom meshes worked well for stylized scene construction. Smooth shading does not fix a faceted silhouette: give focal shapes enough geometry. Cap exposed curve ends or cover them with modeled joints.
- Inspect the rendered image after meaningful changes. Check the silhouette, grip and pedal contacts, floating parts, frame cropping, shadows, and whether background details are actually visible. A successfully saved render is not visual QA.
- Avoid overlapping coplanar surfaces. The retained studio floor hid the new beach and ocean; coincident surfaces produced black bands. Remove obsolete geometry and deliberately separate surface heights. For a box, calculate the top as center Z plus half its height.
- Frame an orthographic camera deliberately: an infinite ground plane fills the background without a natural horizon. A distant sky backdrop perpendicular to the horizontal viewing direction can provide a level horizon. Check projected positions of the sun, clouds, and distant props; adding them does not guarantee they appear in frame.
- For a substantial quality improvement, prioritize coherent composition, character anatomy, materials, and light over adding more objects. Preview warm key light, cooler fill, and rim light; avoid washed-out colors and unlit distant props. Keep decorative details from obscuring the subject.
Deliver the inspected render inline and link the editable `.blend` using absolute paths. Preserve earlier versions when making major revisions unless the user requests replacement.
-1
View File
@@ -1 +0,0 @@
../../../mattpocock-skills/skills/engineering/implement-spec/
+1
View File
@@ -0,0 +1 @@
../../../mattpocock-skills/skills/engineering/resolving-merge-conflicts
@@ -1,14 +0,0 @@
---
name: resolving-merge-conflicts
description: "Use when you need to resolve an in-progress git merge/rebase conflict."
---
1. **See the current state** of the merge/rebase. Check git history, and the conflicting files.
2. **Find the primary sources** for each conflict. Understand deeply why each change was made, and what the original intent was. Read the commit messages, check the PRs, check original issues/tickets.
3. **Resolve each hunk.** Preserve both intents where possible. Where incompatible, pick the one matching the merge's stated goal and note the trade-off. Do **not** invent new behaviour. Always resolve; never `--abort`.
4. Discover the project's **automated checks** and run them, typically typecheck, then tests, then format. Fix anything the merge broke.
5. **Finish the merge/rebase.** Stage everything and commit. If rebasing, continue the rebase process until all commits are rebased.
@@ -1,3 +0,0 @@
interface:
display_name: "Resolving Merge Conflicts"
short_description: "Resolve merge and rebase conflicts"
@@ -1,66 +0,0 @@
---
name: traefik-expose
description: Make a service on the tachi host reachable at https://NAME.i.grosinger.net through Traefik, or remove it. Use when asked to expose, register, route, or publish a dev server, host process, or docker container on an internal hostname, or to unexpose/deregister one.
---
> [!info] This skill only applies to the host `voyager`
> This skill may be synced to other hosts, but it only applies to `voyager`. If you are running on a different host and need to expose a service to an internal or external hostname, stop and ask for guidance from the user.
# traefik-expose — put a service on NAME.i.grosinger.net
Traefik on this host (`/tachi/docker`) serves `*.i.grosinger.net` on its `internal` entrypoint. That entrypoint is the default and already carries the wildcard TLS certificate and the home-only IP allowlist, and Blocky resolves every `*.i.grosinger.net` name to this host. So registering a service is only a routing rule and a target; there is no DNS, certificate, or middleware step.
Pick the branch by where the service runs.
## Host process (not in a container)
Register with the script in the docker repo:
```sh
/tachi/docker/traefik/expose NAME PORT # https://NAME.i.grosinger.net -> host:PORT
/tachi/docker/traefik/expose -l # list
/tachi/docker/traefik/expose -d NAME # remove
```
It writes one file to `traefik/dynamic.d/`, which Traefik watches, so the route is live within seconds and needs no restart. The file is gitignored.
The process must listen on `0.0.0.0` or on `172.19.0.1`. Traefik connects from inside its container network and cannot reach a listener bound to `127.0.0.1`, which most dev servers default to; pass the tool's host flag (`--host 0.0.0.0` or equivalent).
## Docker container
Join the container to the `docker_traefik` network and add labels. From a compose file outside `/tachi/docker`, declare the network as external:
```yaml
services:
myapp:
networks: [traefik]
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`myapp.i.grosinger.net`)"
- "traefik.http.services.myapp.loadbalancer.server.port=3000"
networks:
traefik:
external: true
name: docker_traefik
```
Inside `/tachi/docker/docker-compose.yaml` the network is simply `traefik`. Traefik ignores containers without `traefik.enable=true`. Always set the port label: it is the port the app listens on inside the container, not a published one, and no `ports:` mapping is needed. Removing the labels or the container removes the route.
## Verify
```sh
curl -sk -o /dev/null -w '%{http_code}\n' https://NAME.i.grosinger.net/
```
- **200-ish**: done.
- **502**: Traefik has the route but cannot reach the target. Host process: check the bind address with `ss -ltnp | grep PORT`. Container: check the port label matches what the app listens on and the container is on `docker_traefik`.
- **404**: Traefik has no router for that host. Ask the dashboard API, which needs no docker socket:
```sh
curl -sk https://traefik.i.grosinger.net/api/http/routers/NAME@file # host process
curl -sk https://traefik.i.grosinger.net/api/http/routers/NAME@docker # container
```
## Public exposure is a different task
Everything above is reachable only from the LAN and Tailscale. Making a service internet-facing means a real `grosinger.net` name, an explicit `traefik.http.routers.NAME.entrypoints=websecure` label, and a deliberate decision by the user. Do not add `websecure` when asked for an internal hostname.
+6 -4
View File
@@ -30,7 +30,7 @@
],
"defaultMode": "auto"
},
"model": "opus[1m]",
"model": "claude-opus-4-8",
"disableClaudeAiConnectors": true,
"hooks": {
"PostToolUse": [
@@ -120,16 +120,19 @@
"~/.local/share/pnpm",
"~/.cache/pnpm",
"~/Documents/Atrium",
"/tachi/atrium"
"/tachi/docker/atribot/vault"
],
"denyRead": [
"~/.ssh",
"~/.config/Signal",
"~/obsidian/obsidian/ansible/variables",
"~/Documents",
"/tachi/backups",
"/tachi/documents",
"/tachi/docker"
],
"allowRead": [
"~/Documents/Atrium",
"/tachi/docker/atribot/vault"
]
},
"excludedCommands": [
@@ -137,7 +140,6 @@
"brew *"
]
},
"feedbackDrafts": "off",
"spinnerVerbs": {
"mode": "replace",
"verbs": [
+36
View File
@@ -48,6 +48,9 @@ graph_symbol = "braille"
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
graph_symbol_cpu = "default"
# Graph symbol to use for graphs in gpu box, "default", "braille", "block" or "tty".
graph_symbol_gpu = "default"
# Graph symbol to use for graphs in cpu box, "default", "braille", "block" or "tty".
graph_symbol_mem = "default"
@@ -114,6 +117,9 @@ cpu_graph_upper = "Auto"
#* Select from a list of detected attributes from the options menu.
cpu_graph_lower = "Auto"
#* If gpu info should be shown in the cpu box. Available values = "Auto", "On" and "Off".
show_gpu_info = "Auto"
#* Toggles if the lower CPU graph should be inverted.
cpu_invert_lower = true
@@ -248,3 +254,33 @@ log_level = "WARNING"
#* Automatically save current settings to config file on exit.
save_config_on_exit = true
#* Measure PCIe throughput on NVIDIA cards, may impact performance on certain cards.
nvml_measure_pcie_speeds = true
#* Measure PCIe throughput on AMD cards, may impact performance on certain cards.
rsmi_measure_pcie_speeds = true
#* Horizontally mirror the GPU graph.
gpu_mirror_graph = true
#* Set which GPU vendors to show. Available values are "nvidia amd intel apple"
shown_gpus = "nvidia amd intel"
#* Custom gpu0 model name, empty string to disable.
custom_gpu_name0 = ""
#* Custom gpu1 model name, empty string to disable.
custom_gpu_name1 = ""
#* Custom gpu2 model name, empty string to disable.
custom_gpu_name2 = ""
#* Custom gpu3 model name, empty string to disable.
custom_gpu_name3 = ""
#* Custom gpu4 model name, empty string to disable.
custom_gpu_name4 = ""
#* Custom gpu5 model name, empty string to disable.
custom_gpu_name5 = ""
+2 -9
View File
@@ -1,7 +1,7 @@
@import "latte.css";
* {
font-family: 'Ubuntu Nerd Font';
font-family: 'JetBrainsMono Nerd Font';
font-size: 13px;
}
@@ -197,6 +197,7 @@ label:focus {
}
#custom-break-timer.overdue {
background-color: @red;
animation-name: blink;
animation-duration: 0.5s;
animation-timing-function: steps(12);
@@ -204,14 +205,6 @@ label:focus {
animation-direction: alternate;
}
#custom-break-timer.overdue-short {
background-color: @peach;
}
#custom-break-timer.overdue-long {
background-color: @red;
}
#pulseaudio.muted {
background-color: @crust;
color: @subtext1;
+1 -1
View File
@@ -5,7 +5,7 @@
"defaultModel": "gpt-5.6-luna",
"defaultThinkingLevel": "high",
"skills": [
"~/.agents/skills"
"~/.claude/skills"
],
"hideThinkingBlock": true,
"enableInstallTelemetry": false
+1 -5
View File
@@ -5,11 +5,7 @@ set-option -g renumber-windows on
set-option -g history-limit 10000
set -s escape-time 0
set-option -g detach-on-destroy off
# This is a variant on the choose-tree hook that filters out Remote Access Console throw-away sessions
# to prevent dropping me into the session picker for automated actions.
#set-hook -g session-closed 'choose-tree -Zs'
set-hook -g session-closed 'if -F "#{||:#{m:rac-*,#{hook_session_name}},#{client_control_mode}}" "" "choose-tree -Zs"'
set-hook -g session-closed 'choose-tree -Zs'
### Fix supporting italics
set -g default-terminal "tmux-256color"