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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

All notable changes to APIMux CLI are documented here.

## [1.1.4] - 2026-05-12

### Fixed

- Changed the fresh-install default APIMux service URL from local development
(`http://127.0.0.1:8081`) to production (`https://apimux.io/api/core`).
- Kept local/private service usage available through `APIMUX_BASE_URL`,
`--base-url`, or `apimux config set --base-url ...`.

### Documentation

- Clarified that localhost is a development override, not the default product
endpoint.

## [1.1.3] - 2026-05-12

### Added
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Authorize the CLI:
apimux auth login
```

The CLI defaults to the production APIMux service at `https://apimux.io/api/core`.

On SSH/headless servers, print the authorization URL instead of opening a browser:

```bash
Expand All @@ -49,7 +51,13 @@ apimux auth login --no-browser

`auth login` also auto-detects common headless environments such as SSH, CI, `NO_BROWSER=1`, and Linux without `$DISPLAY`.

For CI or manual API key setup, use `apimux config set --api-key ... --base-url ...`.
For CI or manual API key setup, use `apimux config set --api-key ...`. Override the service URL only for local development or private deployments:

```bash
APIMUX_BASE_URL=http://127.0.0.1:8081 apimux schema capabilities
apimux --base-url http://127.0.0.1:8081 schema capabilities
apimux config set --base-url http://127.0.0.1:8081
```

Run a capability:

Expand Down
4 changes: 2 additions & 2 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ make test
make release-build
```

Local config is stored under `APIMUX_CONFIG_DIR` when set, otherwise `~/.apimux/config.json`. Older configs under the platform user config directory are still read as a fallback and are migrated on the next write.
Local config is stored under `APIMUX_CONFIG_DIR` when set, otherwise `~/.apimux/config.json`. Older configs under the platform user config directory are still read as a fallback and are migrated on the next write. Fresh installs default to the production APIMux service at `https://apimux.io/api/core`.

Use `apimux auth login --web-url http://localhost:<port>` to exercise browser-assisted CLI auth against a local web app without persisting the web URL. For CI or manual API key setup, use `apimux config set --base-url ... --api-key ...`.
Use `apimux auth login --web-url http://localhost:<port>` to exercise browser-assisted CLI auth against a local web app without persisting the web URL. Use `APIMUX_BASE_URL`, `--base-url`, or `apimux config set --base-url ...` to point CLI capability calls at a local service such as `http://127.0.0.1:8081`. For CI or manual API key setup against production, `apimux config set --api-key ...` is enough unless you intentionally need a non-production service.
2 changes: 2 additions & 0 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Default install path:
curl -fsSL https://github.com/reorc/apimux-cli/releases/latest/download/install.sh | sh
```

After installation, `apimux` defaults to the production APIMux service at `https://apimux.io/api/core`. Use `APIMUX_BASE_URL`, `--base-url`, or `apimux config set --base-url ...` only when you need to point the CLI at a local or private service.

Environment variables:

- `APIMUX_VERSION`: install a pinned version such as `v1.0.0`
Expand Down
2 changes: 1 addition & 1 deletion internal/command/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func (r *Root) newCommand(runCtx *runContext) *cobra.Command {
cfg := runCtx.cfg
cfg.BaseURL = strings.TrimSpace(baseURL)
if cfg.BaseURL == "" {
cfg.BaseURL = "http://127.0.0.1:8081"
cfg.BaseURL = config.DefaultBaseURL
}

bodyOutput, ok := output.ParseBodyOutput(outputMode)
Expand Down
3 changes: 2 additions & 1 deletion internal/command/root_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/reorc/apimux-cli/internal/buildinfo"
"github.com/reorc/apimux-cli/internal/client"
"github.com/reorc/apimux-cli/internal/config"
"github.com/reorc/apimux-cli/internal/output"
)

Expand Down Expand Up @@ -214,7 +215,7 @@ func applyPersistentArgs(runCtx *runContext, args []string) error {
}

