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
7 changes: 5 additions & 2 deletions .claude/scripts/setup-runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Generated: 2025-12-23
#
# Usage: ./setup-runner.sh <HOST_TYPE>
# Where HOST_TYPE is one of: ai-lab, vps, cloudstartup, kvm4
# Where HOST_TYPE is one of: ai-lab, vps, cloudstartup, kvm4, kvm4-1, kvm4-2, kvm2

set -e

Expand All @@ -21,10 +21,13 @@ HOST_LABELS["ai-lab"]="self-hosted,ai-lab,gpu,Linux,X64"
HOST_LABELS["vps"]="self-hosted,vps,Linux,X64"
HOST_LABELS["cloudstartup"]="self-hosted,cloudstartup,staging,Linux,X64"
HOST_LABELS["kvm4"]="self-hosted,kvm4,production,Linux,X64"
HOST_LABELS["kvm4-1"]="self-hosted,vps,kvm4,kvm4-1,production,Linux,X64"
HOST_LABELS["kvm4-2"]="self-hosted,vps,kvm4,kvm4-2,production,Linux,X64"
HOST_LABELS["kvm2"]="self-hosted,vps,kvm2,backup,Linux,X64"

if [[ -z "$HOST_TYPE" ]] || [[ ! ${HOST_LABELS[$HOST_TYPE]+_} ]]; then
echo "Usage: $0 <HOST_TYPE>"
echo "HOST_TYPE must be one of: ai-lab, vps, cloudstartup, kvm4"
echo "HOST_TYPE must be one of: ai-lab, vps, cloudstartup, kvm4, kvm4-1, kvm4-2, kvm2"
exit 1
fi

Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/build-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ env:

jobs:
setup-matrix:
runs-on: [self-hosted, Linux, X64]
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
Expand Down Expand Up @@ -47,6 +47,7 @@ jobs:
runs-on: [self-hosted, Linux, X64]
strategy:
fail-fast: false
max-parallel: 4
matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}
defaults:
run:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/codex-parity-advisory.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ on:
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
codex-parity-advisory:
name: codex-parity-advisory
Expand Down
15 changes: 10 additions & 5 deletions .github/workflows/deploy-gateway-agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ env:
jobs:
validate:
name: Validate Configuration
# PMOVES.AI: Use self-hosted runners for production CI
runs-on: [self-hosted, Linux, X64]
runs-on: ubuntu-latest
permissions:
contents: read
steps:
Expand Down Expand Up @@ -177,9 +176,15 @@ jobs:

