@quantiya/codevibe 2.0.67 → 2.0.68
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/bin/codevibe +132 -0
- package/package.json +5 -5
package/bin/codevibe
CHANGED
|
@@ -361,6 +361,135 @@ _verify_claude_plugin_files() {
|
|
|
361
361
|
' "$state" "$expected_version" 2>/dev/null
|
|
362
362
|
}
|
|
363
363
|
|
|
364
|
+
# ─── Keyring module check (keytar) ───────────────────────────────────
|
|
365
|
+
#
|
|
366
|
+
# keytar is an OPTIONAL dependency of codevibe-core, so npm never fails an install
|
|
367
|
+
# when its native binary is missing. Claude Code's plugin installer can leave the
|
|
368
|
+
# Claude plugin with keytar's source but no build/Release/keytar.node (and no
|
|
369
|
+
# node_modules/.bin): observed 2026-09-23 for the live 2.0.54 cache and for every fresh
|
|
370
|
+
# `claude plugin install` in an empty npm cache, while another install of 2.0.55 did
|
|
371
|
+
# build it. On a machine where core needs the OS keyring, core then fails closed and
|
|
372
|
+
# the Claude companion cannot sign in.
|
|
373
|
+
#
|
|
374
|
+
# Checked on EVERY update, not only reinstalls: a cache can be at the right version
|
|
375
|
+
# and still be missing the binary. Only a keytar present inside the installed plugin
|
|
376
|
+
# that fails to load is repaired, and only where CodeVibe needs it; an absent optional
|
|
377
|
+
# dependency is left alone. The repair re-runs keytar's own install through npm with
|
|
378
|
+
# prebuild-install's bin linked, which downloads the prebuilt binary exactly as a
|
|
379
|
+
# normal install does and needs no compiler toolchain.
|
|
380
|
+
|
|
381
|
+
# Exit 0 = loads, 1 = resolves inside the plugin but fails to load (the first line of
|
|
382
|
+
# the load error is printed on stdout), 3 = not present inside the plugin.
|
|
383
|
+
_claude_plugin_keytar_state() {
|
|
384
|
+
local install_path="$1"
|
|
385
|
+
(cd "$install_path" 2>/dev/null && node -e '
|
|
386
|
+
const fs = require("fs");
|
|
387
|
+
const path = require("path");
|
|
388
|
+
const root = fs.realpathSync(process.cwd());
|
|
389
|
+
let from = root;
|
|
390
|
+
try {
|
|
391
|
+
from = path.dirname(require.resolve("@quantiya/codevibe-core/package.json", { paths: [root] }));
|
|
392
|
+
} catch {}
|
|
393
|
+
let resolved;
|
|
394
|
+
try { resolved = fs.realpathSync(require.resolve("keytar", { paths: [from] })); } catch { process.exit(3); }
|
|
395
|
+
// Only a keytar INSIDE this plugin counts; never probe or repair an unrelated copy
|
|
396
|
+
// that happens to resolve from an ancestor directory.
|
|
397
|
+
if (resolved !== root && !resolved.startsWith(root + path.sep)) process.exit(3);
|
|
398
|
+
try { require(resolved); } catch (e) {
|
|
399
|
+
process.stdout.write(String((e && e.message) || e).split("\n")[0]);
|
|
400
|
+
process.exit(1);
|
|
401
|
+
}
|
|
402
|
+
process.exit(0);
|
|
403
|
+
' 2>/dev/null)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
# The credential service core uses for this ENVIRONMENT (config.ts: production and
|
|
407
|
+
# development share one service; any other value falls back to production).
|
|
408
|
+
_codevibe_keychain_service() {
|
|
409
|
+
case "${ENVIRONMENT:-}" in
|
|
410
|
+
experiment) echo "ai.quantiya.app.codevibe.experiment" ;;
|
|
411
|
+
*) echo "ai.quantiya.app.codevibe" ;;
|
|
412
|
+
esac
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
# Does CodeVibe need keytar on this machine? Mirrors the order in which
|
|
416
|
+
# codevibe-core's keychain-backend.ts (initBackends) picks the backend for ONE service:
|
|
417
|
+
# 1. that service's migrated-to-keyring tombstone: keyring only, file storage retired;
|
|
418
|
+
# 2. CODEVIBE_ALLOW_FILE_KEYCHAIN=1 or that service's durable file credentials: file;
|
|
419
|
+
# 3. Linux: only a structurally headless session falls back to file storage, and not
|
|
420
|
+
# when the keyring-used marker says a keyring identity exists here. The updater
|
|
421
|
+
# cannot see the companion's session, so without the marker it depends on it;
|
|
422
|
+
# 4. anywhere else (macOS, Windows): keytar is required.
|
|
423
|
+
# Returns 0 = required, 1 = file storage, 2 = depends on the session.
|
|
424
|
+
_codevibe_keyring_required() {
|
|
425
|
+
local service
|
|
426
|
+
service=$(_codevibe_keychain_service)
|
|
427
|
+
[ -e "$HOME/.codevibe/.migrated-to-keyring-$service" ] && return 0
|
|
428
|
+
[ "${CODEVIBE_ALLOW_FILE_KEYCHAIN:-}" = "1" ] && return 1
|
|
429
|
+
[ -e "$HOME/.codevibe/$service.json" ] && return 1
|
|
430
|
+
if [ "$(uname -s)" = "Linux" ]; then
|
|
431
|
+
[ -e "$HOME/.codevibe/.keyring-used" ] && return 0
|
|
432
|
+
return 2
|
|
433
|
+
fi
|
|
434
|
+
return 0
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
_ensure_claude_plugin_keytar() {
|
|
438
|
+
local state="$1"
|
|
439
|
+
local install_path rc log load_error need problem
|
|
440
|
+
if ! install_path=$(_claude_plugin_state_field "$state" installPath) \
|
|
441
|
+
|| ! install_path=$(cd "$install_path" 2>/dev/null && pwd -P); then
|
|
442
|
+
echo -e "${YELLOW}!${NC} Could not locate the installed Claude plugin to check its keyring module."
|
|
443
|
+
return 1
|
|
444
|
+
fi
|
|
445
|
+
|
|
446
|
+
load_error=$(_claude_plugin_keytar_state "$install_path")
|
|
447
|
+
rc=$?
|
|
448
|
+
[ "$rc" -eq 0 ] && return 0
|
|
449
|
+
[ "$rc" -eq 3 ] && return 0
|
|
450
|
+
|
|
451
|
+
case "$load_error" in
|
|
452
|
+
*"Cannot find module"*keytar.node*) problem="is missing its native binary" ;;
|
|
453
|
+
*) problem="does not load (${load_error:-unknown error})" ;;
|
|
454
|
+
esac
|
|
455
|
+
|
|
456
|
+
_codevibe_keyring_required
|
|
457
|
+
need=$?
|
|
458
|
+
if [ "$need" -eq 1 ]; then
|
|
459
|
+
echo -e "${YELLOW}!${NC} The Claude plugin's keyring module (keytar) ${problem}."
|
|
460
|
+
echo -e " ${DIM}This machine uses file-based credential storage, so CodeVibe does not need it.${NC}"
|
|
461
|
+
return 0
|
|
462
|
+
fi
|
|
463
|
+
|
|
464
|
+
echo -e "${YELLOW}!${NC} The Claude plugin's keyring module (keytar) ${problem}."
|
|
465
|
+
echo -e " ${DIM}Restoring it in ${install_path} ...${NC}"
|
|
466
|
+
if ! log=$(mktemp "${TMPDIR:-/tmp}/codevibe-keytar-repair.XXXXXX"); then
|
|
467
|
+
echo -e "${YELLOW}!${NC} Could not create a log file for the repair."
|
|
468
|
+
log=/dev/null
|
|
469
|
+
fi
|
|
470
|
+
(cd "$install_path" && npm rebuild prebuild-install keytar) >"$log" 2>&1
|
|
471
|
+
|
|
472
|
+
if load_error=$(_claude_plugin_keytar_state "$install_path"); then
|
|
473
|
+
[ "$log" = /dev/null ] || rm -f "$log"
|
|
474
|
+
echo -e "${GREEN}✓${NC} Keyring module restored"
|
|
475
|
+
return 0
|
|
476
|
+
fi
|
|
477
|
+
if [ "$need" -eq 0 ]; then
|
|
478
|
+
echo ""
|
|
479
|
+
echo -e "${YELLOW}!${NC} Could not restore the keyring module (${load_error:-unknown error})."
|
|
480
|
+
echo -e " CodeVibe needs it on this machine to read your credentials, so the Claude"
|
|
481
|
+
echo -e " companion cannot sign in until it loads."
|
|
482
|
+
echo -e " ${DIM}Repair log: ${log}${NC}"
|
|
483
|
+
echo -e " ${DIM}Retry: (cd \"${install_path}\" && npm rebuild prebuild-install keytar)${NC}"
|
|
484
|
+
return 1
|
|
485
|
+
fi
|
|
486
|
+
echo -e "${YELLOW}!${NC} Keyring module unavailable (${load_error:-unknown error}). A headless session uses"
|
|
487
|
+
echo -e " file-based credential storage; a desktop session cannot sign in until it loads."
|
|
488
|
+
echo -e " ${DIM}Repair log: ${log}${NC}"
|
|
489
|
+
echo -e " ${DIM}Retry: (cd \"${install_path}\" && npm rebuild prebuild-install keytar)${NC}"
|
|
490
|
+
return 0
|
|
491
|
+
}
|
|
492
|
+
|
|
364
493
|
do_update() {
|
|
365
494
|
local update_phase="${CODEVIBE_UPDATE_AFTER_META:-meta}"
|
|
366
495
|
unset CODEVIBE_UPDATE_AFTER_META
|
|
@@ -605,6 +734,9 @@ do_update() {
|
|
|
605
734
|
echo -e "${YELLOW}!${NC} Claude plugin files do not match the required package identity."
|
|
606
735
|
return 1
|
|
607
736
|
fi
|
|
737
|
+
if ! _ensure_claude_plugin_keytar "$PREVIEW_STATE"; then
|
|
738
|
+
return 1
|
|
739
|
+
fi
|
|
608
740
|
|
|
609
741
|
# ─── Step 5: Tell the user about running sessions ──────────────────────────
|
|
610
742
|
if [ "$NEEDS_REINSTALL" = "true" ] || [ "$REGISTRATION_CHANGED" = "true" ]; then
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quantiya/codevibe",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.68",
|
|
4
4
|
"description": "Companion and orchestration for Claude Code, OpenAI Codex CLI, and Antigravity, with secure mobile control.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"codevibe": "./bin/codevibe"
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
"test": "node --test test/cli-surface.test.js"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@quantiya/codevibe-antigravity-plugin": "2.0.
|
|
18
|
-
"@quantiya/codevibe-claude-plugin": "2.0.
|
|
19
|
-
"@quantiya/codevibe-codex-plugin": "2.0.
|
|
20
|
-
"@quantiya/codevibe-core": "2.0.
|
|
17
|
+
"@quantiya/codevibe-antigravity-plugin": "2.0.54",
|
|
18
|
+
"@quantiya/codevibe-claude-plugin": "2.0.56",
|
|
19
|
+
"@quantiya/codevibe-codex-plugin": "2.0.57",
|
|
20
|
+
"@quantiya/codevibe-core": "2.0.50"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"codevibe",
|