Conversation
Add new platform module for managing CLI session state: - PlatformSession struct with project/org context - Persistent storage to ~/.syncable/platform-session.json - Load/save/clear operations with proper error handling - Display context helper for showing selected project This is a new parallel system for platform state, separate from conversation persistence. Co-Authored-By: Claude <noreply@anthropic.com>
Integrate PlatformSession into the agent: - Add platform_session field to ChatSession struct - Load platform session from disk in ChatSession::new() - Add update_platform_session() method for saving changes - Display platform context on agent startup when project selected This is informational only - loads and displays the platform context but does not change any agent behavior yet. Co-Authored-By: Claude <noreply@anthropic.com>
Add new platform API client module with: - PlatformApiError enum with comprehensive error types (HttpError, ApiError, ParseError, Unauthorized, NotFound, PermissionDenied, RateLimited, ServerError) - Response types: Organization, Project, ProjectMember, UserProfile - PlatformApiClient with HTTP client configured for 30s timeout and custom user-agent - Integration with existing credentials module for auth token retrieval - API methods: get_current_user, list_organizations, get_organization, list_projects, get_project, create_project - Proper HTTP status code handling (401, 403, 404, 429, 5xx) - Unit tests for client construction, URL building, and error types Co-Authored-By: Claude <noreply@anthropic.com>
Add new platform tools module for Syncable Platform API integration: - ListOrganizationsTool: List organizations user belongs to - ListProjectsTool: List projects within an organization - SelectProjectTool: Select a project as current context (persists to session) - CurrentContextTool: Get the currently selected project context Tools use PlatformApiClient for API calls and PlatformSession for persistence. Error handling follows existing tool patterns with format_error_for_llm for LLM-friendly error responses. Co-Authored-By: Claude <noreply@anthropic.com>
Add platform tools to all agent builder chains (OpenAI, Anthropic, Bedrock) in both run_interactive and run_query functions. Registered tools: - ListOrganizationsTool - ListProjectsTool - SelectProjectTool - CurrentContextTool These tools are available in all modes (analysis, planning, generation) to allow users to manage their Syncable Platform project context. Co-Authored-By: Claude <noreply@anthropic.com>
Add CloudProvider enum and CloudCredentialStatus types for checking cloud provider connection status. The API only returns connection metadata (id, provider name) and NEVER exposes actual credentials like OAuth tokens or API keys. Co-Authored-By: Claude <noreply@anthropic.com>
Add two new agent tools for cloud provider connection management: - OpenProviderSettingsTool: Opens the cloud providers settings page in the user's browser where they can connect GCP/AWS/Azure/Hetzner - CheckProviderConnectionTool: Checks if a provider is connected to a project (returns status only, NEVER credentials) SECURITY: The agent never handles actual credentials. All OAuth/API key management happens securely in the browser through the platform. Co-Authored-By: Claude <noreply@anthropic.com>
Register OpenProviderSettingsTool and CheckProviderConnectionTool in all agent builder chains (OpenAI, Anthropic, Bedrock providers for both interactive and single-query modes). Co-Authored-By: Claude <noreply@anthropic.com>
Add deployment-related types (DeploymentConfig, TriggerDeploymentRequest, TriggerDeploymentResponse, DeploymentTaskStatus, DeployedService, PaginatedDeployments) and corresponding PlatformApiClient methods for: - list_deployment_configs - trigger_deployment - get_deployment_status - list_deployments Co-Authored-By: Claude <noreply@anthropic.com>
Add four new agent tools for service deployment management: - ListDeploymentConfigsTool: List deployment configs for a project - TriggerDeploymentTool: Trigger deployment using a config - GetDeploymentStatusTool: Get deployment task status/progress - ListDeploymentsTool: List recent deployments with URLs Each tool follows the established platform tool patterns with proper error handling and user-friendly JSON responses. Co-Authored-By: Claude <noreply@anthropic.com>
Register four deployment tools with the agent builder for all providers: - ListDeploymentConfigsTool - TriggerDeploymentTool - GetDeploymentStatusTool - ListDeploymentsTool Update tools module exports and documentation to include the new deployment tools. Co-Authored-By: Claude <noreply@anthropic.com>
Add LogEntry, LogQueryStats, and GetLogsResponse types for container logs. Add get_service_logs method to PlatformApiClient for fetching service logs with support for time filters (start/end) and line limits. Co-Authored-By: Claude <noreply@anthropic.com>
Add GetServiceLogsTool for fetching container logs from deployed services. Features: - Retrieves logs with timestamps and container metadata - Supports time filtering (start/end ISO timestamps) - Supports line limits for efficient retrieval - Returns user-friendly JSON output for the agent Register tool in all agent builder chains. Co-Authored-By: Claude <noreply@anthropic.com>
- Add ProjectCommand enum with list, select, current, info subcommands - Add OrgCommand enum with list, select subcommands - Add Project and Org variants to Commands enum
Backend API returns responses wrapped in GenericResponse<T> format
({"data": ...}) but CLI was deserializing directly to T, causing
parse errors.
Co-Authored-By: Claude <noreply@anthropic.com>
Add handlers for new CLI commands: - project list: List projects in current organization - project select: Select a project by ID - project current: Show current org/project context - project info: Show project details - org list: List organizations - org select: Select an organization Uses PlatformApiClient for API calls and PlatformSession for context persistence. Co-Authored-By: Claude <noreply@anthropic.com>
Add Project and Org commands to main.rs routing: - Added to command_name match for telemetry tracking - Added to result match for command execution - Routes to lib.rs handlers Co-Authored-By: Claude <noreply@anthropic.com>
Shows selected org/project in chat welcome banner: - If project selected: "📦 Project: org-name/project-name" - If no project: "📦 Project: (none selected)" with hint Co-Authored-By: Claude <noreply@anthropic.com>
Shows selected org/project in the input prompt: - If project selected: "[org/project] >" - If no project: ">" (standard prompt) Co-Authored-By: Claude <noreply@anthropic.com>
- Add retry configuration constants (3 retries, 500ms-5s backoff) - Add is_retryable_error() for HttpError, RateLimited, ServerError - Update get() with exponential backoff retry for transient errors - Update get_optional() with same retry logic - Update post() to only retry on network errors (safe for non-idempotent) - Log retry attempts to stderr for user visibility Co-Authored-By: Claude <noreply@anthropic.com>
- Add suggestion() method returning user-friendly resolution advice - Add with_suggestion() for formatted error + suggestion output - Cover all error variants with appropriate suggestions - Suggestions help users understand how to fix common issues Co-Authored-By: Claude <noreply@anthropic.com>
- Add ConnectionFailed error variant for explicit connection failures - Add check_connection() method with 5s timeout for quick health checks - Add suggestion for ConnectionFailed error - Update is_retryable_error() to include ConnectionFailed - Update all platform tool format_api_error functions to handle ConnectionFailed Co-Authored-By: Claude <noreply@anthropic.com>
- Add ClusterEntity and ClusterStatus types for K8s clusters - Add ArtifactRegistry and RegistryStatus types for container registries - Add list_clusters_for_project() and get_cluster() methods - Add list_registries_for_project() and list_ready_registries_for_project() - Export new types from platform::api module Part of v1.10 CLI Service Deployment (Phase 54) Co-Authored-By: Claude <noreply@anthropic.com>
- Add DiscoveredDockerfile type with deployment-focused fields - Add suggest_service_name() with sanitization for K8s service names - Add compute_build_context() for relative path computation - Add infer_default_port() for common base images - Add discover_dockerfiles_for_deployment() main discovery function - Export new types from analyzer module - Add 16 unit tests for discovery functions Co-Authored-By: Claude <noreply@anthropic.com>
- Add DeploymentTarget enum (CloudRunner vs Kubernetes) - Add WizardDeploymentConfig for wizard state tracking - Add CreateDeploymentConfigRequest for API calls - Add ProviderDeploymentStatus with ClusterSummary/RegistrySummary - Add 8 unit tests for new types Co-Authored-By: Claude <noreply@anthropic.com>
Add wizard module with shared rendering utilities for deployment wizard: - wizard_render_config(): Custom RenderConfig with LightCyan styling - display_step_header(): Box UI for wizard steps with term_width support - status_indicator(): Green checkmark/red X for connection status - count_badge(): Formatted count display Co-Authored-By: Claude <noreply@anthropic.com>
Add get_provider_deployment_statuses() to query clusters/registries: - Groups resources by cloud provider - Determines connection status from existing resources - Identifies Cloud Runner availability (GCP/Hetzner) - Builds human-readable status summary - Add Hash derive to CloudProvider for HashMap key usage Co-Authored-By: Claude <noreply@anthropic.com>
Add interactive provider selection with visual status display: - ProviderSelectionResult enum for selection outcomes - select_provider() with inquire Select prompt - Status indicators (checkmark/X) for connection state - Graceful handling for no connected providers - Cancel and escape handling - Update mod.rs with explicit named exports Co-Authored-By: Claude <noreply@anthropic.com>
Add deployment target selection (Cloud Runner vs Kubernetes): - TargetSelectionResult enum with Selected/Back/Cancelled - select_target() shows targets available for selected provider - Cloud Runner shows "fully managed" description - Kubernetes shows cluster count - Back option for wizard navigation Co-Authored-By: Claude <noreply@anthropic.com>
Add Kubernetes cluster selection for deployments: - ClusterSelectionResult enum with Selected/Back/Cancelled - select_cluster() shows healthy clusters with regions - Status indicators (checkmark) for cluster health - Back option to return to target selection Co-Authored-By: Claude <noreply@anthropic.com>
…mmand
Bug fixes for deployment flow:
1. Fix dockerfile_path to be relative to build_context
- When build_context is a subdirectory (e.g., services/api), the
dockerfile_path was being sent as the full repo-relative path
(e.g., services/api/Dockerfile)
- Docker build expects the path relative to the context directory
(just "Dockerfile" in this case)
- Now strips the build_context prefix from dockerfile_path when they
share a common prefix
2. Add missing `deploy status` command
- CLI output said "Track progress: sync-ctl deploy status <task-id>"
but the command didn't exist
- Added DeployCommand::Status { task_id, watch } subcommand
- Displays deployment progress, status, errors with colors
- --watch flag polls every 5 seconds until completion
Fixes cloud runner build error:
"lstat /workspace/source/Dockerfile: no such file or directory"
Co-Authored-By: Claude <noreply@anthropic.com>
Add verbose logging to help diagnose deployment trigger issues: - Log trigger request parameters (projectId, configId) - Log successful trigger response (backstageTaskId, status) - Make error messages more prominent with colored output Use -v or -vv flag with sync-ctl deploy to see debug logs. Co-Authored-By: Claude <noreply@anthropic.com>
Docker's -f flag expects the path relative to where docker is invoked (repo root), not relative to the build context directory. Before: dockerfile="Dockerfile", context="services/contact-intelligence" -> Docker looks for /workspace/source/Dockerfile (not found) After: dockerfile="services/contact-intelligence/Dockerfile", context="services/contact-intelligence" -> Docker finds /workspace/source/services/contact-intelligence/Dockerfile Co-Authored-By: Claude <noreply@anthropic.com>
Previous approach using strip_prefix had edge cases with relative vs absolute paths. New approach constructs dockerfile path by joining build_context with filename, which is more robust. For Dockerfile at services/contact-intelligence/Dockerfile: - build_context = "services/contact-intelligence" - dockerfile_name = "Dockerfile" - result = "services/contact-intelligence/Dockerfile" This ensures Docker's -f flag receives the correct path relative to repo root where docker is invoked. Co-Authored-By: Claude <noreply@anthropic.com>
Adds detailed debug logging to show exact request fields being sent when creating a deployment config. Run with -vv to see: - All request fields (projectId, serviceName, environmentId, etc.) - Dockerfile path and build context - CloudRunnerConfig JSON - Response confirmation with config ID Co-Authored-By: Claude <noreply@anthropic.com>
Add PortSource enum to track where ports are detected from: - Dockerfile, DockerCompose, PackageJson, FrameworkDefault, EnvVar, SourceCode, ConfigFile Update all Port struct usages to include source field. Backward compatible - source field is optional. Co-Authored-By: Claude <noreply@anthropic.com>
Add HealthEndpoint and HealthEndpointSource types for deployment recommendations. Detect health endpoints from: - Framework conventions (Spring Actuator, Quarkus, etc.) - Source code patterns (route definitions) Includes health_endpoints field in ProjectAnalysis. Fix pre-existing test issue in types.rs. Co-Authored-By: Claude <noreply@anthropic.com>
Add detection for existing infrastructure configurations: - Kubernetes manifests (k8s/, deploy/, manifests/ directories) - Helm charts (Chart.yaml detection) - Terraform files (*.tf) - Docker Compose files - Syncable deployment configs Includes InfrastructurePresence struct with has_any() and detected_types() helper methods. Detection is integrated into analyze_project_with_config. Co-Authored-By: Claude <noreply@anthropic.com>
Create intelligent deployment recommendation module that: - Selects provider based on availability and existing infrastructure - Selects target (Cloud Runner vs K8s) based on project analysis - Selects machine type based on framework memory requirements (JVM=high, Python=medium, Node/Go/Rust=low) - Selects region with user hint support - Selects port from best detection source - Includes health check path when detected - Calculates confidence score - Provides alternatives for user customization Includes 9 comprehensive tests covering Express, Spring Boot, K8s detection, port fallback, health endpoints, and alternatives. Co-Authored-By: Claude <noreply@anthropic.com>
Create compound agent tool that enables end-to-end deployment: - Analyzes project (language, framework, ports, health endpoints) - Checks available deployment capabilities - Generates recommendations with reasoning using 11.3-02 engine - Returns preview with confirmation prompt (preview_only=true) - Executes deployment when confirmed (preview_only=false) Features: - Provider/machine/region/port overrides for customization - Monorepo support with optional path parameter - Derives dockerfile path and build context from analysis - Uses PlatformSession for context, recommendation engine for settings - Includes alternatives for user customization 5 tests covering tool name, preview mode, service name derivation, and error handling for nonexistent paths. Co-Authored-By: Claude <noreply@anthropic.com>
…yServiceTool Prevents creating duplicate deployment configs by: - Checking existing configs before deploying - Routing to redeploy if service already exists - Showing environment info (name, is_production) in preview - Adding production deployment warnings - Showing REDEPLOY vs NEW_DEPLOYMENT mode clearly Co-Authored-By: Claude <noreply@anthropic.com>
The API wraps all responses in { "data": ... } but check_provider_connection
and get_cluster were not unwrapping this, causing parse errors when the
provider IS connected.
This explains why the agent couldn't detect connected providers.
Co-Authored-By: Claude <noreply@anthropic.com>
The endpoint /api/cloud-credentials/provider/{provider} may not exist.
Changed to use list_cloud_credentials_for_project (which works) and
filter by provider.
This is the same approach the wizard uses via get_provider_deployment_statuses.
Co-Authored-By: Claude <noreply@anthropic.com>
The tool exists but wasn't exported from tools/mod.rs or registered in the agent. This tool uses the working wizard code to detect connected providers, which is more reliable than check_provider_connection. Now the agent has access to list_deployment_capabilities which shows all connected providers, clusters, and registries at once. Co-Authored-By: Claude <noreply@anthropic.com>
The agent couldn't create deployments because these tools weren't registered: - CreateDeploymentConfigTool - manual config creation - DeployServiceTool - intelligent deployment with analysis Now the agent can: 1. Analyze projects and recommend deployment settings 2. Create deployment configs 3. Trigger deployments Co-Authored-By: Claude <noreply@anthropic.com>
The Backstage task can show "completed" (100%) when infrastructure is provisioned, but Cloud Runner actual deployment (build + deploy) takes longer. Added optional project_id and service_name params that when provided: - Also check list_deployments for actual service status - Look for public_url which indicates service is truly ready - Return service_ready: true only when URL is available - Show helpful note when task is 100% but service still deploying Now the agent can accurately report when a Cloud Runner service is actually ready to serve traffic, not just when infrastructure is ready. Co-Authored-By: Claude <noreply@anthropic.com>
Added guidelines to not narrate actions like "I'll call X tool" or "The user wants Y so I'll Z". The agent should take action directly without announcing what it's about to do. Users care about results, not internal reasoning. Co-Authored-By: Claude <noreply@anthropic.com>
…oyments When deploying a service from a subdirectory (e.g., path: "services/contact-intelligence"), the dockerfile path and build context must be relative to the repo root, not the analyzed subdirectory. Before: dockerfile="Dockerfile", context="." (relative to subdirectory) After: dockerfile="services/contact-intelligence/Dockerfile", context="services/contact-intelligence" Changes: - Extract dockerfile filename, then prepend the subpath to construct repo-relative paths - Follow the same pattern as orchestrator.rs (commit 3cb8698) - Add docker_config to deployment response for visibility - Add debug logging for path derivation troubleshooting Fixes cloud runner failing with "unable to evaluate symlinks in Dockerfile path: lstat /workspace/source/Dockerfile: no such file or directory" when deploying monorepo services. Co-Authored-By: Claude <noreply@anthropic.com>
For monorepo deployments, the agent now sends the same values as the manual wizard: - dockerfile: full path from repo root (e.g., "services/foo/Dockerfile") - context: the service folder (e.g., "services/foo") This matches what the user would select in the manual wizard when choosing the Dockerfile's directory as the build context. The context is crucial for Docker's COPY commands - if the Dockerfile has `COPY . .`, it copies from the context directory, not repo root. Co-Authored-By: Claude <noreply@anthropic.com>
When user specifies path="services/foo" to deploy a subdirectory, the dockerfile paths should be relative to THAT directory, not the project root. This matches the manual wizard behavior when you run `sync-ctl deploy` from within the service directory: - dockerfile: "Dockerfile" - context: "." The GitHub repo structure may differ from the local filesystem structure. For example, locally you might have: /project/services/contact-intelligence/Dockerfile But the GitHub repo might have: /Dockerfile (at root) Previously we were prepending args.path to make paths "repo-root-relative", but this broke deployments when the repo structure differed from local. Co-Authored-By: Claude <noreply@anthropic.com>
… Runner Cloud Runner clones the GitHub repo and needs paths relative to the repo root, not relative to the analyzed subdirectory. When deploying from a monorepo subdirectory (e.g., services/contact-intelligence), the dockerfile_path and build_context must include the full path from repo root. Example for path="services/contact-intelligence": - Before: dockerfile="Dockerfile", context="." - After: dockerfile="services/contact-intelligence/Dockerfile", context="services/contact-intelligence" Co-Authored-By: Claude <noreply@anthropic.com>
The agent was picking the first repository from the project's connected repos, which happened to be the GitOps infrastructure repo instead of the application repo. Now the agent: 1. Detects the local git remote URL 2. Parses the repo name from the URL 3. Matches against connected repositories 4. Falls back to non-gitops repo if no match This matches the manual wizard behavior which shows: "Using detected repository: syncable-dev/ai-demo-project" Co-Authored-By: Claude <noreply@anthropic.com>
…e loop The agent was calling get_deployment_status repeatedly without waiting, creating an infinite polling loop. Updated the tool to: 1. Add explicit "action" field in response: - STOP_POLLING: deployment done (success/failure) - INFORM_USER_AND_WAIT: tell user to wait, let them ask for updates 2. Updated tool description with CRITICAL warning about not polling in loop 3. Changed next_steps to explicitly say "DO NOT call again automatically" The agent should now check status once, inform the user, and wait for them to request updates. Co-Authored-By: Claude <noreply@anthropic.com>
The agent was deploying all services as public without asking the user. Now: 1. Added is_public parameter to DeployServiceArgs (default: false) 2. Preview shows is_public with clear explanation: - "Service will be INTERNAL only (not accessible from internet)" - "Service will be PUBLICLY accessible from the internet" 3. Uses args.is_public when creating deployment config This ensures services are internal by default for safety, and the agent must explicitly show and confirm public access with the user. Co-Authored-By: Claude <noreply@anthropic.com>
When user requests a change (e.g., "make it public", "use GCP"), the agent was deploying immediately instead of showing a new preview. Updated tool description to be explicit: - A change request is NOT a deployment confirmation - Must show NEW preview with updated settings - Only deploy after explicit "yes", "deploy", "confirm" Flow: request → preview → change request → NEW preview → confirm → deploy Co-Authored-By: Claude <noreply@anthropic.com>
This was referenced Jan 20, 2026
Merged
Merged
Merged
Alex793x
added a commit
that referenced
this pull request
Mar 28, 2026
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
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.