Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .opencode/agents/dependency-auditor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
description: Audits Go dependencies and vulnerabilities without changing files
mode: subagent
permissions:
- action: edit
resource: "*"
effect: deny
- action: shell
resource: "*"
effect: deny
- action: shell
resource: "go list *"
effect: allow
- action: shell
resource: "go mod download *"
effect: allow
- action: shell
resource: "go test *"
effect: allow
- action: shell
resource: "go vet *"
effect: allow
- action: shell
resource: "go build *"
effect: allow
- action: shell
resource: "go run golang.org/x/vuln/cmd/govulncheck@*"
effect: allow
- action: shell
resource: "git diff *"
effect: allow
---

Audit this Go module. Run:

- `go list -m -u all`
- `govulncheck ./...`
- `go test ./... -race`
- `go vet ./...`
- `go build ./...`

Report direct and indirect updates, deprecated modules, and any Go toolchain
bump required by dependencies. Do not edit `go.mod`, `go.sum`, or source files;
propose exact commands for the primary agent.
29 changes: 29 additions & 0 deletions .opencode/agents/reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
description: Reviews changes for correctness, safety, and regressions without editing files
mode: subagent
permissions:
- action: edit
resource: "*"
effect: deny
- action: shell
resource: "*"
effect: deny
- action: shell
resource: "git diff *"
effect: allow
- action: shell
resource: "git status"
effect: allow
- action: shell
resource: "git log *"
effect: allow
---

Review the current diff. Focus on:

- `Analyze` remaining side-effect-free and `Clean` being the only mutating path
- correct command construction and error handling
- tests for parsers and fake `RunCommand`
- accidental destructive behavior on Arch Linux

Report findings in severity order with file and line references. Do not edit files.
22 changes: 22 additions & 0 deletions .opencode/skills/cleaner-development/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: Cleaner Development
description: Add or modify a Squeaky cleaner safely with fake-command tests
---

## Contract

Implement `cleaner.Cleaner`:

- `Name() string`
- `Analyze() (*Result, error)` — read-only
- `Clean() (*Result, error)` — mutating

## Rules

- Use the package-level `RunCommand` variable for external commands.
- In tests, replace `RunCommand` and restore it with `defer`.
- Extract output parsing into pure functions and table-test them.
- Register the cleaner in both `cmd/dry.go` and `cmd/clean.go`.
- Add config fields to `internal/config` and document them in
`squeaky.example.yaml`.
- Never run destructive host commands in tests; use `t.TempDir()`.
20 changes: 20 additions & 0 deletions .opencode/skills/dependency-audit/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Dependency Audit
description: Check Go modules for outdated, deprecated, or vulnerable dependencies and validate upgrades safely
---

## Workflow

1. Read `go.mod` and note the `go` directive.
2. Run `go list -m -u all` and separate direct from indirect updates.
3. Check whether any dependency requires a newer Go toolchain.
4. Treat `gopkg.in/yaml.v3` as deprecated; use `go.yaml.in/yaml/v3` for YAML v3.
5. Apply changes in a scratch copy or worktree first.
6. Run:
- `go mod tidy`
- `go test ./... -race`
- `go vet ./...`
- `go build ./...`
- `govulncheck ./...`
7. Report exact version changes and any toolchain bump.
8. Do not commit unless explicitly asked.
55 changes: 55 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Squeaky — agent instructions

## What this project is

`squeaky` is a Go CLI for Arch Linux that removes old pacman cache packages,
orphaned packages, old journal logs, stale `~/.cache` files, and old `/tmp`
files. `dry` is read-only. `clean` is the only mutating command.

## Commands

- Build: `make build`
- Test: `make test` (`go test ./... -race`)
- Vet: `go vet ./...`
- Lint: `golangci-lint run ./...`
- Vulnerability scan: `govulncheck ./...`
- Dependency audit: `go list -m -u all`

## Layout

- `cmd/` — Cobra commands. `dry.go` and `clean.go` each build the cleaner list.
- `internal/cleaner/` — one cleaner per file. Every cleaner implements:
- `Name() string`
- `Analyze() (*Result, error)` — must never modify the system
- `Clean() (*Result, error)` — performs the mutation
- `internal/config/` — YAML config and defaults.
- `internal/ui/` — terminal output and summaries.
- `squeaky.example.yaml` — documented user config template.

## Conventions

- `Analyze` must be side-effect-free. Only `Clean` may modify the host.
- Use the package-level `RunCommand` variable for external commands.
Tests must replace it and restore it with `defer`.
- Add table-driven tests for parsers and fake-command behavior.
- Register a new cleaner in BOTH `cmd/dry.go` and `cmd/clean.go`.
- Put user-configurable values in `internal/config` and document them in
`squeaky.example.yaml`.
- Prefer the standard library. Add dependencies only with a clear need.
- Do not commit the built `squeaky` binary.

## Safety — non-negotiable

- Never run `squeaky clean`, `paccache -r`, `pacman -Rns`,
`journalctl --vacuum-*`, or any `sudo` command from an agent session.
- Use unit tests, fake `RunCommand` implementations, or `t.TempDir()`.
- `squeaky dry` is acceptable for read-only inspection, but tests are preferred.
- Do not delete or modify files under `/tmp`, `~/.cache`,
`/var/cache/pacman`, or the system journal.

## Verification before finishing

- `go test ./... -race`
- `go vet ./...`
- `go build ./...`
- If dependencies changed: `go mod tidy` and `govulncheck ./...`
14 changes: 7 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
module github.com/jcstr/squeaky

go 1.25.7
go 1.27.0

require (
github.com/fatih/color v1.18.0
github.com/fatih/color v1.19.0
github.com/spf13/cobra v1.10.2
gopkg.in/yaml.v3 v3.0.1
go.yaml.in/yaml/v3 v3.0.6
)

require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/spf13/pflag v1.0.9 // indirect
golang.org/x/sys v0.25.0 // indirect
github.com/mattn/go-colorable v0.1.16 // indirect
github.com/mattn/go-isatty v0.0.24 // indirect
github.com/spf13/pflag v1.0.10 // indirect
golang.org/x/sys v0.49.0 // indirect
)
27 changes: 12 additions & 15 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-colorable v0.1.16 h1:+2YjeAe7xP1OQbZW1jERPWWCDLlNqFNCvjiqGiAt84A=
github.com/mattn/go-colorable v0.1.16/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
go.yaml.in/yaml/v3 v3.0.6 h1:zcDfvjXEqTQmpjniUBLc91xYJMB2c4QOFxEF/LCEckM=
go.yaml.in/yaml/v3 v3.0.6/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA=
golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"os"
"path/filepath"

"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v3"
)

// Config holds all user-configurable thresholds.
Expand Down
9 changes: 9 additions & 0 deletions opencode.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://opencode.ai/config.json",
"permissions": [
{ "action": "shell", "resource": "sudo *", "effect": "deny" },
{ "action": "shell", "resource": "*sudo *", "effect": "deny" },
{ "action": "shell", "resource": "squeaky clean*", "effect": "deny" },
{ "action": "shell", "resource": "*squeaky clean*", "effect": "deny" }
]
}
Loading