agent-relay 2.0.18 → 2.0.20

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.
Files changed (165) hide show
  1. package/bin/relay-pty-darwin-arm64 +0 -0
  2. package/bin/relay-pty-darwin-x64 +0 -0
  3. package/bin/relay-pty-linux-x64 +0 -0
  4. package/dist/dashboard/out/404.html +1 -1
  5. package/dist/dashboard/out/_next/static/chunks/320-a6304232cd0ee2ce.js +1 -0
  6. package/dist/dashboard/out/_next/static/chunks/631-16b905e5920f9b59.js +1 -0
  7. package/dist/dashboard/out/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +1 -0
  8. package/dist/dashboard/out/_next/static/css/{45361ce86b2847c4.css → 6892f8422896ef7a.css} +1 -1
  9. package/dist/dashboard/out/app/onboarding.html +1 -1
  10. package/dist/dashboard/out/app/onboarding.txt +1 -1
  11. package/dist/dashboard/out/app.html +1 -1
  12. package/dist/dashboard/out/app.txt +2 -2
  13. package/dist/dashboard/out/cloud/link.html +1 -1
  14. package/dist/dashboard/out/cloud/link.txt +1 -1
  15. package/dist/dashboard/out/complete-profile.html +2 -2
  16. package/dist/dashboard/out/complete-profile.txt +1 -1
  17. package/dist/dashboard/out/connect-repos.html +1 -1
  18. package/dist/dashboard/out/connect-repos.txt +1 -1
  19. package/dist/dashboard/out/history.html +1 -1
  20. package/dist/dashboard/out/history.txt +1 -1
  21. package/dist/dashboard/out/index.html +1 -1
  22. package/dist/dashboard/out/index.txt +2 -2
  23. package/dist/dashboard/out/login.html +2 -2
  24. package/dist/dashboard/out/login.txt +1 -1
  25. package/dist/dashboard/out/metrics.html +1 -1
  26. package/dist/dashboard/out/metrics.txt +1 -1
  27. package/dist/dashboard/out/pricing.html +2 -2
  28. package/dist/dashboard/out/pricing.txt +1 -1
  29. package/dist/dashboard/out/providers/setup/claude.html +1 -1
  30. package/dist/dashboard/out/providers/setup/claude.txt +1 -1
  31. package/dist/dashboard/out/providers/setup/codex.html +1 -1
  32. package/dist/dashboard/out/providers/setup/codex.txt +1 -1
  33. package/dist/dashboard/out/providers/setup/cursor.html +1 -1
  34. package/dist/dashboard/out/providers/setup/cursor.txt +1 -1
  35. package/dist/dashboard/out/providers.html +1 -1
  36. package/dist/dashboard/out/providers.txt +2 -2
  37. package/dist/dashboard/out/signup.html +2 -2
  38. package/dist/dashboard/out/signup.txt +1 -1
  39. package/package.json +23 -17
  40. package/packages/api-types/package.json +2 -2
  41. package/packages/bridge/dist/spawner.d.ts +2 -0
  42. package/packages/bridge/dist/spawner.js +75 -23
  43. package/packages/bridge/package.json +8 -8
  44. package/packages/cli-tester/README.md +277 -0
  45. package/packages/cli-tester/dist/index.d.ts +21 -0
  46. package/packages/cli-tester/dist/index.js +21 -0
  47. package/packages/cli-tester/dist/utils/credential-check.d.ts +56 -0
  48. package/packages/cli-tester/dist/utils/credential-check.js +230 -0
  49. package/packages/cli-tester/dist/utils/socket-client.d.ts +76 -0
  50. package/packages/cli-tester/dist/utils/socket-client.js +153 -0
  51. package/packages/cli-tester/docker/entrypoint.sh +58 -0
  52. package/packages/cli-tester/package.json +32 -0
  53. package/packages/cli-tester/scripts/clear-auth.sh +101 -0
  54. package/packages/cli-tester/scripts/inject-message.sh +42 -0
  55. package/packages/cli-tester/scripts/start.sh +71 -0
  56. package/packages/cli-tester/scripts/test-cli.sh +56 -0
  57. package/packages/cli-tester/scripts/test-full-spawn.sh +238 -0
  58. package/packages/cli-tester/scripts/test-registration.sh +182 -0
  59. package/packages/cli-tester/scripts/test-setup-flow.sh +202 -0
  60. package/packages/cli-tester/scripts/test-spawn.sh +140 -0
  61. package/packages/cli-tester/scripts/test-with-daemon.sh +247 -0
  62. package/packages/cli-tester/scripts/verify-auth.sh +112 -0
  63. package/packages/cloud/dist/api/cli-pty-runner.js +9 -6
  64. package/packages/cloud/package.json +6 -6
  65. package/packages/config/dist/cli-auth-config.js +75 -0
  66. package/packages/config/package.json +2 -2
  67. package/packages/continuity/package.json +1 -1
  68. package/packages/daemon/dist/cli-auth.js +5 -1
  69. package/packages/daemon/dist/router.js +4 -4
  70. package/packages/daemon/dist/server.js +38 -19
  71. package/packages/daemon/dist/spawn-manager.d.ts +4 -0
  72. package/packages/daemon/dist/spawn-manager.js +2 -0
  73. package/packages/daemon/package.json +12 -12
  74. package/packages/dashboard/dist/server.js +4 -0
  75. package/packages/dashboard/package.json +14 -14
  76. package/packages/dashboard/ui/app/providers/page.tsx +2 -2
  77. package/packages/dashboard/ui/react-components/ProviderConnectionList.tsx +23 -8
  78. package/packages/dashboard/ui/react-components/SpawnModal.tsx +16 -6
  79. package/packages/dashboard/ui/react-components/settings/WorkspaceSettingsPanel.tsx +22 -6
  80. package/packages/dashboard/ui-dist/404.html +1 -1
  81. package/packages/dashboard/ui-dist/_next/static/chunks/320-a6304232cd0ee2ce.js +1 -0
  82. package/packages/dashboard/ui-dist/_next/static/chunks/631-16b905e5920f9b59.js +1 -0
  83. package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +1 -0
  84. package/packages/dashboard/ui-dist/_next/static/css/{45361ce86b2847c4.css → 6892f8422896ef7a.css} +1 -1
  85. package/packages/dashboard/ui-dist/app/onboarding.html +1 -1
  86. package/packages/dashboard/ui-dist/app/onboarding.txt +1 -1
  87. package/packages/dashboard/ui-dist/app.html +1 -1
  88. package/packages/dashboard/ui-dist/app.txt +2 -2
  89. package/packages/dashboard/ui-dist/cloud/link.html +1 -1
  90. package/packages/dashboard/ui-dist/cloud/link.txt +1 -1
  91. package/packages/dashboard/ui-dist/complete-profile.html +2 -2
  92. package/packages/dashboard/ui-dist/complete-profile.txt +1 -1
  93. package/packages/dashboard/ui-dist/connect-repos.html +1 -1
  94. package/packages/dashboard/ui-dist/connect-repos.txt +1 -1
  95. package/packages/dashboard/ui-dist/history.html +1 -1
  96. package/packages/dashboard/ui-dist/history.txt +1 -1
  97. package/packages/dashboard/ui-dist/index.html +1 -1
  98. package/packages/dashboard/ui-dist/index.txt +2 -2
  99. package/packages/dashboard/ui-dist/login.html +2 -2
  100. package/packages/dashboard/ui-dist/login.txt +1 -1
  101. package/packages/dashboard/ui-dist/metrics.html +1 -1
  102. package/packages/dashboard/ui-dist/metrics.txt +1 -1
  103. package/packages/dashboard/ui-dist/pricing.html +2 -2
  104. package/packages/dashboard/ui-dist/pricing.txt +1 -1
  105. package/packages/dashboard/ui-dist/providers/setup/claude.html +1 -1
  106. package/packages/dashboard/ui-dist/providers/setup/claude.txt +1 -1
  107. package/packages/dashboard/ui-dist/providers/setup/codex.html +1 -1
  108. package/packages/dashboard/ui-dist/providers/setup/codex.txt +1 -1
  109. package/packages/dashboard/ui-dist/providers/setup/cursor.html +1 -1
  110. package/packages/dashboard/ui-dist/providers/setup/cursor.txt +1 -1
  111. package/packages/dashboard/ui-dist/providers.html +1 -1
  112. package/packages/dashboard/ui-dist/providers.txt +2 -2
  113. package/packages/dashboard/ui-dist/signup.html +2 -2
  114. package/packages/dashboard/ui-dist/signup.txt +1 -1
  115. package/packages/dashboard-server/dist/server.js +4 -0
  116. package/packages/dashboard-server/package.json +12 -12
  117. package/packages/hooks/package.json +4 -4
  118. package/packages/mcp/package.json +2 -2
  119. package/packages/memory/package.json +2 -2
  120. package/packages/policy/package.json +2 -2
  121. package/packages/protocol/package.json +1 -1
  122. package/packages/resiliency/package.json +1 -1
  123. package/packages/sdk/README.md +512 -58
  124. package/packages/sdk/dist/client.d.ts +135 -1
  125. package/packages/sdk/dist/client.js +338 -0
  126. package/packages/sdk/dist/index.d.ts +2 -1
  127. package/packages/sdk/dist/index.js +2 -0
  128. package/packages/sdk/dist/logs.d.ts +61 -0
  129. package/packages/sdk/dist/logs.js +95 -0
  130. package/packages/sdk/dist/protocol/index.d.ts +1 -1
  131. package/packages/sdk/dist/protocol/types.d.ts +186 -1
  132. package/packages/sdk/package.json +3 -3
  133. package/packages/spawner/package.json +2 -2
  134. package/packages/state/package.json +1 -1
  135. package/packages/storage/dist/sqlite-adapter.js +2 -0
  136. package/packages/storage/package.json +2 -2
  137. package/packages/telemetry/package.json +1 -1
  138. package/packages/trajectory/package.json +2 -2
  139. package/packages/user-directory/package.json +2 -2
  140. package/packages/utils/package.json +1 -1
  141. package/packages/wrapper/dist/base-wrapper.js +27 -10
  142. package/packages/wrapper/dist/idle-detector.d.ts +4 -0
  143. package/packages/wrapper/dist/idle-detector.js +21 -8
  144. package/packages/wrapper/dist/relay-pty-orchestrator.d.ts +5 -0
  145. package/packages/wrapper/dist/relay-pty-orchestrator.js +60 -5
  146. package/packages/wrapper/dist/tmux-wrapper.js +16 -0
  147. package/packages/wrapper/package.json +7 -7
  148. package/scripts/hooks/install.sh +16 -0
  149. package/scripts/hooks/pre-commit +60 -0
  150. package/scripts/postinstall.js +41 -1
  151. package/specs/PRIMITIVES_ROADMAP.md +2154 -0
  152. package/dist/dashboard/out/_next/static/chunks/320-402ffc8646b31da1.js +0 -1
  153. package/dist/dashboard/out/_next/static/chunks/631-af51bad94027527a.js +0 -1
  154. package/dist/dashboard/out/_next/static/chunks/app/providers/page-bcf46064ac4474ce.js +0 -1
  155. package/packages/dashboard/ui-dist/_next/static/chunks/320-402ffc8646b31da1.js +0 -1
  156. package/packages/dashboard/ui-dist/_next/static/chunks/631-af51bad94027527a.js +0 -1
  157. package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/page-bcf46064ac4474ce.js +0 -1
  158. /package/dist/dashboard/out/_next/static/{JIjqkuDKNeoSg7KaMMuhx → PwtT8u1tFMW_S1HUv0i5S}/_buildManifest.js +0 -0
  159. /package/dist/dashboard/out/_next/static/{JIjqkuDKNeoSg7KaMMuhx → PwtT8u1tFMW_S1HUv0i5S}/_ssgManifest.js +0 -0
  160. /package/packages/dashboard/ui-dist/_next/static/{JIjqkuDKNeoSg7KaMMuhx → 52xh7eSCZzG97BVf5zzLY}/_buildManifest.js +0 -0
  161. /package/packages/dashboard/ui-dist/_next/static/{JIjqkuDKNeoSg7KaMMuhx → 52xh7eSCZzG97BVf5zzLY}/_ssgManifest.js +0 -0
  162. /package/packages/dashboard/ui-dist/_next/static/{nmkOi7bqeDmLMoWBih8lz → NN1eZ4W4r5XU6mkmJWV2-}/_buildManifest.js +0 -0
  163. /package/packages/dashboard/ui-dist/_next/static/{nmkOi7bqeDmLMoWBih8lz → NN1eZ4W4r5XU6mkmJWV2-}/_ssgManifest.js +0 -0
  164. /package/packages/dashboard/ui-dist/_next/static/{wk_gKRNSPpWE-ZhGL6UMl → PwtT8u1tFMW_S1HUv0i5S}/_buildManifest.js +0 -0
  165. /package/packages/dashboard/ui-dist/_next/static/{wk_gKRNSPpWE-ZhGL6UMl → PwtT8u1tFMW_S1HUv0i5S}/_ssgManifest.js +0 -0
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Socket client for communicating with relay-pty Unix socket
3
+ * Used for programmatic message injection and status queries
4
+ */
5
+ import { createConnection } from 'node:net';
6
+ export class RelayPtyClient {
7
+ socket = null;
8
+ socketPath;
9
+ responseBuffer = '';
10
+ constructor(socketPath) {
11
+ this.socketPath = socketPath;
12
+ }
13
+ /**
14
+ * Connect to the relay-pty socket
15
+ */
16
+ async connect() {
17
+ return new Promise((resolve, reject) => {
18
+ this.socket = createConnection(this.socketPath, () => {
19
+ resolve();
20
+ });
21
+ this.socket.on('error', (err) => {
22
+ reject(new Error(`Failed to connect to ${this.socketPath}: ${err.message}`));
23
+ });
24
+ this.socket.on('data', (data) => {
25
+ this.responseBuffer += data.toString();
26
+ });
27
+ });
28
+ }
29
+ /**
30
+ * Send a request and wait for response
31
+ */
32
+ async sendRequest(request) {
33
+ if (!this.socket) {
34
+ throw new Error('Not connected. Call connect() first.');
35
+ }
36
+ return new Promise((resolve, reject) => {
37
+ const timeout = setTimeout(() => {
38
+ reject(new Error('Request timed out'));
39
+ }, 10000);
40
+ // Clear buffer before sending
41
+ this.responseBuffer = '';
42
+ // Set up response handler
43
+ const checkResponse = () => {
44
+ const lines = this.responseBuffer.split('\n');
45
+ for (const line of lines) {
46
+ if (line.trim()) {
47
+ try {
48
+ const response = JSON.parse(line);
49
+ clearTimeout(timeout);
50
+ resolve(response);
51
+ return;
52
+ }
53
+ catch {
54
+ // Not valid JSON yet, keep waiting
55
+ }
56
+ }
57
+ }
58
+ // Keep checking
59
+ setTimeout(checkResponse, 50);
60
+ };
61
+ // Send request
62
+ const requestStr = JSON.stringify(request) + '\n';
63
+ this.socket.write(requestStr, (err) => {
64
+ if (err) {
65
+ clearTimeout(timeout);
66
+ reject(err);
67
+ }
68
+ else {
69
+ checkResponse();
70
+ }
71
+ });
72
+ });
73
+ }
74
+ /**
75
+ * Inject a message into the CLI
76
+ */
77
+ async inject(message) {
78
+ const request = {
79
+ type: 'inject',
80
+ id: `ts-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
81
+ from: message.from,
82
+ body: message.body,
83
+ priority: message.priority ?? 0,
84
+ };
85
+ return this.sendRequest(request);
86
+ }
87
+ /**
88
+ * Get current status of the CLI session
89
+ */
90
+ async getStatus() {
91
+ const request = { type: 'status' };
92
+ return this.sendRequest(request);
93
+ }
94
+ /**
95
+ * Wait for a specific message to be delivered
96
+ * Returns when the message reaches 'delivered' or 'failed' status
97
+ */
98
+ async waitForDelivered(messageId, timeoutMs = 30000) {
99
+ const startTime = Date.now();
100
+ return new Promise((resolve, reject) => {
101
+ const checkBuffer = () => {
102
+ if (Date.now() - startTime > timeoutMs) {
103
+ reject(new Error(`Timeout waiting for message ${messageId} to be delivered`));
104
+ return;
105
+ }
106
+ const lines = this.responseBuffer.split('\n');
107
+ for (const line of lines) {
108
+ if (line.trim()) {
109
+ try {
110
+ const response = JSON.parse(line);
111
+ if (response.type === 'inject_result' &&
112
+ response.id === messageId &&
113
+ (response.status === 'delivered' || response.status === 'failed')) {
114
+ resolve(response);
115
+ return;
116
+ }
117
+ }
118
+ catch {
119
+ // Not valid JSON, skip
120
+ }
121
+ }
122
+ }
123
+ // Keep checking
124
+ setTimeout(checkBuffer, 100);
125
+ };
126
+ checkBuffer();
127
+ });
128
+ }
129
+ /**
130
+ * Close the connection
131
+ */
132
+ close() {
133
+ if (this.socket) {
134
+ this.socket.destroy();
135
+ this.socket = null;
136
+ }
137
+ }
138
+ }
139
+ /**
140
+ * Helper to create a connected client
141
+ */
142
+ export async function createClient(socketPath) {
143
+ const client = new RelayPtyClient(socketPath);
144
+ await client.connect();
145
+ return client;
146
+ }
147
+ /**
148
+ * Get socket path for a named session
149
+ */
150
+ export function getSocketPath(sessionName) {
151
+ return `/tmp/relay-pty-${sessionName}.sock`;
152
+ }
153
+ //# sourceMappingURL=socket-client.js.map
@@ -0,0 +1,58 @@
1
+ #!/bin/bash
2
+ # CLI Tester Container Entrypoint
3
+ # Simplified entrypoint for CLI authentication testing
4
+
5
+ set -e
6
+
7
+ # Ensure config directories exist with correct permissions
8
+ mkdir -p ~/.claude ~/.codex ~/.gemini ~/.cursor ~/.config ~/.local/share/opencode 2>/dev/null || true
9
+
10
+ echo "========================================"
11
+ echo " CLI Auth Tester Environment"
12
+ echo "========================================"
13
+ echo ""
14
+
15
+ # Show available CLIs
16
+ echo "Available CLI tools:"
17
+ for cli in claude codex gemini opencode droid copilot; do
18
+ if command -v $cli &> /dev/null; then
19
+ version=$($cli --version 2>/dev/null | head -n1 || echo "installed")
20
+ echo " ✓ $cli ($version)"
21
+ else
22
+ echo " ✗ $cli (not installed)"
23
+ fi
24
+ done
25
+ # Cursor installs as 'agent'
26
+ if command -v agent &> /dev/null; then
27
+ version=$(agent --version 2>/dev/null | head -n1 || echo "installed")
28
+ echo " ✓ cursor/agent ($version)"
29
+ else
30
+ echo " ✗ cursor/agent (not installed)"
31
+ fi
32
+ echo ""
33
+
34
+ # Show relay-pty status
35
+ if command -v relay-pty &> /dev/null; then
36
+ echo "relay-pty: ✓ available"
37
+ else
38
+ echo "relay-pty: ✗ not found"
39
+ fi
40
+ echo ""
41
+
42
+ # Show usage
43
+ echo "Quick Start:"
44
+ echo " test-cli.sh claude # Test Claude CLI with relay-pty"
45
+ echo " test-cli.sh codex # Test Codex CLI with relay-pty"
46
+ echo " verify-auth.sh claude # Check if credentials exist"
47
+ echo " clear-auth.sh claude # Clear credentials for fresh test"
48
+ echo ""
49
+ echo "For debugging:"
50
+ echo " DEBUG=1 test-cli.sh cursor # Verbose output"
51
+ echo ""
52
+
53
+ # Execute the provided command or drop into shell
54
+ if [ $# -gt 0 ]; then
55
+ exec "$@"
56
+ else
57
+ exec /bin/bash
58
+ fi
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@agent-relay/cli-tester",
3
+ "version": "2.0.20",
4
+ "description": "Manual interactive testing for CLI authentication flows",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "start": "./scripts/start.sh",
11
+ "start:clean": "./scripts/start.sh --clean",
12
+ "start:daemon": "./scripts/start.sh --daemon",
13
+ "docker:build": "docker compose -f docker/docker-compose.yml build",
14
+ "docker:up": "docker compose -f docker/docker-compose.yml up",
15
+ "docker:up:daemon": "docker compose -f docker/docker-compose.yml --profile daemon up",
16
+ "docker:down": "docker compose -f docker/docker-compose.yml down",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest"
19
+ },
20
+ "keywords": [
21
+ "cli",
22
+ "testing",
23
+ "authentication",
24
+ "relay-pty"
25
+ ],
26
+ "author": "Agent Workforce",
27
+ "license": "Apache-2.0",
28
+ "devDependencies": {
29
+ "typescript": "^5.3.3",
30
+ "vitest": "^1.2.0"
31
+ }
32
+ }
@@ -0,0 +1,101 @@
1
+ #!/bin/bash
2
+ # Clear CLI credentials for fresh testing
3
+ # Usage: ./clear-auth.sh <cli|all>
4
+ # Example: ./clear-auth.sh claude
5
+ # ./clear-auth.sh all
6
+
7
+ CLI=${1:-}
8
+
9
+ if [ -z "$CLI" ]; then
10
+ echo "Usage: ./clear-auth.sh <cli|all>"
11
+ echo ""
12
+ echo "Options:"
13
+ echo " claude - Clear Claude credentials"
14
+ echo " codex - Clear Codex credentials"
15
+ echo " gemini - Clear Gemini credentials"
16
+ echo " cursor - Clear Cursor credentials"
17
+ echo " opencode - Clear OpenCode credentials"
18
+ echo " droid - Clear Droid credentials"
19
+ echo " copilot - Clear GitHub Copilot credentials"
20
+ echo " all - Clear all credentials"
21
+ exit 1
22
+ fi
23
+
24
+ clear_cli() {
25
+ local cli=$1
26
+ local dir=""
27
+ local files=()
28
+
29
+ case $cli in
30
+ claude)
31
+ dir="$HOME/.claude"
32
+ files=(".credentials.json" "settings.json" "settings.local.json")
33
+ ;;
34
+ codex)
35
+ dir="$HOME/.codex"
36
+ files=("auth.json" "config.json" "config.toml")
37
+ ;;
38
+ gemini)
39
+ dir="$HOME/.gemini"
40
+ files=("credentials.json" "settings.json")
41
+ # Also check gcloud location
42
+ if [ -f "$HOME/.config/gcloud/application_default_credentials.json" ]; then
43
+ echo " Removing: $HOME/.config/gcloud/application_default_credentials.json"
44
+ rm -f "$HOME/.config/gcloud/application_default_credentials.json"
45
+ fi
46
+ ;;
47
+ cursor|agent)
48
+ # Cursor CLI installs as 'agent', credentials in ~/.cursor/
49
+ dir="$HOME/.cursor"
50
+ files=("auth.json" "settings.json")
51
+ ;;
52
+ opencode)
53
+ dir="$HOME/.local/share/opencode"
54
+ files=("auth.json")
55
+ ;;
56
+ droid)
57
+ dir="$HOME/.droid"
58
+ files=("auth.json")
59
+ ;;
60
+ copilot)
61
+ # GitHub Copilot uses gh CLI auth - stored in ~/.config/gh/
62
+ dir="$HOME/.config/gh"
63
+ files=("hosts.yml" "config.yml")
64
+ ;;
65
+ *)
66
+ echo "Unknown CLI: $cli"
67
+ return 1
68
+ ;;
69
+ esac
70
+
71
+ echo "Clearing credentials for: $cli"
72
+
73
+ if [ -d "$dir" ]; then
74
+ for file in "${files[@]}"; do
75
+ if [ -f "$dir/$file" ]; then
76
+ echo " Removing: $dir/$file"
77
+ rm -f "$dir/$file"
78
+ fi
79
+ done
80
+ echo " ✓ Done"
81
+ else
82
+ echo " (no config directory found)"
83
+ fi
84
+ }
85
+
86
+ echo "========================================"
87
+ echo " Clearing CLI Credentials"
88
+ echo "========================================"
89
+ echo ""
90
+
91
+ if [ "$CLI" = "all" ]; then
92
+ for c in claude codex gemini cursor opencode droid copilot; do
93
+ clear_cli "$c"
94
+ echo ""
95
+ done
96
+ else
97
+ clear_cli "$CLI"
98
+ fi
99
+
100
+ echo ""
101
+ echo "Credentials cleared. Run test-cli.sh to test fresh authentication."
@@ -0,0 +1,42 @@
1
+ #!/bin/bash
2
+ # Send a message to a CLI via relay-pty socket
3
+ # Usage: ./inject-message.sh <session-name> <message>
4
+ # Example: ./inject-message.sh test-claude "What is 2+2?"
5
+
6
+ NAME=${1:-test-claude}
7
+ MESSAGE=${2:-"Test message from inject script"}
8
+ SOCKET="/tmp/relay-pty-${NAME}.sock"
9
+
10
+ if [ ! -S "$SOCKET" ]; then
11
+ echo "Error: Socket not found: $SOCKET"
12
+ echo ""
13
+ echo "Make sure relay-pty is running with --name ${NAME}"
14
+ echo "Run: test-cli.sh ${NAME#test-}"
15
+ exit 1
16
+ fi
17
+
18
+ # Generate unique message ID
19
+ MSG_ID="manual-$(date +%s)-$RANDOM"
20
+
21
+ echo "Sending message to $NAME..."
22
+ echo " Socket: $SOCKET"
23
+ echo " Message ID: $MSG_ID"
24
+ echo " Body: $MESSAGE"
25
+ echo ""
26
+
27
+ # Build JSON request
28
+ REQUEST=$(cat <<EOF
29
+ {"type":"inject","id":"$MSG_ID","from":"Tester","body":"$MESSAGE","priority":0}
30
+ EOF
31
+ )
32
+
33
+ # Send request and read response
34
+ # nc -U connects to Unix socket, -q 1 waits 1 second for response
35
+ echo "$REQUEST" | nc -U "$SOCKET" -q 2 | while read -r line; do
36
+ if [ -n "$line" ]; then
37
+ echo "Response: $line" | jq '.' 2>/dev/null || echo "Response: $line"
38
+ fi
39
+ done
40
+
41
+ echo ""
42
+ echo "Message sent. Check the CLI session to see if it was delivered."
@@ -0,0 +1,71 @@
1
+ #!/bin/bash
2
+ # Start the CLI tester Docker environment
3
+ # Usage: ./start.sh [--clean] [--build] [--daemon]
4
+
5
+ set -e
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ PACKAGE_DIR="$(dirname "$SCRIPT_DIR")"
9
+ DOCKER_DIR="$PACKAGE_DIR/docker"
10
+
11
+ # Parse arguments
12
+ CLEAN=false
13
+ BUILD=false
14
+ WITH_DAEMON=false
15
+ while [[ $# -gt 0 ]]; do
16
+ case $1 in
17
+ --clean)
18
+ CLEAN=true
19
+ shift
20
+ ;;
21
+ --build)
22
+ BUILD=true
23
+ shift
24
+ ;;
25
+ --daemon)
26
+ WITH_DAEMON=true
27
+ shift
28
+ ;;
29
+ *)
30
+ echo "Unknown option: $1"
31
+ echo "Usage: ./start.sh [--clean] [--build] [--daemon]"
32
+ echo " --clean Remove credential volumes before starting"
33
+ echo " --build Force rebuild of Docker image"
34
+ echo " --daemon Start with relay daemon for full integration testing"
35
+ exit 1
36
+ ;;
37
+ esac
38
+ done
39
+
40
+ cd "$DOCKER_DIR"
41
+
42
+ # Clean volumes if requested
43
+ if [ "$CLEAN" = true ]; then
44
+ echo "Removing credential volumes..."
45
+ docker compose down -v 2>/dev/null || true
46
+ fi
47
+
48
+ # Build compose args
49
+ COMPOSE_ARGS=()
50
+ if [ "$WITH_DAEMON" = true ]; then
51
+ COMPOSE_ARGS+=(--profile daemon)
52
+ fi
53
+
54
+ # Build if requested or if image doesn't exist
55
+ if [ "$BUILD" = true ]; then
56
+ echo "Building Docker image..."
57
+ docker compose "${COMPOSE_ARGS[@]}" build
58
+ fi
59
+
60
+ # Start the container interactively
61
+ echo ""
62
+ if [ "$WITH_DAEMON" = true ]; then
63
+ echo "Starting CLI tester environment with daemon..."
64
+ echo "The daemon will be available at http://daemon:3377"
65
+ else
66
+ echo "Starting CLI tester environment..."
67
+ fi
68
+ echo "Use Ctrl+D or 'exit' to leave the container."
69
+ echo ""
70
+
71
+ docker compose "${COMPOSE_ARGS[@]}" run --rm cli-tester
@@ -0,0 +1,56 @@
1
+ #!/bin/bash
2
+ # Test a specific CLI with relay-pty
3
+ # Usage: ./test-cli.sh <cli> [extra-args...]
4
+ # Example: ./test-cli.sh claude
5
+ # ./test-cli.sh codex --device-auth
6
+ # DEBUG=1 ./test-cli.sh cursor
7
+
8
+ set -e
9
+
10
+ CLI=${1:-claude}
11
+ shift 2>/dev/null || true # Shift to get extra args, ignore if no more args
12
+
13
+ # Map CLI name to actual command (cursor installs as 'agent')
14
+ CLI_CMD="$CLI"
15
+ if [ "$CLI" = "cursor" ]; then
16
+ CLI_CMD="agent"
17
+ fi
18
+
19
+ NAME="test-${CLI}"
20
+ SOCKET="/tmp/relay-pty-${NAME}.sock"
21
+
22
+ # Remove stale socket if exists
23
+ rm -f "$SOCKET"
24
+
25
+ echo "========================================"
26
+ echo " Testing: $CLI"
27
+ echo "========================================"
28
+ echo ""
29
+ echo "Session name: $NAME"
30
+ echo "Socket path: $SOCKET"
31
+ echo ""
32
+ echo "After authenticating, open another terminal and run:"
33
+ echo " verify-auth.sh $CLI"
34
+ echo " inject-message.sh $NAME 'Hello world'"
35
+ echo ""
36
+ echo "Press Ctrl+C to stop the session."
37
+ echo "========================================"
38
+ echo ""
39
+
40
+ # Build relay-pty args
41
+ RELAY_ARGS=(
42
+ --name "$NAME"
43
+ --socket "$SOCKET"
44
+ --idle-timeout 500
45
+ )
46
+
47
+ # Add debug output if DEBUG is set
48
+ if [ -n "$DEBUG" ]; then
49
+ RELAY_ARGS+=(--json-output)
50
+ echo "[DEBUG] JSON output enabled - relay commands will be printed to stderr"
51
+ echo ""
52
+ fi
53
+
54
+ # Run relay-pty with the CLI
55
+ # Pass through any extra arguments to the CLI
56
+ exec relay-pty "${RELAY_ARGS[@]}" -- "$CLI_CMD" "$@"