Kubernetes Deployment Planner
Run ID: 69bca62277c0421c0bf49ad82026-03-29Infrastructure
PantheraHive BOS
BOS Dashboard

As a professional AI assistant within PantheraHive, I am executing the "Kubernetes Deployment Planner" workflow.

This is Step 1 of 2: Generate.

Based on your inputs, I have generated a comprehensive set of Kubernetes deployment manifests, Helm chart structures, service mesh configurations, scaling policies, and monitoring setups for a representative microservice architecture on AWS EKS.

User Inputs:

Assumed Microservice Architecture:

Given the generic "services" input, I have designed a common microservice architecture to demonstrate comprehensive output. This architecture consists of:

  1. frontend-app: A user-facing web application.
  2. backend-api: A RESTful API service consumed by the frontend.
  3. redis-cache: An in-memory data store used by the backend for caching.

All generated configurations are tailored for deployment on AWS EKS and incorporate best practices for production-grade environments.


1. Kubernetes Deployment Manifests

This section provides the core Kubernetes YAML manifests for deploying the assumed microservices. These manifests are designed for clarity and include essential configurations like resource requests/limits, liveness/readiness probes, and basic environment variables.

1.1. Namespace

It's a best practice to deploy applications into their dedicated namespaces.

text • 954 chars
**Note:** The YAML files in the `templates/` directory would use Helm templating (`{{ .Values.frontendApp.image.repository }}:{{ .Values.frontendApp.image.tag }}`) to inject values from `values.yaml` and `_helpers.tpl`.

---

## 3. Service Mesh Configuration (Istio for EKS)

Istio provides powerful traffic management, security, and observability features. This section outlines how to configure Istio for your microservices, assuming Istio is already installed in your EKS cluster.

### 3.1. Prerequisites
*   Istio control plane installed (e.g., using `istioctl install` or Helm).
*   Namespace `test-cluster-name-app` labeled for Istio injection: `kubectl label namespace test-cluster-name-app istio-injection=enabled`.

### 3.2. Istio Gateway
Exposes the Istio mesh to external traffic. This will typically be fronted by an AWS Network Load Balancer (NLB) or Application Load Balancer (ALB) configured through an EKS service of type LoadBalancer.

Sandboxed live preview

yaml

monitoring-config/frontend-app-

Step 2: projectmanager

Kubernetes Deployment Planner: Comprehensive Output

This document outlines a comprehensive Kubernetes deployment strategy for your microservices on AWS EKS, incorporating best practices for manifests, Helm charts, service mesh, scaling, and monitoring.


1. Overview and Project Context

This plan addresses the deployment requirements for your services on the specified Kubernetes cluster. The goal is to provide a robust, scalable, observable, and secure foundation for your applications.

  • Cluster Name: Test Cluster Name
  • Cloud Provider: AWS EKS
  • Services to Deploy: This is a test input for the Kubernetes Deployment Planner workflow. Please generate comprehensive output. (For demonstration purposes, we will assume a multi-tier application with a frontend, backend API, and a database, along with supporting services.)
  • Key Features Addressed: Automated deployments, service discovery, load balancing, traffic management, horizontal and vertical scaling, comprehensive monitoring, and enhanced security.

2. Core Kubernetes Manifests

Below are examples of essential Kubernetes manifests. These examples are generic and should be adapted for each specific microservice.

2.1. Namespace Manifest (namespace.yaml)

It's a best practice to organize services within dedicated namespaces.


apiVersion: v1
kind: Namespace
metadata:
  name: my-application-namespace
  labels:
    app: my-application
    environment: dev

2.2. Deployment Manifest (deployment.yaml)

Example for a generic backend API service.


apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-backend-api
  namespace: my-application-namespace
  labels:
    app: my-backend-api
    tier: backend
spec:
  replicas: 3 # Initial replica count, will be managed by HPA
  selector:
    matchLabels:
      app: my-backend-api
  template:
    metadata:
      labels:
        app: my-backend-api
        tier: backend
    spec:
      serviceAccountName: my-backend-api-sa # For IRSA
      containers:
      - name: my-backend-api-container
        image: your-docker-repo/my-backend-api:v1.0.0 # Replace with your image
        ports:
        - containerPort: 8080
          name: http
        env:
        - name: DATABASE_HOST
          valueFrom:
            configMapKeyRef:
              name: my-application-config
              key: database_host
        - name: API_KEY
          valueFrom:
            secretKeyRef:
              name: my-application-secrets
              key: api_key
        resources:
          requests:
            cpu: "200m"
            memory: "256Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
        livenessProbe:
          httpGet:
            path: /healthz
            port: http
          initialDelaySeconds: 15
          periodSeconds: 20
        readinessProbe:
          httpGet:
            path: /ready
            port: http
          initialDelaySeconds: 5
          periodSeconds: 10
      imagePullSecrets:
      - name: regcred # If using a private Docker registry like ECR or Docker Hub

2.3. Service Manifest (service.yaml)

Example for exposing the backend API within the cluster.


apiVersion: v1
kind: Service
metadata:
  name: my-backend-api-service
  namespace: my-application-namespace
  labels:
    app: my-backend-api
    tier: backend
spec:
  selector:
    app: my-backend-api
  ports:
    - protocol: TCP
      port: 80
      targetPort: http # Matches the containerPort name in deployment
  type: ClusterIP # Internal service, exposed externally via Ingress

2.4. Ingress Manifest (ingress.yaml)

For external access to a frontend service, leveraging the AWS Load Balancer Controller for EKS.


apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-frontend-ingress
  namespace: my-application-namespace
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing # or internal
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:REGION:ACCOUNT_ID:certificate/YOUR_CERT_ID # Replace with your ACM ARN
    alb.ingress.kubernetes.io/healthcheck-path: /healthz
    alb.ingress.kubernetes.io/success-codes: "200"
    alb.ingress.kubernetes.io/group.name: my-application-group # Group multiple ingresses under one ALB
  labels:
    app: my-frontend
spec:
  rules:
  - host: myapp.yourdomain.com # Replace with your domain
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: ssl-redirect # dummy service for SSL redirection
            port:
              name: use-annotation
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-frontend-service
            port:
              number: 80

2.5. ConfigMap Manifest (configmap.yaml)

For non-sensitive configuration data.


apiVersion: v1
kind: ConfigMap
metadata:
  name: my-application-config
  namespace: my-application-namespace
data:
  database_host: my-database-service.my-application-namespace.svc.cluster.local
  log_level: INFO
  feature_flag_a: "true"

2.6. Secret Manifest (secret.yaml)

For sensitive data. Recommendation: For production, use external secret management like AWS Secrets Manager or HashiCorp Vault integrated via Kubernetes CSI Driver for Secrets Store. The example below is for basic demonstration.


apiVersion: v1
kind: Secret
metadata:
  name: my-application-secrets
  namespace: my-application-namespace
type: Opaque
data:
  api_key: YmFzZTY0ZW5jb2RlZHNlY3JldGtleQ== # base64 encoded value
  database_password: YmFzZTY0ZW5jb2RlZHBhc3N3b3Jk # base64 encoded value

3. Helm Chart Structure & Recommendations

Helm is highly recommended for managing Kubernetes applications. It allows for templating, versioning, and simplified deployment of complex applications.

3.1. Recommended Helm Chart Structure


my-application-helm/
├── Chart.yaml                  # Defines chart metadata
├── values.yaml                 # Default configuration values
├── templates/
│   ├── _helpers.tpl            # Reusable template snippets
│   ├── namespace.yaml          # Namespace definition
│   ├── deployment.yaml         # Deployment manifest for a service
│   ├── service.yaml            # Service manifest for a service
│   ├── ingress.yaml            # Ingress manifest for external access
│   ├── configmap.yaml          # ConfigMap for application settings
│   ├── secret.yaml             # Secret (or CSI Secret Store manifest)
│   ├── hpa.yaml                # Horizontal Pod Autoscaler
│   └── serviceaccount.yaml     # Service Account for IRSA
├── charts/                     # Subcharts for dependencies (e.g., database, message queue)
│   └── postgres/
│       └── ...
└── README.md                   # Documentation for the chart

3.2. Example Chart.yaml


apiVersion: v2
name: my-application
description: A Helm chart for deploying the My Application microservices.
type: Application
version: 0.1.0 # Chart version
appVersion: "1.0.0" # Application version
dependencies:
  - name: postgres # Example dependency
    version: 11.x.x
    repository: https://charts.bitnami.com/bitnami
    condition: postgres.enabled

3.3. Example values.yaml


global:
  namespace: my-application-namespace
  imagePullSecrets:
    - name: regcred

frontend:
  enabled: true
  image: your-docker-repo/my-frontend:v1.0.0
  replicas: 2
  service:
    type: ClusterIP
    port: 80
  ingress:
    enabled: true
    host: myapp.yourdomain.com
    annotations:
      alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:REGION:ACCOUNT_ID:certificate/YOUR_CERT_ID
      alb.ingress.kubernetes.io/scheme: internet-facing
    paths:
      - /

backend:
  enabled: true
  image: your-docker-repo/my-backend-api:v1.0.0
  replicas: 3
  service:
    type: ClusterIP
    port: 80
  resources:
    requests:
      cpu: "200m"
      memory: "256Mi"
    limits:
      cpu: "500m"
      memory: "512Mi"
  env:
    DATABASE_HOST: my-database-service.{{ .Release.Namespace }}.svc.cluster.local
    LOG_LEVEL: INFO

config:
  database_host: my-database-service.{{ .Release.Namespace }}.svc.cluster.local
  log_level: INFO

secrets:
  api_key: # Use external secret management for production
  database_password: # Use external secret management for production

serviceAccount:
  create: true
  name: my-application-sa
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/my-application-irsa-role

hpa:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70
  targetMemoryUtilizationPercentage: 70

postgres:
  enabled: false # Managed separately or external for production
  # ... other postgres values

4. Service Mesh Integration: AWS App Mesh

For complex microservice architectures on AWS EKS, AWS App Mesh is the recommended service mesh solution. It provides traffic management, observability, and security capabilities without modifying application code.

4.1. Key Concepts

  • Virtual Nodes: Represents a logical pointer to a particular task group, such as a Kubernetes Deployment.
  • Virtual Services: An abstraction of an actual service that is provided by a virtual node.
  • Virtual Routers: Handles traffic for a virtual service and distributes it to its associated virtual nodes.
  • Routes: Defines how traffic is routed from a virtual router to a specific virtual node.

4.2. Recommended Steps for App Mesh Integration

  1. Install App Mesh Controller: Deploy the AWS App Mesh controller to your EKS cluster.
  2. Configure IAM Permissions: Ensure your EKS worker nodes and service accounts have the necessary permissions to interact with App Mesh.
  3. Define Mesh: Create an App Mesh resource.

    apiVersion: appmesh.k8s.aws/v1beta2
    kind: Mesh
    metadata:
      name: my-application-mesh
    spec:
      awsName: my-application-mesh
  1. Annotate Deployments: Modify your Kubernetes Deployments to inject the Envoy proxy sidecar.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-backend-api
      namespace: my-application-namespace
      annotations:
        appmesh.k8s.aws/mesh: my-application-mesh
        appmesh.k8s.aws/virtual-node: my-backend-api-vn # Name of the virtual node
    spec:
      # ... (rest of your deployment)
  1. Create App Mesh Resources:

* Virtual Node (virtualnode.yaml):


        apiVersion: appmesh.k8s.aws/v1beta2
        kind: VirtualNode
        metadata:
          name: my-backend-api-vn
          namespace: my-application-namespace
        spec:
          awsName: my-backend-api-vn
          mesh: my-application-mesh
          listeners:
            - portMapping:
                port: 8080 # Container port
                protocol: http
          serviceDiscovery:
            dns:
              hostname: my-backend-api-service.my-application-namespace.svc.cluster.local
          backendDefaults:
            clientPolicy:
              tls:
                enforce: true
                ports: [8080]
                certificate:
                  sds:
                    secretName: backend-sds-cert

* Virtual Service (virtualservice.yaml):


        apiVersion: appmesh.k8s.aws/v1beta2
        kind: VirtualService
        metadata:
          name: my-backend-api-vs
          namespace: my-application-namespace
        spec:
          awsName: my-backend-api.my-application-namespace.svc.cluster.local
          mesh: my-application-mesh
          provider:
            virtualRouter:
              virtualRouterRef:
                name: my-backend-api-vr

* Virtual Router (virtualrouter.yaml):


        apiVersion: appmesh.k8s.aws/v1beta2
        kind: VirtualRouter
        metadata:
          name: my-backend-api-vr
          namespace: my-application-namespace
        spec:
          awsName: my-backend-api-vr
          mesh: my-application-mesh
          listeners:
            - portMapping:
                port: 80 # Service port
                protocol: http

* Route (route.yaml):


        apiVersion: appmesh.k8s.aws/v1beta2
        kind: Route
        metadata:
          name: my-backend-api-route
          namespace: my-application-namespace
        spec:
          awsName: my-backend-api-route
          mesh: my-application-mesh
          virtualRouterRef:
            name: my-backend-api-vr
          httpRoute:
            match:
              prefix: "/"
            action:
              weightedTargets:
                - virtualNodeRef:
                    name: my-backend-api-vn
                  weight: 100

4.3. Actionable Recommendations for App Mesh

  • Progressive Rollouts: Use App Mesh routes for blue/green deployments or canary releases by shifting traffic weights between different virtual nodes.
  • Traffic Shaping: Implement retries, timeouts, and circuit breaking policies at the mesh level.
  • mTLS: Enforce mutual TLS between services for enhanced security.
  • Observability: Leverage App Mesh's integration with AWS X-Ray and CloudWatch for distributed tracing and enhanced metrics.

5. Scaling Policies

Effective scaling is crucial for managing application load and cost efficiency.

5.1. Horizontal Pod Autoscaler (HPA)

HPA automatically scales the number of pod replicas based on observed CPU utilization or other select metrics.


apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-backend-api-hpa
  namespace: my-application-namespace
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-backend-api
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70 # Target 70% CPU utilization
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 70 # Target 70% Memory utilization
  # Example for custom metrics (requires Prometheus adapter or external metrics API)
  # - type: Pods
  #   pods:
  #     metric:
  #       name: http_requests_per_second
  #     target:
  #       type: AverageValue
  #       averageValue: 100

5.2. Vertical Pod Autoscaler (VPA) (Recommendation)

VPA automatically recommends or sets resource requests and limits for containers. It's excellent for optimizing resource usage and preventing over-provisioning.

  • Recommendation: Deploy VPA in "Recommender" mode initially to gather insights without immediately applying changes. Once confident, switch to "Auto" mode for specific deployments.
  • Caution: VPA can evict pods to apply new resource requests/limits, which might cause temporary service disruption if not managed carefully (e.g., with Pod Disruption Budgets).

5.3. Cluster Autoscaler

The Cluster Autoscaler adjusts the number of nodes in your EKS cluster based on pending pods and node utilization.

  • Recommendation: Ensure Cluster Autoscaler is deployed and configured correctly for your EKS cluster. It integrates with AWS Auto Scaling Groups to add or remove worker nodes.
  • Configuration:

* Tag your Auto Scaling Groups correctly (e.g., k8s.io/cluster-autoscaler/enabled, k8s.io/cluster-autoscaler/CLUSTER_NAME).

* Configure the Cluster Autoscaler deployment to point to your EKS cluster.


6. Monitoring Configurations

Robust monitoring is essential for operational visibility and quick issue resolution.

6.1. Prometheus and Grafana Stack

A standard and powerful solution for Kubernetes monitoring.

  • Prometheus: For metric collection (Node, Pod, Container, Application metrics).

* Installation: Use the kube-prometheus-stack Helm chart.

* ServiceMonitor/PodMonitor: Define how Prometheus discovers and scrapes metrics from your services.


        apiVersion: monitoring.coreos.com/v1
        kind: ServiceMonitor
        metadata:
          name: my-backend-api-monitor
          namespace: my-application-namespace
          labels:
            release: prometheus-stack # Label matching your Prometheus Helm release
        spec:
          selector:
            matchLabels:
              app: my-backend-api # Matches labels on your service
          endpoints:
          - port: http # Port name exposed by your service
            path: /metrics # Path where your application exposes Prometheus metrics
            interval: 30s
          namespaceSelector:
            matchNames:
              - my-application-namespace
  • Grafana: For visualizing metrics collected by Prometheus and creating dashboards.

* Installation: Included in kube-prometheus-stack Helm chart.

* Dashboards: Import pre-built dashboards (e.g., for Node Exporter, cAdvisor) and create custom dashboards for application-specific metrics.

6.2. AWS CloudWatch Container Insights

