Skip to content

Commit 0f57547

Browse files
committed
Story RHOAIENG-45393: Add left panel hide and resize capabilities
1 parent 1d0d7e1 commit 0f57547

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1973
-8351
lines changed

.github/workflows/claude-live-test.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,6 @@ jobs:
216216
217217
- name: Run Claude with Playwright MCP
218218
uses: anthropics/claude-code-action@v1
219-
continue-on-error: true
220-
id: claude_test
221219
env:
222220
TEST_TOKEN: ${{ steps.token.outputs.token }}
223221
DEBUG: "*"

.github/workflows/components-build-deploy.yml

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ on:
1010
- 'components/operator/**'
1111
- 'components/backend/**'
1212
- 'components/frontend/**'
13-
- 'components/public-api/**'
1413
pull_request_target:
1514
branches: [main]
1615
paths:
@@ -20,7 +19,6 @@ on:
2019
- 'components/operator/**'
2120
- 'components/backend/**'
2221
- 'components/frontend/**'
23-
- 'components/public-api/**'
2422
workflow_dispatch:
2523
inputs:
2624
force_build_all:
@@ -29,7 +27,7 @@ on:
2927
type: boolean
3028
default: false
3129
components:
32-
description: 'Components to build (comma-separated: frontend,backend,operator,claude-runner,state-sync,public-api) - leave empty for all'
30+
description: 'Components to build (comma-separated: frontend,backend,operator,claude-runner,state-sync) - leave empty for all'
3331
required: false
3432
type: string
3533
default: ''
@@ -47,7 +45,6 @@ jobs:
4745
operator: ${{ steps.filter.outputs.operator }}
4846
claude-runner: ${{ steps.filter.outputs.claude-runner }}
4947
state-sync: ${{ steps.filter.outputs.state-sync }}
50-
public-api: ${{ steps.filter.outputs.public-api }}
5148
steps:
5249
- name: Checkout code
5350
uses: actions/checkout@v6
@@ -69,8 +66,6 @@ jobs:
6966
- 'components/runners/claude-code-runner/**'
7067
state-sync:
7168
- 'components/runners/state-sync/**'
72-
public-api:
73-
- 'components/public-api/**'
7469
7570
build-and-push:
7671
runs-on: ubuntu-latest
@@ -108,11 +103,6 @@ jobs:
108103
image: quay.io/ambient_code/vteam_state_sync
109104
dockerfile: ./components/runners/state-sync/Dockerfile
110105
changed: ${{ needs.detect-changes.outputs.state-sync }}
111-
- name: public-api
112-
context: ./components/public-api
113-
image: quay.io/ambient_code/vteam_public_api
114-
dockerfile: ./components/public-api/Dockerfile
115-
changed: ${{ needs.detect-changes.outputs.public-api }}
116106
steps:
117107
- name: Checkout code
118108
if: matrix.component.changed == 'true' || github.event.inputs.force_build_all == 'true' || contains(github.event.inputs.components, matrix.component.name) || (github.event_name == 'workflow_dispatch' && github.event.inputs.components == '' && github.event.inputs.force_build_all != 'true')
@@ -197,7 +187,7 @@ jobs:
197187
deploy-to-openshift:
198188
runs-on: ubuntu-latest
199189
needs: [detect-changes, build-and-push, update-rbac-and-crd]
200-
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && (needs.detect-changes.outputs.frontend == 'true' || needs.detect-changes.outputs.backend == 'true' || needs.detect-changes.outputs.operator == 'true' || needs.detect-changes.outputs.claude-runner == 'true' || needs.detect-changes.outputs.state-sync == 'true' || needs.detect-changes.outputs.public-api == 'true')
190+
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && (needs.detect-changes.outputs.frontend == 'true' || needs.detect-changes.outputs.backend == 'true' || needs.detect-changes.outputs.operator == 'true' || needs.detect-changes.outputs.claude-runner == 'true' || needs.detect-changes.outputs.state-sync == 'true')
201191
steps:
202192
- name: Checkout code
203193
uses: actions/checkout@v6
@@ -250,12 +240,6 @@ jobs:
250240
echo "state_sync_tag=stage" >> $GITHUB_OUTPUT
251241
fi
252242
253-
if [ "${{ needs.detect-changes.outputs.public-api }}" == "true" ]; then
254-
echo "public_api_tag=${{ github.sha }}" >> $GITHUB_OUTPUT
255-
else
256-
echo "public_api_tag=stage" >> $GITHUB_OUTPUT
257-
fi
258-
259243
- name: Update kustomization with image tags
260244
working-directory: components/manifests/overlays/production
261245
run: |
@@ -264,7 +248,6 @@ jobs:
264248
kustomize edit set image quay.io/ambient_code/vteam_operator:latest=quay.io/ambient_code/vteam_operator:${{ steps.image-tags.outputs.operator_tag }}
265249
kustomize edit set image quay.io/ambient_code/vteam_claude_runner:latest=quay.io/ambient_code/vteam_claude_runner:${{ steps.image-tags.outputs.runner_tag }}
266250
kustomize edit set image quay.io/ambient_code/vteam_state_sync:latest=quay.io/ambient_code/vteam_state_sync:${{ steps.image-tags.outputs.state_sync_tag }}
267-
kustomize edit set image quay.io/ambient_code/vteam_public_api:latest=quay.io/ambient_code/vteam_public_api:${{ steps.image-tags.outputs.public_api_tag }}
268251
269252
- name: Validate kustomization
270253
working-directory: components/manifests/overlays/production
@@ -282,8 +265,7 @@ jobs:
282265
run: |
283266
oc set env deployment/frontend -n ambient-code -c frontend \
284267
GITHUB_APP_SLUG="ambient-code-stage" \
285-
VTEAM_VERSION="${{ github.sha }}" \
286-
FEEDBACK_URL="https://forms.gle/7XiWrvo6No922DUz6"
268+
VTEAM_VERSION="${{ github.sha }}"
287269
288270
- name: Update backend environment variables
289271
if: needs.detect-changes.outputs.backend == 'true'
@@ -330,7 +312,6 @@ jobs:
330312
kustomize edit set image quay.io/ambient_code/vteam_operator:latest=quay.io/ambient_code/vteam_operator:stage
331313
kustomize edit set image quay.io/ambient_code/vteam_claude_runner:latest=quay.io/ambient_code/vteam_claude_runner:stage
332314
kustomize edit set image quay.io/ambient_code/vteam_state_sync:latest=quay.io/ambient_code/vteam_state_sync:stage
333-
kustomize edit set image quay.io/ambient_code/vteam_public_api:latest=quay.io/ambient_code/vteam_public_api:stage
334315
335316
- name: Validate kustomization
336317
working-directory: components/manifests/overlays/production
@@ -347,8 +328,7 @@ jobs:
347328
run: |
348329
oc set env deployment/frontend -n ambient-code -c frontend \
349330
GITHUB_APP_SLUG="ambient-code-stage" \
350-
VTEAM_VERSION="${{ github.sha }}" \
351-
FEEDBACK_URL="https://forms.gle/7XiWrvo6No922DUz6"
331+
VTEAM_VERSION="${{ github.sha }}"
352332
353333
- name: Update backend environment variables
354334
run: |

.github/workflows/prod-release-deploy.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,7 @@ jobs:
265265
run: |
266266
oc set env deployment/frontend -n ambient-code -c frontend \
267267
GITHUB_APP_SLUG="ambient-code" \
268-
VTEAM_VERSION="${{ needs.release.outputs.new_tag }}" \
269-
FEEDBACK_URL="https://forms.gle/7XiWrvo6No922DUz6"
268+
VTEAM_VERSION="${{ needs.release.outputs.new_tag }}"
270269
271270
- name: Update backend environment variables
272271
run: |

CLAUDE.md

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -461,23 +461,6 @@ Langfuse supports OpenTelemetry as of 2025:
461461
- FORBIDDEN: `BlockOwnerDeletion` (causes permission issues in multi-tenant environments)
462462
- Pattern: (operator/internal/handlers/sessions.go:125-134, handlers/sessions.go:470-476)
463463

464-
### Exception: Public API Gateway Service
465-
466-
The `components/public-api/` service is a **stateless HTTP gateway** that does NOT follow the standard backend patterns above. This is intentional:
467-
468-
- **No K8s Clients**: The public-api does NOT use `GetK8sClientsForRequest()` or access Kubernetes directly
469-
- **No RBAC Permissions**: The ServiceAccount has NO RoleBindings - it cannot access any K8s resources
470-
- **Token Forwarding Only**: All requests are proxied to the backend with the user's token in the `Authorization` header
471-
- **Backend Validates**: All K8s operations and RBAC enforcement happen in the backend service
472-
473-
**Why different?** The public-api is a thin shim layer that:
474-
1. Extracts and validates tokens
475-
2. Extracts project context (from header or ServiceAccount token)
476-
3. Validates input parameters (prevents injection attacks)
477-
4. Forwards requests with proper authorization headers
478-
479-
This separation of concerns improves security by minimizing the attack surface of the externally-exposed service.
480-
481464
### Package Organization
482465

483466
**Backend Structure** (`components/backend/`):

Makefile

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: help setup build-all build-frontend build-backend build-operator build-runner build-state-sync build-public-api deploy clean check-architecture
1+
.PHONY: help setup build-all build-frontend build-backend build-operator build-runner build-state-sync deploy clean check-architecture
22
.PHONY: local-up local-down local-clean local-status local-rebuild local-reload-backend local-reload-frontend local-reload-operator local-sync-version
33
.PHONY: local-dev-token
44
.PHONY: local-logs local-logs-backend local-logs-frontend local-logs-operator local-shell local-shell-frontend
@@ -59,7 +59,6 @@ BACKEND_IMAGE ?= vteam_backend:latest
5959
OPERATOR_IMAGE ?= vteam_operator:latest
6060
RUNNER_IMAGE ?= vteam_claude_runner:latest
6161
STATE_SYNC_IMAGE ?= vteam_state_sync:latest
62-
PUBLIC_API_IMAGE ?= vteam_public_api:latest
6362

6463
# Vertex AI Configuration (for LOCAL_VERTEX=true)
6564
# These inherit from environment if set, or can be overridden on command line
@@ -115,7 +114,7 @@ help: ## Display this help message
115114

116115
##@ Building
117116

118-
build-all: build-frontend build-backend build-operator build-runner build-state-sync build-public-api ## Build all container images
117+
build-all: build-frontend build-backend build-operator build-runner build-state-sync ## Build all container images
119118

120119
build-frontend: ## Build frontend image
121120
@echo "$(COLOR_BLUE)$(COLOR_RESET) Building frontend with $(CONTAINER_ENGINE)..."
@@ -147,12 +146,6 @@ build-state-sync: ## Build state-sync image for S3 persistence
147146
-t vteam_state_sync:latest .
148147
@echo "$(COLOR_GREEN)$(COLOR_RESET) State-sync built: vteam_state_sync:latest"
149148

150-
build-public-api: ## Build public API gateway image
151-
@echo "$(COLOR_BLUE)$(COLOR_RESET) Building public-api with $(CONTAINER_ENGINE)..."
152-
@cd components/public-api && $(CONTAINER_ENGINE) build $(PLATFORM_FLAG) $(BUILD_FLAGS) \
153-
-t $(PUBLIC_API_IMAGE) .
154-
@echo "$(COLOR_GREEN)$(COLOR_RESET) Public API built: $(PUBLIC_API_IMAGE)"
155-
156149
##@ Git Hooks
157150

158151
setup-hooks: ## Install git hooks for branch protection

components/backend/handlers/content.go

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -663,20 +663,15 @@ func ContentWorkflowMetadata(c *gin.Context) {
663663
log.Printf("ContentWorkflowMetadata: agents directory not found or unreadable: %v", err)
664664
}
665665

666-
configResponse := gin.H{
667-
"name": ambientConfig.Name,
668-
"description": ambientConfig.Description,
669-
"systemPrompt": ambientConfig.SystemPrompt,
670-
"artifactsDir": ambientConfig.ArtifactsDir,
671-
}
672-
if ambientConfig.Rubric != nil {
673-
configResponse["rubric"] = ambientConfig.Rubric
674-
}
675-
676666
c.JSON(http.StatusOK, gin.H{
677667
"commands": commands,
678668
"agents": agents,
679-
"config": configResponse,
669+
"config": gin.H{
670+
"name": ambientConfig.Name,
671+
"description": ambientConfig.Description,
672+
"systemPrompt": ambientConfig.SystemPrompt,
673+
"artifactsDir": ambientConfig.ArtifactsDir,
674+
},
680675
})
681676
}
682677

@@ -718,21 +713,12 @@ func parseFrontmatter(filePath string) map[string]string {
718713
return result
719714
}
720715

721-
// RubricConfig represents the rubric evaluation configuration in ambient.json.
722-
// Schema is a JSON Schema object that defines the tool's input_schema for
723-
// additional metadata fields beyond final_score and reasoning.
724-
type RubricConfig struct {
725-
ActivationPrompt string `json:"activationPrompt,omitempty"`
726-
Schema map[string]interface{} `json:"schema,omitempty"`
727-
}
728-
729716
// AmbientConfig represents the ambient.json configuration
730717
type AmbientConfig struct {
731-
Name string `json:"name"`
732-
Description string `json:"description"`
733-
SystemPrompt string `json:"systemPrompt"`
734-
ArtifactsDir string `json:"artifactsDir"`
735-
Rubric *RubricConfig `json:"rubric,omitempty"`
718+
Name string `json:"name"`
719+
Description string `json:"description"`
720+
SystemPrompt string `json:"systemPrompt"`
721+
ArtifactsDir string `json:"artifactsDir"`
736722
}
737723

738724
// parseAmbientConfig reads and parses ambient.json from workflow directory

components/backend/handlers/gitlab_auth.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,12 @@ func validateGitLabInput(instanceURL, token string) error {
102102
}
103103

