158 lines
7.9 KiB
Markdown
158 lines
7.9 KiB
Markdown
# Kandev CLI (internal docs)
|
|
|
|
## Architecture
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A["kandev"] --> B["CLI parses arguments"]
|
|
B --> C{"Install channel?"}
|
|
|
|
C -->|Homebrew / Scoop / manual| H["bin/kandev native launcher"]
|
|
C -->|npm / npx| D["bin/cli.js native shim"]
|
|
|
|
D --> D1{"KANDEV_BUNDLE_DIR set?"}
|
|
D1 -->|yes| D2["Use env bundle (Homebrew)"]
|
|
D1 -->|no| D3["require.resolve('@kdlbs/runtime-{platform}')"]
|
|
D3 -->|hit| D4["Use installed npm bundle"]
|
|
D3 -->|miss| D5["Throw: 'No runtime found'"]
|
|
|
|
D2 --> E["Start Go backend serving static SPA"]
|
|
D4 --> E
|
|
D6 --> E
|
|
|
|
F --> F1["make dev + web dev server"]
|
|
G --> G1["backend binary serving Vite dist"]
|
|
```
|
|
|
|
## Overview
|
|
|
|
This package provides the `kandev` CLI launcher. The runtime bundle (Go backend, agentctl, and static Vite web assets) is **installed by the package manager** — there is no first-run download.
|
|
|
|
Three native bundle consumers share the same release artifacts:
|
|
|
|
- **npm/npx**: `kandev@X.Y.Z` declares `optionalDependencies` for `@kdlbs/runtime-{platform}@X.Y.Z`. npm 7+ filters by `os`/`cpu` and installs only the matching one.
|
|
- **Homebrew**: `kdlbs/homebrew-kandev` formula downloads the GitHub release tarball into the Cellar and installs `bin/kandev` as the public command.
|
|
- **Scoop**: `kdlbs/scoop-kandev` manifest downloads the Windows x64 GitHub release tarball and exposes `bin\kandev.exe` as the public command.
|
|
|
|
All three consumers resolve to a native runtime bundle. Homebrew/Scoop/manual bundles contain the platform launcher and `bin/agentctl`; npm runtime packages also include the platform-matched binaries. The public command remains `kandev`; the hidden backend mode is `kandev __backend`.
|
|
|
|
## Artifact shapes
|
|
|
|
The GitHub release bundle and the npm runtime package are **different shapes** because they serve different consumers:
|
|
|
|
```
|
|
# GitHub release bundle (used by Homebrew + Scoop + manual installs)
|
|
kandev/
|
|
└── bin/{kandev,agentctl,agentctl-linux-amd64,agentctl-darwin-arm64,agentctl-darwin-amd64}
|
|
|
|
# npm runtime package (@kdlbs/runtime-{platform})
|
|
@kdlbs/runtime-{platform}/
|
|
└── bin/{kandev,agentctl,agentctl-linux-amd64,agentctl-darwin-arm64,agentctl-darwin-amd64}
|
|
|
|
# Tauri desktop resource directory
|
|
apps/desktop/src-tauri/resources/kandev/
|
|
└── bin/{kandev[.exe],agentctl[.exe],agentctl-linux-amd64,agentctl-darwin-arm64,agentctl-darwin-amd64}
|
|
```
|
|
|
|
For npm installs, the main `kandev` package provides only a tiny Node bin shim that execs `bin/kandev` from the platform runtime package.
|
|
For desktop release builds, `scripts/release/prepare-desktop-runtime.sh` extracts the matching GitHub release bundle into the Tauri resource directory before `tauri build` runs.
|
|
|
|
## Commands
|
|
|
|
| Command | Description |
|
|
| ------------------------ | -------------------------------------------------------- |
|
|
| `kandev` or `kandev run` | Run from installed runtime bundle (default) |
|
|
| `kandev dev` | Run local repo with hot-reload (requires repo checkout) |
|
|
| `kandev start` | Run local production build (requires `make build` first) |
|
|
|
|
## CLI Options
|
|
|
|
| Option | Description |
|
|
| -------------------------- | --------------------------------------------------- |
|
|
| `--version`, `-V` | Print CLI version and exit |
|
|
| `--port`, `--backend-port` | Backend port |
|
|
| `--web-internal-port` | Override internal Vite dev web port (dev mode only) |
|
|
| `--verbose`, `-v` | Show info logs |
|
|
| `--debug` | Show debug logs + agent message dumps |
|
|
| `--help`, `-h` | Show help |
|
|
|
|
## Updates (package-manager owned)
|
|
|
|
The CLI no longer self-updates. Updates flow through the install channel:
|
|
|
|
```bash
|
|
brew upgrade kandev # Homebrew
|
|
scoop update kandev # Scoop
|
|
npm install -g kandev@latest # npm global
|
|
npx kandev@latest # always pulls latest
|
|
```
|
|
|
|
There is no `KANDEV_NO_UPDATE_PROMPT` or `KANDEV_SKIP_UPDATE` env var anymore — they're gone with the self-updater.
|
|
|
|
## npm shim
|
|
|
|
The npm package has no runtime dependencies beyond its platform optional runtime package. `bin/cli.js` resolves `KANDEV_BUNDLE_DIR` first, then the matching `@kdlbs/runtime-*` package, and execs the native `bin/kandev` binary with the original arguments.
|
|
|
|
```bash
|
|
pnpm -C apps/cli build # syntax-checks the shim
|
|
pnpm -C apps/cli test # tests runtime resolution
|
|
```
|
|
|
|
Smoke test the bundle in a clean directory:
|
|
|
|
```bash
|
|
KANDEV_BUNDLE_DIR=/path/to/dist/kandev node /path/to/apps/cli/bin/cli.js --help
|
|
```
|
|
|
|
If the runtime package or bundle is missing, the shim prints an actionable runtime-resolution error.
|
|
|
|
## Local Development
|
|
|
|
This package is a publish-only shim; there is no TypeScript source anymore. The native Go launcher owns every launch mode (`dev`, `start`, `run`, `service`), so `make dev` and friends exec `apps/backend/bin/kandev` directly.
|
|
|
|
## Release
|
|
|
|
Releases run entirely in GitHub Actions. From the GHA UI:
|
|
|
|
1. Open the **Release** workflow.
|
|
2. Click **Run workflow**.
|
|
3. Choose `bump` (patch / minor / major) from the dropdown.
|
|
4. Optionally tick `dry_run` to validate without publishing.
|
|
5. Click **Run workflow**.
|
|
|
|
The workflow does everything: version bump, CHANGELOG, PR, merge, tag, runtime bundles, desktop artifacts, npm publish, Homebrew tap update, and Scoop bucket update. See [/.github/workflows/release.yml](../../.github/workflows/release.yml).
|
|
|
|
Single SemVer flow: `apps/cli/package.json` version, git tag, npm packages, Homebrew formula, Scoop manifest, GitHub runtime tarballs, and desktop artifacts are all bumped to the same `X.Y.Z`.
|
|
|
|
Versioning:
|
|
|
|
- One SemVer `X.Y.Z` for everything (npm, GitHub tag, Homebrew formula, Scoop manifest)
|
|
- Git tag format: `vX.Y.Z`
|
|
- Legacy `vM.m` tags normalized to `M.m.0` during migration; new releases always use `vX.Y.Z`
|
|
|
|
## Environment Overrides
|
|
|
|
| Variable | Description |
|
|
| ------------------------------------- | -------------------------------------------------------------- |
|
|
| `KANDEV_BUNDLE_DIR` | Force runtime bundle location (set by Homebrew wrapper, tests) |
|
|
| `KANDEV_PORT` / `KANDEV_BACKEND_PORT` | Backend port |
|
|
| `KANDEV_WEB_PORT` | Internal Vite dev web port override |
|
|
| `KANDEV_HEALTH_TIMEOUT_MS` | Override health check timeout (ms) |
|
|
|
|
## Supported Platforms
|
|
|
|
| Platform | npm runtime package | GitHub asset name |
|
|
| --------------------- | ------------------------------------------- | --------------------------- |
|
|
| macOS (Apple Silicon) | `@kdlbs/runtime-darwin-arm64` | `kandev-macos-arm64.tar.gz` |
|
|
| macOS (Intel) | `@kdlbs/runtime-darwin-x64` | `kandev-macos-x64.tar.gz` |
|
|
| Linux (x64) | `@kdlbs/runtime-linux-x64` | `kandev-linux-x64.tar.gz` |
|
|
| Linux (ARM64) | `@kdlbs/runtime-linux-arm64` | `kandev-linux-arm64.tar.gz` |
|
|
| Windows (x64) | `@kdlbs/runtime-win32-x64` | `kandev-windows-x64.tar.gz` |
|
|
| Windows (ARM64) | Falls back to `windows-x64` (x64 emulation) | |
|
|
|
|
Note: the shim's platform naming (`macos`, `windows` internally) differs from the npm `os` field conventions (`darwin`, `win32`); `platformPackage()` in `native-shim.js` maps between the two.
|
|
|
|
## npm requirements
|
|
|
|
The optional-dependency runtime resolution requires **npm 7 or newer**. npm 6 silently skips optional deps during `npx`, which would leave users with no runtime. `package.json` declares `engines.npm: ">=7"` to surface this at install time as a clear error.
|