if strings.TrimSpace(baseURL) == "" {
baseURL = "http://127.0.0.1:8081"
baseURL = config.DefaultBaseURL
}
parsedOutput, ok := output.ParseBodyOutput(bodyOutput)
if !ok {
Expand Down
55 changes: 55 additions & 0 deletions internal/command/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"net/http/httptest"
"strings"
"testing"

"github.com/reorc/apimux-cli/internal/config"
)

func TestInvalidOutputReturnsNonZero(t *testing.T) {
Expand Down Expand Up @@ -141,6 +143,59 @@ func TestSchemaCapabilitiesJSONFlag(t *testing.T) {
}
}

func TestHelpShowsProductionBaseURLDefault(t *testing.T) {
tempDir := t.TempDir()
t.Setenv("APIMUX_CONFIG_DIR", tempDir)

var stdout bytes.Buffer
var stderr bytes.Buffer

root := NewRoot(&stdout, &stderr)
exitCode, err := root.Execute(context.Background(), []string{"--help"})
if err != nil {
t.Fatalf("execute root: %v", err)
}
if exitCode != 0 {
t.Fatalf("expected exit code 0, got %d, stderr=%s", exitCode, stderr.String())
}
if !strings.Contains(stdout.String(), `default "`+config.DefaultBaseURL+`"`) {
t.Fatalf("expected production base URL default in help, got %s", stdout.String())
}
}

func TestConfigShowsProductionBaseURLDefault(t *testing.T) {
tempDir := t.TempDir()
t.Setenv("APIMUX_CONFIG_DIR", tempDir)

var stdout bytes.Buffer
var stderr bytes.Buffer

root := NewRoot(&stdout, &stderr)
exitCode, err := root.Execute(context.Background(), []string{"config"})
if err != nil {
t.Fatalf("execute root: %v", err)
}
if exitCode != 0 {
t.Fatalf("expected exit code 0, got %d, stderr=%s", exitCode, stderr.String())
}
if !strings.Contains(stdout.String(), `"base_url": "`+config.DefaultBaseURL+`"`) {
t.Fatalf("expected production base URL in config output, got %s", stdout.String())
}
if !strings.Contains(stdout.String(), `"base_url": "default"`) {
t.Fatalf("expected default source in config output, got %s", stdout.String())
}
}

func TestPersistentArgFallbackUsesProductionBaseURL(t *testing.T) {
runCtx := &runContext{}
if err := applyPersistentArgs(runCtx, nil); err != nil {
t.Fatalf("apply persistent args: %v", err)
}
if runCtx.cfg.BaseURL != config.DefaultBaseURL {
t.Fatalf("expected production base URL fallback, got %s", runCtx.cfg.BaseURL)
}
}

func TestCompletionZshGeneratesScript(t *testing.T) {
var stdout bytes.Buffer
var stderr bytes.Buffer
Expand Down
4 changes: 3 additions & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (

const envConfigDir = "APIMUX_CONFIG_DIR"

const DefaultBaseURL = "https://apimux.io/api/core"

type Config struct {
BaseURL string `json:"base_url,omitempty"`
APIKey string `json:"api_key,omitempty"`
Expand All @@ -32,7 +34,7 @@ func Load() (Config, error) {

func LoadDetailed() (Loaded, error) {
cfg := Config{
BaseURL: "http://127.0.0.1:8081",
BaseURL: DefaultBaseURL,
}
sources := map[string]string{
"base_url": "default",
Expand Down
13 changes: 13 additions & 0 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ func TestLoadPrefersEnvOverFile(t *testing.T) {
}
}

func TestLoadDefaultsToProductionBaseURL(t *testing.T) {
tempDir := t.TempDir()
t.Setenv(envConfigDir, tempDir)

cfg, err := Load()
if err != nil {
t.Fatalf("load config: %v", err)
}
if cfg.BaseURL != DefaultBaseURL {
t.Fatalf("expected default base URL %s, got %s", DefaultBaseURL, cfg.BaseURL)
}
}

func TestSaveWritesConfigFile(t *testing.T) {
tempDir := t.TempDir()
t.Setenv(envConfigDir, tempDir)
Expand Down
Loading