-
Notifications
You must be signed in to change notification settings - Fork 1
e2e fixes #55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
e2e fixes #55
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Add Gemini, OpenCode, and Droid to spawn modal agent templates - Add Providers tab to SettingsPanel for API key management - Add Gemini CLI installation to workspace Dockerfile - Update landing page to show all 5 supported CLIs (Claude, Codex, Gemini, OpenCode, Droid) with proper branding colors
- Add /api/git/token endpoint that fetches fresh tokens via Nango - Create git-credential-relay helper script for workspace containers - Install gh CLI in workspace Dockerfile - Update entrypoint.sh to configure gateway-based git auth - Update Fly, Railway, and Docker provisioners to pass gateway credentials - Tokens auto-refresh via Nango, solving the 1-hour expiry problem The gateway pattern ensures agents can always push to GitHub: 1. Agent runs `git push` 2. Git calls credential helper 3. Helper calls /api/git/token with workspace token 4. Cloud API fetches fresh token from Nango 5. Nango returns cached or refreshed GitHub App installation token
- Replace fragile grep/cut JSON parsing with jq - Add better error handling for API errors - Show API error messages in credential helper output
- Create AgentPolicyService with multi-level fallback: 1. Repo config (.claude/agents/*.md) 2. User-level PRPM policies (~/.config/agent-relay/policies/) 3. Cloud workspace policy (from dashboard) 4. Built-in defaults - Add spawn authorization with policy checks - Inject policy instructions into agent task prompts - Add cloud API endpoint for workspace policy configuration - Add audit logging for policy decisions Policy is enforced at runtime via AGENT_POLICY_ENFORCEMENT=1 env var. Agents are informed of their restrictions via injected prompts.
- Add AGENT_POLICY_ENFORCEMENT=1 to entrypoint.sh for cloud mode - Create cloud policy fetcher to call /api/policy/:workspaceId/internal - Policy is automatically fetched and enforced without user action
Spawned agents in arbitrary repos won't have the agent-relay-snippet installed in their AGENTS.md or CLAUDE.md files. This change: - Loads the relay snippet (docs/agent-relay-snippet.md) at spawn time - Prepends communication rules to all spawned agent task prompts - Includes fallback minimal snippet if file not found Also fixes build errors in policy.ts by using correct db query methods.
… agents Spawned agents now receive both: - agent-relay-snippet: Basic communication patterns (->relay: syntax) - agent-relay-protocol: Advanced features including: - Session persistence (SUMMARY/SESSION_END blocks) - Session continuity (->continuity: patterns) - Work trajectories (trail commands - MANDATORY) - Cross-project messaging - Dashboard integration This ensures all spawned agents can properly track their work via trajectories and report session status for dashboard monitoring.
DECISIONS RECORDED: 1. Default trajectories to opt-out (user-level storage) - Most repos won't want trajectory files in source control - Users must explicitly opt-in via .relay/config.json 2. Store user-level trajectories in ~/.config/agent-relay/trajectories/<hash>/ - XDG-compliant path, project-isolated, survives repo deletion 3. Settings configurable after GitHub app setup - Happens during workspace onboarding flow Changes: - Add src/trajectory/config.ts for trajectory storage configuration - Update integration.ts to use config-based paths - Merge trajectory indexes from both repo and user-level locations - Pass correct env vars to trail CLI for storage location
New endpoints: - GET /api/settings - Returns all settings with documentation - GET /api/settings/trajectory - Get trajectory storage settings - PUT /api/settings/trajectory - Update trajectory storage settings Includes comprehensive documentation for UI: - What trajectories are (PDERO paradigm) - Benefits of trajectory tracking - Why users might opt-in to store in repo - Link to pdero.com for more info Users can configure trajectory preferences after GitHub app setup during workspace onboarding.
New settings tab includes: - Explanation of what trajectories are (PDERO paradigm) - List of benefits for trajectory tracking - Link to pdero.com for more info - Toggle for repo vs user-level storage - Display of current storage location - Explanation of why teams might opt-in
- Switch from child_process.spawn to node-pty for proper TTY emulation - Handle Claude's interactive setup flow (dark mode, auth method prompts) - Auto-respond to prompts to reach the OAuth login URL - Add capture group to URL regex patterns - Handle "already authenticated" case in SettingsPanel - Add OAuth session management with polling for completion - Provide fallback API key input option for providers that support it - Clean up PTY processes properly on cancel/complete/timeout
- Refactor CLI auth config with structured PromptHandler interface - Add provider-specific prompt patterns and responses - Export validation functions for config integrity - Create mock CLI script for integration testing - Add comprehensive unit tests (32 tests passing) - Document process for adding new providers Key features: - Each provider has configurable prompts, responses, and timeouts - validateProviderConfig() ensures capture groups, required fields - Mock CLI simulates real interactive flows for testing - Integration test runner for all providers Files: - src/cloud/api/onboarding.ts - Refactored with testable helpers - src/cloud/api/onboarding.test.ts - 32 unit tests - scripts/test-cli-auth/ - Integration testing tools
- Create Dockerfile with mock CLI symlinks for all providers - Add ci-test-runner.ts with structured JSON output - Add GitHub Actions workflow with: - Unit tests on every push to onboarding.ts - Docker integration tests - Weekly scheduled runs to catch provider changes - Auto-issue creation on scheduled test failures - Update mock-cli.sh to auto-detect provider from $0 - Update README with CI documentation The CI tests ensure: - URL extraction works for each provider - Prompt detection and auto-response works - Tests are repeatable and provider-agnostic
- Add Dockerfile.real that installs actual provider CLIs - Add ci-test-real-clis.ts that tests against real CLI binaries - Update GitHub Actions workflow to use real CLIs - Real CLIs catch actual behavior changes immediately - Skips CLIs that aren't installed (doesn't fail) - Imports patterns from onboarding.ts to ensure consistency Benefits over mocks: - No maintenance of mock scripts - Tests actual user experience - Catches new prompts or output changes - Detects CLI updates automatically
- Match deploy/workspace/Dockerfile installation approach - Claude: curl install script + pre-seed config - Codex: npm install -g as root - OpenCode/Droid: curl install scripts - Gemini: npm with fallback to curl - Create testuser for CLI installs (like workspace user) - Add ~/.local/bin to PATH for user-installed CLIs
Extract runCLIAuthViaPTY as a reusable function that handles: - PTY spawning with proper TTY emulation - Auto-responding to interactive prompts - Auth URL extraction from CLI output - Success pattern detection - Timeout handling Both the production API endpoint and CI tests now use the same PTY runner function, ensuring consistent behavior and eliminating code duplication.
- Use namespace import for crypto module (import * as crypto) - Replace for...of Map iteration with forEach to avoid downlevelIteration requirement
Update file system mocks to properly handle relay snippet files: - Mock existsSync to return false for snippet files - Mock readFileSync to return appropriate content based on path - Update assertion to check task is contained in write call
Implements Slack-like agent profile panels showing: - Agent spawn prompt (the task that created the agent) - Persona prompt (agent profile/role instructions) - Persona name, title, and description - Agent metadata (model, capabilities, tags) - First seen/last seen timestamps This helps users understand agent behavior by seeing the prompts that define the agent's role and the task it was spawned with. Components: - AgentProfilePanel: Slide-out panel with profile details - AgentCard: Added profile button to trigger panel - AgentRegistry: Extended to store profile metadata - Dashboard types: Added AgentProfile interface
- Fix control regex in onboarding.ts for ANSI stripping - Convert require() imports to ES module imports (provisioner, trajectory) - Prefix unused variables with underscore where needed - Remove truly dead code: - Unused spawn/os imports in cli profiler - Unused snapshotCount variable - Unused isCliProvider type guard - Unused getTrajectoriesDir wrapper function - Unused type imports in test files
- Add make and g++ for node-pty native compilation - Fix Gemini CLI installation (remove non-existent npm package)
The package is @google/gemini-cli, not @anthropic-ai/gemini-cli. Fixed in both production workspace Dockerfile and test container.
- Extract cli-pty-runner.ts as shared module with minimal deps (only node-pty) - Update test container to use repo root as build context - Fix import paths in ci-test-real-clis.ts - Re-export types from onboarding.ts for backward compatibility This allows the test container to import the PTY runner without pulling in the full server stack (express, db, vault, etc).
Put cli-pty-runner.ts in /app/ alongside the test file so it can access node_modules. Previously it was in /src/cloud/api/ which couldn't resolve modules from /app/node_modules/.
- Gemini: Add prompt handler for auth method selection - OpenCode: Use 'opencode auth login' command (not just 'opencode') - Droid: Use '--login' flag and add login prompt handler - Increase waitTimeout to 5000ms for all three providers Based on official CLI documentation: - https://github.com/google-gemini/gemini-cli - https://opencode.ai/docs/cli/ - https://docs.factory.ai/cli/
The /complete endpoint now: - Accepts authCode (redirect URL) from request body - Extracts the code parameter from URL if it's a redirect URL - Submits the code to the CLI PTY process - Then polls for credentials This fixes Codex auth flow where users paste the redirect URL containing the code parameter. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Display the "Page not found is expected" warning directly below the Codex provider option, so users know what to expect before clicking to start the auth flow. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Changes: - Update OpenCode URL pattern to match actual OAuth provider URLs (Anthropic, OpenAI, Google, OpenCode.ai) - Add credential path for OpenCode (~/.local/share/opencode/auth.json) - Add OpenCode credential extraction (checks opencode, anthropic, openai, google keys) - Check for existing credentials before starting auth flow - If already authenticated, return success immediately instead of showing the login page 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Bug: submitAuthCode() is async but was not awaited, causing: - result was a Promise, not the actual result object - result.success was undefined (Promise has no .success) - !undefined = true, so it always returned an error Fix: Add async/await to properly handle the Promise.
Critical security issues identified in CLI OAuth flow: - bd-critical-016: Unauthenticated workspace daemon endpoints - bd-critical-017: PTY output may log sensitive tokens - bd-critical-018: No rate limiting on auth endpoints - bd-critical-019: OAuth session timeout too long (5 min) - bd-critical-020: Must force device flow in cloud mode
bd-critical-021: Architectural design for allowing team members to use their own provider credentials instead of sharing the workspace owner's credentials. Includes: - Database schema for workspace_credentials table - Credential resolution order (user override → workspace default → owner) - API endpoints for credential management - UI changes for provider settings - Migration path for backwards compatibility
Key insight: Container env vars are set at provisioning time, but PTY wrapper already supports per-process env overrides. Solution: 1. Spawn request includes userId 2. Daemon fetches user's credential from cloud API 3. Override ANTHROPIC_API_KEY etc. in PTY spawn env Requires daemon-to-cloud auth (bd-critical-016) first.
Key insight: CLI tools (claude, codex) read their OWN credential
files, they IGNORE SDK env vars like ANTHROPIC_API_KEY.
Solution: Set HOME=/home/workspace-users/{userId} when spawning
so each user's CLI finds credentials in $HOME/.claude/ etc.
Added:
- Per-provider credential file formats
- Cleanup considerations for credential files
- New credential-writer.ts module
Git operations are SAFE when changing HOME because: - git-credential-relay uses env vars (CLOUD_API_URL, WORKSPACE_TOKEN) - Does NOT read files from HOME directory Added prepareUserHome() function that: 1. Writes user's CLI credentials to user HOME 2. Copies gh CLI config from container HOME 3. Returns path for spawn env override Reference: deploy/workspace/entrypoint.sh shows credential format
bd-critical-016 (Daemon Auth): priority 148 → 160 - Now highest priority - blocks per-user credentials - Added implementation example using WORKSPACE_TOKEN - Tagged with blocks-per-user-creds bd-critical-021 (Per-User Creds): priority 120 → 155 - Elevated to p00 launch-blocker - Still depends on bd-critical-016 Execution order: 1. bd-critical-016: Add daemon auth middleware 2. bd-critical-021: Implement per-user HOME directories
…qgant/agent-relay into claude/pull-pre-launch-fixes-MlnSb
Root cause: Claude CLI's Ink text input needs time to process typed input before receiving Enter. Sending code + Enter immediately failed. Changes: - cli-auth.ts: Write code first, wait 1 second, then send Enter - cli-auth.ts: Remove BROWSER=echo (caused CLI to wait for callback) - cli-auth.ts: Add keep-alive pings and better logging - dashboard-server: Wait up to 5s for credentials after code submission - dashboard-server: Return session status in code submission response - cli-auth-config: Add prompts for login success, trust directory - onboarding.test.ts: Update test assertions for new patterns - provisioner: Add WORKSPACE_DEV_MOUNT for faster local iteration - package.json: Auto-enable dev mount in cloud:api script Tested: Auth flow completes successfully with credentials saved. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Add "safety check" and "yes, i trust" patterns to better match Claude Code's trust prompt. Increase delay to 300ms for menu render. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
When spawning agents, the pty-wrapper now auto-accepts:
1. --dangerously-skip-permissions prompt ("Yes, I accept")
2. Trust directory prompt ("Yes, I trust this folder")
This ensures agents can start without manual intervention.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <[email protected]>
…ce spawner message
- Fix Express 5 wildcard parameter returning array instead of string in
proxy route (path segments joined with comma instead of slash)
- Remove SSH dead code (ssh_host, ssh_port, ssh_password) - device flow
OAuth is used instead of localhost callback tunneling
- Add workspace creator as owner in workspace_members during provisioning
- Reduce spawner message size from 400+ lines of docs to 5-line reminder
to prevent agents from getting overwhelmed ("Meandering" state)
- Fix summary reminder injection to use single-line format with proper
Enter delay
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Store workspace ID in localStorage when connecting to a workspace - Add initializeWorkspaceId() to load workspace ID on other pages - Update metrics page to initialize workspace context on mount - Redirect to /app if in cloud mode without workspace selected 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Agents without a proper CLI (or CLI='Unknown') were being marked as human team members and shown in the Team tab. These are typically improperly registered or stale agents. Now they're excluded entirely. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add comprehensive [SPAWN-DEBUG] logging to pty-wrapper to track spawn command detection, prefix stripping, and execution - Fix tmux-wrapper to strip common line prefixes (including ●) before matching spawn/release commands, matching pty-wrapper behavior - Fix TypeScript error with Set.values().next().value being undefined 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
The dashboard-server was creating AgentSpawner without passing the dashboard port, so spawned agents couldn't call the spawn/release APIs for nested spawning. Now passes the port so canSpawn and canRelease are true in spawned agents. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
The agent name parameter wasn't URL encoded in the DELETE request, which could cause issues with agent names containing special characters. Now matches the tmux-wrapper implementation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add proper import for CLI_AUTH_CONFIG in onboarding.ts (was only re-exported) - Prefix unused repository parameters with underscore in mention-handler.ts - Remove unused readFileSync import from browser-testing.ts - Remove unused ExecSyncOptions import from container-spawner.ts - Add missing deps to usePresence hook to satisfy eslint - Add debug logging to git-credential-relay 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Agents need make and g++ to run npm install on repos with native dependencies like node-pty. Previously these were only in the builder stage, not available at runtime. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Image paste creates blob: URLs which were blocked by the Content-Security-Policy. Added blob: to imgSrc directive. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.