harness: LiteLLM client, Redmine intake, REPORT writeback, gated bash tool
OpenAI-compatible chat client for the LiteLLM proxy (base_url normalization,
Bearer auth, retry/backoff on 429/5xx/transport, usage accounting) - stdlib
http only. Intake lists issues in scope from /issues.json with the task
class read from a configurable custom field. Writeback lands each turn as
REPORT-<vertical>-<task>-<ts>.md plus REPORT-latest.md (atomic rename) with
model/tier/token telemetry. The bash tool ports maki's permission semantics
without tree-sitter: segment-by-segment compound-command checks, deny beats
allow, word-boundary "cmd *" matching, $()/backtick/subshell denied, output
truncation, per-command timeout with process-group cleanup.
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
//go:build unix
|
||||
|
||||
package tools
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// setPgroup puts the bash child in its own process group so a timeout or
|
||||
// cancel kills the whole tree, not just the shell (crush/maki gotcha:
|
||||
// plain Kill orphans grandchildren).
|
||||
func setPgroup(c *exec.Cmd) {
|
||||
c.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
}
|
||||
|
||||
// killGroup SIGKILLs the child's process group after Wait; no-op if the
|
||||
// child never started.
|
||||
func killGroup(c *exec.Cmd) {
|
||||
if c.Process == nil {
|
||||
return
|
||||
}
|
||||
_ = syscall.Kill(-c.Process.Pid, syscall.SIGKILL)
|
||||
}
|
||||
Reference in New Issue
Block a user