agent-relay 2.3.2 → 2.3.5
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/README.md +1 -1
- package/dist/index.cjs +1 -1
- package/dist/src/cli/index.js +124 -7
- package/dist/src/cli/index.js.map +1 -1
- package/package.json +20 -26
- package/packages/acp-bridge/package.json +2 -2
- package/packages/bridge/package.json +7 -7
- package/packages/config/dist/cloud-config.d.ts +1 -1
- package/packages/config/dist/cloud-config.d.ts.map +1 -1
- package/packages/config/dist/cloud-config.js.map +1 -1
- package/packages/config/dist/schemas.d.ts +5 -5
- package/packages/config/dist/schemas.js +1 -1
- package/packages/config/dist/schemas.js.map +1 -1
- package/packages/config/package.json +2 -2
- package/packages/config/src/cloud-config.ts +2 -2
- package/packages/config/src/schemas.test.ts +48 -0
- package/packages/config/src/schemas.ts +1 -1
- package/packages/continuity/package.json +2 -2
- package/packages/daemon/package.json +12 -12
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/package.json +5 -5
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/package.json +1 -1
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/dist/index.d.ts +1 -29
- package/packages/sdk/dist/index.d.ts.map +1 -1
- package/packages/sdk/dist/index.js +1 -38
- package/packages/sdk/dist/index.js.map +1 -1
- package/packages/sdk/package.json +4 -25
- package/packages/sdk/src/index.ts +1 -69
- package/packages/sdk-py/README.md +56 -0
- package/packages/sdk-py/pyproject.toml +23 -0
- package/packages/sdk-py/src/agent_relay/__init__.py +27 -0
- package/packages/sdk-py/src/agent_relay/builder.py +367 -0
- package/packages/sdk-py/src/agent_relay/types.py +92 -0
- package/packages/sdk-py/tests/__init__.py +0 -0
- package/packages/sdk-py/tests/test_builder.py +101 -0
- package/packages/sdk-ts/dist/__tests__/facade.test.d.ts +2 -0
- package/packages/sdk-ts/dist/__tests__/facade.test.d.ts.map +1 -0
- package/packages/sdk-ts/dist/__tests__/facade.test.js +257 -0
- package/packages/sdk-ts/dist/__tests__/facade.test.js.map +1 -0
- package/packages/sdk-ts/dist/__tests__/unit.test.d.ts +2 -0
- package/packages/sdk-ts/dist/__tests__/unit.test.d.ts.map +1 -0
- package/packages/sdk-ts/dist/__tests__/unit.test.js +124 -0
- package/packages/sdk-ts/dist/__tests__/unit.test.js.map +1 -0
- package/packages/sdk-ts/dist/client.d.ts +2 -0
- package/packages/sdk-ts/dist/client.d.ts.map +1 -1
- package/packages/sdk-ts/dist/client.js +2 -0
- package/packages/sdk-ts/dist/client.js.map +1 -1
- package/packages/sdk-ts/dist/index.d.ts +1 -0
- package/packages/sdk-ts/dist/index.d.ts.map +1 -1
- package/packages/sdk-ts/dist/index.js +1 -0
- package/packages/sdk-ts/dist/index.js.map +1 -1
- package/packages/sdk-ts/dist/protocol.d.ts +1 -0
- package/packages/sdk-ts/dist/protocol.d.ts.map +1 -1
- package/packages/sdk-ts/dist/relay.d.ts +44 -0
- package/packages/sdk-ts/dist/relay.d.ts.map +1 -1
- package/packages/sdk-ts/dist/relay.js +89 -11
- package/packages/sdk-ts/dist/relay.js.map +1 -1
- package/packages/sdk-ts/dist/relaycast.js +2 -2
- package/packages/sdk-ts/dist/relaycast.js.map +1 -1
- package/packages/sdk-ts/dist/workflows/barrier.d.ts +72 -0
- package/packages/sdk-ts/dist/workflows/barrier.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/barrier.js +162 -0
- package/packages/sdk-ts/dist/workflows/barrier.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/builder.d.ts +101 -0
- package/packages/sdk-ts/dist/workflows/builder.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/builder.js +179 -0
- package/packages/sdk-ts/dist/workflows/builder.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/cli.d.ts +10 -0
- package/packages/sdk-ts/dist/workflows/cli.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/cli.js +82 -0
- package/packages/sdk-ts/dist/workflows/cli.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/coordinator.d.ts +68 -0
- package/packages/sdk-ts/dist/workflows/coordinator.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/coordinator.js +353 -0
- package/packages/sdk-ts/dist/workflows/coordinator.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/index.d.ts +10 -0
- package/packages/sdk-ts/dist/workflows/index.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/index.js +10 -0
- package/packages/sdk-ts/dist/workflows/index.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/memory-db.d.ts +17 -0
- package/packages/sdk-ts/dist/workflows/memory-db.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/memory-db.js +33 -0
- package/packages/sdk-ts/dist/workflows/memory-db.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/run.d.ts +31 -0
- package/packages/sdk-ts/dist/workflows/run.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/run.js +24 -0
- package/packages/sdk-ts/dist/workflows/run.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/runner.d.ts +119 -0
- package/packages/sdk-ts/dist/workflows/runner.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/runner.js +650 -0
- package/packages/sdk-ts/dist/workflows/runner.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/state.d.ts +77 -0
- package/packages/sdk-ts/dist/workflows/state.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/state.js +140 -0
- package/packages/sdk-ts/dist/workflows/state.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/templates.d.ts +47 -0
- package/packages/sdk-ts/dist/workflows/templates.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/templates.js +395 -0
- package/packages/sdk-ts/dist/workflows/templates.js.map +1 -0
- package/packages/sdk-ts/dist/workflows/types.d.ts +126 -0
- package/packages/sdk-ts/dist/workflows/types.d.ts.map +1 -0
- package/packages/sdk-ts/dist/workflows/types.js +8 -0
- package/packages/sdk-ts/dist/workflows/types.js.map +1 -0
- package/packages/sdk-ts/package.json +9 -3
- package/packages/sdk-ts/src/__tests__/error-scenarios.test.ts +682 -0
- package/packages/sdk-ts/src/__tests__/facade.test.ts +296 -0
- package/packages/sdk-ts/src/__tests__/swarm-coordinator.test.ts +416 -0
- package/packages/sdk-ts/src/__tests__/unit.test.ts +152 -0
- package/packages/sdk-ts/src/__tests__/workflow-runner.test.ts +333 -0
- package/packages/sdk-ts/src/client.ts +4 -0
- package/packages/sdk-ts/src/index.ts +1 -0
- package/packages/sdk-ts/src/protocol.ts +1 -1
- package/packages/sdk-ts/src/relay.ts +112 -11
- package/packages/sdk-ts/src/relaycast.ts +2 -2
- package/packages/sdk-ts/src/workflows/README.md +450 -0
- package/packages/sdk-ts/src/workflows/barrier.ts +254 -0
- package/packages/sdk-ts/src/workflows/builder.ts +241 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/bug-fix.yaml +75 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/code-review.yaml +82 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/documentation.yaml +70 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/feature-dev.yaml +76 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/refactor.yaml +82 -0
- package/packages/sdk-ts/src/workflows/builtin-templates/security-audit.yaml +84 -0
- package/packages/sdk-ts/src/workflows/cli.ts +93 -0
- package/packages/sdk-ts/src/workflows/coordinator.ts +520 -0
- package/packages/sdk-ts/src/workflows/index.ts +9 -0
- package/packages/sdk-ts/src/workflows/memory-db.ts +39 -0
- package/packages/sdk-ts/src/workflows/run.ts +47 -0
- package/packages/sdk-ts/src/workflows/runner.ts +873 -0
- package/packages/sdk-ts/src/workflows/schema.json +321 -0
- package/packages/sdk-ts/src/workflows/state.ts +279 -0
- package/packages/sdk-ts/src/workflows/templates.ts +544 -0
- package/packages/sdk-ts/src/workflows/types.ts +178 -0
- package/packages/sdk-ts/tsconfig.json +6 -1
- package/packages/spawner/package.json +1 -1
- package/packages/state/package.json +1 -1
- package/packages/storage/package.json +2 -2
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/package.json +3 -3
- package/packages/wrapper/package.json +5 -6
- package/scripts/postinstall.js +106 -2
- package/packages/api-types/.trajectories/active/traj_xbsvuzogscey.json +0 -15
- package/packages/api-types/.trajectories/index.json +0 -12
- package/packages/api-types/dist/index.d.ts +0 -21
- package/packages/api-types/dist/index.d.ts.map +0 -1
- package/packages/api-types/dist/index.js +0 -22
- package/packages/api-types/dist/index.js.map +0 -1
- package/packages/api-types/dist/schemas/agent.d.ts +0 -259
- package/packages/api-types/dist/schemas/agent.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/agent.js +0 -102
- package/packages/api-types/dist/schemas/agent.js.map +0 -1
- package/packages/api-types/dist/schemas/api.d.ts +0 -290
- package/packages/api-types/dist/schemas/api.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/api.js +0 -162
- package/packages/api-types/dist/schemas/api.js.map +0 -1
- package/packages/api-types/dist/schemas/decision.d.ts +0 -230
- package/packages/api-types/dist/schemas/decision.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/decision.js +0 -104
- package/packages/api-types/dist/schemas/decision.js.map +0 -1
- package/packages/api-types/dist/schemas/fleet.d.ts +0 -615
- package/packages/api-types/dist/schemas/fleet.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/fleet.js +0 -71
- package/packages/api-types/dist/schemas/fleet.js.map +0 -1
- package/packages/api-types/dist/schemas/history.d.ts +0 -180
- package/packages/api-types/dist/schemas/history.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/history.js +0 -72
- package/packages/api-types/dist/schemas/history.js.map +0 -1
- package/packages/api-types/dist/schemas/index.d.ts +0 -14
- package/packages/api-types/dist/schemas/index.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/index.js +0 -22
- package/packages/api-types/dist/schemas/index.js.map +0 -1
- package/packages/api-types/dist/schemas/message.d.ts +0 -456
- package/packages/api-types/dist/schemas/message.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/message.js +0 -88
- package/packages/api-types/dist/schemas/message.js.map +0 -1
- package/packages/api-types/dist/schemas/session.d.ts +0 -60
- package/packages/api-types/dist/schemas/session.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/session.js +0 -36
- package/packages/api-types/dist/schemas/session.js.map +0 -1
- package/packages/api-types/dist/schemas/task.d.ts +0 -111
- package/packages/api-types/dist/schemas/task.d.ts.map +0 -1
- package/packages/api-types/dist/schemas/task.js +0 -64
- package/packages/api-types/dist/schemas/task.js.map +0 -1
- package/packages/api-types/package.json +0 -61
- package/packages/api-types/scripts/generate-openapi.ts +0 -106
- package/packages/api-types/src/index.ts +0 -22
- package/packages/api-types/src/schemas/agent.test.ts +0 -164
- package/packages/api-types/src/schemas/agent.ts +0 -110
- package/packages/api-types/src/schemas/api.test.ts +0 -372
- package/packages/api-types/src/schemas/api.ts +0 -194
- package/packages/api-types/src/schemas/decision.test.ts +0 -324
- package/packages/api-types/src/schemas/decision.ts +0 -136
- package/packages/api-types/src/schemas/fleet.test.ts +0 -212
- package/packages/api-types/src/schemas/fleet.ts +0 -83
- package/packages/api-types/src/schemas/history.test.ts +0 -242
- package/packages/api-types/src/schemas/history.ts +0 -84
- package/packages/api-types/src/schemas/index.ts +0 -148
- package/packages/api-types/src/schemas/message.test.ts +0 -192
- package/packages/api-types/src/schemas/message.ts +0 -98
- package/packages/api-types/src/schemas/session.test.ts +0 -104
- package/packages/api-types/src/schemas/session.ts +0 -40
- package/packages/api-types/src/schemas/task.test.ts +0 -192
- package/packages/api-types/src/schemas/task.ts +0 -78
- package/packages/api-types/tsconfig.json +0 -19
- package/packages/api-types/vitest.config.ts +0 -9
- package/packages/benchmark/README.md +0 -200
- package/packages/benchmark/datasets/coding-tasks.yaml +0 -127
- package/packages/benchmark/datasets/coordination-tasks.yaml +0 -122
- package/packages/benchmark/datasets/quick-test.yaml +0 -20
- package/packages/benchmark/dist/benchmark.d.ts +0 -47
- package/packages/benchmark/dist/benchmark.d.ts.map +0 -1
- package/packages/benchmark/dist/benchmark.js +0 -224
- package/packages/benchmark/dist/benchmark.js.map +0 -1
- package/packages/benchmark/dist/cli.d.ts +0 -8
- package/packages/benchmark/dist/cli.d.ts.map +0 -1
- package/packages/benchmark/dist/cli.js +0 -185
- package/packages/benchmark/dist/cli.js.map +0 -1
- package/packages/benchmark/dist/harbor.d.ts +0 -53
- package/packages/benchmark/dist/harbor.d.ts.map +0 -1
- package/packages/benchmark/dist/harbor.js +0 -127
- package/packages/benchmark/dist/harbor.js.map +0 -1
- package/packages/benchmark/dist/index.d.ts +0 -48
- package/packages/benchmark/dist/index.d.ts.map +0 -1
- package/packages/benchmark/dist/index.js +0 -50
- package/packages/benchmark/dist/index.js.map +0 -1
- package/packages/benchmark/dist/runners/base.d.ts +0 -63
- package/packages/benchmark/dist/runners/base.d.ts.map +0 -1
- package/packages/benchmark/dist/runners/base.js +0 -156
- package/packages/benchmark/dist/runners/base.js.map +0 -1
- package/packages/benchmark/dist/runners/index.d.ts +0 -10
- package/packages/benchmark/dist/runners/index.d.ts.map +0 -1
- package/packages/benchmark/dist/runners/index.js +0 -10
- package/packages/benchmark/dist/runners/index.js.map +0 -1
- package/packages/benchmark/dist/runners/single.d.ts +0 -19
- package/packages/benchmark/dist/runners/single.d.ts.map +0 -1
- package/packages/benchmark/dist/runners/single.js +0 -111
- package/packages/benchmark/dist/runners/single.js.map +0 -1
- package/packages/benchmark/dist/runners/subagent.d.ts +0 -32
- package/packages/benchmark/dist/runners/subagent.d.ts.map +0 -1
- package/packages/benchmark/dist/runners/subagent.js +0 -212
- package/packages/benchmark/dist/runners/subagent.js.map +0 -1
- package/packages/benchmark/dist/runners/swarm.d.ts +0 -36
- package/packages/benchmark/dist/runners/swarm.d.ts.map +0 -1
- package/packages/benchmark/dist/runners/swarm.js +0 -273
- package/packages/benchmark/dist/runners/swarm.js.map +0 -1
- package/packages/benchmark/dist/types.d.ts +0 -178
- package/packages/benchmark/dist/types.d.ts.map +0 -1
- package/packages/benchmark/dist/types.js +0 -16
- package/packages/benchmark/dist/types.js.map +0 -1
- package/packages/benchmark/package.json +0 -80
- package/packages/benchmark/src/benchmark.ts +0 -298
- package/packages/benchmark/src/cli.ts +0 -240
- package/packages/benchmark/src/harbor.ts +0 -170
- package/packages/benchmark/src/index.ts +0 -73
- package/packages/benchmark/src/runners/base.ts +0 -205
- package/packages/benchmark/src/runners/index.ts +0 -10
- package/packages/benchmark/src/runners/single.ts +0 -121
- package/packages/benchmark/src/runners/subagent.ts +0 -240
- package/packages/benchmark/src/runners/swarm.ts +0 -326
- package/packages/benchmark/src/types.ts +0 -205
- package/packages/benchmark/tsconfig.json +0 -20
- package/packages/cli-tester/README.md +0 -277
- package/packages/cli-tester/dist/index.d.ts +0 -21
- package/packages/cli-tester/dist/index.d.ts.map +0 -1
- package/packages/cli-tester/dist/index.js +0 -21
- package/packages/cli-tester/dist/index.js.map +0 -1
- package/packages/cli-tester/dist/utils/credential-check.d.ts +0 -56
- package/packages/cli-tester/dist/utils/credential-check.d.ts.map +0 -1
- package/packages/cli-tester/dist/utils/credential-check.js +0 -230
- package/packages/cli-tester/dist/utils/credential-check.js.map +0 -1
- package/packages/cli-tester/dist/utils/socket-client.d.ts +0 -76
- package/packages/cli-tester/dist/utils/socket-client.d.ts.map +0 -1
- package/packages/cli-tester/dist/utils/socket-client.js +0 -153
- package/packages/cli-tester/dist/utils/socket-client.js.map +0 -1
- package/packages/cli-tester/docker/Dockerfile +0 -61
- package/packages/cli-tester/docker/docker-compose.yml +0 -71
- package/packages/cli-tester/docker/entrypoint.sh +0 -58
- package/packages/cli-tester/package.json +0 -32
- package/packages/cli-tester/scripts/clear-auth.sh +0 -101
- package/packages/cli-tester/scripts/inject-message.sh +0 -42
- package/packages/cli-tester/scripts/start.sh +0 -71
- package/packages/cli-tester/scripts/test-cli.sh +0 -56
- package/packages/cli-tester/scripts/test-full-spawn.sh +0 -238
- package/packages/cli-tester/scripts/test-registration.sh +0 -182
- package/packages/cli-tester/scripts/test-setup-flow.sh +0 -202
- package/packages/cli-tester/scripts/test-spawn.sh +0 -140
- package/packages/cli-tester/scripts/test-with-daemon.sh +0 -247
- package/packages/cli-tester/scripts/verify-auth.sh +0 -112
- package/packages/cli-tester/src/index.ts +0 -40
- package/packages/cli-tester/src/utils/credential-check.ts +0 -284
- package/packages/cli-tester/src/utils/socket-client.ts +0 -211
- package/packages/cli-tester/tests/credential-check.test.ts +0 -56
- package/packages/cli-tester/tsconfig.json +0 -11
- package/packages/sdk/dist/browser-client.d.ts +0 -212
- package/packages/sdk/dist/browser-client.d.ts.map +0 -1
- package/packages/sdk/dist/browser-client.js +0 -750
- package/packages/sdk/dist/browser-client.js.map +0 -1
- package/packages/sdk/dist/browser-framing.d.ts +0 -46
- package/packages/sdk/dist/browser-framing.d.ts.map +0 -1
- package/packages/sdk/dist/browser-framing.js +0 -122
- package/packages/sdk/dist/browser-framing.js.map +0 -1
- package/packages/sdk/dist/standalone.d.ts +0 -89
- package/packages/sdk/dist/standalone.d.ts.map +0 -1
- package/packages/sdk/dist/standalone.js +0 -131
- package/packages/sdk/dist/standalone.js.map +0 -1
- package/packages/sdk/dist/transports/index.d.ts +0 -92
- package/packages/sdk/dist/transports/index.d.ts.map +0 -1
- package/packages/sdk/dist/transports/index.js +0 -129
- package/packages/sdk/dist/transports/index.js.map +0 -1
- package/packages/sdk/dist/transports/socket-transport.d.ts +0 -30
- package/packages/sdk/dist/transports/socket-transport.d.ts.map +0 -1
- package/packages/sdk/dist/transports/socket-transport.js +0 -94
- package/packages/sdk/dist/transports/socket-transport.js.map +0 -1
- package/packages/sdk/dist/transports/types.d.ts +0 -69
- package/packages/sdk/dist/transports/types.d.ts.map +0 -1
- package/packages/sdk/dist/transports/types.js +0 -10
- package/packages/sdk/dist/transports/types.js.map +0 -1
- package/packages/sdk/dist/transports/websocket-transport.d.ts +0 -55
- package/packages/sdk/dist/transports/websocket-transport.d.ts.map +0 -1
- package/packages/sdk/dist/transports/websocket-transport.js +0 -180
- package/packages/sdk/dist/transports/websocket-transport.js.map +0 -1
- package/packages/sdk/src/browser-client.ts +0 -985
- package/packages/sdk/src/browser-framing.test.ts +0 -115
- package/packages/sdk/src/browser-framing.ts +0 -150
- package/packages/sdk/src/standalone.ts +0 -183
- package/packages/sdk/src/transports/index.ts +0 -197
- package/packages/sdk/src/transports/socket-transport.ts +0 -115
- package/packages/sdk/src/transports/types.ts +0 -77
- package/packages/sdk/src/transports/websocket-transport.ts +0 -245
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Full integration test with daemon
|
|
3
|
-
# This starts a local daemon and tests the complete spawn flow
|
|
4
|
-
#
|
|
5
|
-
# Usage: ./test-with-daemon.sh <cli>
|
|
6
|
-
# Example: ./test-with-daemon.sh cursor
|
|
7
|
-
# DEBUG=1 ./test-with-daemon.sh cursor
|
|
8
|
-
|
|
9
|
-
set -e
|
|
10
|
-
|
|
11
|
-
CLI=${1:-cursor}
|
|
12
|
-
|
|
13
|
-
# Map CLI name to actual command
|
|
14
|
-
CLI_CMD="$CLI"
|
|
15
|
-
if [ "$CLI" = "cursor" ]; then
|
|
16
|
-
CLI_CMD="agent"
|
|
17
|
-
fi
|
|
18
|
-
|
|
19
|
-
NAME="daemon-test-${CLI}"
|
|
20
|
-
SOCKET="/tmp/relay-pty-${NAME}.sock"
|
|
21
|
-
|
|
22
|
-
# Daemon configuration
|
|
23
|
-
DAEMON_PORT=${DAEMON_PORT:-3377}
|
|
24
|
-
DAEMON_HOST="127.0.0.1"
|
|
25
|
-
DAEMON_URL="http://${DAEMON_HOST}:${DAEMON_PORT}"
|
|
26
|
-
DATA_DIR="/tmp/relay-daemon-test"
|
|
27
|
-
|
|
28
|
-
# Cleanup function
|
|
29
|
-
cleanup() {
|
|
30
|
-
echo ""
|
|
31
|
-
echo "========================================"
|
|
32
|
-
echo " Cleaning up"
|
|
33
|
-
echo "========================================"
|
|
34
|
-
rm -f "$SOCKET"
|
|
35
|
-
if [ -n "$DAEMON_PID" ]; then
|
|
36
|
-
echo "Stopping daemon (PID: $DAEMON_PID)..."
|
|
37
|
-
kill $DAEMON_PID 2>/dev/null || true
|
|
38
|
-
fi
|
|
39
|
-
if [ -n "$PTY_PID" ]; then
|
|
40
|
-
echo "Stopping relay-pty (PID: $PTY_PID)..."
|
|
41
|
-
kill $PTY_PID 2>/dev/null || true
|
|
42
|
-
fi
|
|
43
|
-
echo "Done."
|
|
44
|
-
}
|
|
45
|
-
trap cleanup EXIT
|
|
46
|
-
|
|
47
|
-
# Create data directory
|
|
48
|
-
mkdir -p "$DATA_DIR"
|
|
49
|
-
|
|
50
|
-
echo "========================================"
|
|
51
|
-
echo " Full Daemon Integration Test: $CLI"
|
|
52
|
-
echo "========================================"
|
|
53
|
-
echo ""
|
|
54
|
-
echo "This test starts a real daemon and tests the complete flow:"
|
|
55
|
-
echo " 1. Start relay-daemon"
|
|
56
|
-
echo " 2. Start relay-pty with CLI"
|
|
57
|
-
echo " 3. Wait for agent registration"
|
|
58
|
-
echo " 4. Monitor the full flow"
|
|
59
|
-
echo ""
|
|
60
|
-
echo "Configuration:"
|
|
61
|
-
echo " CLI: $CLI_CMD"
|
|
62
|
-
echo " Agent name: $NAME"
|
|
63
|
-
echo " Daemon URL: $DAEMON_URL"
|
|
64
|
-
echo " Data dir: $DATA_DIR"
|
|
65
|
-
echo ""
|
|
66
|
-
|
|
67
|
-
# Check if daemon binary is available
|
|
68
|
-
if ! command -v relay-daemon &> /dev/null; then
|
|
69
|
-
echo "WARNING: relay-daemon not found in PATH"
|
|
70
|
-
echo ""
|
|
71
|
-
echo "To build the daemon:"
|
|
72
|
-
echo " cd packages/daemon && npm run build"
|
|
73
|
-
echo ""
|
|
74
|
-
echo "Or run a daemon manually:"
|
|
75
|
-
echo " npm run daemon"
|
|
76
|
-
echo ""
|
|
77
|
-
echo "Then re-run this test."
|
|
78
|
-
exit 1
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
echo "========================================"
|
|
82
|
-
echo " Phase 1: Starting Daemon"
|
|
83
|
-
echo "========================================"
|
|
84
|
-
echo ""
|
|
85
|
-
|
|
86
|
-
# Check if a daemon is already running
|
|
87
|
-
if curl -s "${DAEMON_URL}/health" > /dev/null 2>&1; then
|
|
88
|
-
echo "Daemon already running at $DAEMON_URL"
|
|
89
|
-
DAEMON_PID=""
|
|
90
|
-
else
|
|
91
|
-
echo "Starting daemon on port $DAEMON_PORT..."
|
|
92
|
-
|
|
93
|
-
# Start daemon in background with test configuration
|
|
94
|
-
RELAY_DATA_DIR="$DATA_DIR" \
|
|
95
|
-
RELAY_PORT="$DAEMON_PORT" \
|
|
96
|
-
DEBUG="${DEBUG:-}" \
|
|
97
|
-
relay-daemon > "$DATA_DIR/daemon.log" 2>&1 &
|
|
98
|
-
|
|
99
|
-
DAEMON_PID=$!
|
|
100
|
-
echo "Daemon started (PID: $DAEMON_PID)"
|
|
101
|
-
|
|
102
|
-
# Wait for daemon to be ready
|
|
103
|
-
echo "Waiting for daemon to be ready..."
|
|
104
|
-
for i in $(seq 1 30); do
|
|
105
|
-
if curl -s "${DAEMON_URL}/health" > /dev/null 2>&1; then
|
|
106
|
-
echo "Daemon is ready!"
|
|
107
|
-
break
|
|
108
|
-
fi
|
|
109
|
-
if [ $i -eq 30 ]; then
|
|
110
|
-
echo "ERROR: Daemon failed to start within 30 seconds"
|
|
111
|
-
echo ""
|
|
112
|
-
echo "Daemon log:"
|
|
113
|
-
cat "$DATA_DIR/daemon.log" | tail -50
|
|
114
|
-
exit 1
|
|
115
|
-
fi
|
|
116
|
-
sleep 1
|
|
117
|
-
done
|
|
118
|
-
fi
|
|
119
|
-
|
|
120
|
-
echo ""
|
|
121
|
-
|
|
122
|
-
echo "========================================"
|
|
123
|
-
echo " Phase 2: Starting CLI with relay-pty"
|
|
124
|
-
echo "========================================"
|
|
125
|
-
echo ""
|
|
126
|
-
|
|
127
|
-
# Build CLI arguments
|
|
128
|
-
CLI_ARGS=()
|
|
129
|
-
case $CLI in
|
|
130
|
-
claude)
|
|
131
|
-
CLI_ARGS+=(--dangerously-skip-permissions)
|
|
132
|
-
;;
|
|
133
|
-
cursor)
|
|
134
|
-
CLI_ARGS+=(--force)
|
|
135
|
-
;;
|
|
136
|
-
esac
|
|
137
|
-
|
|
138
|
-
echo "Command: $CLI_CMD ${CLI_ARGS[*]}"
|
|
139
|
-
|
|
140
|
-
# Build relay-pty args
|
|
141
|
-
RELAY_ARGS=(
|
|
142
|
-
--name "$NAME"
|
|
143
|
-
--socket "$SOCKET"
|
|
144
|
-
--idle-timeout 300
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
# Enable verbose output
|
|
148
|
-
if [ -n "$DEBUG" ]; then
|
|
149
|
-
RELAY_ARGS+=(--json-output)
|
|
150
|
-
fi
|
|
151
|
-
|
|
152
|
-
# Set daemon URL environment variable so relay-pty connects to our test daemon
|
|
153
|
-
export RELAY_DAEMON_URL="$DAEMON_URL"
|
|
154
|
-
|
|
155
|
-
echo "Starting relay-pty..."
|
|
156
|
-
if [ ${#CLI_ARGS[@]} -gt 0 ]; then
|
|
157
|
-
relay-pty "${RELAY_ARGS[@]}" -- "$CLI_CMD" "${CLI_ARGS[@]}" 2>&1 &
|
|
158
|
-
else
|
|
159
|
-
relay-pty "${RELAY_ARGS[@]}" -- "$CLI_CMD" 2>&1 &
|
|
160
|
-
fi
|
|
161
|
-
|
|
162
|
-
PTY_PID=$!
|
|
163
|
-
echo "relay-pty started (PID: $PTY_PID)"
|
|
164
|
-
echo ""
|
|
165
|
-
|
|
166
|
-
echo "========================================"
|
|
167
|
-
echo " Phase 3: Monitoring Registration"
|
|
168
|
-
echo "========================================"
|
|
169
|
-
echo ""
|
|
170
|
-
|
|
171
|
-
# Poll for registration via daemon API
|
|
172
|
-
START_TIME=$(date +%s)
|
|
173
|
-
TIMEOUT_SEC=60
|
|
174
|
-
|
|
175
|
-
echo "Polling daemon for agent registration (timeout: ${TIMEOUT_SEC}s)..."
|
|
176
|
-
echo ""
|
|
177
|
-
|
|
178
|
-
while true; do
|
|
179
|
-
CURRENT_TIME=$(date +%s)
|
|
180
|
-
ELAPSED=$((CURRENT_TIME - START_TIME))
|
|
181
|
-
|
|
182
|
-
# Check if PTY process is still running
|
|
183
|
-
if ! kill -0 $PTY_PID 2>/dev/null; then
|
|
184
|
-
echo ""
|
|
185
|
-
echo "[$(date +%T)] ERROR: relay-pty exited after ${ELAPSED}s"
|
|
186
|
-
echo ""
|
|
187
|
-
echo "The CLI crashed or exited before completing registration."
|
|
188
|
-
echo ""
|
|
189
|
-
if [ -f "$DATA_DIR/daemon.log" ]; then
|
|
190
|
-
echo "Daemon log (last 20 lines):"
|
|
191
|
-
tail -20 "$DATA_DIR/daemon.log"
|
|
192
|
-
fi
|
|
193
|
-
exit 1
|
|
194
|
-
fi
|
|
195
|
-
|
|
196
|
-
# Query daemon for connected agents
|
|
197
|
-
AGENTS=$(curl -s "${DAEMON_URL}/api/agents" 2>/dev/null || echo "[]")
|
|
198
|
-
|
|
199
|
-
# Check if our agent is registered
|
|
200
|
-
if echo "$AGENTS" | grep -q "\"$NAME\""; then
|
|
201
|
-
echo ""
|
|
202
|
-
echo "========================================"
|
|
203
|
-
echo " SUCCESS: Agent Registered!"
|
|
204
|
-
echo "========================================"
|
|
205
|
-
echo ""
|
|
206
|
-
echo "Agent '$NAME' successfully registered with daemon after ${ELAPSED}s"
|
|
207
|
-
echo ""
|
|
208
|
-
echo "Connected agents:"
|
|
209
|
-
echo "$AGENTS" | jq . 2>/dev/null || echo "$AGENTS"
|
|
210
|
-
echo ""
|
|
211
|
-
echo "Press Ctrl+C to stop the test, or leave running to interact with the CLI."
|
|
212
|
-
|
|
213
|
-
# Keep running so user can interact
|
|
214
|
-
wait $PTY_PID
|
|
215
|
-
exit 0
|
|
216
|
-
fi
|
|
217
|
-
|
|
218
|
-
echo "[$(date +%T)] +${ELAPSED}s: Waiting for registration... (agents: $(echo "$AGENTS" | grep -o '"' | wc -l | xargs))"
|
|
219
|
-
|
|
220
|
-
# Check timeout
|
|
221
|
-
if [ $ELAPSED -ge $TIMEOUT_SEC ]; then
|
|
222
|
-
echo ""
|
|
223
|
-
echo "========================================"
|
|
224
|
-
echo " TIMEOUT: Registration Failed"
|
|
225
|
-
echo "========================================"
|
|
226
|
-
echo ""
|
|
227
|
-
echo "Agent '$NAME' did not register within ${TIMEOUT_SEC}s"
|
|
228
|
-
echo ""
|
|
229
|
-
echo "This is the same timeout the real spawner would hit."
|
|
230
|
-
echo ""
|
|
231
|
-
echo "Debugging info:"
|
|
232
|
-
echo ""
|
|
233
|
-
echo "1. Connected agents from daemon:"
|
|
234
|
-
echo "$AGENTS" | jq . 2>/dev/null || echo "$AGENTS"
|
|
235
|
-
echo ""
|
|
236
|
-
if [ -f "$DATA_DIR/daemon.log" ]; then
|
|
237
|
-
echo "2. Daemon log (last 30 lines):"
|
|
238
|
-
tail -30 "$DATA_DIR/daemon.log"
|
|
239
|
-
fi
|
|
240
|
-
echo ""
|
|
241
|
-
echo "3. Check if CLI is stuck on a prompt (auth, trust, etc.)"
|
|
242
|
-
echo ""
|
|
243
|
-
exit 1
|
|
244
|
-
fi
|
|
245
|
-
|
|
246
|
-
sleep 2
|
|
247
|
-
done
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Verify CLI credentials exist and show (redacted) contents
|
|
3
|
-
# Usage: ./verify-auth.sh <cli>
|
|
4
|
-
# Example: ./verify-auth.sh claude
|
|
5
|
-
|
|
6
|
-
CLI=${1:-claude}
|
|
7
|
-
|
|
8
|
-
# Map CLI to credential file path
|
|
9
|
-
case $CLI in
|
|
10
|
-
claude)
|
|
11
|
-
CRED_FILE="$HOME/.claude/.credentials.json"
|
|
12
|
-
;;
|
|
13
|
-
codex)
|
|
14
|
-
CRED_FILE="$HOME/.codex/auth.json"
|
|
15
|
-
;;
|
|
16
|
-
gemini)
|
|
17
|
-
# Gemini stores in application_default_credentials.json
|
|
18
|
-
CRED_FILE="$HOME/.config/gcloud/application_default_credentials.json"
|
|
19
|
-
ALT_FILE="$HOME/.gemini/credentials.json"
|
|
20
|
-
;;
|
|
21
|
-
cursor|agent)
|
|
22
|
-
# Cursor CLI installs as 'agent', credentials in ~/.cursor/
|
|
23
|
-
CRED_FILE="$HOME/.cursor/auth.json"
|
|
24
|
-
CLI="cursor" # Normalize name
|
|
25
|
-
;;
|
|
26
|
-
opencode)
|
|
27
|
-
CRED_FILE="$HOME/.local/share/opencode/auth.json"
|
|
28
|
-
;;
|
|
29
|
-
droid)
|
|
30
|
-
CRED_FILE="$HOME/.droid/auth.json"
|
|
31
|
-
;;
|
|
32
|
-
copilot)
|
|
33
|
-
# GitHub Copilot uses gh CLI auth - stored in YAML format
|
|
34
|
-
CRED_FILE="$HOME/.config/gh/hosts.yml"
|
|
35
|
-
;;
|
|
36
|
-
*)
|
|
37
|
-
echo "Unknown CLI: $CLI"
|
|
38
|
-
echo "Supported: claude, codex, gemini, cursor, opencode, droid, copilot"
|
|
39
|
-
exit 1
|
|
40
|
-
;;
|
|
41
|
-
esac
|
|
42
|
-
|
|
43
|
-
echo "========================================"
|
|
44
|
-
echo " Checking credentials for: $CLI"
|
|
45
|
-
echo "========================================"
|
|
46
|
-
echo ""
|
|
47
|
-
|
|
48
|
-
# Check primary credential file
|
|
49
|
-
if [ -f "$CRED_FILE" ]; then
|
|
50
|
-
echo "✓ Credentials found: $CRED_FILE"
|
|
51
|
-
echo ""
|
|
52
|
-
echo "Contents (tokens redacted):"
|
|
53
|
-
echo "----------------------------------------"
|
|
54
|
-
# Redact any values that look like tokens (long strings, JWTs, etc.)
|
|
55
|
-
cat "$CRED_FILE" | jq '.' 2>/dev/null | \
|
|
56
|
-
sed -E 's/"([^"]*[Tt]oken[^"]*|[Aa]ccess[^"]*|[Rr]efresh[^"]*|[Ss]ecret[^"]*)": "[^"]{20,}"/"***\1***": "[REDACTED]"/g' || \
|
|
57
|
-
cat "$CRED_FILE" | sed -E 's/"[^"]{40,}"/"[REDACTED]"/g'
|
|
58
|
-
echo "----------------------------------------"
|
|
59
|
-
echo ""
|
|
60
|
-
|
|
61
|
-
# Check for specific fields
|
|
62
|
-
if command -v jq &> /dev/null && [ -f "$CRED_FILE" ]; then
|
|
63
|
-
echo "Token check:"
|
|
64
|
-
if jq -e '.claudeAiOauth.accessToken' "$CRED_FILE" &>/dev/null; then
|
|
65
|
-
echo " ✓ Access token present (Claude format)"
|
|
66
|
-
elif jq -e '.tokens.access_token' "$CRED_FILE" &>/dev/null; then
|
|
67
|
-
echo " ✓ Access token present (Codex format)"
|
|
68
|
-
elif jq -e '.accessToken' "$CRED_FILE" &>/dev/null; then
|
|
69
|
-
echo " ✓ Access token present (generic format)"
|
|
70
|
-
elif jq -e '.access_token' "$CRED_FILE" &>/dev/null; then
|
|
71
|
-
echo " ✓ Access token present (OAuth format)"
|
|
72
|
-
else
|
|
73
|
-
echo " ? Access token format unknown"
|
|
74
|
-
fi
|
|
75
|
-
|
|
76
|
-
if jq -e '.claudeAiOauth.refreshToken' "$CRED_FILE" &>/dev/null || \
|
|
77
|
-
jq -e '.tokens.refresh_token' "$CRED_FILE" &>/dev/null || \
|
|
78
|
-
jq -e '.refreshToken' "$CRED_FILE" &>/dev/null || \
|
|
79
|
-
jq -e '.refresh_token' "$CRED_FILE" &>/dev/null; then
|
|
80
|
-
echo " ✓ Refresh token present"
|
|
81
|
-
else
|
|
82
|
-
echo " ✗ No refresh token found"
|
|
83
|
-
fi
|
|
84
|
-
fi
|
|
85
|
-
|
|
86
|
-
exit 0
|
|
87
|
-
else
|
|
88
|
-
echo "✗ No credentials found at: $CRED_FILE"
|
|
89
|
-
|
|
90
|
-
# Check alternate location for Gemini
|
|
91
|
-
if [ -n "$ALT_FILE" ] && [ -f "$ALT_FILE" ]; then
|
|
92
|
-
echo ""
|
|
93
|
-
echo "✓ Found alternate credentials: $ALT_FILE"
|
|
94
|
-
cat "$ALT_FILE" | jq '.' 2>/dev/null | \
|
|
95
|
-
sed -E 's/"[^"]{40,}"/"[REDACTED]"/g' || \
|
|
96
|
-
cat "$ALT_FILE"
|
|
97
|
-
exit 0
|
|
98
|
-
fi
|
|
99
|
-
|
|
100
|
-
# Show what files exist in the CLI's config directory
|
|
101
|
-
CLI_DIR=$(dirname "$CRED_FILE")
|
|
102
|
-
if [ -d "$CLI_DIR" ]; then
|
|
103
|
-
echo ""
|
|
104
|
-
echo "Files in $CLI_DIR:"
|
|
105
|
-
ls -la "$CLI_DIR" 2>/dev/null || echo " (directory exists but is empty or unreadable)"
|
|
106
|
-
else
|
|
107
|
-
echo ""
|
|
108
|
-
echo "Config directory does not exist: $CLI_DIR"
|
|
109
|
-
fi
|
|
110
|
-
|
|
111
|
-
exit 1
|
|
112
|
-
fi
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI Auth Tester - Manual interactive testing for CLI authentication flows
|
|
3
|
-
*
|
|
4
|
-
* This package provides utilities for testing CLI authentication in a Docker container.
|
|
5
|
-
* Primary use case is debugging auth issues with various CLI tools (Claude, Codex, Gemini, etc.)
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```bash
|
|
9
|
-
* # Start the test environment
|
|
10
|
-
* npm run cli-tester:start
|
|
11
|
-
*
|
|
12
|
-
* # Inside container, test a CLI
|
|
13
|
-
* ./scripts/test-cli.sh claude
|
|
14
|
-
*
|
|
15
|
-
* # Verify credentials
|
|
16
|
-
* ./scripts/verify-auth.sh claude
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
export {
|
|
21
|
-
RelayPtyClient,
|
|
22
|
-
createClient,
|
|
23
|
-
getSocketPath,
|
|
24
|
-
type InjectRequest,
|
|
25
|
-
type InjectResponse,
|
|
26
|
-
type StatusRequest,
|
|
27
|
-
type StatusResponse,
|
|
28
|
-
type RelayPtyResponse,
|
|
29
|
-
} from './utils/socket-client.js';
|
|
30
|
-
|
|
31
|
-
export {
|
|
32
|
-
checkCredentials,
|
|
33
|
-
clearCredentials,
|
|
34
|
-
checkAllCredentials,
|
|
35
|
-
clearAllCredentials,
|
|
36
|
-
getCredentialPath,
|
|
37
|
-
getConfigPaths,
|
|
38
|
-
type CLIType,
|
|
39
|
-
type CredentialCheck,
|
|
40
|
-
} from './utils/credential-check.js';
|
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Credential checking utilities for CLI authentication testing
|
|
3
|
-
* Verifies and parses credential files for various CLI tools
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { readFileSync, existsSync, unlinkSync, rmSync } from 'node:fs';
|
|
7
|
-
import { homedir } from 'node:os';
|
|
8
|
-
import { join } from 'node:path';
|
|
9
|
-
|
|
10
|
-
export type CLIType = 'claude' | 'codex' | 'gemini' | 'cursor' | 'opencode' | 'droid';
|
|
11
|
-
|
|
12
|
-
export interface CredentialCheck {
|
|
13
|
-
/** CLI type being checked */
|
|
14
|
-
cli: CLIType;
|
|
15
|
-
/** Whether the credential file exists */
|
|
16
|
-
exists: boolean;
|
|
17
|
-
/** Whether the credentials appear valid (have required fields) */
|
|
18
|
-
valid: boolean;
|
|
19
|
-
/** Whether an access token is present */
|
|
20
|
-
hasAccessToken: boolean;
|
|
21
|
-
/** Whether a refresh token is present */
|
|
22
|
-
hasRefreshToken: boolean;
|
|
23
|
-
/** Token expiration date if available */
|
|
24
|
-
expiresAt?: Date;
|
|
25
|
-
/** Path to the credential file */
|
|
26
|
-
filePath: string;
|
|
27
|
-
/** Raw credential data (tokens redacted) */
|
|
28
|
-
data?: Record<string, unknown>;
|
|
29
|
-
/** Error message if check failed */
|
|
30
|
-
error?: string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Get the credential file path for a CLI
|
|
35
|
-
*/
|
|
36
|
-
export function getCredentialPath(cli: CLIType): string {
|
|
37
|
-
const home = homedir();
|
|
38
|
-
|
|
39
|
-
switch (cli) {
|
|
40
|
-
case 'claude':
|
|
41
|
-
return join(home, '.claude', '.credentials.json');
|
|
42
|
-
case 'codex':
|
|
43
|
-
return join(home, '.codex', 'auth.json');
|
|
44
|
-
case 'gemini':
|
|
45
|
-
return join(home, '.config', 'gcloud', 'application_default_credentials.json');
|
|
46
|
-
case 'cursor':
|
|
47
|
-
return join(home, '.cursor', 'auth.json');
|
|
48
|
-
case 'opencode':
|
|
49
|
-
return join(home, '.local', 'share', 'opencode', 'auth.json');
|
|
50
|
-
case 'droid':
|
|
51
|
-
return join(home, '.droid', 'auth.json');
|
|
52
|
-
default:
|
|
53
|
-
throw new Error(`Unknown CLI type: ${cli}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Get all config paths for a CLI (for clearing)
|
|
59
|
-
*/
|
|
60
|
-
export function getConfigPaths(cli: CLIType): string[] {
|
|
61
|
-
const home = homedir();
|
|
62
|
-
|
|
63
|
-
switch (cli) {
|
|
64
|
-
case 'claude':
|
|
65
|
-
return [
|
|
66
|
-
join(home, '.claude', '.credentials.json'),
|
|
67
|
-
join(home, '.claude', 'settings.json'),
|
|
68
|
-
join(home, '.claude', 'settings.local.json'),
|
|
69
|
-
];
|
|
70
|
-
case 'codex':
|
|
71
|
-
return [
|
|
72
|
-
join(home, '.codex', 'auth.json'),
|
|
73
|
-
join(home, '.codex', 'config.json'),
|
|
74
|
-
join(home, '.codex', 'config.toml'),
|
|
75
|
-
];
|
|
76
|
-
case 'gemini':
|
|
77
|
-
return [
|
|
78
|
-
join(home, '.config', 'gcloud', 'application_default_credentials.json'),
|
|
79
|
-
join(home, '.gemini', 'credentials.json'),
|
|
80
|
-
join(home, '.gemini', 'settings.json'),
|
|
81
|
-
];
|
|
82
|
-
case 'cursor':
|
|
83
|
-
return [
|
|
84
|
-
join(home, '.cursor', 'auth.json'),
|
|
85
|
-
join(home, '.cursor', 'settings.json'),
|
|
86
|
-
];
|
|
87
|
-
case 'opencode':
|
|
88
|
-
return [join(home, '.local', 'share', 'opencode', 'auth.json')];
|
|
89
|
-
case 'droid':
|
|
90
|
-
return [join(home, '.droid', 'auth.json')];
|
|
91
|
-
default:
|
|
92
|
-
throw new Error(`Unknown CLI type: ${cli}`);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Extract token info from credential data based on CLI type
|
|
98
|
-
*/
|
|
99
|
-
function extractTokenInfo(
|
|
100
|
-
cli: CLIType,
|
|
101
|
-
data: Record<string, unknown>
|
|
102
|
-
): { hasAccessToken: boolean; hasRefreshToken: boolean; expiresAt?: Date } {
|
|
103
|
-
let hasAccessToken = false;
|
|
104
|
-
let hasRefreshToken = false;
|
|
105
|
-
let expiresAt: Date | undefined;
|
|
106
|
-
|
|
107
|
-
switch (cli) {
|
|
108
|
-
case 'claude': {
|
|
109
|
-
// Claude format: { claudeAiOauth: { accessToken, refreshToken, expiresAt } }
|
|
110
|
-
const oauth = data.claudeAiOauth as Record<string, unknown> | undefined;
|
|
111
|
-
if (oauth) {
|
|
112
|
-
hasAccessToken = typeof oauth.accessToken === 'string' && oauth.accessToken.length > 0;
|
|
113
|
-
hasRefreshToken = typeof oauth.refreshToken === 'string' && oauth.refreshToken.length > 0;
|
|
114
|
-
if (typeof oauth.expiresAt === 'number') {
|
|
115
|
-
expiresAt = new Date(oauth.expiresAt);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
case 'codex': {
|
|
122
|
-
// Codex format: { tokens: { access_token, refresh_token, expires_at } }
|
|
123
|
-
const tokens = data.tokens as Record<string, unknown> | undefined;
|
|
124
|
-
if (tokens) {
|
|
125
|
-
hasAccessToken =
|
|
126
|
-
typeof tokens.access_token === 'string' && tokens.access_token.length > 0;
|
|
127
|
-
hasRefreshToken =
|
|
128
|
-
typeof tokens.refresh_token === 'string' && tokens.refresh_token.length > 0;
|
|
129
|
-
if (typeof tokens.expires_at === 'number') {
|
|
130
|
-
expiresAt = new Date(tokens.expires_at * 1000); // Unix timestamp
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
case 'gemini': {
|
|
137
|
-
// Google OAuth format: { access_token, refresh_token, expiry_date }
|
|
138
|
-
hasAccessToken =
|
|
139
|
-
typeof data.access_token === 'string' && data.access_token.length > 0;
|
|
140
|
-
hasRefreshToken =
|
|
141
|
-
typeof data.refresh_token === 'string' && data.refresh_token.length > 0;
|
|
142
|
-
if (typeof data.expiry_date === 'number') {
|
|
143
|
-
expiresAt = new Date(data.expiry_date);
|
|
144
|
-
}
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
case 'cursor':
|
|
149
|
-
case 'opencode':
|
|
150
|
-
case 'droid': {
|
|
151
|
-
// Generic format: { accessToken, refreshToken } or { access_token, refresh_token }
|
|
152
|
-
hasAccessToken =
|
|
153
|
-
(typeof data.accessToken === 'string' && data.accessToken.length > 0) ||
|
|
154
|
-
(typeof data.access_token === 'string' && data.access_token.length > 0);
|
|
155
|
-
hasRefreshToken =
|
|
156
|
-
(typeof data.refreshToken === 'string' && data.refreshToken.length > 0) ||
|
|
157
|
-
(typeof data.refresh_token === 'string' && data.refresh_token.length > 0);
|
|
158
|
-
break;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return { hasAccessToken, hasRefreshToken, expiresAt };
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Redact sensitive values in credential data
|
|
167
|
-
*/
|
|
168
|
-
function redactData(data: Record<string, unknown>): Record<string, unknown> {
|
|
169
|
-
const redacted: Record<string, unknown> = {};
|
|
170
|
-
|
|
171
|
-
for (const [key, value] of Object.entries(data)) {
|
|
172
|
-
if (typeof value === 'string') {
|
|
173
|
-
// Redact anything that looks like a token
|
|
174
|
-
if (
|
|
175
|
-
key.toLowerCase().includes('token') ||
|
|
176
|
-
key.toLowerCase().includes('secret') ||
|
|
177
|
-
key.toLowerCase().includes('key') ||
|
|
178
|
-
value.length > 40
|
|
179
|
-
) {
|
|
180
|
-
redacted[key] = '[REDACTED]';
|
|
181
|
-
} else {
|
|
182
|
-
redacted[key] = value;
|
|
183
|
-
}
|
|
184
|
-
} else if (typeof value === 'object' && value !== null) {
|
|
185
|
-
redacted[key] = redactData(value as Record<string, unknown>);
|
|
186
|
-
} else {
|
|
187
|
-
redacted[key] = value;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return redacted;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Check credentials for a specific CLI
|
|
196
|
-
*/
|
|
197
|
-
export function checkCredentials(cli: CLIType): CredentialCheck {
|
|
198
|
-
const filePath = getCredentialPath(cli);
|
|
199
|
-
|
|
200
|
-
const result: CredentialCheck = {
|
|
201
|
-
cli,
|
|
202
|
-
exists: false,
|
|
203
|
-
valid: false,
|
|
204
|
-
hasAccessToken: false,
|
|
205
|
-
hasRefreshToken: false,
|
|
206
|
-
filePath,
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
if (!existsSync(filePath)) {
|
|
210
|
-
return result;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
result.exists = true;
|
|
214
|
-
|
|
215
|
-
try {
|
|
216
|
-
const content = readFileSync(filePath, 'utf-8');
|
|
217
|
-
const data = JSON.parse(content) as Record<string, unknown>;
|
|
218
|
-
|
|
219
|
-
const tokenInfo = extractTokenInfo(cli, data);
|
|
220
|
-
result.hasAccessToken = tokenInfo.hasAccessToken;
|
|
221
|
-
result.hasRefreshToken = tokenInfo.hasRefreshToken;
|
|
222
|
-
result.expiresAt = tokenInfo.expiresAt;
|
|
223
|
-
|
|
224
|
-
// Valid if at least access token is present
|
|
225
|
-
result.valid = result.hasAccessToken;
|
|
226
|
-
|
|
227
|
-
// Include redacted data for debugging
|
|
228
|
-
result.data = redactData(data);
|
|
229
|
-
} catch (err) {
|
|
230
|
-
result.error = err instanceof Error ? err.message : 'Unknown error';
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return result;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Clear credentials for a specific CLI
|
|
238
|
-
*/
|
|
239
|
-
export function clearCredentials(cli: CLIType): { cleared: string[]; errors: string[] } {
|
|
240
|
-
const paths = getConfigPaths(cli);
|
|
241
|
-
const cleared: string[] = [];
|
|
242
|
-
const errors: string[] = [];
|
|
243
|
-
|
|
244
|
-
for (const path of paths) {
|
|
245
|
-
if (existsSync(path)) {
|
|
246
|
-
try {
|
|
247
|
-
unlinkSync(path);
|
|
248
|
-
cleared.push(path);
|
|
249
|
-
} catch (err) {
|
|
250
|
-
errors.push(`Failed to remove ${path}: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return { cleared, errors };
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Clear all CLI credentials
|
|
260
|
-
*/
|
|
261
|
-
export function clearAllCredentials(): Record<CLIType, { cleared: string[]; errors: string[] }> {
|
|
262
|
-
const clis: CLIType[] = ['claude', 'codex', 'gemini', 'cursor', 'opencode', 'droid'];
|
|
263
|
-
const results: Record<string, { cleared: string[]; errors: string[] }> = {};
|
|
264
|
-
|
|
265
|
-
for (const cli of clis) {
|
|
266
|
-
results[cli] = clearCredentials(cli);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return results as Record<CLIType, { cleared: string[]; errors: string[] }>;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Check all CLI credentials
|
|
274
|
-
*/
|
|
275
|
-
export function checkAllCredentials(): Record<CLIType, CredentialCheck> {
|
|
276
|
-
const clis: CLIType[] = ['claude', 'codex', 'gemini', 'cursor', 'opencode', 'droid'];
|
|
277
|
-
const results: Record<string, CredentialCheck> = {};
|
|
278
|
-
|
|
279
|
-
for (const cli of clis) {
|
|
280
|
-
results[cli] = checkCredentials(cli);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return results as Record<CLIType, CredentialCheck>;
|
|
284
|
-
}
|