@quantiya/codevibe-codex-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 +29 -0
- package/README.md +155 -0
- package/bin/codevibe-codex +187 -0
- package/dist/approval-detector.d.ts +38 -0
- package/dist/approval-detector.d.ts.map +1 -0
- package/dist/approval-detector.js +174 -0
- package/dist/approval-detector.js.map +1 -0
- package/dist/appsync-client.d.ts +69 -0
- package/dist/appsync-client.d.ts.map +1 -0
- package/dist/appsync-client.js +937 -0
- package/dist/appsync-client.js.map +1 -0
- package/dist/auth-cli.d.ts +11 -0
- package/dist/auth-cli.d.ts.map +1 -0
- package/dist/auth-cli.js +241 -0
- package/dist/auth-cli.js.map +1 -0
- package/dist/config.d.ts +29 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +116 -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/event-mapper.d.ts +24 -0
- package/dist/event-mapper.d.ts.map +1 -0
- package/dist/event-mapper.js +268 -0
- package/dist/event-mapper.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-parser.d.ts +3 -0
- package/dist/prompt-parser.d.ts.map +1 -0
- package/dist/prompt-parser.js +8 -0
- package/dist/prompt-parser.js.map +1 -0
- package/dist/prompt-responder.d.ts +18 -0
- package/dist/prompt-responder.d.ts.map +1 -0
- package/dist/prompt-responder.js +78 -0
- package/dist/prompt-responder.js.map +1 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1045 -0
- package/dist/server.js.map +1 -0
- package/dist/session-id-cache.d.ts +16 -0
- package/dist/session-id-cache.d.ts.map +1 -0
- package/dist/session-id-cache.js +90 -0
- package/dist/session-id-cache.js.map +1 -0
- package/dist/session-log-watcher.d.ts +61 -0
- package/dist/session-log-watcher.d.ts.map +1 -0
- package/dist/session-log-watcher.js +372 -0
- package/dist/session-log-watcher.js.map +1 -0
- package/dist/tmux-pane-observer.d.ts +39 -0
- package/dist/tmux-pane-observer.d.ts.map +1 -0
- package/dist/tmux-pane-observer.js +255 -0
- package/dist/tmux-pane-observer.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/types.d.ts +158 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -0
- package/package.json +72 -0
package/.env.example
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# CodeVibe Codex Plugin Configuration
|
|
2
|
+
# Copy this file to .env.development for local development
|
|
3
|
+
|
|
4
|
+
# AWS AppSync (production values are embedded, only override for development)
|
|
5
|
+
# APPSYNC_URL=https://your-appsync-url.appsync-api.us-east-1.amazonaws.com/graphql
|
|
6
|
+
|
|
7
|
+
# Cognito Configuration (production values are embedded, only override for development)
|
|
8
|
+
# COGNITO_USER_POOL_ID=us-east-1_xxxxx
|
|
9
|
+
# COGNITO_CLIENT_ID=xxxxx
|
|
10
|
+
# COGNITO_DOMAIN=your-domain.auth.us-east-1.amazoncognito.com
|
|
11
|
+
|
|
12
|
+
# Server Configuration
|
|
13
|
+
PORT=3458
|
|
14
|
+
HOST=localhost
|
|
15
|
+
|
|
16
|
+
# Environment: 'production' (default) or 'development'
|
|
17
|
+
# ENVIRONMENT=development
|
|
18
|
+
|
|
19
|
+
# Logging
|
|
20
|
+
LOG_LEVEL=info
|
|
21
|
+
LOG_FILE=/tmp/codevibe-codex-mcp.log
|
|
22
|
+
|
|
23
|
+
# Codex CLI Configuration
|
|
24
|
+
CODEX_COMMAND=codex
|
|
25
|
+
CODEX_TIMEOUT=60000
|
|
26
|
+
|
|
27
|
+
# Approval Detection
|
|
28
|
+
# Timeout in ms before assuming Codex is waiting for approval
|
|
29
|
+
APPROVAL_TIMEOUT_MS=5000
|
package/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# CodeVibe Codex Plugin
|
|
2
|
+
|
|
3
|
+
Mobile companion plugin for OpenAI Codex CLI. Monitor and interact with your Codex sessions from your iPhone.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This plugin enables bidirectional synchronization between Codex CLI on your Mac and the CodeVibe iOS app. See your conversations, shell commands, file edits, and agent reasoning in real-time on your phone.
|
|
8
|
+
|
|
9
|
+
**Part of the CodeVibe multi-agent ecosystem:**
|
|
10
|
+
- [Claude Plugin](https://github.com/hendryyeh/quantiya-codevibe-claude-plugin) - For Claude Code
|
|
11
|
+
- [Gemini Plugin](https://github.com/hendryyeh/quantiya-codevibe-gemini-plugin) - For Gemini CLI
|
|
12
|
+
- **Codex Plugin** (this repo) - For OpenAI Codex CLI
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g codevibe-codex-plugin
|
|
18
|
+
codevibe-codex login # authenticate with CodeVibe backend
|
|
19
|
+
codevibe-codex # start Codex with mobile sync
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
| Feature | Supported |
|
|
25
|
+
|---------|-----------|
|
|
26
|
+
| User prompts | Yes |
|
|
27
|
+
| Assistant responses | Yes |
|
|
28
|
+
| Agent reasoning/thinking | Yes |
|
|
29
|
+
| Shell commands | Yes |
|
|
30
|
+
| File edits (patches) | Yes |
|
|
31
|
+
| Tool outputs | Yes |
|
|
32
|
+
| Image attachments | Yes |
|
|
33
|
+
| Approval prompts | Yes (via tmux pane detection) |
|
|
34
|
+
| File diff preview | Yes |
|
|
35
|
+
|
|
36
|
+
### What gets synced
|
|
37
|
+
|
|
38
|
+
- **Desktop → Mobile:** user prompts, assistant responses, shell commands, tool/file edits, approval prompts, images, logs
|
|
39
|
+
- **Mobile → Desktop:** text prompts and approval responses sent from iOS app into the active Codex session (via tmux)
|
|
40
|
+
|
|
41
|
+
## Prerequisites
|
|
42
|
+
|
|
43
|
+
- macOS
|
|
44
|
+
- Node.js 18+
|
|
45
|
+
- tmux (`brew install tmux`)
|
|
46
|
+
- [Codex CLI](https://github.com/openai/codex) installed and authenticated
|
|
47
|
+
- CodeVibe iOS app
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install -g codevibe-codex-plugin
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### From Source (Development)
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git clone https://github.com/hendryyeh/quantiya-codevibe-codex-plugin.git
|
|
59
|
+
cd codevibe-codex-plugin
|
|
60
|
+
npm install
|
|
61
|
+
npm run build
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
Use `codevibe-codex` instead of `codex` to enable mobile sync:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Start Codex with mobile sync
|
|
70
|
+
codevibe-codex
|
|
71
|
+
|
|
72
|
+
# Start with an initial prompt
|
|
73
|
+
codevibe-codex "fix the bug in auth.ts"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### CLI Commands
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
codevibe-codex login # Authenticate with CodeVibe backend
|
|
80
|
+
codevibe-codex status # Check authentication status
|
|
81
|
+
codevibe-codex logout # Sign out
|
|
82
|
+
codevibe-codex # Start Codex with mobile sync
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## How It Works
|
|
86
|
+
|
|
87
|
+
1. **Session Log Watching** - Monitors `~/.codex/sessions/` for JSONL log files
|
|
88
|
+
2. **Real-time Sync** - Parses log entries and syncs to AWS AppSync backend
|
|
89
|
+
3. **Mobile Display** - iOS app receives events via WebSocket subscription
|
|
90
|
+
4. **Mobile Input** - Messages from iOS are sent to terminal via tmux
|
|
91
|
+
|
|
92
|
+
Each live Codex process appears as its own CodeVibe session, even if multiple Codex sessions are running in the same project directory.
|
|
93
|
+
|
|
94
|
+
### Data Flow
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Desktop → Mobile:
|
|
98
|
+
Codex CLI → Session JSONL → Plugin → AppSync → iOS App
|
|
99
|
+
|
|
100
|
+
Mobile → Desktop:
|
|
101
|
+
iOS App → AppSync → Plugin → tmux send-keys → Codex CLI
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Configuration
|
|
105
|
+
|
|
106
|
+
Create a `.env.development` file (see `.env.example`):
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# AWS AppSync
|
|
110
|
+
APPSYNC_URL=https://xxx.appsync-api.us-east-1.amazonaws.com/graphql
|
|
111
|
+
APPSYNC_REALTIME_URL=wss://xxx.appsync-realtime-api.us-east-1.amazonaws.com/graphql
|
|
112
|
+
|
|
113
|
+
# Cognito
|
|
114
|
+
COGNITO_USER_POOL_ID=us-east-1_xxx
|
|
115
|
+
COGNITO_CLIENT_ID=xxx
|
|
116
|
+
COGNITO_DOMAIN=xxx.auth.us-east-1.amazoncognito.com
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Troubleshooting
|
|
120
|
+
|
|
121
|
+
### Session not appearing in iOS app
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Check if session logs exist
|
|
125
|
+
ls -la ~/.codex/sessions/$(date +%Y)/$(date +%m)/$(date +%d)/
|
|
126
|
+
|
|
127
|
+
# Check plugin logs
|
|
128
|
+
tail -f /tmp/codevibe-codex-mcp.log
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Mobile prompts not working
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Verify tmux session exists
|
|
135
|
+
tmux list-sessions | grep codevibe-codex
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Known Limitations
|
|
139
|
+
|
|
140
|
+
- **Approval prompts are not in JSONL logs** - Detected via tmux pane observation instead of structured log entries
|
|
141
|
+
- **macOS only** - Requires tmux for terminal integration
|
|
142
|
+
|
|
143
|
+
## Related
|
|
144
|
+
|
|
145
|
+
- **CodeVibe iOS App** - Available on the App Store
|
|
146
|
+
- [Claude Plugin](https://github.com/hendryyeh/codevibe-claude-plugin) - For Claude Code
|
|
147
|
+
- [Gemini Plugin](https://github.com/hendryyeh/codevibe-gemini-plugin) - For Gemini CLI
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
|
|
151
|
+
MIT
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
**Maintained by:** CodeVibe Team
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# codevibe-codex - Wrapper to run Codex CLI inside tmux for mobile control
|
|
4
|
+
#
|
|
5
|
+
# This script launches Codex CLI inside a tmux session, enabling:
|
|
6
|
+
# - Mobile prompts when screen is locked (via tmux send-keys)
|
|
7
|
+
# - Same user experience as regular codex command
|
|
8
|
+
# - Automatic sync with iOS app via session log watching
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
# codevibe-codex [codex-args...]
|
|
12
|
+
# codevibe-codex login # Sign in via browser
|
|
13
|
+
# codevibe-codex logout # Sign out
|
|
14
|
+
# codevibe-codex status # Show auth status
|
|
15
|
+
#
|
|
16
|
+
# Environment:
|
|
17
|
+
# ENVIRONMENT # Set to 'production' (default) or 'development'
|
|
18
|
+
#
|
|
19
|
+
# Examples:
|
|
20
|
+
# codevibe-codex # Start new session
|
|
21
|
+
# codevibe-codex "fix the bug" # Start with prompt
|
|
22
|
+
# ENVIRONMENT=development codevibe-codex login # Login to development
|
|
23
|
+
#
|
|
24
|
+
|
|
25
|
+
set -e
|
|
26
|
+
|
|
27
|
+
# Default to production environment if not specified
|
|
28
|
+
export ENVIRONMENT="${ENVIRONMENT:-production}"
|
|
29
|
+
|
|
30
|
+
# Use TMPDIR if set (macOS sets this to user-specific temp), otherwise /tmp
|
|
31
|
+
CODEVIBE_TMPDIR="${TMPDIR:-/tmp}"
|
|
32
|
+
|
|
33
|
+
# Get the directory where this script is located (resolving symlinks)
|
|
34
|
+
# This is needed because npm global installs symlink bin scripts to /usr/local/bin/
|
|
35
|
+
SOURCE="${BASH_SOURCE[0]}"
|
|
36
|
+
while [ -L "$SOURCE" ]; do
|
|
37
|
+
DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
|
|
38
|
+
SOURCE="$(readlink "$SOURCE")"
|
|
39
|
+
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
|
|
40
|
+
done
|
|
41
|
+
SCRIPT_DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
|
|
42
|
+
PLUGIN_DIR="$(dirname "$SCRIPT_DIR")"
|
|
43
|
+
|
|
44
|
+
# Handle auth commands (login, logout, status, reset-device)
|
|
45
|
+
# Delegate to codevibe-core CLI (shared auth across all plugins)
|
|
46
|
+
case "$1" in
|
|
47
|
+
login|logout|status|reset-device)
|
|
48
|
+
CORE_CLI="$PLUGIN_DIR/node_modules/@quantiya/codevibe-core/bin/codevibe.js"
|
|
49
|
+
if [ -f "$CORE_CLI" ]; then
|
|
50
|
+
exec node "$CORE_CLI" "$1"
|
|
51
|
+
else
|
|
52
|
+
echo "Error: codevibe-core not found. Run 'npm install' in the plugin directory first."
|
|
53
|
+
exit 1
|
|
54
|
+
fi
|
|
55
|
+
;;
|
|
56
|
+
esac
|
|
57
|
+
|
|
58
|
+
# Configuration
|
|
59
|
+
TMUX_SESSION_PREFIX="codevibe-codex"
|
|
60
|
+
LOG_FILE="${CODEVIBE_TMPDIR}/codevibe-codex-wrapper.log"
|
|
61
|
+
MCP_LOG_FILE="${CODEVIBE_TMPDIR}/codevibe-codex-mcp.log"
|
|
62
|
+
|
|
63
|
+
log() {
|
|
64
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# Cleanup function to kill server when wrapper exits
|
|
68
|
+
cleanup() {
|
|
69
|
+
log "Cleanup triggered"
|
|
70
|
+
if [ -n "$SERVER_PID" ] && kill -0 "$SERVER_PID" 2>/dev/null; then
|
|
71
|
+
log "Stopping server (PID: $SERVER_PID)"
|
|
72
|
+
kill "$SERVER_PID" 2>/dev/null || true
|
|
73
|
+
wait "$SERVER_PID" 2>/dev/null || true
|
|
74
|
+
fi
|
|
75
|
+
# Remove PID file
|
|
76
|
+
rm -f "${CODEVIBE_TMPDIR}/codevibe-codex-server-$$.pid"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# Set up trap for cleanup
|
|
80
|
+
trap cleanup EXIT INT TERM
|
|
81
|
+
|
|
82
|
+
# Check if tmux is installed
|
|
83
|
+
if ! command -v tmux &> /dev/null; then
|
|
84
|
+
echo "Error: tmux is required but not installed."
|
|
85
|
+
echo "Install with: brew install tmux"
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
# Check if codex is installed
|
|
90
|
+
if ! command -v codex &> /dev/null; then
|
|
91
|
+
echo "Error: codex CLI is not installed."
|
|
92
|
+
echo "Install with: npm install -g @openai/codex"
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Check if node is installed
|
|
97
|
+
if ! command -v node &> /dev/null; then
|
|
98
|
+
echo "Error: Node.js is required but not installed."
|
|
99
|
+
exit 1
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
# Check if server is built
|
|
103
|
+
if [ ! -f "$PLUGIN_DIR/dist/server.js" ]; then
|
|
104
|
+
echo "Error: Server not built. Run 'npm run build' in the plugin directory first."
|
|
105
|
+
exit 1
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
# Generate a unique session name
|
|
109
|
+
SESSION_NAME="${TMUX_SESSION_PREFIX}-$$"
|
|
110
|
+
WORKING_DIR="$(pwd)"
|
|
111
|
+
|
|
112
|
+
log "Starting codevibe-codex with session: $SESSION_NAME"
|
|
113
|
+
log "Working directory: $WORKING_DIR"
|
|
114
|
+
log "Arguments: $*"
|
|
115
|
+
|
|
116
|
+
# Check if we're already inside tmux
|
|
117
|
+
if [ -n "$TMUX" ]; then
|
|
118
|
+
log "Already inside tmux, running codex directly"
|
|
119
|
+
exec codex "$@"
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# Check if running in a terminal
|
|
123
|
+
if [ ! -t 0 ] || [ ! -t 1 ]; then
|
|
124
|
+
log "Not running in a terminal, running codex directly"
|
|
125
|
+
exec codex "$@"
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
# Start the session log watcher server in background
|
|
129
|
+
log "Starting session log watcher server..."
|
|
130
|
+
export CODEX_WORKING_DIRECTORY="$WORKING_DIR"
|
|
131
|
+
export CODEVIBE_CODEX_TMUX_SESSION="$SESSION_NAME"
|
|
132
|
+
|
|
133
|
+
# Start server and capture its PID
|
|
134
|
+
node "$PLUGIN_DIR/dist/server.js" >> "$MCP_LOG_FILE" 2>&1 &
|
|
135
|
+
SERVER_PID=$!
|
|
136
|
+
echo "$SERVER_PID" > "${CODEVIBE_TMPDIR}/codevibe-codex-server-$$.pid"
|
|
137
|
+
|
|
138
|
+
log "Server started with PID: $SERVER_PID"
|
|
139
|
+
|
|
140
|
+
# Wait a moment for server to initialize
|
|
141
|
+
sleep 1
|
|
142
|
+
|
|
143
|
+
# Check if server is still running (exits if auth failed)
|
|
144
|
+
if ! kill -0 "$SERVER_PID" 2>/dev/null; then
|
|
145
|
+
log "ERROR: Server failed to start"
|
|
146
|
+
# Show the last few lines of the log for context (e.g., auth error)
|
|
147
|
+
echo ""
|
|
148
|
+
tail -3 "$MCP_LOG_FILE" 2>/dev/null | grep -v '^\[' | head -1
|
|
149
|
+
echo ""
|
|
150
|
+
echo "Server failed to start. Check $MCP_LOG_FILE for details."
|
|
151
|
+
exit 1
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
# Create tmux session and run codex
|
|
155
|
+
log "Creating tmux session: $SESSION_NAME"
|
|
156
|
+
|
|
157
|
+
# Build the codex command with proper escaping
|
|
158
|
+
CODEX_CMD="codex"
|
|
159
|
+
for arg in "$@"; do
|
|
160
|
+
# Escape single quotes in arguments
|
|
161
|
+
escaped_arg=$(printf '%s' "$arg" | sed "s/'/'\\\\''/g")
|
|
162
|
+
CODEX_CMD="$CODEX_CMD '$escaped_arg'"
|
|
163
|
+
done
|
|
164
|
+
|
|
165
|
+
# Create the session running codex
|
|
166
|
+
tmux new-session -d -s "$SESSION_NAME" -x "$(tput cols)" -y "$(tput lines)" \
|
|
167
|
+
"export CODEVIBE_CODEX_TMUX_SESSION='$SESSION_NAME'; export ENVIRONMENT='$ENVIRONMENT'; $CODEX_CMD; exit"
|
|
168
|
+
|
|
169
|
+
# Enable mouse support for scrolling
|
|
170
|
+
tmux set-option -t "$SESSION_NAME" -g mouse on
|
|
171
|
+
|
|
172
|
+
# Enable copy/paste with system clipboard (macOS)
|
|
173
|
+
tmux set-option -t "$SESSION_NAME" set-clipboard on
|
|
174
|
+
tmux set-window-option -t "$SESSION_NAME" mode-keys vi
|
|
175
|
+
tmux bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"
|
|
176
|
+
tmux bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy"
|
|
177
|
+
|
|
178
|
+
# Store session mapping for mobile prompts
|
|
179
|
+
echo "$SESSION_NAME" > "${CODEVIBE_TMPDIR}/codevibe-codex-tmux-session-$$"
|
|
180
|
+
|
|
181
|
+
log "Attaching to tmux session: $SESSION_NAME"
|
|
182
|
+
|
|
183
|
+
# Attach to the session
|
|
184
|
+
tmux attach-session -t "$SESSION_NAME"
|
|
185
|
+
|
|
186
|
+
# After tmux exits, cleanup is handled by trap
|
|
187
|
+
log "Tmux session ended"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { PendingToolCall } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Detects when Codex might be waiting for approval using timeout heuristic.
|
|
5
|
+
* Emits an event with contextual metadata (file path, diff, parsed input) so the
|
|
6
|
+
* mobile client can show an interactive prompt with details.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ApprovalDetector extends EventEmitter {
|
|
9
|
+
private pendingCalls;
|
|
10
|
+
private timers;
|
|
11
|
+
private timeoutMs;
|
|
12
|
+
constructor();
|
|
13
|
+
/**
|
|
14
|
+
* Called when a tool call starts.
|
|
15
|
+
*/
|
|
16
|
+
onToolCallStart(callId: string, name: string, input: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* Called when a tool call completes (output received).
|
|
19
|
+
*/
|
|
20
|
+
onToolCallComplete(callId: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Check if a call is still pending after timeout.
|
|
23
|
+
*/
|
|
24
|
+
private checkPendingCall;
|
|
25
|
+
/**
|
|
26
|
+
* Extract a user-facing hint for the pending approval.
|
|
27
|
+
*/
|
|
28
|
+
private extractHint;
|
|
29
|
+
private mapToolName;
|
|
30
|
+
private parseInput;
|
|
31
|
+
private extractFilePath;
|
|
32
|
+
private extractDiff;
|
|
33
|
+
getPendingCalls(): PendingToolCall[];
|
|
34
|
+
hasPendingCalls(): boolean;
|
|
35
|
+
clear(): void;
|
|
36
|
+
shutdown(): void;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=approval-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-detector.d.ts","sourceRoot":"","sources":["../src/approval-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,YAAY,CAA2C;IAC/D,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,SAAS,CAAS;;IAQ1B;;OAEG;IACI,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IA4BzE;;OAEG;IACI,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAY/C;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA4BxB;;OAEG;IACH,OAAO,CAAC,WAAW;IA2BnB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,WAAW;IAYZ,eAAe,IAAI,eAAe,EAAE;IAIpC,eAAe,IAAI,OAAO;IAI1B,KAAK,IAAI,IAAI;IASb,QAAQ,IAAI,IAAI;CAKxB"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApprovalDetector = void 0;
|
|
4
|
+
const events_1 = require("events");
|
|
5
|
+
const codevibe_core_1 = require("@quantiya/codevibe-core");
|
|
6
|
+
const logger_1 = require("./logger");
|
|
7
|
+
/**
|
|
8
|
+
* Detects when Codex might be waiting for approval using timeout heuristic.
|
|
9
|
+
* Emits an event with contextual metadata (file path, diff, parsed input) so the
|
|
10
|
+
* mobile client can show an interactive prompt with details.
|
|
11
|
+
*/
|
|
12
|
+
class ApprovalDetector extends events_1.EventEmitter {
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
this.pendingCalls = new Map();
|
|
16
|
+
this.timers = new Map();
|
|
17
|
+
this.timeoutMs = (0, codevibe_core_1.getConfig)().codex.approvalTimeoutMs;
|
|
18
|
+
logger_1.logger.info('Approval detector initialized', { timeoutMs: this.timeoutMs });
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Called when a tool call starts.
|
|
22
|
+
*/
|
|
23
|
+
onToolCallStart(callId, name, input) {
|
|
24
|
+
logger_1.logger.debug('Tool call started', { callId, name });
|
|
25
|
+
// Parse input for extra context (file path, diff, parsed JSON)
|
|
26
|
+
const parsedInput = this.parseInput(input);
|
|
27
|
+
const filePath = this.extractFilePath(name, input, parsedInput);
|
|
28
|
+
const diff = this.extractDiff(name, input, parsedInput);
|
|
29
|
+
const pending = {
|
|
30
|
+
callId,
|
|
31
|
+
name,
|
|
32
|
+
input,
|
|
33
|
+
filePath,
|
|
34
|
+
diff,
|
|
35
|
+
parsedInput,
|
|
36
|
+
timestamp: Date.now(),
|
|
37
|
+
notificationSent: false,
|
|
38
|
+
};
|
|
39
|
+
this.pendingCalls.set(callId, pending);
|
|
40
|
+
const timer = setTimeout(() => {
|
|
41
|
+
this.checkPendingCall(callId);
|
|
42
|
+
}, this.timeoutMs);
|
|
43
|
+
this.timers.set(callId, timer);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Called when a tool call completes (output received).
|
|
47
|
+
*/
|
|
48
|
+
onToolCallComplete(callId) {
|
|
49
|
+
logger_1.logger.debug('Tool call completed', { callId });
|
|
50
|
+
this.pendingCalls.delete(callId);
|
|
51
|
+
const timer = this.timers.get(callId);
|
|
52
|
+
if (timer) {
|
|
53
|
+
clearTimeout(timer);
|
|
54
|
+
this.timers.delete(callId);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if a call is still pending after timeout.
|
|
59
|
+
*/
|
|
60
|
+
checkPendingCall(callId) {
|
|
61
|
+
const pending = this.pendingCalls.get(callId);
|
|
62
|
+
if (!pending)
|
|
63
|
+
return;
|
|
64
|
+
if (pending.notificationSent)
|
|
65
|
+
return;
|
|
66
|
+
const elapsed = Date.now() - pending.timestamp;
|
|
67
|
+
logger_1.logger.info('Tool call still pending after timeout', {
|
|
68
|
+
callId,
|
|
69
|
+
name: pending.name,
|
|
70
|
+
elapsedMs: elapsed,
|
|
71
|
+
});
|
|
72
|
+
pending.notificationSent = true;
|
|
73
|
+
this.pendingCalls.set(callId, pending);
|
|
74
|
+
this.emit('approval-pending', {
|
|
75
|
+
callId,
|
|
76
|
+
toolName: pending.name,
|
|
77
|
+
hint: this.extractHint(pending.name, pending.input, pending.filePath),
|
|
78
|
+
filePath: pending.filePath,
|
|
79
|
+
diff: pending.diff,
|
|
80
|
+
toolInput: pending.parsedInput,
|
|
81
|
+
rawInput: pending.input,
|
|
82
|
+
elapsedMs: elapsed,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Extract a user-facing hint for the pending approval.
|
|
87
|
+
*/
|
|
88
|
+
extractHint(name, input, filePath) {
|
|
89
|
+
if (filePath) {
|
|
90
|
+
return `File: ${filePath}`;
|
|
91
|
+
}
|
|
92
|
+
if (name === 'apply_patch' && input) {
|
|
93
|
+
const match = input.match(/\*\*\* (?:Update|Add|Delete) File: (.+)/);
|
|
94
|
+
if (match) {
|
|
95
|
+
return `File: ${match[1].trim()}`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (name === 'shell_command' || name === 'shell') {
|
|
99
|
+
try {
|
|
100
|
+
const args = JSON.parse(input);
|
|
101
|
+
if (args.command) {
|
|
102
|
+
const cmd = args.command.substring(0, 50);
|
|
103
|
+
return `Command: ${cmd}${args.command.length > 50 ? '...' : ''}`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Ignore parse errors
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return `Tool: ${this.mapToolName(name)}`;
|
|
111
|
+
}
|
|
112
|
+
mapToolName(name) {
|
|
113
|
+
const mapping = {
|
|
114
|
+
shell_command: 'Bash',
|
|
115
|
+
shell: 'Bash',
|
|
116
|
+
apply_patch: 'File Edit',
|
|
117
|
+
write_file: 'Write File',
|
|
118
|
+
read_file: 'Read File',
|
|
119
|
+
};
|
|
120
|
+
return mapping[name] || name;
|
|
121
|
+
}
|
|
122
|
+
parseInput(input) {
|
|
123
|
+
if (!input)
|
|
124
|
+
return undefined;
|
|
125
|
+
try {
|
|
126
|
+
return JSON.parse(input);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
extractFilePath(name, rawInput, parsedInput) {
|
|
133
|
+
if (name === 'apply_patch' && rawInput) {
|
|
134
|
+
const match = rawInput.match(/\*\*\* (?:Update|Add|Delete) File: (.+)/);
|
|
135
|
+
if (match)
|
|
136
|
+
return match[1].trim();
|
|
137
|
+
}
|
|
138
|
+
const candidate = parsedInput?.file_path || parsedInput?.path || parsedInput?.filePath;
|
|
139
|
+
if (candidate && typeof candidate === 'string') {
|
|
140
|
+
return candidate;
|
|
141
|
+
}
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
extractDiff(name, rawInput, parsedInput) {
|
|
145
|
+
if (name === 'apply_patch' && rawInput) {
|
|
146
|
+
return rawInput;
|
|
147
|
+
}
|
|
148
|
+
if (parsedInput?.diff && typeof parsedInput.diff === 'string') {
|
|
149
|
+
return parsedInput.diff;
|
|
150
|
+
}
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
getPendingCalls() {
|
|
154
|
+
return Array.from(this.pendingCalls.values());
|
|
155
|
+
}
|
|
156
|
+
hasPendingCalls() {
|
|
157
|
+
return this.pendingCalls.size > 0;
|
|
158
|
+
}
|
|
159
|
+
clear() {
|
|
160
|
+
for (const timer of this.timers.values()) {
|
|
161
|
+
clearTimeout(timer);
|
|
162
|
+
}
|
|
163
|
+
this.timers.clear();
|
|
164
|
+
this.pendingCalls.clear();
|
|
165
|
+
logger_1.logger.debug('Approval detector cleared');
|
|
166
|
+
}
|
|
167
|
+
shutdown() {
|
|
168
|
+
this.clear();
|
|
169
|
+
this.removeAllListeners();
|
|
170
|
+
logger_1.logger.info('Approval detector shutdown');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.ApprovalDetector = ApprovalDetector;
|
|
174
|
+
//# sourceMappingURL=approval-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-detector.js","sourceRoot":"","sources":["../src/approval-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
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-codex 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
|
+
isAuthenticated(): boolean;
|
|
61
|
+
registerDeviceKey(deviceId: string, publicKey: string, platform: string, deviceName?: string): Promise<void>;
|
|
62
|
+
removeDeviceKey(deviceId: string): Promise<void>;
|
|
63
|
+
listUserDeviceKeys(): Promise<Array<{
|
|
64
|
+
deviceId: string;
|
|
65
|
+
publicKey: string;
|
|
66
|
+
}>>;
|
|
67
|
+
grantSessionKey(sessionId: string, deviceId: string, encryptedKey: string, ephemeralPublicKey: string): Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
//# 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;AA0OjB,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;IAwC1D,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;IAuI1B;;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;IAmB3E,eAAe,IAAI,OAAO;IAOpB,iBAAiB,CAC5B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAuBH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAchD,kBAAkB,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAqB7E,eAAe,CAC1B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC;CAmBjB"}
|