- name: Verify secrets loaded
run: |
secrets=$(curl -s http://localhost:8100/secrets)
echo "βœ“ Secrets endpoint response:"
echo "$secrets" | jq '.'
count=$(curl -sf http://localhost:8100/secrets | jq 'length' 2>/dev/null) || {
echo "βœ— Failed to query secrets endpoint"
exit 1
}
if [ "$count" -eq 0 ] 2>/dev/null; then
echo "βœ— Zero secret keys loaded β€” check GitHub Secrets configuration"
exit 1
fi
echo "βœ“ $count secret keys loaded"

# ============================================================================
# Rollback
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/hardening-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
# ============================================================================
validate-hardening:
name: Validate Hardening Patterns
runs-on: [self-hosted, Linux, X64]
runs-on: ubuntu-latest

steps:
- name: Harden Runner
Expand Down Expand Up @@ -88,7 +88,7 @@ jobs:
# ============================================================================
validate-dockerfiles:
name: Validate Dockerfiles
runs-on: [self-hosted, Linux, X64]
runs-on: ubuntu-latest
strategy:
fail-fast: false
# Limit fan-out to reduce self-hosted queue contention.
Expand Down Expand Up @@ -166,7 +166,7 @@ jobs:
# ============================================================================
docker-bench:
name: Docker Bench Security
runs-on: [self-hosted, Linux, X64]
runs-on: [self-hosted, Linux, X64, vps]

steps:
- name: Harden Runner
Expand Down Expand Up @@ -200,7 +200,7 @@ jobs:
# ============================================================================
validate-compose:
name: Validate Compose Files
runs-on: [self-hosted, Linux, X64]
runs-on: ubuntu-latest

steps:
- name: Harden Runner
Expand Down Expand Up @@ -277,7 +277,7 @@ jobs:
# ============================================================================
summary:
name: Validation Summary
runs-on: [self-hosted, Linux, X64]
runs-on: ubuntu-latest
needs: [validate-hardening, validate-dockerfiles, validate-compose]
if: always()

Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ concurrency:

jobs:
tests:
# PMOVES.AI: Use self-hosted runners for production CI
runs-on: [self-hosted, Linux, X64]
runs-on: ubuntu-latest
permissions:
contents: read
actions: read
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/self-hosted-builds-hardened.yml
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ jobs:
runs-on: [self-hosted, Linux, X64]
strategy:
fail-fast: false
max-parallel: 3
matrix:
service:
- name: pmoves-yt
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/sql-policy-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ permissions:

jobs:
lint:
# PMOVES.AI: Use self-hosted runners for production CI
runs-on: [self-hosted, Linux, X64]
runs-on: ubuntu-latest
permissions:
contents: read
steps:
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/sync-secrets-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ jobs:
GHCR_USERNAME: ${{ secrets.GHCR_USERNAME }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
# Hostinger VPS
HOSTINGER_API_TOKEN: ${{ secrets.HOSTINGER_API_TOKEN }}
HOSTINGER_KVM4_1_IP: ${{ secrets.HOSTINGER_KVM4_1_IP }}
HOSTINGER_KVM4_1_USER: ${{ secrets.HOSTINGER_KVM4_1_USER }}
HOSTINGER_KVM4_2_IP: ${{ secrets.HOSTINGER_KVM4_2_IP }}
HOSTINGER_KVM4_2_USER: ${{ secrets.HOSTINGER_KVM4_2_USER }}
HOSTINGER_KVM2_IP: ${{ secrets.HOSTINGER_KVM2_IP }}
HOSTINGER_KVM2_USER: ${{ secrets.HOSTINGER_KVM2_USER }}
run: |
import json, os, sys
from pathlib import Path
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/webhook-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ on:
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
smoke:
runs-on: [self-hosted, Linux, X64]
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@v2
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/yt-dlp-bump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ permissions:

jobs:
bump-yt-dlp:
# PMOVES.AI: Use self-hosted runners for production CI
runs-on: [self-hosted, Linux, X64]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
Expand All @@ -38,6 +37,12 @@ jobs:
fi
echo "version=$latest" >> $GITHUB_OUTPUT

- name: Set up QEMU
uses: docker/setup-qemu-action@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Build pmoves-yt with bumped yt-dlp
uses: docker/build-push-action@v6
with:
Expand Down
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@ pmoves/env.jellyfin-ai
pmoves/env.supa.runtime.bak.*


# =============================================================================
# Terraform
# =============================================================================
*.tfvars
!*.tfvars.example
.terraform/
*.tfstate
*.tfstate.*

# Windows
desktop.ini
Thumbs.db
19 changes: 16 additions & 3 deletions deploy/runners/vps/install-hardened.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@
#
# Labels applied based on RUNNER_NAME:
# cloudstartup: self-hosted, vps, cloudstartup, staging, linux, x64
# kvm4: self-hosted, vps, kvm4, production, linux, x64
# kvm4-1: self-hosted, vps, kvm4, kvm4-1, production, linux, x64
# kvm4-2: self-hosted, vps, kvm4, kvm4-2, production, linux, x64
# kvm2: self-hosted, vps, kvm2, backup, linux, x64

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RUNNER_DIR="${RUNNER_DIR:-/opt/actions-runner}"
RUNNER_VERSION="${RUNNER_VERSION:-2.311.0}"
RUNNER_VERSION="${RUNNER_VERSION:-2.321.0}"
RUNNER_ARCH="linux-x64"
GITHUB_ORG="${GITHUB_ORG:-frostbytten}"
GITHUB_ORG="${GITHUB_ORG:-POWERFULMOVES}"
GITHUB_REPO="${GITHUB_REPO:-PMOVES.AI}"
RUNNER_NAME="${RUNNER_NAME:-vps-$(hostname)}"
JIT_MODE=false
Expand All @@ -51,6 +52,12 @@ get_labels() {
*cloudstartup*)
echo "${base_labels},cloudstartup,staging"
;;
*kvm4-1*)
echo "${base_labels},kvm4,kvm4-1,production"
;;
*kvm4-2*)
echo "${base_labels},kvm4-2,production"
;;
Comment on lines +55 to +60

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | πŸ”΄ Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Workflows still targeting the legacy kvm4 label:"
rg -n -C2 'runs-on:\s*\[self-hosted,\s*kvm4,\s*production\]' .github/workflows

echo
echo "Provisioning scripts that emit kvm4 labels:"
rg -n -C2 'kvm4-1|kvm4-2|kvm4,production' deploy/runners/vps/install-hardened.sh .claude/scripts/setup-runner.sh

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 4403


Remove the kvm4 label from kvm4-2 instances to prevent unintended job routing.

Workflows in .github/workflows/self-hosted-builds.yml:270 and .github/workflows/self-hosted-builds-hardened.yml:381 target runs-on: [self-hosted, kvm4, production]. Both kvm4-1 and kvm4-2 currently emit the kvm4 label, making the data-services node (kvm4-2) eligible for these legacy jobs. Keep the kvm4 alias on kvm4-1 only.

Fix required in two files:

  1. deploy/runners/vps/install-hardened.sh, line 59: Remove kvm4, from the kvm4-2 label emission.
  2. **.claude/scripts/setup-runner.sh, line 25**: Update HOST_LABELS["kvm4-2"]to remove thekvm4` label.

After these changes:

  • kvm4-1 β†’ emits kvm4 (eligible for legacy workflows)
  • kvm4-2 β†’ does NOT emit kvm4 (not eligible for legacy workflows)
πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deploy/runners/vps/install-hardened.sh` around lines 55 - 60, Remove the
shared "kvm4" alias from the kvm4-2 runner so legacy jobs don't target the
data-services node: in the case handling for "*kvm4-2*" inside
install-hardened.sh (the echo that currently prints
"${base_labels},kvm4,kvm4-2,production") remove the "kvm4," token so it emits
only the kvm4-2 and production labels, and also update the HOST_LABELS["kvm4-2"]
entry in .claude/scripts/setup-runner.sh to remove "kvm4" from that host's label
list so only kvm4-1 continues to advertise the kvm4 alias.

