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
4 changes: 2 additions & 2 deletions .github/workflows/native-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- name: Native build and credential-free smoke
shell: pwsh
run: |
$binary = if ($IsWindows) { './jev-ci.exe' } else { './jev-ci' }
$binary = if ($IsWindows) { './jevwise-ci.exe' } else { './jevwise-ci' }
go build -o $binary ./cmd
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
foreach ($arguments in @(@('--help'), @('--version'), @('version'), @('skill', '--online'))) {
Expand All @@ -42,5 +42,5 @@ jobs:
GOARCH: arm64
CGO_ENABLED: '0'
run: |
go build -o jev-windows-arm64.exe ./cmd
go build -o jevwise-windows-arm64.exe ./cmd
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
72 changes: 37 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Jevwise

A Go SDK for TypeSafe AI and the `jev` decision CLI.
A Go SDK for TypeSafe AI and the `jevwise` decision CLI.

- SDK: `pkg/typesafe`, with typed questions, responses, raw metadata, and retries.
- CLI: send a prompt and options to Jev, then print the service's probabilities as JSON.
Expand All @@ -13,19 +13,21 @@ Use Go 1.27.2 or newer, matching `go.mod`. Run these commands from the checkout:
```sh
git clone https://github.com/bitbrew-dev/jevwise.git
cd jevwise
go build -o bin/jev ./cmd
bin/jev --help
bin/jev decide --help
go build -o bin/jevwise ./cmd
bin/jevwise --help
bin/jevwise decide --help
```

Help does not read credentials, configuration files, or contact the API.

The current checkout uses `jevwise`; releases through v1.2.0 used `jev`. There is no `jev` alias. Existing configuration and the `jev` provider remain unchanged. Verify ownership before removing an older binary; another project may own the `jev` command.

```sh
export TYPESAFE_API_KEY='<your-key>'
bin/jev decide --prompt 'Which task should I tackle first?' \
bin/jevwise decide --prompt 'Which task should I tackle first?' \
--option 'Fix the bug' --option 'Write documentation'

printf '%s' 'Which task should I tackle first?' | bin/jev decide --stdin \
printf '%s' 'Which task should I tackle first?' | bin/jevwise decide --stdin \
--option 'Fix the bug' --option 'Write documentation'
```

Expand All @@ -41,23 +43,23 @@ printf '%s' 'Which task should I tackle first?' | bin/jev decide --stdin \
## Version and platform builds

```sh
bin/jev version
bin/jev --version
bin/jevwise version
bin/jevwise --version
make build-platform GOOS=windows GOARCH=amd64
make build-platform GOOS=windows GOARCH=arm64
```

- Both version forms report version, commit, and build date without credentials, config loading, or network requests.
- Plain `go build` reports `dev` with unknown metadata. Make injects metadata; only a clean exact tag is automatically a release version, otherwise `dev`.
- Release linker symbols are `github.com/bitbrew-dev/jevwise/internal/buildinfo.Version`, `.Commit`, and `.Date`.
- Make produces `build/jev-windows-amd64.exe` or `build/jev-windows-arm64.exe`. Make helpers require Unix shell tools; native Windows PowerShell can use `go build -o jev.exe ./cmd`, then `.\jev.exe --version`.
- Make produces `build/jevwise-windows-amd64.exe` or `build/jevwise-windows-arm64.exe`. Make helpers require Unix shell tools; native Windows PowerShell can use `go build -o jevwise.exe ./cmd`, then `.\jevwise.exe --version`.

## Release checks and updates

```sh
bin/jev update --check
bin/jev update --check --timeout 20s
bin/jev update --timeout 60s # Install on supported standalone Linux/macOS builds
bin/jevwise update --check
bin/jevwise update --check --timeout 20s
bin/jevwise update --timeout 60s # Install on supported standalone Linux/macOS builds
```

- `--check` checks the latest stable GitHub release without downloading a binary or changing files. No background checks, API credentials, or decision configuration are used.
Expand All @@ -66,7 +68,7 @@ bin/jev update --timeout 60s # Install on supported standalone Linux/macOS build
- Accepts canonical stable `vX.Y.Z` tags only; prereleases/drafts and malformed or oversized responses are refused.
- Without `--check`, downloads and verifies a strictly newer release before replacement. Equal/newer installed versions are not rewritten or downgraded. Development, unknown and unstamped builds require manual installation.
- Automatic installation supports Linux/macOS amd64/arm64 only. Windows still supports version reporting and release checks, but updates are manual. Use your package manager for managed installations.
- After success, start a new invocation to use the new binary. An error saying the update was installed means publication succeeded but cancellation, cleanup or reporting failed: inspect `jev version` and any lock before retrying; no rollback occurs.
- After success, start a new invocation to use the new binary. An error saying the update was installed means publication succeeded but cancellation, cleanup or reporting failed: inspect `jevwise version` and any lock before retrying; no rollback occurs.

## Release binaries

Expand Down Expand Up @@ -118,11 +120,11 @@ Precedence: **changed flags > nonblank environment > TOML > defaults**.
## Skill setup

```sh
bin/jev skill # Default: .agent/skills/typesafe-ai/SKILL.md
bin/jev skill --agent # Explicit default target
bin/jev skill --claude # .claude/skills/typesafe-ai/SKILL.md
bin/jev skill --force # Replace an existing regular skill file
bin/jev skill --online # Print the upstream GitHub URL only
bin/jevwise skill # Default: .agent/skills/typesafe-ai/SKILL.md
bin/jevwise skill --agent # Explicit default target
bin/jevwise skill --claude # .claude/skills/typesafe-ai/SKILL.md
bin/jevwise skill --force # Replace an existing regular skill file
bin/jevwise skill --online # Print the upstream GitHub URL only
```

- Downloads the latest [upstream skill](https://github.com/typesafe-ai/skills/blob/main/skills/typesafe-ai/SKILL.md) unchanged, relative to the current project directory.
Expand All @@ -135,7 +137,7 @@ bin/jev skill --online # Print the upstream GitHub URL only

## Go SDK quickstart

Import the public SDK from `github.com/bitbrew-dev/jevwise/pkg/typesafe`. The CLI executable remains `jev`.
Import the public SDK from `github.com/bitbrew-dev/jevwise/pkg/typesafe`. The CLI executable is `jevwise`.

Migration: replace previous `github.com/benbenbang/ts-jev-go-sdk/pkg/typesafe` imports with the new path. No old-module compatibility alias is provided; SDK APIs and configuration names are unchanged.

Expand Down Expand Up @@ -208,34 +210,34 @@ Tests use injected services/transports and local HTTP fixtures, not paid API req

## Local MCP

MCP is included in v1.1.0. Diagnostic PID tracking is a newer, unreleased addition in the current checkout.
MCP is included in v1.1.0; diagnostic PID tracking and schema-2 state are included in v1.2.0. The executable rename is newer than those releases.

| Capability | v1.0.0 | v1.1.0 | Current checkout |
| --- | --- | --- | --- |
| Foreground and background MCP | Not included | Included | Included |
| Authenticated status and stop | Not included | Included | Included |
| Recorded child PID and schema-2 state | Not included | Not included | Included, unreleased |
| Capability | v1.0.0 | v1.1.0 | v1.2.0 | Current checkout |
| --- | --- | --- | --- | --- |
| Foreground and background MCP | Not included | Included | Included | Included |
| Authenticated status and stop | Not included | Included | Included | Included |
| Recorded child PID and schema-2 state | Not included | Not included | Included | Included |

The examples below describe the current checkout, using synthetic paths and addresses. They are not services started by this documentation.

### Start and manage

Configure upstream credentials as for `jev decide`. Separately prepare a random agent bearer token in a protected, current-user-only file. Do not reuse your API key.
Configure upstream credentials as for `jevwise decide`. Separately prepare a random agent bearer token in a protected, current-user-only file. Do not reuse your API key.

```sh
# Synthetic examples: supply your own protected token file before running.
bin/jev mcp --token-file /private/example/agent-token --listen 127.0.0.1:8080
bin/jev mcp --background --token-file /private/example/agent-token
bin/jev mcp status
bin/jev mcp stop
bin/jevwise mcp --token-file /private/example/agent-token --listen 127.0.0.1:8080
bin/jevwise mcp --background --token-file /private/example/agent-token
bin/jevwise mcp status
bin/jevwise mcp stop
```

| Command or flag | Behavior |
| --- | --- |
| `jev mcp` | Foreground server; prints the public `/mcp` endpoint after startup. Ctrl+C stops it. |
| `jevwise mcp` | Foreground server; prints the public `/mcp` endpoint after startup. Ctrl+C stops it. |
| `--background` | Starts a terminal-independent child after authenticated readiness and ownership checks. |
| `jev mcp status` | Authenticates the exact instance and reports its startup/running state. The post-v1.1.0 checkout also shows the recorded PID when available. |
| `jev mcp stop` | Authenticates the exact instance and requests shutdown; an acknowledgement is not a promise that cleanup has already finished. |
| `jevwise mcp status` | Authenticates the exact instance and reports its startup/running state. v1.2.0 and newer also show the recorded PID when available. |
| `jevwise mcp stop` | Authenticates the exact instance and requests shutdown; an acknowledgement is not a promise that cleanup has already finished. |
| `--listen` | Literal loopback IP and nonzero port; default `127.0.0.1:8080`. |
| `--runtime-dir` | Private background state directory; default `os.UserCacheDir()/jevwise-mcp`. Use the same override for start, status and stop. |
| `--token-file` | Explicit protected agent-token file, overriding `JEV_MCP_TOKEN`; unreadable or unsafe files fail without fallback. |
Expand All @@ -246,8 +248,8 @@ bin/jev mcp stop
- Background mode does not install a login item, reboot service or automatic restart. On Windows, a restrictive parent Job Object can prevent detachment or terminate the child when its parent exits.
- A repeated background start returns an endpoint only for an authenticated running instance. If it is still preparing or stopping, wait and check status instead.
- Stop and restart after changing credentials, decision configuration or the executable. Updating a binary does not change an already-running process.
- Unreleased PID support (post-v1.1.0 checkout): background children save their own PID in private `<runtime-dir>/state.json`; authenticated status prints `PID: NUMBER (inspection only)`. Normal owned shutdown removes that state along with the key and lease. PID reuse means this number is not proof of ownership or liveness: use `jev mcp stop`, not a blind PID-based kill.
- Unreleased state format: updated children write schema-2 state. The updated CLI still manages schema-1 instances without displaying a PID; older CLIs, including v1.1.0, cannot read schema-2 state. Stop an old instance before upgrading/restarting, and use the matching or newer CLI to manage a new child.
- PID support (v1.2.0 and newer): background children save their own PID in private `<runtime-dir>/state.json`; authenticated status prints `PID: NUMBER (inspection only)`. Normal owned shutdown removes that state along with the key and lease. PID reuse means this number is not proof of ownership or liveness: use `jevwise mcp stop`, not a blind PID-based kill.
- State format (v1.2.0 and newer): updated children write schema-2 state. The updated CLI still manages schema-1 instances without displaying a PID; older CLIs, including v1.1.0, cannot read schema-2 state. Stop an old instance before upgrading/restarting, and use the matching or newer CLI to manage a new child.

### Agent connection and limits

Expand Down
17 changes: 17 additions & 0 deletions docs/internal/cli-rename.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Executable rename: jev to jevwise

## Plan and scope

- [x] 25 - Rename command/help/version output, default Make and native-CI filenames, actionable MCP hints and public command examples. Test name/help/completion/version and Make output. Keep release tooling's native-version check compatible with existing tags. Parent: `cebb336`.
- [ ] 26 - Rename future release assets to `jevwise_...`; teach the updater to prefer the new exact name and use legacy names only when the new name is absent. Preserve size/checksum/redirect/version guards. Add offline publisher/downloader regression tests and migration notes. Depends on 25.
- Both scopes approved by the user. One PR at a time; feature branches stacked linearly on `virtual-main`, worktrees under `.agent/worktrees`; soft 300 / hard 450 aggregate changed lines including docs/tests.
- Keep SDK import paths, `cmd` entry-point path, Jev provider/model/hidden skill flag, `TS_JEV_*` / `TYPESAFE_*`, `ts-jev` config path, runtime state and update stamps unchanged. No `jev` alias, user-binary deletion, release/tag/visibility changes or Windows dependency upgrade.

## Migration and QA

- Existing published v1.0.0, v1.1.0 and v1.2.0 retain their `jev` command/artifact family. Never rewrite published binaries or manifests. New names apply to the next release and current source builds.
- Old clients know only `jev_...` assets: document manual installation under `jevwise` for the first renamed release. Never rename/remove another vendor's `jev` binary automatically; the updater replaces its current executable path, not its filename.
- Require root and independent QA: normal/race tests, tidy/vet/build/format/diff, offline Python fixtures, six builds and credential-free smoke. Installed-agent probes remain opt-in; no paid decisions or ordinary user configuration edits.
- Require all five exact-head CI successes before an approved merge, then verify merged tree/main/virtual-main and rerun checks. Preserve private spec and user artifacts; remove only merged task-owned worktrees/branches/temp files.

- 25 local QA passed: root fresh normal/race/tidy/vet/build/format/diff, 11 Python fixtures and six Make builds; independent full tests plus focused race checks repeated three times. Command-only smoke is credential-free. CI/publication/merge pending.
20 changes: 11 additions & 9 deletions docs/mcp-agents.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
# Connect a local agent to Jevwise

Use Codex or Claude Code on the **same computer** as the Jevwise MCP server. Jevwise serves Streamable HTTP at a literal-loopback `/mcp` endpoint, not stdio or legacy `/sse`. Do not register `jev mcp` as a stdio command or expose it through a public tunnel.
Use Codex or Claude Code on the **same computer** as the Jevwise MCP server. Jevwise serves Streamable HTTP at a literal-loopback `/mcp` endpoint, not stdio or legacy `/sse`. Do not register `jevwise mcp` as a stdio command or expose it through a public tunnel.

MCP is available in v1.1.0. Recorded PID/schema-2 state requires the newer unreleased checkout; see [release availability](../README.md#local-mcp).
MCP is available in v1.1.0. Recorded PID/schema-2 state requires v1.2.0 or newer; see [release availability](../README.md#local-mcp).

The commands below use the renamed checkout CLI, `jevwise`; published releases through v1.2.0 use `jev`.

## 1. Start Jevwise in the server terminal

Prerequisites:

- Install/build `jev` and configure the Jev provider as in the [README](../README.md#build-and-run).
- Install/build `jevwise` and configure the Jev provider as in the [README](../README.md#build-and-run).
- Prepare a random, separate agent bearer token in a protected current-user-only file. Follow the [token and runtime permissions](../README.md#credentials-state-and-safety), including Windows ACL requirements.
- Replace the example token-file path below with your own existing protected file. Do not reuse your upstream API key or the runtime management key.

```sh
# macOS/Linux shell; use jev.exe on Windows.
jev mcp --background --token-file /absolute/path/to/protected/agent-token \
# macOS/Linux shell; use jevwise.exe on Windows.
jevwise mcp --background --token-file /absolute/path/to/protected/agent-token \
--listen 127.0.0.1:8080
jev mcp status
jevwise mcp status
```

Foreground mode omits `--background`. Keep its terminal open; Ctrl+C stops it. If you set `--runtime-dir`, use the same directory for start, status and stop.
Expand Down Expand Up @@ -99,13 +101,13 @@ See [Claude Code's official MCP documentation](https://code.claude.com/docs/en/m

| Check | What it establishes |
| --- | --- |
| `jev mcp status` | The exact background instance authenticated its private management response. |
| `jevwise mcp status` | The exact background instance authenticated its private management response. |
| Client connected status and `decide` discovery | The client can authenticate and discover the MCP tool. |
| Calling `decide` | A real decision request, which can incur upstream API charges. Not needed for setup verification. |

If you intentionally want a decision, supply a `prompt` and at least two distinct `options`. Keep tool approval enabled and review the call before sending it.

### Optional installed-client smoke test (unreleased checkout)
### Optional installed-client smoke test (source checkout)

From the source checkout, with both `codex` and `claude` installed on PATH, run in a macOS/Linux shell:

Expand All @@ -127,6 +129,6 @@ JEVWISE_MCP_AGENT_SMOKE=1 go test -mod=readonly -run '^TestRealAgentMCPDiscovery
| Claude project server pending approval | Review the project and approve its `.mcp.json` entry in the client. |
| Cannot verify background state | Inspect manually; do not delete state or kill a PID based only on metadata. |

Stop with `jev mcp stop` using the same runtime directory. Acknowledgement is not a guarantee cleanup has already finished. Stop/restart after executable or credential changes. Use the matching/newer CLI for schema-2 instances.
Stop with `jevwise mcp stop` using the same runtime directory. Acknowledgement is not a guarantee cleanup has already finished. Stop/restart after executable or credential changes. Use the matching/newer CLI for schema-2 instances.

Remove only the client entry you added: `codex mcp remove jevwise`, or `claude mcp remove jevwise --scope local` for the local-scoped example. For project JSON, remove only that entry. Removing client configuration does not stop Jevwise. Clear `JEV_MCP_TOKEN` from the client terminal when finished.
5 changes: 4 additions & 1 deletion internal/buildinfo/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import (
"runtime"
)

// CommandName is the public executable and root-command identity.
const CommandName = "jevwise"

// Update stamps survive stripped, path-trimmed release builds for passive inspection.
const UpdateStampPrefix = "JEVWISE_UPDATE_V1["
const UpdateStampSuffix = "]JEVWISE_UPDATE_END"
Expand All @@ -23,6 +26,6 @@ func String() string {
if UpdateStamp != "" && UpdateStamp != UpdateStampPrefix+Version+UpdateStampSuffix {
version = "unknown"
}
return fmt.Sprintf("jev %s\ncommit: %s\nbuilt: %s\ngo: %s\nplatform: %s/%s\n",
return fmt.Sprintf(CommandName+" %s\ncommit: %s\nbuilt: %s\ngo: %s\nplatform: %s/%s\n",
version, Commit, Date, runtime.Version(), runtime.GOOS, runtime.GOARCH)
}
8 changes: 4 additions & 4 deletions internal/buildinfo/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func TestDefaultAndLinkedMetadataFormat(t *testing.T) {
t.Fatal("incorrect default metadata")
}
Version, Commit, Date = "v1.2.3", "abc123", "2026-10-07T00:00:00Z"
want := "jev v1.2.3\ncommit: abc123\nbuilt: 2026-10-07T00:00:00Z\ngo: " + runtime.Version() + "\nplatform: " + runtime.GOOS + "/" + runtime.GOARCH + "\n"
want := "jevwise v1.2.3\ncommit: abc123\nbuilt: 2026-10-07T00:00:00Z\ngo: " + runtime.Version() + "\nplatform: " + runtime.GOOS + "/" + runtime.GOARCH + "\n"
if String() != want || strings.Contains(String(), "unknown") {
t.Fatal("metadata not used by formatter")
}
Expand All @@ -24,9 +24,9 @@ func TestUpdateStampConsistency(t *testing.T) {
t.Cleanup(func() { Version, UpdateStamp = beforeVersion, beforeStamp })
Version = "v1.2.3"
for _, tc := range []struct{ stamp, want string }{
{"", "jev v1.2.3\n"},
{UpdateStampPrefix + Version + UpdateStampSuffix, "jev v1.2.3\n"},
{UpdateStampPrefix + "v2.0.0" + UpdateStampSuffix, "jev unknown\n"},
{"", "jevwise v1.2.3\n"},
{UpdateStampPrefix + Version + UpdateStampSuffix, "jevwise v1.2.3\n"},
{UpdateStampPrefix + "v2.0.0" + UpdateStampSuffix, "jevwise unknown\n"},
} {
UpdateStamp = tc.stamp
if !strings.HasPrefix(String(), tc.want) {
Expand Down
Loading
Loading