Skip to content
Closed
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
13 changes: 12 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ on:
jobs:
build-and-test:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Codecov OIDC upload; no stored token needed
steps:
- uses: actions/checkout@v4

Expand All @@ -34,4 +37,12 @@ jobs:
# outside internal/httpx constructs a raw http.Client / http.NewRequest —
# so un-receipted egress can't merge.
- name: Test
run: go test ./...
run: go test -coverprofile=coverage.out -covermode=atomic ./...

- name: Upload coverage
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
uses: codecov/codecov-action@v5
with:
files: coverage.out
use_oidc: true
fail_ci_if_error: false
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ build/
dist/
security-roast-report.md
.claude/
coverage.out
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ All notable changes to qmax-code. Versions follow [Semantic Versioning](https://

## [Unreleased]

### Changed
- Go module path is now `github.com/Quality-Max/qmax-code`, matching the
GitHub repository. The old lowercase path stopped the Go proxy and
pkg.go.dev from resolving the module. `go install
github.com/Quality-Max/qmax-code@latest` works from the next tagged release.

### Added
- Package documentation for `pkg.go.dev` and a Go Reference badge.
- CI uploads test coverage to Codecov.

## [1.38.0] - 2026-10-14

### Changed
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
[![GitHub downloads](https://img.shields.io/github/downloads/Quality-Max/qmax-code/total?label=downloads)](https://github.com/Quality-Max/qmax-code/releases)
[![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
[![Made with Go](https://img.shields.io/badge/made%20with-Go%201.25.13+-00ADD8.svg)](https://go.dev/)
[![Go Reference](https://pkg.go.dev/badge/github.com/Quality-Max/qmax-code.svg)](https://pkg.go.dev/github.com/Quality-Max/qmax-code)
[![Announcement](https://img.shields.io/badge/announcement-Apache%202.0-7c6cf0.svg)](docs/releases/v1.38.0.md)

[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-support-yellow?logo=buymeacoffee)](https://buymeacoffee.com/qualitymax)
Expand Down Expand Up @@ -123,6 +124,12 @@ curl -sL https://qualitymax.io/static/install-qmax-code.txt | bash

To build from source instead:

```bash
go install github.com/Quality-Max/qmax-code@latest
```

Or from a checkout:

```bash
git clone https://github.com/Quality-Max/qmax-code.git
cd qmax-code
Expand Down
4 changes: 2 additions & 2 deletions claude_code_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (
"runtime"
"strings"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/setup"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/setup"
)

const maxClaudeCodeAuthBytes = 64 * 1024
Expand Down
2 changes: 1 addition & 1 deletion claude_code_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"path/filepath"
"testing"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/api"
)

func TestReadClaudeCodeAuthFile(t *testing.T) {
Expand Down
6 changes: 3 additions & 3 deletions codex_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import (
"os/exec"
"path/filepath"

"github.com/qualitymax/qmax-code/internal/agent"
"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/setup"
"github.com/Quality-Max/qmax-code/internal/agent"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/setup"
)

const maxCodexAuthBytes = 64 * 1024
Expand Down
2 changes: 1 addition & 1 deletion codex_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"path/filepath"
"testing"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/api"
)

func TestReadCodexAuthFileRequiresOAuthTokens(t *testing.T) {
Expand Down
8 changes: 4 additions & 4 deletions config_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import (
"strconv"
"strings"

"github.com/qualitymax/qmax-code/internal/agent"
"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/sysutil"
"github.com/qualitymax/qmax-code/internal/tui"
"github.com/Quality-Max/qmax-code/internal/agent"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/sysutil"
"github.com/Quality-Max/qmax-code/internal/tui"
)

// handleConfigCommand implements the `qmax-code config ...` subcommand
Expand Down
4 changes: 2 additions & 2 deletions config_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"path/filepath"
"testing"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/tui"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/tui"
)

func withTempHome(t *testing.T) string {
Expand Down
18 changes: 18 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Command qmax-code is a QA-focused AI terminal agent.
//
// It runs standalone against a local repository or connects to QualityMax,
// and can switch inference between the Anthropic API, Cerebras, Ollama, and
// hosted coding agents (Claude Code, Codex, Antigravity, OpenCode) through
// /orch. Its focus is QA work: generating and running tests, crawling apps,
// reviewing diffs, and recording receipts.
//
// Install a release binary:
//
// curl -sL https://qualitymax.io/static/install-qmax-code.txt | bash
//
// Or build from source with Go 1.25.13 or newer:
//
// go install github.com/Quality-Max/qmax-code@latest
//
// Run qmax-code --help for flags and the README for slash commands.
package main
2 changes: 1 addition & 1 deletion gate_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"io"

"github.com/qualitymax/qmax-code/internal/gate"
"github.com/Quality-Max/qmax-code/internal/gate"
)

func runGateCommand(ctx context.Context, args []string, stdout, stderr io.Writer) int {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/qualitymax/qmax-code
module github.com/Quality-Max/qmax-code

go 1.25.13

Expand Down
10 changes: 5 additions & 5 deletions internal/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import (
"sync"
"time"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/httpx"
"github.com/qualitymax/qmax-code/internal/session"
"github.com/qualitymax/qmax-code/internal/sysutil"
"github.com/qualitymax/qmax-code/internal/tui"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/httpx"
"github.com/Quality-Max/qmax-code/internal/session"
"github.com/Quality-Max/qmax-code/internal/sysutil"
"github.com/Quality-Max/qmax-code/internal/tui"
)

// AgentConfig holds configuration for the LLM agent.
Expand Down
32 changes: 16 additions & 16 deletions internal/agent/agy_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import (
"sync"
"time"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/sysutil"
"github.com/qualitymax/qmax-code/internal/tui"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/sysutil"
"github.com/Quality-Max/qmax-code/internal/tui"
)

// AgyAgent orchestrates an Antigravity CLI (`agy`) subprocess for LLM
Expand All @@ -33,23 +33,23 @@ import (
// 5. conversation_id is kept for --conversation on the next turn
type AgyAgent struct {
TurnTranscript
agyBin string
modelID string // "" = agy default; otherwise --model
agyBin string
modelID string // "" = agy default; otherwise --model
effort string // "low" | "medium" | "high"
outputVerbose bool
narrateToolCalls string // "off" | "brief" | "full" — see narrationDirective
permissionMode string // "standard" | "unattended"
conversationID string
sctx *api.SessionContext
lastTurnIn int
lastTurnOut int
lastTurnOK bool
lastLimitHit bool
lastLimitReset time.Time
lastStderr string
mu sync.Mutex
runMu sync.Mutex
runCancel context.CancelFunc
conversationID string
sctx *api.SessionContext
lastTurnIn int
lastTurnOut int
lastTurnOK bool
lastLimitHit bool
lastLimitReset time.Time
lastStderr string
mu sync.Mutex
runMu sync.Mutex
runCancel context.CancelFunc
}

const agyQASystemPrompt = `You are QMax, an elite QA engineer running inside Google Antigravity.
Expand Down
36 changes: 18 additions & 18 deletions internal/agent/cc_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import (
"sync"
"time"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/sysutil"
"github.com/qualitymax/qmax-code/internal/tui"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/sysutil"
"github.com/Quality-Max/qmax-code/internal/tui"
)

// CLIAgent is the interface implemented by both CCAgent (claude CLI) and
Expand Down Expand Up @@ -70,24 +70,24 @@ type PlanLimitReporter interface {
// 5. CC session ID is saved for --resume on the next turn
type CCAgent struct {
TurnTranscript
claudeBin string
modelID string // "" = let CC decide; otherwise passed as --model
effort string // "low" | "medium" | "high" — injected into system prompt
claudeBin string
modelID string // "" = let CC decide; otherwise passed as --model
effort string // "low" | "medium" | "high" — injected into system prompt
outputVerbose bool // false = compact answer style; true = previous detailed style
narrateToolCalls string // "off" | "brief" | "full" — see narrationDirective
permissionMode string // "standard" | "unattended" — see Run() for behavior
ccSessionID string // CC's own session ID, for --resume
mcpConfigPath string // temp MCP config written once per qmax session
mcpConfigInfo os.FileInfo
sctx *api.SessionContext
lastToolName string // track last tool name for result display
fileSnaps map[string]fileSnapshot // CC tool_use id → pre-edit snapshot
lastTurnIn int // token usage of the most recent turn (from CC's result event)
lastTurnOut int
lastTurnOK bool // true once a result event carried usage this turn
mu sync.Mutex
runMu sync.Mutex
runCancel context.CancelFunc // non-nil while Run() is active
ccSessionID string // CC's own session ID, for --resume
mcpConfigPath string // temp MCP config written once per qmax session
mcpConfigInfo os.FileInfo
sctx *api.SessionContext
lastToolName string // track last tool name for result display
fileSnaps map[string]fileSnapshot // CC tool_use id → pre-edit snapshot
lastTurnIn int // token usage of the most recent turn (from CC's result event)
lastTurnOut int
lastTurnOK bool // true once a result event carried usage this turn
mu sync.Mutex
runMu sync.Mutex
runCancel context.CancelFunc // non-nil while Run() is active
}

// ccStandardAllowlist is the curated list passed to `claude --allowedTools` in
Expand Down
6 changes: 3 additions & 3 deletions internal/agent/cc_agent_session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import (
"strings"
"testing"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/session"
"github.com/qualitymax/qmax-code/internal/tui"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/session"
"github.com/Quality-Max/qmax-code/internal/tui"
)

// mockCLIAgent is a CLIAgent stub that returns scripted responses without
Expand Down
4 changes: 2 additions & 2 deletions internal/agent/cerebras.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"strings"
"time"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/httpx"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/httpx"
)

// Cerebras integration — drive the full native agent loop through Cerebras's
Expand Down
6 changes: 3 additions & 3 deletions internal/agent/cerebras_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"encoding/json"
"fmt"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/session"
"github.com/qualitymax/qmax-code/internal/tui"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/session"
"github.com/Quality-Max/qmax-code/internal/tui"
)

// RunCerebrasAgent runs a complete conversation turn through Cerebras using
Expand Down
4 changes: 2 additions & 2 deletions internal/agent/cerebras_agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"strings"
"testing"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/tui"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/tui"
)

// captureStdout redirects os.Stdout for the duration of fn and returns
Expand Down
2 changes: 1 addition & 1 deletion internal/agent/cerebras_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"strings"
"testing"

"github.com/qualitymax/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/api"
)

func TestValidateCerebrasKey(t *testing.T) {
Expand Down
26 changes: 13 additions & 13 deletions internal/agent/codex_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import (
"sync"
"time"

"github.com/qualitymax/qmax-code/codexrunner"
"github.com/qualitymax/qmax-code/internal/api"
"github.com/qualitymax/qmax-code/internal/sysutil"
"github.com/qualitymax/qmax-code/internal/tui"
"github.com/Quality-Max/qmax-code/codexrunner"
"github.com/Quality-Max/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/internal/sysutil"
"github.com/Quality-Max/qmax-code/internal/tui"
)

// CodexAgent orchestrates an OpenAI Codex CLI subprocess for LLM inference.
Expand All @@ -36,15 +36,15 @@ type CodexAgent struct {
narrateToolCalls string // "off" | "brief" | "full" — see narrationDirective
sctx *api.SessionContext
continuity *codexrunner.Continuity
lastTurnIn int // token usage of the most recent turn, when codex reports it
lastTurnOut int
lastTurnOK bool
lastLimitHit bool // true if the plan limit was hit this turn
lastLimitReset time.Time // provider-reported reset (usually zero for codex)
mu sync.Mutex
turnMu sync.Mutex // keeps checkpoint selection and execution atomic
runMu sync.Mutex
runCancel context.CancelFunc // non-nil while Run() is active
lastTurnIn int // token usage of the most recent turn, when codex reports it
lastTurnOut int
lastTurnOK bool
lastLimitHit bool // true if the plan limit was hit this turn
lastLimitReset time.Time // provider-reported reset (usually zero for codex)
mu sync.Mutex
turnMu sync.Mutex // keeps checkpoint selection and execution atomic
runMu sync.Mutex
runCancel context.CancelFunc // non-nil while Run() is active
}

// FindCodex returns the path to the codex CLI binary, or "" if not installed.
Expand Down
4 changes: 2 additions & 2 deletions internal/agent/codex_agent_continuity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"strings"
"testing"

"github.com/qualitymax/qmax-code/codexrunner"
"github.com/qualitymax/qmax-code/internal/api"
"github.com/Quality-Max/qmax-code/codexrunner"
"github.com/Quality-Max/qmax-code/internal/api"
)

func TestCodexAgentUsesNativeContinuityAndClearStartsFresh(t *testing.T) {
Expand Down
Loading
Loading