NimsForest Issues

NimsForest Issue Runbook

Overview

NimsForest Issue is an issue tracking service for the NimsForest ecosystem. It provides a public web form for reporting issues, an API for programmatic access, and an admin dashboard for triage and management.

Infrastructure

Environment Variables

| Variable | Purpose | Required | |----------|---------|----------| | NATS_URL | Wind (NATS) connection for events + chat widget | Optional (events/chat disabled without it) |

Health Check

curl https://issues.nimsforest.nimsforest.com/api/v1/health

API Endpoints

| Method | Path | Auth | Description | |--------|------|------|-------------| | GET /api/v1/health | none | Health check | | POST /api/v1/issues | Bearer (api) | Create issue | | GET /api/v1/issues | Bearer (api) | List issues (query: status, category, project, active_only, stage) | | GET /api/v1/issues/{id} | Bearer (api) | Get single issue | | PATCH /api/v1/issues/{id} | Bearer (api) | Update issue | | DELETE /api/v1/issues/{id} | Bearer (api) | Delete issue | | PUT /api/v1/issues/{id}/plan | Bearer (api) | Update plan text and status | | POST /api/v1/issues/{id}/comments | Bearer (api) | Add comment | | POST /api/v1/issues/{id}/nim-actions | Bearer (api) | Record agent action | | GET /api/v1/stats | Bearer (api) | Aggregate statistics | | GET /api/v1/reports/quality | Bearer (api) | Quality review report | | GET /api/v1/runbook | none | This runbook (markdown) |

Issue Lifecycle

Status

| Status | Meaning | Set by | |--------|---------|--------| | open | New issue, not yet groomed | Issue creation | | groomed | Triaged and ready for planning | groom-issues skill | | planning | Agent is writing an implementation plan | plan-issues skill | | proposed | Plan submitted for human review | plan-issues skill | | accepted | Plan approved, ready for implementation | Human via UI | | rejected | Plan rejected | Human via UI | | implementing | Agent is actively implementing the plan | next-plan skill | | done | Implementation is complete | next-plan skill | | closed | Issue closed manually | Human via UI |

Stage (shorthand filter)

| Stage | Resolves to | Used by | |-------|------------|---------| | groomable | open | groom-issues | | plannable | groomed | plan-issues | | implementable | accepted | next-plan | | active | all except done, closed | dashboards |

Wind Events

Issue events are published to Wind (NATS) as leaves:

Chat Widget

Embeddable nim chat on admin issue detail pages. Uses github.com/nimsforest/nimschatwidget package.

Requirements

How it works

  1. Admin opens /admin/issues/{id} → floating green chat button appears (bottom-right)
  2. User clicks button → slide panel with nim selector dropdown
  3. User sends message → Source publishes to river.chat.widget via JetStream
  4. Forest tree (message-chat) watches river.chat.>, routes to target nim with reply_subject=song.nimschatwidget.{sessionID}
  5. Nim responds via agentclaudecode → response published to song.nimschatwidget.{sessionID}
  6. Songbird catches response → delivers via SSE → appears in chat panel

Standalone service

nimschatwidget also runs as a standalone container on land at chatwidget.nimsforest.com (:8096). Other services can embed the widget via script tag without importing the Go package:

<script>
window.nimschatwidgetConfig = {
    baseURL: 'https://chatwidget.nimsforest.com',
    sessionId: 'unique-session-id',
    context: 'context for the nim',
    defaultNim: 'nimble'
};
</script>
<script src="https://chatwidget.nimsforest.com/widget"></script>

Endpoints (behind admin auth at /admin/chat/)

| Method | Path | Description | |--------|------|-------------| | POST /admin/chat/send | Send message to nim | | GET /admin/chat/nims | List available nims | | GET /admin/chat/events?session={id} | SSE stream for responses | | GET /admin/chat/widget | Serve widget JS |

Troubleshooting

Chat button not visible: Check that NATS is connected. Verify logs show "Chat widget enabled (publishing to river.chat.widget)".

"Nim is thinking..." never resolves: Check agentclaudecode logs on land. Most common cause: expired Claude API credentials. Fix: copy fresh ~/.claude/.credentials.json from neoremote to /opt/agentclaudecode/credentials.json on land and restart the container.

Response not arriving: If response goes to song.webchat.* instead of song.nimschatwidget.*, the message.lua tree script needs updating. The tree must respect reply_subject from the incoming message.

Authentication

Two separate tokens configured in config.yaml: