Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@
*.whatif.txt
infra/main.json


.tmp-gh-*.ps1

.tmp-venv*/

TestResults/
34 changes: 34 additions & 0 deletions .planning/phases/06-PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Implementation Plan: Phase 06 - Elite Graphical Console

## Objective
Implement an Enterprise-Grade Next.js Visual Orchestrator for the CAS Swarm in strict adherence to the `06-UI-SPEC.md` design contract and the GSD Verifier-Led SDLC.

## Breakdown

### Step 1: Initialize Verified React Environment
- Purge any existing unverified UI code in `cas-platform/src/graphical-console` to prevent context contamination.
- Re-initialize a Next.js 16 app with TypeScript, Tailwind, and strict ESLint routing.
- Install dependencies: `@xyflow/react`, `dagre`, `framer-motion`, `lucide-react`, `react-syntax-highlighter`.
- **Verifier Gate**: `npm run build` must pass. `npm run lint` must return 0 errors.

### Step 2: Implement Core Components
- `AgentNode.tsx`: A custom React Flow node component implementing glassmorphism, pulsing indicators, and the typography defined in the UI-SPEC.
- `TelemetryDrawer.tsx`: A Framer Motion side panel to display the selected edge's raw JSON payload.
- `SwarmGraph.tsx`: The main React Flow orchestration component. It must use the `dagre` auto-layout engine to route nodes top-to-bottom.
- **Verifier Gate**: Jest unit tests must cover component rendering.

### Step 3: Implement Telemetry Pipeline
- Implement a robust `EventSource` hook to consume the `/api/swarm/events` SSE stream from the Autogen backend.
- Parse incoming `snapshot`, `node_created`, and `edge_created` frames to dynamically update the React Flow state.
- **Verifier Gate**: A dedicated integration test (or mock API harness) to verify the SSE parser correctly maps frames to DAG states.

### Step 4: Red Team Audit (Verification)
- Spawn a `qa-automation-engineer` subagent to perform an adversarial review of the codebase.
- Verify adherence to `06-UI-SPEC.md`.
- Ensure no hardcoded dummy data remains.

## Acceptance Criteria
- [ ] Dagre layout properly aligns dynamically generated nodes.
- [ ] Framer motion drawer smoothly triggers on Edge click.
- [ ] Next.js app builds flawlessly.
- [ ] 100% of Verifier Gates passed.
23 changes: 23 additions & 0 deletions .planning/phases/06-UI-SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# UI Design Contract: Phase 06 - Elite Graphical Console

## 1. Visual Identity
- **Theme**: Ultra-dark modern interface (`bg-[#0f0f13]`).
- **Typography**:
- Primary UI text: `Inter`
- Telemetry / Code / Payloads: `JetBrains Mono`
- **Component Style**: Glassmorphism with deep backdrop blurs (`backdrop-blur-xl`) and hyper-thin colored borders (`border-purple-500/50`).

## 2. Layout & Interactions
- **DAG Engine**: Dagre Auto-Layout must be used for deterministic node routing (Top-to-Bottom).
- **Node Anatomy**: Custom React Flow nodes. Must include a status indicator, icon, and dynamic pulsing shadows based on active state.
- **Edge Anatomy**: Animated SVG paths. Must be clickable.
- **Side Panel Drawer**: Triggered by clicking an edge. Slides from the right using `framer-motion`. Displays raw A2A JSON payload with syntax highlighting.

## 3. Required Verification Gates
- 100% test coverage requirement.
- Must include a `SmokeTest` to verify the Next.js app mounts without hydration errors.
- Must include a `ContractTest` to verify the `EventSource` parser correctly interprets the Autogen SSE schema.

## 4. Subagent Routing
- **Implementer**: `personas/frontend-engineer.md`
- **Verifier**: `personas/qa-automation-engineer.md`
112 changes: 112 additions & 0 deletions infra/modules/functions.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
targetScope = 'resourceGroup'

@description('Short workload name.')
param workloadName string

@description('Deployment environment.')
param environment string

@description('Azure region.')
param location string

@description('Deterministic uniqueness suffix.')
param suffix string

@description('Non-secret Application Insights connection string injected by the platform.')
param applicationInsightsConnectionString string

@description('Log Analytics workspace identifier for diagnostic settings.')
param logAnalyticsWorkspaceId string

@description('Common Azure resource tags.')
param tags object

resource storageAccount 'Microsoft.Storage/storageAccounts@2025-01-01' = {
name: 'st${workloadName}${environment}${suffix}'
location: location
tags: tags
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
minimumTlsVersion: 'TLS1_2'
allowBlobPublicAccess: false
supportsHttpsTrafficOnly: true
}
}

resource hostingPlan 'Microsoft.Web/serverfarms@2025-03-01' = {
name: 'plan-${workloadName}-${environment}-${suffix}'
location: location
tags: tags
sku: {
name: 'FC1'
tier: 'FlexConsumption'
}
properties: {
reserved: true
}
}

resource functionApp 'Microsoft.Web/sites@2025-03-01' = {
name: 'func-${workloadName}-${environment}-${suffix}'
location: location
tags: tags
kind: 'functionapp,linux'
identity: {
type: 'SystemAssigned'
}
properties: {
serverFarmId: hostingPlan.id
siteConfig: {
linuxFxVersion: 'PYTHON|3.12'
appSettings: [
{
name: 'AzureWebJobsStorage'
value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};EndpointSuffix=core.windows.net'
}
{
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: applicationInsightsConnectionString
}
{
name: 'FUNCTIONS_EXTENSION_VERSION'
value: '~4'
}
{
name: 'FUNCTIONS_WORKER_RUNTIME'
value: 'python'
}
]
}
httpsOnly: true
}
}

#disable-next-line use-recent-api-versions
resource appDiagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
name: 'send-to-log-analytics'
scope: functionApp
properties: {
workspaceId: logAnalyticsWorkspaceId
logs: [
{
categoryGroup: 'allLogs'
enabled: true
}
]
metrics: [
{
category: 'AllMetrics'
enabled: true
}
]
}
}

@description('Function App identifier.')
output functionAppId string = functionApp.id

@description('System-assigned managed identity principal identifier.')
output workloadPrincipalId string = functionApp.identity.principalId
41 changes: 41 additions & 0 deletions src/graphical-console/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
5 changes: 5 additions & 0 deletions src/graphical-console/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->
1 change: 1 addition & 0 deletions src/graphical-console/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
36 changes: 36 additions & 0 deletions src/graphical-console/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
18 changes: 18 additions & 0 deletions src/graphical-console/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";

const eslintConfig = defineConfig([
...nextVitals,
...nextTs,
// Override default ignores of eslint-config-next.
globalIgnores([
// Default ignores of eslint-config-next:
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
]),
]);

export default eslintConfig;
7 changes: 7 additions & 0 deletions src/graphical-console/next.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
/* config options here */
};

export default nextConfig;
Loading
Loading