104104
// Validate token contains only valid characters (alphanumeric and some special chars)
105-
// GitLab tokens use: a-z, A-Z, 0-9, -, _, .
105+
// GitLab tokens use: a-z, A-Z, 0-9, -, _
106106
for _, char := range token {
107107
if (char < 'a' || char > 'z') &&
108108
(char < 'A' || char > 'Z') &&
109109
(char < '0' || char > '9') &&
110-
char != '-' && char != '_' && char != '.' {
110+
char != '-' && char != '_' {
111111
return fmt.Errorf("token contains invalid characters")
112112
}
113113
}

components/backend/handlers/gitlab_auth_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ var _ = Describe("GitLab Auth Handler", Label(test_constants.LabelUnit, test_con
103103
"token-with-dashes-456", // with dashes
104104
"UPPERCASE_TOKEN_789012", // uppercase, 20 chars
105105
"MixedCase-Token_1234567", // mixed case, 20 chars
106-
"glpat-abc123xyz.01.def456ghi", // with periods (GitLab token format)
107106
}
108107

109108
for _, token := range validTokens {
@@ -196,6 +195,7 @@ var _ = Describe("GitLab Auth Handler", Label(test_constants.LabelUnit, test_con
196195
"token;with;semicolons",
197196
"token:with:colons",
198197
"token,with,commas",
198+
"token.with.dots",
199199
"token?with?questions",
200200
"token!with!exclamations",
201201
}

components/backend/handlers/integrations_status.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package handlers
33
import (
44
"context"
55
"net/http"
6+
"time"
67

78
"github.com/gin-gonic/gin"
89
)
@@ -62,13 +63,13 @@ func getGitHubStatusForUser(ctx context.Context, userID string) gin.H {
6263
// Check GitHub PAT
6364
patCreds, err := GetGitHubPATCredentials(ctx, userID)
6465
if err == nil && patCreds != nil {
65-
// NOTE: Validation disabled - if credentials are stored, assume they're valid
66-
// The integration will fail gracefully if credentials are actually invalid
66+
// Validate PAT token
67+
valid, _ := ValidateGitHubToken(ctx, patCreds.Token)
6768

6869
status["pat"] = gin.H{
6970
"configured": true,
7071
"updatedAt": patCreds.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
71-
"valid": true,
72+
"valid": valid,
7273
}
7374
}
7475

@@ -88,15 +89,19 @@ func getGoogleStatusForUser(ctx context.Context, userID string) gin.H {
8889
return gin.H{"connected": false}
8990
}
9091

91-
// NOTE: Validation disabled - if credentials are stored, assume they're valid
92-
// The backend auto-refreshes tokens and the integration will fail gracefully if invalid
92+
// Check if token is expired
93+
isExpired := time.Now().After(creds.ExpiresAt)
94+
valid := !isExpired
95+
96+
// If near expiry, could validate with Google API, but checking expiry is sufficient
97+
// since backend auto-refreshes tokens
9398

9499
return gin.H{
95100
"connected": true,
96101
"email": creds.Email,
97102
"expiresAt": creds.ExpiresAt.Format("2006-01-02T15:04:05Z07:00"),
98103
"updatedAt": creds.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
99-
"valid": true,
104+
"valid": valid,
100105
}
101106
}
102107

@@ -126,13 +131,13 @@ func getGitLabStatusForUser(ctx context.Context, userID string) gin.H {
126131
return gin.H{"connected": false}
127132
}
128133

129-
// NOTE: Validation disabled - if credentials are stored, assume they're valid
130-
// The integration will fail gracefully if credentials are actually invalid
134+
// Validate token
135+
valid, _ := ValidateGitLabToken(ctx, creds.Token, creds.InstanceURL)
131136

132137
return gin.H{
133138
"connected": true,
134139
"instanceUrl": creds.InstanceURL,
135140
"updatedAt": creds.UpdatedAt,
136-
"valid": true,
141+
"valid": valid,
137142
}
138143
}

components/backend/main.go

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -94,25 +94,13 @@ func main() {
9494
// Initialize git package
9595
git.GetProjectSettingsResource = k8s.GetProjectSettingsResource
9696
git.GetGitHubInstallation = func(ctx context.Context, userID string) (interface{}, error) {
97-
installation, err := github.GetInstallation(ctx, userID)
98-
if installation == nil {
99-
return nil, err
100-
}
101-
return installation, err
97+
return github.GetInstallation(ctx, userID)
10298
}
10399
git.GetGitHubPATCredentials = func(ctx context.Context, userID string) (interface{}, error) {
104-
creds, err := handlers.GetGitHubPATCredentials(ctx, userID)
105-
if creds == nil {
106-
return nil, err
107-
}
108-
return creds, err
100+
return handlers.GetGitHubPATCredentials(ctx, userID)
109101
}
110102
git.GetGitLabCredentials = func(ctx context.Context, userID string) (interface{}, error) {
111-
creds, err := handlers.GetGitLabCredentials(ctx, userID)
112-
if creds == nil {
113-
return nil, err
114-
}
115-
return creds, err
103+
return handlers.GetGitLabCredentials(ctx, userID)
116104
}
117105
git.GitHubTokenManager = github.Manager
118106
git.GetBackendNamespace = func() string {

0 commit comments

Comments
 (0)