Install and update from a private Git checkout
This is the MVP private distribution path (issue #25). It has no public npm publication and no signed release artifact; both remain the scope of the later standalone installer card (#12). It assumes you already have authorized access to the private thalix-vault Git repository.
Prerequisites
- Node.js and Bun installed.
- An authorized clone of the private repository, on a branch with a configured upstream (for example
maintrackingorigin/main).
Install globally from your checkout
- Build the compiled CLI once:
bun run build:node
- Link the package globally. Either of the following works, and neither publishes anything or copies files out of your checkout:
# bun
bun run build:node && bun link --cwd packages/cli
# npm (equivalent, using npm's own global link mechanism)
npm link --prefix packages/cli
Both create a global tv executable that is a symlink back into this checkout.
- Verify the install:
command -v tv
tv version
tv version --json
tv version --json reports origin.source: "git-checkout" plus the commit, optional tag description, branch, and checkout path the running executable was linked from. If tv is not running from a linked checkout at all (for example a future packaged distribution), origin reports { "source": "unknown" } instead of failing.
Updating
tv update [--json]
tv update resolves the checkout that installed the running tv executable, then performs exactly one mutating Git operation against its already-configured upstream: git pull --ff-only. It never rebases, merges, resets, or force-pushes.
Before pulling, it refuses with a stable JSON error code and a safe, actionable human message whenever the checkout is not in a state a fast-forward can safely apply to:
| Condition | JSON error.code |
|---|---|
| The checkout has uncommitted changes | UPDATE_DIRTY_WORKING_TREE |
HEAD is detached | UPDATE_DETACHED_HEAD |
| The current branch has no configured upstream | UPDATE_NO_UPSTREAM |
| The local branch and upstream have both moved apart (diverged) | UPDATE_DIVERGED_HISTORY |
| The upstream no longer shares history with the local branch (for example after a force-push) | UPDATE_HISTORY_REWRITTEN |
| The remote could not be fetched (network, permission, or authentication failure) | UPDATE_FETCH_FAILED |
| The running executable is not linked from a Git checkout at all | UPDATE_NOT_GIT_CHECKOUT |
Successful output reports the checkout path, branch, redacted remote, and the previous/current commit:
{
"schemaVersion": 1,
"command": "update",
"status": "updated",
"checkoutPath": "/path/to/checkout",
"branch": "main",
"remote": "https://github.com/thalixinc/thalix-vault.git",
"previousCommit": "...",
"currentCommit": "..."
}
Any remote URL that embeds credentials (for example https://<user>:<token>@host/..., a common pattern for private-repository HTTPS access) has that userinfo stripped before it is ever written to human or JSON output, in both success and failure output. Process-level tests in tests/integration/cli-update-git.test.mjs and tests/security/cli-update-redaction.test.mjs exercise the successful pull, every refusal above, and credential redaction against isolated temporary Git repositories.
How this differs from the standalone signed installer (#12)
This card only makes an _existing authorized clone_ installable and updatable through ordinary Git. It intentionally does not add a public npm package/registry publication, a signed versioned release artifact or download host, release channels or version pinning, or any distribution path for people without repository access. Those are the standalone installer card's scope (#12, now implemented) -- see Install and Releasing tv. A checkout install's tv update always means "fast-forward this checkout from its configured Git upstream," never "install a different released version," and it has no retained previous version to roll back to (tv update --rollback on a checkout install refuses with UPDATE_ROLLBACK_NOT_SUPPORTED) -- rollback only applies to a standalone install, which retains exactly one prior version for exactly that purpose.
Continue with CLI overview, Getting started, Command reference, or Install the standalone binary.