Compare commits
2 Commits
dev/giteac
...
waitfor-la
| Author | SHA1 | Date | |
|---|---|---|---|
| f8bfa71f5f | |||
| 6b4f1441ac |
@@ -20,7 +20,7 @@ jobs:
|
|||||||
- name: Detektera ändrade tools
|
- name: Detektera ändrade tools
|
||||||
id: changed
|
id: changed
|
||||||
run: |
|
run: |
|
||||||
TOOLS="pixel-sprite-maker mesh-tool bitmap-font-maker sfx-maker hitbox-tool"
|
TOOLS="pixel-sprite-maker mesh-tool bitmap-font-maker sfx-maker hitbox-tool notifyr svg-maker waitfor cronr giteactl"
|
||||||
BEFORE="${{ github.event.before }}"
|
BEFORE="${{ github.event.before }}"
|
||||||
CHANGED=""
|
CHANGED=""
|
||||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ] \
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ] \
|
||||||
@@ -59,6 +59,11 @@ jobs:
|
|||||||
bitmap-font-maker) BIN=fontc ;;
|
bitmap-font-maker) BIN=fontc ;;
|
||||||
sfx-maker) BIN=sfxc ;;
|
sfx-maker) BIN=sfxc ;;
|
||||||
hitbox-tool) BIN=hitbox ;;
|
hitbox-tool) BIN=hitbox ;;
|
||||||
|
notifyr) BIN=notifyr ;;
|
||||||
|
svg-maker) BIN=svgc ;;
|
||||||
|
waitfor) BIN=waitfor ;;
|
||||||
|
cronr) BIN=cronr ;;
|
||||||
|
giteactl) BIN=giteactl ;;
|
||||||
*) echo "okänt tool $t"; exit 1 ;;
|
*) echo "okänt tool $t"; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
echo "=== $t ($BIN) ==="
|
echo "=== $t ($BIN) ==="
|
||||||
@@ -88,6 +93,11 @@ jobs:
|
|||||||
bitmap-font-maker) BIN=fontc ;;
|
bitmap-font-maker) BIN=fontc ;;
|
||||||
sfx-maker) BIN=sfxc ;;
|
sfx-maker) BIN=sfxc ;;
|
||||||
hitbox-tool) BIN=hitbox ;;
|
hitbox-tool) BIN=hitbox ;;
|
||||||
|
notifyr) BIN=notifyr ;;
|
||||||
|
svg-maker) BIN=svgc ;;
|
||||||
|
waitfor) BIN=waitfor ;;
|
||||||
|
cronr) BIN=cronr ;;
|
||||||
|
giteactl) BIN=giteactl ;;
|
||||||
esac
|
esac
|
||||||
TAG="$t-latest"
|
TAG="$t-latest"
|
||||||
BODY="$t (binär: $BIN) - rullande bygge från senaste master. Commit: ${{ github.sha }}. Arkitekturer: linux x64 + arm64 (Pi5)."
|
BODY="$t (binär: $BIN) - rullande bygge från senaste master. Commit: ${{ github.sha }}. Arkitekturer: linux x64 + arm64 (Pi5)."
|
||||||
|
|||||||
218
.vscode/tasks.json
vendored
218
.vscode/tasks.json
vendored
@@ -5,87 +5,261 @@
|
|||||||
"label": "build pixel-sprite-maker",
|
"label": "build pixel-sprite-maker",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "go build -trimpath -ldflags '-s -w' -o build/spritec .",
|
"command": "go build -trimpath -ldflags '-s -w' -o build/spritec .",
|
||||||
"options": { "cwd": "${workspaceFolder}/pixel-sprite-maker" },
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/pixel-sprite-maker"
|
||||||
|
},
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"problemMatcher": ["$go"]
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "build mesh-tool",
|
"label": "build mesh-tool",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "go build -trimpath -ldflags '-s -w' -o build/mesht .",
|
"command": "go build -trimpath -ldflags '-s -w' -o build/mesht .",
|
||||||
"options": { "cwd": "${workspaceFolder}/mesh-tool" },
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/mesh-tool"
|
||||||
|
},
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"problemMatcher": ["$go"]
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "build bitmap-font-maker",
|
"label": "build bitmap-font-maker",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "go build -trimpath -ldflags '-s -w' -o build/fontc .",
|
"command": "go build -trimpath -ldflags '-s -w' -o build/fontc .",
|
||||||
"options": { "cwd": "${workspaceFolder}/bitmap-font-maker" },
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/bitmap-font-maker"
|
||||||
|
},
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"problemMatcher": ["$go"]
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "test bitmap-font-maker",
|
"label": "test bitmap-font-maker",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "go test ./...",
|
"command": "go test ./...",
|
||||||
"options": { "cwd": "${workspaceFolder}/bitmap-font-maker" },
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/bitmap-font-maker"
|
||||||
|
},
|
||||||
"group": "test",
|
"group": "test",
|
||||||
"problemMatcher": ["$go"]
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "build sfx-maker",
|
"label": "build sfx-maker",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "go build -trimpath -ldflags '-s -w' -o build/sfxc .",
|
"command": "go build -trimpath -ldflags '-s -w' -o build/sfxc .",
|
||||||
"options": { "cwd": "${workspaceFolder}/sfx-maker" },
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/sfx-maker"
|
||||||
|
},
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"problemMatcher": ["$go"]
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "test sfx-maker",
|
"label": "test sfx-maker",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "go test ./...",
|
"command": "go test ./...",
|
||||||
"options": { "cwd": "${workspaceFolder}/sfx-maker" },
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/sfx-maker"
|
||||||
|
},
|
||||||
"group": "test",
|
"group": "test",
|
||||||
"problemMatcher": ["$go"]
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "build hitbox-tool",
|
"label": "build hitbox-tool",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "go build -trimpath -ldflags '-s -w' -o build/hitbox .",
|
"command": "go build -trimpath -ldflags '-s -w' -o build/hitbox .",
|
||||||
"options": { "cwd": "${workspaceFolder}/hitbox-tool" },
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/hitbox-tool"
|
||||||
|
},
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"problemMatcher": ["$go"]
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "test hitbox-tool",
|
"label": "test hitbox-tool",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "go test ./...",
|
"command": "go test ./...",
|
||||||
"options": { "cwd": "${workspaceFolder}/hitbox-tool" },
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/hitbox-tool"
|
||||||
|
},
|
||||||
"group": "test",
|
"group": "test",
|
||||||
"problemMatcher": ["$go"]
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "test pixel-sprite-maker",
|
"label": "test pixel-sprite-maker",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "go test ./...",
|
"command": "go test ./...",
|
||||||
"options": { "cwd": "${workspaceFolder}/pixel-sprite-maker" },
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/pixel-sprite-maker"
|
||||||
|
},
|
||||||
"group": "test",
|
"group": "test",
|
||||||
"problemMatcher": ["$go"]
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "test mesh-tool",
|
"label": "test mesh-tool",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "go test ./...",
|
"command": "go test ./...",
|
||||||
"options": { "cwd": "${workspaceFolder}/mesh-tool" },
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/mesh-tool"
|
||||||
|
},
|
||||||
"group": "test",
|
"group": "test",
|
||||||
"problemMatcher": ["$go"]
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build notifyr",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "go build -trimpath -ldflags '-s -w' -o build/notifyr .",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/notifyr"
|
||||||
|
},
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "test notifyr",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "go test ./...",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/notifyr"
|
||||||
|
},
|
||||||
|
"group": "test",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build svg-maker",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "go build -trimpath -ldflags '-s -w' -o build/svgc .",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/svg-maker"
|
||||||
|
},
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "test svg-maker",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "go test ./...",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/svg-maker"
|
||||||
|
},
|
||||||
|
"group": "test",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build waitfor",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "go build -trimpath -ldflags '-s -w' -o build/waitfor .",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/waitfor"
|
||||||
|
},
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "test waitfor",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "go test ./...",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/waitfor"
|
||||||
|
},
|
||||||
|
"group": "test",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build cronr",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "go build -trimpath -ldflags '-s -w' -o build/cronr .",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/cronr"
|
||||||
|
},
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "test cronr",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "go test ./...",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/cronr"
|
||||||
|
},
|
||||||
|
"group": "test",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build giteactl",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "go build -trimpath -ldflags '-s -w' -o build/giteactl .",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/giteactl"
|
||||||
|
},
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "test giteactl",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "go test ./...",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/giteactl"
|
||||||
|
},
|
||||||
|
"group": "test",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$go"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "build",
|
"label": "build",
|
||||||
"dependsOn": ["build pixel-sprite-maker", "build mesh-tool", "build bitmap-font-maker", "build sfx-maker", "build hitbox-tool"],
|
"dependsOn": [
|
||||||
|
"build pixel-sprite-maker",
|
||||||
|
"build mesh-tool",
|
||||||
|
"build bitmap-font-maker",
|
||||||
|
"build sfx-maker",
|
||||||
|
"build hitbox-tool",
|
||||||
|
"build notifyr",
|
||||||
|
"build svg-maker",
|
||||||
|
"build waitfor",
|
||||||
|
"build cronr",
|
||||||
|
"build giteactl"
|
||||||
|
],
|
||||||
"dependsOrder": "parallel",
|
"dependsOrder": "parallel",
|
||||||
"group": { "kind": "build", "isDefault": true },
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
19
README.md
19
README.md
@@ -13,18 +13,25 @@ agent understands the result without opening an image viewer.
|
|||||||
| [`bitmap-font-maker/`](bitmap-font-maker/) | `fontc` | Turns `.font` text files (pixel glyph grids, proportional widths) into font atlases (PNG + JSON metrics) and renders text strings to PNG or the terminal. |
|
| [`bitmap-font-maker/`](bitmap-font-maker/) | `fontc` | Turns `.font` text files (pixel glyph grids, proportional widths) into font atlases (PNG + JSON metrics) and renders text strings to PNG or the terminal. |
|
||||||
| [`sfx-maker/`](sfx-maker/) | `sfxc` | Synthesizes retro game sound effects (sfxr-style) from `.sfx` text presets to 16-bit WAV: waves, envelope, pitch slides, vibrato, arpeggio, filters. Deterministic, with built-in presets (jump, coin, laser…). |
|
| [`sfx-maker/`](sfx-maker/) | `sfxc` | Synthesizes retro game sound effects (sfxr-style) from `.sfx` text presets to 16-bit WAV: waves, envelope, pitch slides, vibrato, arpeggio, filters. Deterministic, with built-in presets (jump, coin, laser…). |
|
||||||
| [`hitbox-tool/`](hitbox-tool/) | `hitbox` | Scans sprite sheet PNGs and writes per-frame collision boxes as JSON from the alpha channel. Understands the spritec sheet naming convention including upscaled sheets. |
|
| [`hitbox-tool/`](hitbox-tool/) | `hitbox` | Scans sprite sheet PNGs and writes per-frame collision boxes as JSON from the alpha channel. Understands the spritec sheet naming convention including upscaled sheets. |
|
||||||
|
| [`notifyr/`](notifyr/) | `notifyr` | Sends **and reads** notifications on the homelab ntfy bus — alert a human, or check what the infra has been complaining about. |
|
||||||
|
| [`svg-maker/`](svg-maker/) | `svgc` | Builds SVG graphics from `.svgd` text descriptions (shapes, text, groups, color vars) with terminal preview, measurements and out-of-canvas warnings. Display via agent-helm: `helmd share out.svg`. |
|
||||||
|
| [`waitfor/`](waitfor/) | `waitfor` | Blocks until a shell condition holds (exit 0 + optional regex match) — replaces hand-rolled poll loops. `--then` hook composes with notifyr. |
|
||||||
|
| [`cronr/`](cronr/) | `cronr` | Recurring/one-shot jobs as systemd user timers that survive session exit and reboot. add/list/run/logs/rm, schedules validated by systemd-analyze. |
|
||||||
|
| [`giteactl/`](giteactl/) | `giteactl` | Gitea Actions runs, job logs (API/web/ssh+zstd fallback), `wait` (block until green) and `wait-quiet` (the "serialize heavy builds" rule), release assets. |
|
||||||
|
|
||||||
Each tool has its own folder, its own README with the full format/CLI
|
Each tool has its own folder, its own README with the full format/CLI
|
||||||
reference, its own tests and its own dev branch (`dev/<tool>`).
|
reference, its own tests and its own dev branch (`dev/<tool>`).
|
||||||
|
|
||||||
## Planned: agent-capability & homelab-admin tools
|
## Agent-capability & homelab-admin tools
|
||||||
|
|
||||||
[`doc/tool-parity.md`](doc/tool-parity.md) compares Gemini CLI's
|
[`doc/tool-parity.md`](doc/tool-parity.md) compares the Google agent's
|
||||||
built-in tools with Claude Code's, and specs the CLI tools that close
|
built-in tools with Claude Code's, and specs the CLI tools that close
|
||||||
the gaps (`notifyr`, `giteactl`, `waitfor`, `cronr`, `fleet`,
|
the gaps so any agent gets the same capabilities via its shell tool.
|
||||||
`envaudit`, `reghelper`, `pagepub`, `nbcell`, `wtreectl`, `fanout`) so
|
Built so far: `notifyr`, `waitfor`, `cronr`, `giteactl`, `svgc`
|
||||||
any agent gets the same capabilities via `run_shell_command`. Build
|
(2026-08-07). Still on the list: `fleet`, `envaudit`, `reghelper`,
|
||||||
order and rationale live there and in [`doc/plan.md`](doc/plan.md).
|
`pagepub`, `nbcell`, `wtreectl`, `fanout`. Build order and rationale
|
||||||
|
live there and in [`doc/plan.md`](doc/plan.md). Agy finds the tools
|
||||||
|
through the `agent-tools` skill in `~/.gemini/config/skills/`.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ master/main. Only tools whose folders changed get rebuilt.
|
|||||||
multi-view rendering, measurements and watertightness checks.
|
multi-view rendering, measurements and watertightness checks.
|
||||||
3. ✅ Per-tool VS Code build tasks → `<tool>/build/`.
|
3. ✅ Per-tool VS Code build tasks → `<tool>/build/`.
|
||||||
4. ✅ CI: changed-tool detection + per-tool rolling releases.
|
4. ✅ CI: changed-tool detection + per-tool rolling releases.
|
||||||
|
5. ✅ 2026-08-07: agent-capability batch 1 — `notifyr` (ntfy
|
||||||
|
send/read), `waitfor` (block on condition), `cronr` (systemd user
|
||||||
|
timers), `giteactl` (CI runs/logs/wait/wait-quiet/releases) and
|
||||||
|
`svgc` (`svg-maker/`: .svgd → SVG for agent-helm, Björns direkta
|
||||||
|
önskemål). Alla smoke-testade mot riktig infra; agy-integration
|
||||||
|
via `agent-tools`-skill + AGENTS.md i `~/.gemini/config/`.
|
||||||
|
|
||||||
## Roadmap / expansion ideas (not agreed yet)
|
## Roadmap / expansion ideas (not agreed yet)
|
||||||
|
|
||||||
|
|||||||
@@ -289,9 +289,14 @@ binaries), same philosophy — don't duplicate those here.
|
|||||||
|
|
||||||
## 5. Suggested build order
|
## 5. Suggested build order
|
||||||
|
|
||||||
1. `notifyr` — smallest, everything else composes with it, ntfy already runs.
|
1. ✅ `notifyr` — smallest, everything else composes with it, ntfy already runs. *(built 2026-08-07)*
|
||||||
2. `giteactl` — removes the biggest daily friction (CI logs + build serialization).
|
2. ✅ `giteactl` — removes the biggest daily friction (CI logs + build serialization). *(built 2026-08-07; private repos need an API token in the config)*
|
||||||
3. `waitfor` + `cronr` — turns both agents into unattended operators.
|
3. ✅ `waitfor` + `cronr` — turns both agents into unattended operators. *(built 2026-08-07)*
|
||||||
4. `fleet` — replaces the hand-rolled health loops in every runbook.
|
4. `fleet` — replaces the hand-rolled health loops in every runbook.
|
||||||
5. `envaudit`, `reghelper`, `pagepub`, `nbcell`, `wtreectl` — as needed.
|
5. `envaudit`, `reghelper`, `pagepub`, `nbcell`, `wtreectl` — as needed.
|
||||||
6. `fanout` — only if a concrete multi-agent need shows up.
|
6. `fanout` — only if a concrete multi-agent need shows up.
|
||||||
|
|
||||||
|
Also built 2026-08-07 (outside this list, Björns direct request):
|
||||||
|
`svgc` (`svg-maker/`) — SVG graphics from text, displayed in
|
||||||
|
agent-helm via `helmd share`. Agy integration: the `agent-tools`
|
||||||
|
skill + a tools section in `~/.gemini/config/AGENTS.md`.
|
||||||
|
|||||||
Reference in New Issue
Block a user