@codevector/cli 0.5.0 → 0.6.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codevector/cli",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "CodeVector CLI — installs and configures first-party coding-tool integrations.",
5
5
  "license": "UNLICENSED",
6
6
  "bin": {
@@ -5,10 +5,12 @@
5
5
  *
6
6
  * 1. Migrate legacy single-profile credentials.json to the multi-profile
7
7
  * format introduced in v0.4.0.
8
- * 2. Detect which package manager invoked the install (npm / pnpm / yarn),
9
- * parsed out of `process.env.npm_config_user_agent`, and persist it to
10
- * `~/.config/codevector/install.json` so `codevector update` can use
11
- * the same manager without prompting.
8
+ * 2. On a *global* install, detect which package manager invoked it
9
+ * (npm / pnpm / yarn), parsed out of `process.env.npm_config_user_agent`,
10
+ * and persist it to `~/.config/codevector/install.json` so
11
+ * `codevector update` can use the same manager without prompting.
12
+ * Non-global installs are skipped so a monorepo dev install can't
13
+ * clobber the record.
12
14
  *
13
15
  * Runs automatically after `npm install` / `pnpm install` / `yarn add`.
14
16
  * Zero external dependencies — only Node built-ins. Any error is silently
@@ -83,6 +85,14 @@ function migrateCredentialsIfNeeded() {
83
85
  }
84
86
 
85
87
  function capturePackageManagerIfPossible() {
88
+ // Only record on a genuine global install. Otherwise a non-global install
89
+ // that runs this script — most commonly the monorepo's own `pnpm install`,
90
+ // where this CLI is a workspace package — would clobber install.json with
91
+ // the wrong manager. npm, pnpm, and yarn all set npm_config_global=true for
92
+ // `-g` installs. When the binary isn't global, `codevector update` infers
93
+ // the manager from the install path instead.
94
+ if (process.env.npm_config_global !== "true") return;
95
+
86
96
  const pm = detectPackageManager();
87
97
  if (!pm) return;
88
98
 
@@ -1,69 +0,0 @@
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
@@ -1,69 +0,0 @@
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