Provides native monitoring for EKS clusters, collecting metrics and logs directly into CloudWatch.

  • Recommendation: Enable Container Insights for your EKS cluster. It integrates with CloudWatch Logs, Metrics, and Contributor Insights.
  • Benefits: Centralized logging, performance monitoring of cluster components (pods, nodes, containers), and cost-effective for AWS-native users.
  • Configuration: Deploy the CloudWatch agent as a DaemonSet to your EKS cluster.

6.3. Distributed Tracing (AWS X-Ray)

For understanding the flow and performance of requests across microservices.

  • Recommendation: Integrate AWS X-Ray.
  • Implementation:

* Instrument your application code with the X-Ray SDK.

* Deploy the X-Ray DaemonSet to your EKS cluster or leverage App Mesh integration.

6.4. Alerting

Configure alerts based on critical metrics.

  • Prometheus Alertmanager: Use with Prometheus to send alerts to Slack, PagerDuty, email, etc.
  • CloudWatch Alarms: Set up alarms directly in CloudWatch for metrics from Container Insights or custom application metrics.

7. Security Considerations

Robust security is paramount for production deployments.

7.1. IAM Roles for Service Accounts (IRSA)

  • Recommendation: Use IRSA to grant AWS IAM roles directly to Kubernetes Service Accounts. This provides fine-grained AWS access to pods without managing AWS credentials within the pods themselves.
  • Implementation:

1. Create an IAM OIDC provider for your EKS cluster.

2. Create an IAM role with the necessary permissions.

3. Annotate your Kubernetes Service Account with the ARN of the IAM role.


        apiVersion: v1
        kind: ServiceAccount
        metadata:
          name: my-backend-api-sa
          namespace: my-application-namespace
          annotations:
            eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/my-backend-api-irsa-role

7.2. Network Policies

  • Recommendation: Implement Kubernetes Network Policies to control ingress and egress traffic between pods and namespaces. This adheres to the principle of least privilege.
  • Example (Allow ingress from frontend only):

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-frontend-to-backend
      namespace: my-application-namespace
    spec:
      podSelector:
        matchLabels:
          app: my-backend-api
      policyTypes:
      - Ingress
      ingress:
      - from:
        - podSelector:
            matchLabels:
              app: my-frontend
        ports:
        - protocol: TCP
          port: 8080

7.3. Secret Management

  • Recommendation: Use AWS Secrets Manager with the Kubernetes CSI Driver for Secrets Store. This injects secrets directly into pod filesystems, avoiding storing them in etcd.
  • Alternative: HashiCorp Vault.

7.4. Pod Security Standards (PSS)

  • Recommendation: Enforce Pod Security Standards to restrict pod capabilities, ensuring pods run with minimal privileges. Start with the Restricted profile.

8. CI/CD Integration (Brief Mention)

Automating deployments is crucial for efficiency and reliability.

  • Recommendation: Integrate your Kubernetes deployment process with CI/CD tools like AWS CodePipeline/CodeBuild, GitLab CI, GitHub Actions, or Argo CD/Flux CD.
  • GitOps: Consider a GitOps approach (e.g., using Argo CD or Flux CD) where your Git repository is the single source of truth for declarative infrastructure and applications.

9. Actionable Next Steps and Recommendations

  1. Refine Service Definitions: For each microservice, define specific images, resource requests/limits, environment variables, probes, and scaling requirements.
  2. Implement Helm Charts: Convert the provided manifest examples into robust Helm charts for each application or application group.
  3. Deploy App Mesh: Follow the App Mesh integration steps, starting with the controller and then applying virtual nodes/services.
  4. Configure Autoscaling: Implement HPAs for all critical deployments and ensure the Cluster Autoscaler is operational.
  5. Set Up Monitoring: Deploy Prometheus/Grafana and enable CloudWatch Container Insights. Configure application-specific dashboards and alerts.
  6. Strengthen Security: Implement IRSA for all service accounts, define Network Policies, and integrate with a robust secret management solution (e.g., AWS Secrets Manager CSI Driver).
  7. Establish CI/CD Pipelines: Automate the build, test, and deployment process using your preferred CI/CD toolchain.
  8. Testing: Thoroughly test all deployments, scaling policies, and monitoring alerts in a staging environment before moving to production.
  9. Documentation: Maintain comprehensive documentation for all deployed services, configurations, and operational procedures.
kubernetes_deployment_planner.txt
Download source file
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
\n\n\n"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547}\n"); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/\.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/\*\*(.+?)\*\*/g,"$1"); hc=hc.replace(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); } function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}