*kvm4*)
echo "${base_labels},kvm4,production"
;;
Expand Down Expand Up @@ -433,6 +440,12 @@ show_verification() {
*cloudstartup*)
echo " runs-on: [self-hosted, cloudstartup, staging]"
;;
*kvm4-1*)
echo " runs-on: [self-hosted, vps, kvm4-1, production]"
;;
*kvm4-2*)
echo " runs-on: [self-hosted, vps, kvm4-2, production]"
;;
*kvm4*)
echo " runs-on: [self-hosted, kvm4, production]"
;;
Expand Down
17 changes: 17 additions & 0 deletions pbnj/pinokio/api/pmoves-pbnj/kvm2-deploy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"run": [
{
"method": "shell.run",
"params": {
"message": [
"echo 'Deploying KVM2 (Exit Node) via Tailscale SSH...'",
"echo 'NOTE: SSH as root β€” key-only auth enforced (PasswordAuthentication no)'",
"ssh root@pmoves-kvm2 'cd /opt/pmoves && git pull --ff-only origin main && cd pmoves && docker compose -f docker-compose.yml -f docker-compose.vps.override.yml pull nginx && docker compose -f docker-compose.yml -f docker-compose.vps.override.yml up -d nginx'",
"echo 'Verifying exit node...'",
"ssh root@pmoves-kvm2 'tailscale status | head -5'",
"echo 'KVM2 deployment complete.'"
]
}
}
]
}
18 changes: 18 additions & 0 deletions pbnj/pinokio/api/pmoves-pbnj/kvm4-1-deploy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"run": [
{
"method": "shell.run",
"params": {
"message": [
"echo 'Deploying KVM4-1 (API Gateway) via Tailscale SSH...'",
"echo 'NOTE: SSH as root β€” key-only auth enforced (PasswordAuthentication no)'",
"ssh root@pmoves-kvm4-1 'cd /opt/pmoves && git pull --ff-only origin main && cd pmoves && docker compose -f docker-compose.yml -f docker-compose.vps.override.yml pull tensorzero-gateway agent-zero hi-rag-gateway-v2 archon-server mesh-agent gateway-agent extract-worker && docker compose -f docker-compose.yml -f docker-compose.vps.override.yml up -d tensorzero-gateway agent-zero hi-rag-gateway-v2 archon-server mesh-agent gateway-agent extract-worker'",
"echo 'Verifying health...'",
"ssh root@pmoves-kvm4-1 'curl -sf http://localhost:8080/healthz && echo \" Agent Zero: OK\" || echo \" Agent Zero: FAIL\"'",
"ssh root@pmoves-kvm4-1 'curl -sf http://localhost:3030/healthz && echo \" TensorZero: OK\" || echo \" TensorZero: FAIL\"'",
"echo 'KVM4-1 deployment complete.'"
]
}
}
]
}
18 changes: 18 additions & 0 deletions pbnj/pinokio/api/pmoves-pbnj/kvm4-2-deploy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"run": [
{
"method": "shell.run",
"params": {
"message": [
"echo 'Deploying KVM4-2 (Data Services) via Tailscale SSH...'",
"echo 'NOTE: SSH as root β€” key-only auth enforced (PasswordAuthentication no)'",
"ssh root@pmoves-kvm4-2 'cd /opt/pmoves && git pull --ff-only origin main && cd pmoves && docker compose -f docker-compose.yml -f docker-compose.vps.override.yml pull supabase-db supabase-rest qdrant neo4j meilisearch nats prometheus grafana loki minio && docker compose -f docker-compose.yml -f docker-compose.vps.override.yml up -d supabase-db supabase-rest qdrant neo4j meilisearch nats prometheus grafana loki minio'",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | πŸ”΄ Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if prometheus, grafana, loki, minio are defined in base compose
echo "=== Checking for observability services in base compose ==="
rg -n "^\s*(prometheus|grafana|loki|minio):" pmoves/docker-compose.yml
echo ""
echo "=== Checking VPS override for these services ==="
rg -n "^\s*(prometheus|grafana|loki|minio):" pmoves/docker-compose.vps.override.yml

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 297


🏁 Script executed:

#!/bin/bash
# Search more broadly for these services - they might be defined differently
echo "=== Looking for service definitions more broadly ==="
echo "Base compose file grep for all service keys:"
rg -n "^\s+[a-z_-]+:\s*$" pmoves/docker-compose.yml | head -50

echo ""
echo "=== Checking full line context for minio definition ==="
rg -B2 -A10 "^\s*minio:\s*$" pmoves/docker-compose.yml | head -40

echo ""
echo "=== Checking if prometheus, grafana, loki exist anywhere ==="
rg -i "prometheus|grafana|loki" pmoves/docker-compose.yml | head -20

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 2715


🏁 Script executed:

#!/bin/bash
# Look specifically for top-level services (two spaces, followed by service name, colon at end of line)
echo "=== All services defined in base compose ==="
rg -n "^  [a-z_-]+:\s*$" pmoves/docker-compose.yml

echo ""
echo "=== All services defined in VPS override ==="
rg -n "^  [a-z_-]+:\s*$" pmoves/docker-compose.vps.override.yml

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 3919


🏁 Script executed:

#!/bin/bash
# Check if prometheus, grafana, loki are referenced as services anywhere or if they're part of pmoves_monitoring
echo "=== Checking pmoves_monitoring service definition ==="
rg -A30 "^\s+pmoves_monitoring:\s*$" pmoves/docker-compose.yml

echo ""
echo "=== Double-check: can we find prometheus, grafana, loki as service definitions? ==="
grep -n "^  prometheus:" pmoves/docker-compose.yml || echo "prometheus: NOT FOUND"
grep -n "^  grafana:" pmoves/docker-compose.yml || echo "grafana: NOT FOUND"
grep -n "^  loki:" pmoves/docker-compose.yml || echo "loki: NOT FOUND"

echo ""
echo "=== Check if these services are in VPS override ==="
grep -n "prometheus\|grafana\|loki" pmoves/docker-compose.vps.override.yml || echo "NONE FOUND"

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 1060


🏁 Script executed:

#!/bin/bash
# Let's look at the actual deployment script to confirm what's being deployed
echo "=== Viewing the deployment script file ==="
cat -n pbnj/pinokio/api/pmoves-pbnj/kvm4-2-deploy.json | head -20

echo ""
echo "=== Checking if neo4j is defined ==="
grep -n "^  neo4j:" pmoves/docker-compose.yml || echo "neo4j: NOT FOUND"

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 1381


Deployment command references non-existent services: prometheus, grafana, loki.

The deployment command on line 9 attempts to pull and start prometheus, grafana, and loki, but these services are not defined in either docker-compose.yml or docker-compose.vps.override.yml. The deployment will fail with a "service not found" error when docker-compose tries to reference these non-existent services. Additionally, the health check on line 11 expects Prometheus to be running at localhost:9090.

Either:

  1. Add service definitions for prometheus, grafana, and loki to the compose files, or
  2. Remove these services from the deployment command.

Confirm whether these observability services should be deployed on KVM4-2.

πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pbnj/pinokio/api/pmoves-pbnj/kvm4-2-deploy.json` at line 9, The deployment
command includes services "prometheus", "grafana", and "loki" in the ssh deploy
string and the health check expects Prometheus at localhost:9090, but those
services are not defined; either remove those service names from the ssh command
(the long ssh root@... '... docker compose -f docker-compose.yml -f
docker-compose.vps.override.yml pull ... && ... up -d ...' string) and
remove/adjust the Prometheus health check, or add proper service definitions for
prometheus, grafana, and loki into your docker-compose.yml and
docker-compose.vps.override.yml so the names match exactly; update the ssh
command to reference the newly-added services if you choose to add them.

"echo 'Verifying health...'",
"ssh root@pmoves-kvm4-2 'curl -sf http://localhost:9090/api/v1/targets > /dev/null && echo \" Prometheus: OK\" || echo \" Prometheus: FAIL\"'",
"ssh root@pmoves-kvm4-2 'curl -sf http://localhost:6333/healthz > /dev/null && echo \" Qdrant: OK\" || echo \" Qdrant: FAIL\"'",
"echo 'KVM4-2 deployment complete.'"
]
}
}
]
}
8 changes: 7 additions & 1 deletion pbnj/pinokio/api/pmoves-pbnj/pinokio.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ module.exports = {
{ text: "Local Dev (Docker) - Down",href: "local-down.json" },
{ text: "Local Dev (Docker) Logs", href: "local-logs.json" },

{ text: "Cluster Status (AI Lab)", href: "status.json" }
{ text: "Cluster Status (AI Lab)", href: "status.json" },

{ text: "─── VPS Fleet ───", href: "" },
{ text: "Deploy KVM4-1 (API Gateway)", href: "kvm4-1-deploy.json" },
{ text: "Deploy KVM4-2 (Data Services)",href: "kvm4-2-deploy.json" },
{ text: "Deploy KVM2 (Exit Node)", href: "kvm2-deploy.json" },
{ text: "VPS Fleet Status", href: "vps-status.json" }
Comment on lines +17 to +23

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name pinokio.js -path "*/pmoves-pbnj/*" -type f

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 108


🏁 Script executed:

cat -n pbnj/pinokio/api/pmoves-pbnj/pinokio.js | head -50

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 1327


🏁 Script executed:

# Check the full file to understand menu structure
wc -l pbnj/pinokio/api/pmoves-pbnj/pinokio.js

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 109


🏁 Script executed:

# Check if the referenced JSON files exist
ls -la pbnj/pinokio/api/pmoves-pbnj/*.json 2>/dev/null | head -20

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 1185


🏁 Script executed:

# Search for usage of info.exists, info.running, info.local in all pinokio.js files
rg "info\.(exists|running|local)" --type js -B2 -A2

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 2745


🏁 Script executed:

# Find all pinokio.js files to understand the pattern
fd pinokio.js -type f

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 237


🏁 Script executed:

# Fix the fd command to list all pinokio.js files
fd pinokio\.js

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 246


🏁 Script executed:

# Get more context on the pattern - check if the async menu pattern is standard
grep -r "menu: async" --include="pinokio.js" | head -10

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 231


🏁 Script executed:

# Check the full structure of one of the example files to understand the pattern better
cat -n pmoves/docs/ARTSTUFF/realtime/pinokio.js | head -60

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 2142


🏁 Script executed:

# Verify if the pbnj file should also have async menu like the others
grep -A 5 "menu:" pbnj/pinokio/api/pmoves-pbnj/pinokio.js

Repository: POWERFULMOVES/PMOVES.AI

Length of output: 335


Convert the menu from a static array to an async function that uses Pinokio state functions to determine which items to display.

The entire menu is currently hardcoded as a static array, which exposes actions that may not be valid for the current state. Other pinokio.js files in this repository (e.g., pmoves/docs/ARTSTUFF/realtime/pinokio.js) use menu: async (kernel, info) => { ... } to dynamically generate menu items based on:

  • info.exists(relative_path) β€” whether a path exists
  • info.running(relative_path) β€” whether a script is currently running
  • info.local(relative_path) β€” local variables from a running script

This pattern ensures the launcher only exposes valid actions for the current application state.

πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pbnj/pinokio/api/pmoves-pbnj/pinokio.js` around lines 17 - 23, Replace the
static menu array in pinokio.js with an async menu function: export menu: async
(kernel, info) => { ... } that builds and returns the menu list dynamically;
always include the "status.json" Cluster Status entry, then for each
deploy/status item ("kvm4-1-deploy.json", "kvm4-2-deploy.json",
"kvm2-deploy.json", "vps-status.json") call info.exists(relative_path) to decide
whether to include that item, use info.running(relative_path) to change text or
omit items when a script is running (e.g., show "Stop" vs "Deploy" or disable if
running), and consult info.local(relative_path) if you need per-script state to
further tailor labels; ensure the exported symbol is menu (async) and returns
the same shape as the original array so callers remain compatible.

]
};
27 changes: 27 additions & 0 deletions pbnj/pinokio/api/pmoves-pbnj/vps-status.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"run": [
{
"method": "shell.run",
"params": {
"message": [
"echo '=== PMOVES.AI VPS Fleet Status ==='",
"echo ''",
"echo 'KVM4-1 (API Gateway):'",
"tailscale ping --timeout 3s pmoves-kvm4-1 > /dev/null 2>&1 && echo ' Status: ONLINE' || echo ' Status: OFFLINE'",
"echo ''",
"echo 'KVM4-2 (Data Services):'",
"tailscale ping --timeout 3s pmoves-kvm4-2 > /dev/null 2>&1 && echo ' Status: ONLINE' || echo ' Status: OFFLINE'",
"echo ''",
"echo 'KVM2 (Exit Node):'",
"tailscale ping --timeout 3s pmoves-kvm2 > /dev/null 2>&1 && echo ' Status: ONLINE' || echo ' Status: OFFLINE'",
"echo ''",
"echo 'GitHub Actions Runners:'",
"gh api repos/POWERFULMOVES/PMOVES.AI/actions/runners --jq '.runners[] | \" \\(.name): \\(.status)\"' 2>/dev/null || echo ' (unable to fetch)'",
"echo ''",
"echo 'Tailscale Mesh:'",
"tailscale status 2>/dev/null | head -10 || echo ' Tailscale not connected'"
]
}
}
]
}
Loading
Loading