@codevector/cli 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +182 -0
- package/bin/codevector.mjs +2 -0
- package/dist/hooks/acceptance.sh +69 -0
- package/dist/index.js +19168 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -0
- package/src/hooks/acceptance.sh +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# codevector — CodeVector CLI
|
|
2
|
+
|
|
3
|
+
Wire your AI coding tools through a corporate gateway in one command. One API key, per-seat attribution, budget + rate limits, secret-scanning, usage reporting — without every developer manually editing config files.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm i -g @codevector/cli # or: pnpm add -g @codevector/cli
|
|
7
|
+
codevector auth login
|
|
8
|
+
codevector configure
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
That's the whole onboarding. Pick a tool, pick a scope, done.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- **Node.js >= 20**
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## What it does
|
|
22
|
+
|
|
23
|
+
- **Signs you in** with a per-seat API key issued by your gateway admin.
|
|
24
|
+
- **Writes the right config file** for each supported coding tool so its model traffic routes through the gateway instead of calling upstream providers directly.
|
|
25
|
+
- **Picks the right scope** (global, project-wide, or per-machine) based on what you want and what the tool supports.
|
|
26
|
+
- **Installs an acceptance-tracking hook** that fires at session end for tools that expose lifecycle events. Feeds the gateway's usage reporting.
|
|
27
|
+
- **Stays out of your way.** Idempotent writes. Deep-merges into existing settings files — won't clobber your theme, your other hooks, your existing env vars.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Supported tools
|
|
32
|
+
|
|
33
|
+
| Tool | Config path (user scope) | Scopes | Key storage | Hooks wired |
|
|
34
|
+
| -------------------------------- | ---------------------------------------- | ---------------------- | ---------------------------------------------------------- | --------------------- |
|
|
35
|
+
| **Claude Code** | `~/.claude/settings.json` | user / project / local | literal in JSON (`ANTHROPIC_AUTH_TOKEN`) | `Stop` + `SessionEnd` |
|
|
36
|
+
| **opencode** (sst/opencode) | `~/.config/opencode/opencode.json` | user / project / local | literal (user + local); env-var reference in project scope | — |
|
|
37
|
+
| **qwen-code** (Alibaba Qwen CLI) | `~/.qwen/settings.json` + `~/.qwen/.env` | user / project / local | `.env` file alongside settings (`envKey` reference) | `Stop` + `SessionEnd` |
|
|
38
|
+
| **codex** (OpenAI codex CLI) | `~/.codex/config.toml` | **user only** | shell env var (codex does not auto-load `.env`) | not wired |
|
|
39
|
+
|
|
40
|
+
Each writer emits both Anthropic and OpenAI-compatible provider entries where the tool supports both wire formats. codex is OpenAI-only.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Scope model
|
|
45
|
+
|
|
46
|
+
Three scopes, same names across every supported tool that allows more than one:
|
|
47
|
+
|
|
48
|
+
| Scope | Where the file lives | Committed to git? | Recommended for |
|
|
49
|
+
| --------- | ------------------------------------------------------------------------------------------------ | ------------------------------- | --------------------------------------------------------- |
|
|
50
|
+
| `user` | your home directory (`~/.claude/…`, `~/.codex/…`, etc.) | no (outside the repo) | your personal default across every project |
|
|
51
|
+
| `project` | this repo's config dir (`./.claude/settings.json`, etc.) | **yes** — shared with teammates | base URL only; we never embed the API key here |
|
|
52
|
+
| `local` | this repo's local-override file (`./.claude/settings.local.json`, `./opencode.json`, `./.qwen/`) | no — auto-gitignored | the usual default: per-seat API key stays on your machine |
|
|
53
|
+
|
|
54
|
+
`local` is the default when you don't pass `--scope`. The CLI adds gitignore entries automatically for tools that don't natively ignore their local file.
|
|
55
|
+
|
|
56
|
+
**Secret hygiene:** `project` scope will never write your API key to disk. It writes an env-var reference (`{env:CODEVECTOR_GATEWAY_KEY}` or an `envKey` field) and prints a note telling you to export the variable yourself. This is the only safe way to commit a config file.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Commands
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
codevector auth login # sign in — prompts for gateway URL + API key
|
|
64
|
+
codevector auth logout # delete local credentials; hooks are left in place
|
|
65
|
+
codevector auth whoami # print identity the current API key resolves to
|
|
66
|
+
codevector configure # interactive: pick tools, pick scope
|
|
67
|
+
codevector configure claude-code --scope local # non-interactive: scriptable for onboarding
|
|
68
|
+
codevector configure --all # every supported tool at once
|
|
69
|
+
codevector configure opencode --scope user # wire up opencode globally
|
|
70
|
+
codevector models list # list models you can reach through the gateway
|
|
71
|
+
codevector models list --kind chat # filter by kind: chat or embedding
|
|
72
|
+
codevector models list --json # emit raw JSON for scripting
|
|
73
|
+
codevector models sync # refresh model list in an existing opencode.json
|
|
74
|
+
codevector models sync --scope local # with explicit scope
|
|
75
|
+
codevector models sync --path /path/to/opencode.json # with explicit path
|
|
76
|
+
codevector usage # show your gateway usage (today by default)
|
|
77
|
+
codevector usage --days 7 # last 7 days
|
|
78
|
+
codevector usage --json # emit raw JSON for scripting
|
|
79
|
+
codevector status # who am I, where am I pointed, what models can I use
|
|
80
|
+
codevector doctor # health checks: creds, network, hook install, settings
|
|
81
|
+
codevector version # print CLI version
|
|
82
|
+
codevector init # writes .codevector.json (projectName + ticket pattern)
|
|
83
|
+
codevector init --project my-app # with explicit project name
|
|
84
|
+
codevector init --ticket-pattern "JIRA-\d+" # with custom ticket extraction regex
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Every command supports `--help`. Commands that need input will prompt interactively when flags are missing, but every flag still works for scripting.
|
|
88
|
+
|
|
89
|
+
### Auth options
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
codevector auth login --gateway-url https://gateway.corp.com # non-interactive URL
|
|
93
|
+
codevector auth login --api-key "$GATEWAY_KEY" # non-interactive key
|
|
94
|
+
codevector auth login --gateway-url https://gateway.corp.com --api-key "$KEY" # fully scriptable
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Typical flows
|
|
100
|
+
|
|
101
|
+
**First-time onboarding** (what to put in your team wiki):
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
codevector auth login # paste the gateway URL + API key your admin emailed you
|
|
105
|
+
codevector configure claude-code # default scope is local — safe per-seat, gitignored
|
|
106
|
+
codevector doctor # confirm everything's wired
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Configuring multiple tools in one go:**
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
codevector configure --all --scope local
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**CI-friendly, no prompts:**
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
codevector auth login --gateway-url https://gateway.corp.com --api-key "$GATEWAY_KEY"
|
|
119
|
+
codevector configure claude-code --scope user
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Inspecting what got written:**
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
codevector status
|
|
126
|
+
codevector doctor
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Checking your usage:**
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
codevector usage --days 30
|
|
133
|
+
codevector usage --json | jq .totals
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Syncing models for opencode:**
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
codevector models sync --scope local # refresh model list after admin adds models
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Safe config merging
|
|
145
|
+
|
|
146
|
+
`codevector configure` adds the gateway settings to your existing config files without overwriting what's already there:
|
|
147
|
+
|
|
148
|
+
- Your theme, custom env vars, and other hooks are left untouched.
|
|
149
|
+
- Running `codevector configure` a second time won't create duplicate entries — it's safe to re-run.
|
|
150
|
+
- If a config file is corrupted or in an unexpected format, we'll let you know instead of overwriting it.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Credentials
|
|
155
|
+
|
|
156
|
+
Stored at `~/.config/codevector/credentials.json` (chmod `0600`). Contains gateway URL, API key, user ID, email, and a timestamp. `codevector auth logout` deletes this file.
|
|
157
|
+
|
|
158
|
+
`codevector doctor` warns if the file mode is looser than `0600`.
|
|
159
|
+
|
|
160
|
+
Override the config root with `CODEVECTOR_CONFIG_DIR`.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Limitations
|
|
165
|
+
|
|
166
|
+
- **Cursor requires manual setup.** Cursor stores its settings in an internal database, so the CLI can't configure it automatically. Find step-by-step instructions on your gateway dashboard.
|
|
167
|
+
- **codex is user-scope only.** codex (OpenAI's CLI) has no project or local config. `codevector configure codex --scope project` returns a skipped status with a clear message.
|
|
168
|
+
- **codex doesn't auto-load `.env`.** After configuring codex, export `CODEVECTOR_GATEWAY_KEY` in your shell rc yourself. The CLI prints the line to paste.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Config file reference
|
|
173
|
+
|
|
174
|
+
| Tool | File | Format |
|
|
175
|
+
| ----------------- | --------------------------------------------------------- | ---------------------- |
|
|
176
|
+
| Claude Code | `~/.claude/settings.json` / `.claude/settings.local.json` | JSON |
|
|
177
|
+
| opencode | `~/.config/opencode/opencode.json` / `./opencode.json` | JSON (JSONC tolerated) |
|
|
178
|
+
| qwen-code | `~/.qwen/settings.json` / `.qwen/settings.json` | JSON |
|
|
179
|
+
| qwen-code secrets | `~/.qwen/.env` / `.qwen/.env` | dotenv |
|
|
180
|
+
| codex | `~/.codex/config.toml` | TOML |
|
|
181
|
+
| codevector credentials | `~/.config/codevector/credentials.json` | JSON (chmod 0600) |
|
|
182
|
+
| codevector hook script | `~/.config/codevector/hooks/acceptance.sh` | shell |
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# CodeVector acceptance-telemetry hook.
|
|
3
|
+
# Invoked by Claude Code on Stop / SessionEnd events. Never blocks the user's
|
|
4
|
+
# session — any failure exits 0 silently.
|
|
5
|
+
#
|
|
6
|
+
# Claude Code delivers the hook payload as JSON on stdin:
|
|
7
|
+
# { "hook_event_name": "Stop" | "SessionEnd", "session_id": "...",
|
|
8
|
+
# "transcript_path": "...", "cwd": "...", ... }
|
|
9
|
+
# and sets $CLAUDE_PROJECT_DIR to the project root.
|
|
10
|
+
set -u
|
|
11
|
+
|
|
12
|
+
CREDS="${HOME}/.config/codevector/credentials.json"
|
|
13
|
+
[ -f "$CREDS" ] || exit 0
|
|
14
|
+
|
|
15
|
+
API_KEY=$(jq -r .apiKey "$CREDS" 2>/dev/null) || exit 0
|
|
16
|
+
GATEWAY_URL=$(jq -r .gatewayUrl "$CREDS" 2>/dev/null) || exit 0
|
|
17
|
+
[ -n "$API_KEY" ] || exit 0
|
|
18
|
+
[ -n "$GATEWAY_URL" ] || exit 0
|
|
19
|
+
|
|
20
|
+
# Read the Claude Code hook payload from stdin. If stdin is empty or invalid
|
|
21
|
+
# JSON, fall back to event="stop" so we still emit *something*.
|
|
22
|
+
STDIN_PAYLOAD=$(cat 2>/dev/null || true)
|
|
23
|
+
RAW_EVENT=$(printf '%s' "$STDIN_PAYLOAD" | jq -r '.hook_event_name // "Stop"' 2>/dev/null || echo "Stop")
|
|
24
|
+
case "$RAW_EVENT" in
|
|
25
|
+
SessionEnd|session_end) EVENT="session_end" ;;
|
|
26
|
+
*) EVENT="stop" ;;
|
|
27
|
+
esac
|
|
28
|
+
|
|
29
|
+
# Resolve project root: prefer CLAUDE_PROJECT_DIR (set by Claude Code), else the
|
|
30
|
+
# `cwd` field on the stdin payload, else the shell's $PWD.
|
|
31
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-}"
|
|
32
|
+
if [ -z "$PROJECT_DIR" ]; then
|
|
33
|
+
PROJECT_DIR=$(printf '%s' "$STDIN_PAYLOAD" | jq -r '.cwd // ""' 2>/dev/null || true)
|
|
34
|
+
fi
|
|
35
|
+
[ -n "$PROJECT_DIR" ] || PROJECT_DIR="$PWD"
|
|
36
|
+
|
|
37
|
+
PROJECT=""
|
|
38
|
+
TICKET=""
|
|
39
|
+
if git -C "$PROJECT_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
40
|
+
REMOTE=$(git -C "$PROJECT_DIR" remote get-url origin 2>/dev/null || true)
|
|
41
|
+
if [ -n "$REMOTE" ]; then
|
|
42
|
+
PROJECT=$(echo "$REMOTE" | sed -E 's|^.*[/:]([^/]+)(\.git)?$|\1|' | sed -E 's|\.git$||')
|
|
43
|
+
fi
|
|
44
|
+
BRANCH=$(git -C "$PROJECT_DIR" branch --show-current 2>/dev/null || true)
|
|
45
|
+
if [ -n "$BRANCH" ]; then
|
|
46
|
+
TICKET=$(echo "$BRANCH" | grep -oE '[A-Z]+-[0-9]+' | head -1 || true)
|
|
47
|
+
fi
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
if [ -f "${PROJECT_DIR}/.codevector.json" ]; then
|
|
51
|
+
OVERRIDE=$(jq -r '.projectName // empty' "${PROJECT_DIR}/.codevector.json" 2>/dev/null || true)
|
|
52
|
+
if [ -n "$OVERRIDE" ]; then
|
|
53
|
+
PROJECT="$OVERRIDE"
|
|
54
|
+
fi
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
PAYLOAD=$(jq -n \
|
|
58
|
+
--arg event "$EVENT" \
|
|
59
|
+
--arg project "$PROJECT" \
|
|
60
|
+
--arg ticket "$TICKET" \
|
|
61
|
+
'{event:$event} + (if $project=="" then {} else {project:$project} end) + (if $ticket=="" then {} else {ticket:$ticket} end)')
|
|
62
|
+
|
|
63
|
+
curl -sS -m 5 -X POST "${GATEWAY_URL%/}/gateway/telemetry/acceptance" \
|
|
64
|
+
-H "x-api-key: ${API_KEY}" \
|
|
65
|
+
-H "content-type: application/json" \
|
|
66
|
+
--data "$PAYLOAD" \
|
|
67
|
+
>/dev/null 2>&1 || true
|
|
68
|
+
|
|
69
|
+
exit 0
|