@quantiya/codevibe-gemini-plugin 1.0.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/.env.example +28 -0
- package/README.md +117 -0
- package/bin/codevibe-gemini +238 -0
- package/dist/appsync-client.d.ts +66 -0
- package/dist/appsync-client.d.ts.map +1 -0
- package/dist/appsync-client.js +819 -0
- package/dist/appsync-client.js.map +1 -0
- package/dist/auth-cli.d.ts +18 -0
- package/dist/auth-cli.d.ts.map +1 -0
- package/dist/auth-cli.js +472 -0
- package/dist/auth-cli.js.map +1 -0
- package/dist/command-executor.d.ts +20 -0
- package/dist/command-executor.d.ts.map +1 -0
- package/dist/command-executor.js +127 -0
- package/dist/command-executor.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +106 -0
- package/dist/config.js.map +1 -0
- package/dist/crypto-service.d.ts +115 -0
- package/dist/crypto-service.d.ts.map +1 -0
- package/dist/crypto-service.js +278 -0
- package/dist/crypto-service.js.map +1 -0
- package/dist/http-api.d.ts +63 -0
- package/dist/http-api.d.ts.map +1 -0
- package/dist/http-api.js +582 -0
- package/dist/http-api.js.map +1 -0
- package/dist/key-manager.d.ts +87 -0
- package/dist/key-manager.d.ts.map +1 -0
- package/dist/key-manager.js +287 -0
- package/dist/key-manager.js.map +1 -0
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +18 -0
- package/dist/logger.js.map +1 -0
- package/dist/prompt-responder.d.ts +22 -0
- package/dist/prompt-responder.d.ts.map +1 -0
- package/dist/prompt-responder.js +132 -0
- package/dist/prompt-responder.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1422 -0
- package/dist/server.js.map +1 -0
- package/dist/token-storage.d.ts +39 -0
- package/dist/token-storage.d.ts.map +1 -0
- package/dist/token-storage.js +169 -0
- package/dist/token-storage.js.map +1 -0
- package/dist/transcript-watcher.d.ts +111 -0
- package/dist/transcript-watcher.d.ts.map +1 -0
- package/dist/transcript-watcher.js +324 -0
- package/dist/transcript-watcher.js.map +1 -0
- package/dist/types.d.ts +119 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/gemini-extension.json +84 -0
- package/hooks/after-agent.sh +122 -0
- package/hooks/after-tool.sh +71 -0
- package/hooks/before-agent.sh +46 -0
- package/hooks/before-tool.sh +17 -0
- package/hooks/common.sh +220 -0
- package/hooks/hooks.json +81 -0
- package/hooks/notification.sh +32 -0
- package/hooks/session-end.sh +70 -0
- package/hooks/session-start.sh +72 -0
- package/package.json +73 -0
package/.env.example
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Gemini Companion Plugin Configuration
|
|
2
|
+
# ======================================
|
|
3
|
+
# NOTE: You typically don't need to edit this file manually.
|
|
4
|
+
# Configuration is auto-set after running 'codevibe-gemini login'.
|
|
5
|
+
#
|
|
6
|
+
# Copy this file to .env.production or .env.development and fill in values.
|
|
7
|
+
|
|
8
|
+
# Server Configuration
|
|
9
|
+
PORT=3456
|
|
10
|
+
HOST=localhost
|
|
11
|
+
|
|
12
|
+
# AWS Configuration
|
|
13
|
+
# These values are provided by the CodeVibe service
|
|
14
|
+
AWS_REGION=us-east-1
|
|
15
|
+
APPSYNC_URL=https://your-appsync-endpoint.appsync-api.us-east-1.amazonaws.com/graphql
|
|
16
|
+
|
|
17
|
+
# Cognito Configuration (for OAuth authentication)
|
|
18
|
+
COGNITO_USER_POOL_ID=us-east-1_xxxxxxxxx
|
|
19
|
+
COGNITO_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
20
|
+
COGNITO_DOMAIN=your-domain.auth.us-east-1.amazoncognito.com
|
|
21
|
+
|
|
22
|
+
# Gemini Configuration
|
|
23
|
+
GEMINI_COMMAND=gemini
|
|
24
|
+
GEMINI_TIMEOUT=60000
|
|
25
|
+
|
|
26
|
+
# Logging Configuration
|
|
27
|
+
LOG_FILE=/tmp/codevibe-gemini-mcp.log
|
|
28
|
+
LOG_LEVEL=info
|
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# CodeVibe Gemini Plugin
|
|
2
|
+
|
|
3
|
+
Mobile companion for Gemini CLI - monitor and control your Gemini CLI sessions from your iPhone.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
CodeVibe Gemini Plugin syncs your Gemini CLI sessions with the CodeVibe iOS app, allowing you to:
|
|
8
|
+
- **Approve or deny file edits from your phone** - See file diffs before approving
|
|
9
|
+
- View Gemini conversations on your phone in real-time
|
|
10
|
+
- Send prompts to Gemini from your iPhone
|
|
11
|
+
- Send image attachments from iOS (Gemini analyzes them)
|
|
12
|
+
- Monitor multiple coding sessions from anywhere
|
|
13
|
+
- Works alongside Claude Code sessions in the same app
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- **macOS** (required for tmux integration)
|
|
18
|
+
- **Node.js 18+**
|
|
19
|
+
- **tmux** (`brew install tmux`)
|
|
20
|
+
- **Gemini CLI** installed and authenticated
|
|
21
|
+
- **CodeVibe iOS app** installed on your iPhone
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install -g codevibe-gemini-plugin
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### From Source (Development)
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git clone https://github.com/hendryyeh/quantiya-codevibe-gemini-plugin.git
|
|
33
|
+
cd quantiya-codevibe-gemini-plugin
|
|
34
|
+
npm install
|
|
35
|
+
npm run build
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
### First Time Setup
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Authenticate with backend (opens browser for Sign in with Apple/Google)
|
|
44
|
+
codevibe-gemini login
|
|
45
|
+
|
|
46
|
+
# Check authentication status
|
|
47
|
+
codevibe-gemini status
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Running the Plugin
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Start Gemini with mobile sync
|
|
54
|
+
codevibe-gemini
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The plugin will automatically detect Gemini sessions and sync conversations to your iOS app.
|
|
58
|
+
|
|
59
|
+
### CLI Commands
|
|
60
|
+
|
|
61
|
+
| Command | Description |
|
|
62
|
+
|---------|-------------|
|
|
63
|
+
| `codevibe-gemini` | Start Gemini with mobile sync |
|
|
64
|
+
| `codevibe-gemini login` | Authenticate with backend |
|
|
65
|
+
| `codevibe-gemini logout` | Clear stored credentials |
|
|
66
|
+
| `codevibe-gemini status` | Show authentication status |
|
|
67
|
+
|
|
68
|
+
## How It Works
|
|
69
|
+
|
|
70
|
+
This plugin uses Gemini CLI's hook system (available in stable releases since December 2025) combined with transcript file watching for complete coverage.
|
|
71
|
+
|
|
72
|
+
**Hook Integration:**
|
|
73
|
+
1. **BeforeTool** - Captures tool approval requests, shows file diffs on iOS, waits for your approval
|
|
74
|
+
2. **AfterTool** - Captures tool execution results
|
|
75
|
+
3. **SessionStart/SessionEnd** - Manages session lifecycle
|
|
76
|
+
|
|
77
|
+
**Transcript Watching:**
|
|
78
|
+
- Monitors `~/.gemini/tmp/*/chats/` for user prompts and assistant responses
|
|
79
|
+
- Provides accurate timestamps for event ordering
|
|
80
|
+
|
|
81
|
+
**Mobile Integration:**
|
|
82
|
+
- Receives prompts from iOS app via WebSocket subscriptions
|
|
83
|
+
- Executes prompts using tmux send-keys (works even when screen is locked)
|
|
84
|
+
|
|
85
|
+
## Known Limitations
|
|
86
|
+
|
|
87
|
+
- **macOS only**: Requires tmux for terminal integration
|
|
88
|
+
- **Gemini CLI version**: Hooks require December 2025+ stable release
|
|
89
|
+
|
|
90
|
+
## Features
|
|
91
|
+
|
|
92
|
+
| Feature | Status | Notes |
|
|
93
|
+
|---------|--------|-------|
|
|
94
|
+
| Interactive prompts | ✅ Full | Approve/deny from iOS with file diff preview |
|
|
95
|
+
| User prompts | ✅ Full | Real-time sync to iOS |
|
|
96
|
+
| Assistant responses | ✅ Full | Real-time sync to iOS |
|
|
97
|
+
| File diffs | ✅ Full | Preview changes before approving |
|
|
98
|
+
| Tool results | ✅ Full | See what Gemini executed |
|
|
99
|
+
| Image attachments | ✅ Full | Send images from iOS, uses `@./path` format |
|
|
100
|
+
| Mobile prompts | ✅ Full | Send prompts from iOS, auto-submits |
|
|
101
|
+
|
|
102
|
+
**Full feature parity with Claude Code plugin.**
|
|
103
|
+
|
|
104
|
+
## Related
|
|
105
|
+
|
|
106
|
+
- **CodeVibe iOS App** - Available on the App Store
|
|
107
|
+
- [CodeVibe Claude Plugin](https://github.com/hendryyeh/codevibe-claude-plugin) - For Claude Code
|
|
108
|
+
- [CodeVibe Codex Plugin](https://github.com/hendryyeh/codevibe-codex-plugin) - For OpenAI Codex CLI
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
MIT License - See [LICENSE](LICENSE) for details.
|
|
113
|
+
|
|
114
|
+
## Support
|
|
115
|
+
|
|
116
|
+
- **Issues:** [GitHub Issues](https://github.com/hendryyeh/quantiya-codevibe-gemini-plugin/issues)
|
|
117
|
+
- **Email:** support@quantiya.ai
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# codevibe-gemini - Wrapper to run Gemini CLI inside tmux for mobile control
|
|
4
|
+
#
|
|
5
|
+
# This script launches Gemini CLI inside a tmux session, enabling:
|
|
6
|
+
# - Mobile prompts when screen is locked (via tmux send-keys)
|
|
7
|
+
# - Same user experience as regular gemini command
|
|
8
|
+
# - Automatic sync with iOS app via MCP server
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
# codevibe-gemini [gemini-args...]
|
|
12
|
+
# codevibe-gemini login # Sign in via browser
|
|
13
|
+
# codevibe-gemini logout # Sign out
|
|
14
|
+
# codevibe-gemini status # Show auth status
|
|
15
|
+
#
|
|
16
|
+
# Environment:
|
|
17
|
+
# ENVIRONMENT # Set to 'production' (default) or 'development'
|
|
18
|
+
#
|
|
19
|
+
# Examples:
|
|
20
|
+
# codevibe-gemini # Start new session
|
|
21
|
+
# codevibe-gemini --resume # Resume last session
|
|
22
|
+
# codevibe-gemini "fix the bug" # Start with prompt
|
|
23
|
+
# ENVIRONMENT=development codevibe-gemini login # Login to development
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
set -e
|
|
27
|
+
|
|
28
|
+
# Default to production environment if not specified
|
|
29
|
+
# Users can set ENVIRONMENT=development for local development
|
|
30
|
+
export ENVIRONMENT="${ENVIRONMENT:-production}"
|
|
31
|
+
|
|
32
|
+
# Use TMPDIR if set (macOS sets this to user-specific temp), otherwise /tmp
|
|
33
|
+
CODEVIBE_TMPDIR="${TMPDIR:-/tmp}"
|
|
34
|
+
|
|
35
|
+
# Get the directory where this script is located (resolving symlinks)
|
|
36
|
+
# This is needed because npm global installs symlink bin scripts to /usr/local/bin/
|
|
37
|
+
SOURCE="${BASH_SOURCE[0]}"
|
|
38
|
+
while [ -L "$SOURCE" ]; do
|
|
39
|
+
DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
|
|
40
|
+
SOURCE="$(readlink "$SOURCE")"
|
|
41
|
+
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
|
|
42
|
+
done
|
|
43
|
+
SCRIPT_DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
|
|
44
|
+
PLUGIN_DIR="$(dirname "$SCRIPT_DIR")"
|
|
45
|
+
|
|
46
|
+
# Handle auth commands (login, logout, status, reset-device)
|
|
47
|
+
# Delegate to codevibe-core CLI (shared auth across all plugins)
|
|
48
|
+
case "$1" in
|
|
49
|
+
login|logout|status|reset-device)
|
|
50
|
+
CORE_CLI="$PLUGIN_DIR/node_modules/@quantiya/codevibe-core/bin/codevibe.js"
|
|
51
|
+
if [ -f "$CORE_CLI" ]; then
|
|
52
|
+
exec node "$CORE_CLI" "$1"
|
|
53
|
+
else
|
|
54
|
+
echo "Error: codevibe-core not found. Run 'npm install' in the plugin directory first."
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
;;
|
|
58
|
+
esac
|
|
59
|
+
|
|
60
|
+
# Export hooks directory for hook scripts to use
|
|
61
|
+
export CODEVIBE_HOOKS_DIR="$PLUGIN_DIR/hooks"
|
|
62
|
+
|
|
63
|
+
# Auto-configure hooks on startup if not already configured
|
|
64
|
+
configure_hooks_if_needed() {
|
|
65
|
+
GEMINI_SETTINGS_DIR="$HOME/.gemini"
|
|
66
|
+
GEMINI_SETTINGS_FILE="$GEMINI_SETTINGS_DIR/settings.json"
|
|
67
|
+
HOOKS_DIR="$PLUGIN_DIR/hooks"
|
|
68
|
+
TEMPLATE_FILE="$PLUGIN_DIR/gemini-hooks-settings.json"
|
|
69
|
+
|
|
70
|
+
# Make hook scripts executable
|
|
71
|
+
chmod +x "$HOOKS_DIR"/*.sh 2>/dev/null || true
|
|
72
|
+
|
|
73
|
+
# Create .gemini directory if it doesn't exist
|
|
74
|
+
mkdir -p "$GEMINI_SETTINGS_DIR"
|
|
75
|
+
|
|
76
|
+
# Check if hooks need to be configured
|
|
77
|
+
if [ ! -f "$GEMINI_SETTINGS_FILE" ]; then
|
|
78
|
+
# No settings file - create it with hooks
|
|
79
|
+
echo "Configuring Gemini CLI hooks for CodeVibe..."
|
|
80
|
+
sed "s|__CODEVIBE_HOOKS_DIR__|$HOOKS_DIR|g" "$TEMPLATE_FILE" > "$GEMINI_SETTINGS_FILE"
|
|
81
|
+
echo "✓ Hooks configured at: $GEMINI_SETTINGS_FILE"
|
|
82
|
+
elif ! grep -q "BeforeAgent" "$GEMINI_SETTINGS_FILE" 2>/dev/null; then
|
|
83
|
+
# Settings file exists but missing agent hooks - warn user to upgrade
|
|
84
|
+
echo "⚠ Gemini CLI hooks need updating. BeforeAgent/AfterAgent hooks required."
|
|
85
|
+
echo " Update hooks in: $GEMINI_SETTINGS_FILE"
|
|
86
|
+
echo " Or delete the file and restart to auto-configure."
|
|
87
|
+
echo ""
|
|
88
|
+
elif ! grep -q "BeforeTool" "$GEMINI_SETTINGS_FILE" 2>/dev/null; then
|
|
89
|
+
# Settings file exists but no tool hooks - warn user
|
|
90
|
+
echo "⚠ Gemini CLI hooks not fully configured."
|
|
91
|
+
echo " To enable interactive prompts from mobile, add hooks to:"
|
|
92
|
+
echo " $GEMINI_SETTINGS_FILE"
|
|
93
|
+
echo ""
|
|
94
|
+
fi
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# Configure hooks before starting
|
|
98
|
+
configure_hooks_if_needed
|
|
99
|
+
|
|
100
|
+
# Configuration
|
|
101
|
+
TMUX_SESSION_PREFIX="codevibe-gemini"
|
|
102
|
+
LOG_FILE="${CODEVIBE_TMPDIR}/codevibe-gemini-wrapper.log"
|
|
103
|
+
MCP_LOG_FILE="${CODEVIBE_TMPDIR}/codevibe-gemini-mcp.log"
|
|
104
|
+
|
|
105
|
+
log() {
|
|
106
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
# Cleanup function to kill MCP server when wrapper exits
|
|
110
|
+
cleanup() {
|
|
111
|
+
log "Cleanup triggered"
|
|
112
|
+
if [ -n "$MCP_PID" ] && kill -0 "$MCP_PID" 2>/dev/null; then
|
|
113
|
+
log "Stopping MCP server (PID: $MCP_PID)"
|
|
114
|
+
kill "$MCP_PID" 2>/dev/null || true
|
|
115
|
+
wait "$MCP_PID" 2>/dev/null || true
|
|
116
|
+
fi
|
|
117
|
+
# Remove PID file
|
|
118
|
+
rm -f "${CODEVIBE_TMPDIR}/codevibe-gemini-mcp-$$.pid"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# Set up trap for cleanup
|
|
122
|
+
trap cleanup EXIT INT TERM
|
|
123
|
+
|
|
124
|
+
# Check if tmux is installed
|
|
125
|
+
if ! command -v tmux &> /dev/null; then
|
|
126
|
+
echo "Error: tmux is required but not installed."
|
|
127
|
+
echo "Install with: brew install tmux"
|
|
128
|
+
exit 1
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# Check if gemini is installed
|
|
132
|
+
if ! command -v gemini &> /dev/null; then
|
|
133
|
+
echo "Error: gemini CLI is not installed."
|
|
134
|
+
echo "Install from: https://github.com/google-gemini/gemini-cli"
|
|
135
|
+
exit 1
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
# Check if node is installed
|
|
139
|
+
if ! command -v node &> /dev/null; then
|
|
140
|
+
echo "Error: Node.js is required but not installed."
|
|
141
|
+
exit 1
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
# Check if MCP server is built
|
|
145
|
+
if [ ! -f "$PLUGIN_DIR/dist/server.js" ]; then
|
|
146
|
+
echo "Error: MCP server not built. Run 'npm run build' in the plugin directory first."
|
|
147
|
+
exit 1
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
# Generate a unique session name
|
|
151
|
+
SESSION_NAME="${TMUX_SESSION_PREFIX}-$$"
|
|
152
|
+
WORKING_DIR="$(pwd)"
|
|
153
|
+
|
|
154
|
+
log "Starting codevibe-gemini with session: $SESSION_NAME"
|
|
155
|
+
log "Working directory: $WORKING_DIR"
|
|
156
|
+
log "Arguments: $*"
|
|
157
|
+
|
|
158
|
+
# Check if we're already inside tmux
|
|
159
|
+
if [ -n "$TMUX" ]; then
|
|
160
|
+
log "Already inside tmux, running gemini directly"
|
|
161
|
+
# Already in tmux, just run gemini
|
|
162
|
+
exec gemini "$@"
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
# Check if running in a terminal
|
|
166
|
+
if [ ! -t 0 ] || [ ! -t 1 ]; then
|
|
167
|
+
log "Not running in a terminal, running gemini directly"
|
|
168
|
+
exec gemini "$@"
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
# Start MCP server in background BEFORE launching Gemini
|
|
172
|
+
# The MCP server will watch the transcript file for changes
|
|
173
|
+
log "Starting MCP server..."
|
|
174
|
+
export GEMINI_WORKING_DIRECTORY="$WORKING_DIR"
|
|
175
|
+
export CODEVIBE_GEMINI_TMUX_SESSION="$SESSION_NAME"
|
|
176
|
+
|
|
177
|
+
# Start MCP server and capture its PID
|
|
178
|
+
node "$PLUGIN_DIR/dist/server.js" >> "$MCP_LOG_FILE" 2>&1 &
|
|
179
|
+
MCP_PID=$!
|
|
180
|
+
echo "$MCP_PID" > "${CODEVIBE_TMPDIR}/codevibe-gemini-mcp-$$.pid"
|
|
181
|
+
|
|
182
|
+
log "MCP server started with PID: $MCP_PID"
|
|
183
|
+
|
|
184
|
+
# Wait a moment for MCP server to initialize
|
|
185
|
+
sleep 1
|
|
186
|
+
|
|
187
|
+
# Check if MCP server is still running (exits if auth failed)
|
|
188
|
+
if ! kill -0 "$MCP_PID" 2>/dev/null; then
|
|
189
|
+
log "ERROR: MCP server failed to start"
|
|
190
|
+
# Show the last few lines of the log for context (e.g., auth error)
|
|
191
|
+
echo ""
|
|
192
|
+
tail -3 "$MCP_LOG_FILE" 2>/dev/null | grep -v '^\[' | head -1
|
|
193
|
+
echo ""
|
|
194
|
+
echo "Server failed to start. Check $MCP_LOG_FILE for details."
|
|
195
|
+
exit 1
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
# Create tmux session and run gemini
|
|
199
|
+
log "Creating tmux session: $SESSION_NAME"
|
|
200
|
+
|
|
201
|
+
# Build the gemini command with proper escaping
|
|
202
|
+
GEMINI_CMD="gemini"
|
|
203
|
+
for arg in "$@"; do
|
|
204
|
+
# Escape single quotes in arguments
|
|
205
|
+
escaped_arg=$(printf '%s' "$arg" | sed "s/'/'\\\\''/g")
|
|
206
|
+
GEMINI_CMD="$GEMINI_CMD '$escaped_arg'"
|
|
207
|
+
done
|
|
208
|
+
|
|
209
|
+
# Create the session running gemini, then attach
|
|
210
|
+
# We use a wrapper that:
|
|
211
|
+
# 1. Exports the session name so prompts can find it
|
|
212
|
+
# 2. Runs gemini
|
|
213
|
+
# 3. Exits the tmux session when gemini exits
|
|
214
|
+
|
|
215
|
+
tmux new-session -d -s "$SESSION_NAME" -x "$(tput cols)" -y "$(tput lines)" \
|
|
216
|
+
"export CODEVIBE_GEMINI_TMUX_SESSION='$SESSION_NAME'; export ENVIRONMENT='$ENVIRONMENT'; $GEMINI_CMD; exit"
|
|
217
|
+
|
|
218
|
+
# Enable mouse support for scrolling
|
|
219
|
+
tmux set-option -t "$SESSION_NAME" -g mouse on
|
|
220
|
+
|
|
221
|
+
# Enable copy/paste with system clipboard (macOS)
|
|
222
|
+
tmux set-option -t "$SESSION_NAME" set-clipboard on
|
|
223
|
+
tmux set-window-option -t "$SESSION_NAME" mode-keys vi
|
|
224
|
+
tmux bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"
|
|
225
|
+
tmux bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy"
|
|
226
|
+
|
|
227
|
+
# Store session mapping for mobile prompts
|
|
228
|
+
echo "$SESSION_NAME" > "${CODEVIBE_TMPDIR}/codevibe-gemini-tmux-session-$$"
|
|
229
|
+
|
|
230
|
+
log "Attaching to tmux session: $SESSION_NAME"
|
|
231
|
+
|
|
232
|
+
# Attach to the session
|
|
233
|
+
# This will show gemini's UI to the user
|
|
234
|
+
# When tmux session exits, the trap will clean up the MCP server
|
|
235
|
+
tmux attach-session -t "$SESSION_NAME"
|
|
236
|
+
|
|
237
|
+
# After tmux exits, cleanup is handled by trap
|
|
238
|
+
log "Tmux session ended"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { CreateEventInput, CreateSessionInput, UpdateSessionInput, UpdateEventStatusInput, CreateFileChangeInput, Event, Session, EventSource, DownloadUrlResponse } from './types';
|
|
2
|
+
export declare class AppSyncClient {
|
|
3
|
+
private authenticated;
|
|
4
|
+
private currentUserId;
|
|
5
|
+
private currentEmail;
|
|
6
|
+
private storedTokens;
|
|
7
|
+
private activeSubscriptions;
|
|
8
|
+
constructor();
|
|
9
|
+
getCurrentUserId(): string;
|
|
10
|
+
getCurrentUserEmail(): string | null;
|
|
11
|
+
/**
|
|
12
|
+
* Authenticate using stored OAuth tokens from 'codevibe-gemini login'
|
|
13
|
+
* Returns true if successfully authenticated, false otherwise
|
|
14
|
+
*/
|
|
15
|
+
authenticateWithStoredTokens(): Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Refresh expired tokens using the refresh token
|
|
18
|
+
*/
|
|
19
|
+
private refreshStoredTokens;
|
|
20
|
+
/**
|
|
21
|
+
* Check if stored tokens exist and are valid
|
|
22
|
+
*/
|
|
23
|
+
hasValidStoredTokens(): boolean;
|
|
24
|
+
signOutUser(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Make a direct GraphQL request to AppSync using fetch
|
|
27
|
+
* Uses stored OAuth tokens for Cognito User Pool authentication
|
|
28
|
+
* Automatically refreshes token and retries on 401 errors
|
|
29
|
+
*/
|
|
30
|
+
private graphqlRequest;
|
|
31
|
+
createSession(input: CreateSessionInput): Promise<Session>;
|
|
32
|
+
updateSession(input: UpdateSessionInput): Promise<Session>;
|
|
33
|
+
createEvent(input: CreateEventInput): Promise<Event>;
|
|
34
|
+
updateEventStatus(input: UpdateEventStatusInput): Promise<Event>;
|
|
35
|
+
createFileChange(input: CreateFileChangeInput): Promise<any>;
|
|
36
|
+
getSession(sessionId: string): Promise<Session | null>;
|
|
37
|
+
listEvents(sessionId: string, source?: EventSource): Promise<Event[]>;
|
|
38
|
+
subscribeToEvents(sessionId: string, onEvent: (event: Event) => void, onError?: (error: Error) => void): () => void;
|
|
39
|
+
/**
|
|
40
|
+
* Build the AppSync real-time WebSocket URL with authorization
|
|
41
|
+
*/
|
|
42
|
+
private buildRealtimeUrl;
|
|
43
|
+
/**
|
|
44
|
+
* Create a custom WebSocket subscription to AppSync
|
|
45
|
+
* This bypasses Amplify which doesn't work with externally stored tokens
|
|
46
|
+
*/
|
|
47
|
+
private createSubscription;
|
|
48
|
+
/**
|
|
49
|
+
* Send subscription start message
|
|
50
|
+
*/
|
|
51
|
+
private sendSubscriptionStart;
|
|
52
|
+
/**
|
|
53
|
+
* Reset the keep-alive timer - if no message received in 5 minutes, reconnect
|
|
54
|
+
*/
|
|
55
|
+
private resetKeepAliveTimer;
|
|
56
|
+
private handleSubscriptionError;
|
|
57
|
+
private cleanupSubscriptionState;
|
|
58
|
+
cleanupSubscriptions(): void;
|
|
59
|
+
getAttachmentDownloadUrl(s3Key: string): Promise<DownloadUrlResponse>;
|
|
60
|
+
listUserDeviceKeys(): Promise<Array<{
|
|
61
|
+
deviceId: string;
|
|
62
|
+
publicKey: string;
|
|
63
|
+
}>>;
|
|
64
|
+
isAuthenticated(): boolean;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=appsync-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appsync-client.d.ts","sourceRoot":"","sources":["../src/appsync-client.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,EACL,OAAO,EACP,WAAW,EAEX,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAqLjB,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,mBAAmB,CAA6C;;IAOjE,gBAAgB,IAAI,MAAM;IAK1B,mBAAmB,IAAI,MAAM,GAAG,IAAI;IAI3C;;;OAGG;IACU,4BAA4B,IAAI,OAAO,CAAC,OAAO,CAAC;IA2C7D;;OAEG;YACW,mBAAmB;IAoDjC;;OAEG;IACI,oBAAoB,IAAI,OAAO;IAM/B,WAAW,IAAI,IAAI;IAQ1B;;;;OAIG;YACW,cAAc;IAqDf,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IA8B1D,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAsB1D,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC;IA8BpD,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,KAAK,CAAC;IAuBhE,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC;IA6B5D,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IActD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAc3E,iBAAiB,CACtB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAC/B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC/B,MAAM,IAAI;IAoCb;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA+H1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA8B7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,uBAAuB;IAoE/B,OAAO,CAAC,wBAAwB;IAgCzB,oBAAoB,IAAI,IAAI;IActB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAmBrE,kBAAkB,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAqBnF,eAAe,IAAI,OAAO;CAGlC"}
|