[claude] Phase 2 cleanup: route remaining fetch() through data/ modules (#421) #461

Merged
claude merged 1 commits from claude/issue-421 into main 2026-03-24 22:07:20 +00:00
3 changed files with 41 additions and 53 deletions

View File

@@ -2,6 +2,7 @@
import * as THREE from 'three';
import { NEXUS } from './constants.js';
import { scene } from './scene-setup.js';
import { fetchNexusCommits, fetchMergedPRs } from './data/gitea.js';
// === AGENT STATUS PANELS (declared early) ===
export const agentPanelSprites = [];
@@ -37,29 +38,16 @@ function createCommitTexture(hash, message) {
}
export async function initCommitBanners() {
let commits;
try {
const res = await fetch(
'http://143.198.27.163:3000/api/v1/repos/Timmy_Foundation/the-nexus/commits?limit=5',
{ headers: { 'Authorization': 'token dc0517a965226b7a0c5ffdd961b1ba26521ac592' } }
);
if (!res.ok) throw new Error('fetch failed');
const data = await res.json();
commits = data.map(c => ({
hash: c.sha.slice(0, 7),
message: c.commit.message.split('\n')[0],
}));
} catch {
commits = [
{ hash: 'a1b2c3d', message: 'feat: depth of field effect on distant objects' },
{ hash: 'e4f5g6h', message: 'feat: photo mode with orbit controls' },
{ hash: 'i7j8k9l', message: 'feat: sovereignty easter egg animation' },
{ hash: 'm0n1o2p', message: 'feat: overview mode bird\'s-eye view' },
{ hash: 'q3r4s5t', message: 'feat: star field and constellation lines' },
];
initCommitBanners();
}
const raw = await fetchNexusCommits(5);
const commits = raw.length > 0
? raw.map(c => ({ hash: c.sha.slice(0, 7), message: c.commit.message.split('\n')[0] }))
: [
{ hash: 'a1b2c3d', message: 'feat: depth of field effect on distant objects' },
{ hash: 'e4f5g6h', message: 'feat: photo mode with orbit controls' },
{ hash: 'i7j8k9l', message: 'feat: sovereignty easter egg animation' },
{ hash: 'm0n1o2p', message: 'feat: overview mode bird\'s-eye view' },
{ hash: 'q3r4s5t', message: 'feat: star field and constellation lines' },
];
const spreadX = [-7, -3.5, 0, 3.5, 7];
const spreadY = [1.0, -1.5, 2.2, -0.8, 1.6];
@@ -208,23 +196,8 @@ function buildBookshelf(books, position, rotationY) {
}
export async function initBookshelves() {
let prs = [];
try {
const res = await fetch(
'http://143.198.27.163:3000/api/v1/repos/Timmy_Foundation/the-nexus/pulls?state=closed&limit=20',
{ headers: { 'Authorization': 'token dc0517a965226b7a0c5ffdd961b1ba26521ac592' } }
);
if (!res.ok) throw new Error('fetch failed');
const data = await res.json();
prs = data
.filter(p => p.merged)
.map(p => ({
prNum: p.number,
title: p.title
.replace(/^\[[\w\s]+\]\s*/i, '')
.replace(/\s*\(#\d+\)\s*$/, ''),
}));
} catch {
let prs = await fetchMergedPRs(20);
if (prs.length === 0) {
prs = [
{ prNum: 324, title: 'Model training status — LoRA adapters' },
{ prNum: 323, title: 'The Oath — interactive SOUL.md reading' },

View File

@@ -139,4 +139,25 @@ export async function refreshAgentData() {
}
}
export async function fetchMergedPRs(limit = 20) {
try {
const res = await fetch(
`${GITEA_BASE}/repos/Timmy_Foundation/the-nexus/pulls?state=closed&limit=${limit}`,
{ headers: { 'Authorization': `token ${GITEA_TOKEN}` } }
);
if (!res.ok) return [];
const data = await res.json();
return data
.filter(p => p.merged)
.map(p => ({
prNum: p.number,
title: p.title
.replace(/^\[[\w\s]+\]\s*/i, '')
.replace(/\s*\(#\d+\)\s*$/, ''),
}));
} catch {
return [];
}
}
export { GITEA_BASE, GITEA_TOKEN, GITEA_REPOS, AGENT_NAMES, CACHE_MS as AGENT_STATUS_CACHE_MS };

View File

@@ -4,6 +4,7 @@ import { scene, ambientLight } from './scene-setup.js';
import { cloudMaterial } from './platform.js';
import { rebuildRuneRing } from './effects.js';
import { S } from './state.js';
import { fetchWeatherData } from './data/weather.js';
// === PORTAL HEALTH CHECKS ===
const PORTAL_HEALTH_CHECK_MS = 5 * 60 * 1000;
@@ -162,20 +163,13 @@ function updateWeatherHUD(wx) {
export async function fetchWeather() {
try {
const url = `https://api.open-meteo.com/v1/forecast?latitude=${WEATHER_LAT}&longitude=${WEATHER_LON}&current=temperature_2m,weather_code,wind_speed_10m,cloud_cover&temperature_unit=fahrenheit&wind_speed_unit=mph&forecast_days=1`;
const res = await fetch(url);
if (!res.ok) throw new Error('weather fetch failed');
const data = await res.json();
const cur = data.current;
const code = cur.weather_code;
const { condition, icon } = weatherCodeToLabel(code);
const cloudcover = typeof cur.cloud_cover === 'number' ? cur.cloud_cover : 50;
weatherState = { code, temp: cur.temperature_2m, wind: cur.wind_speed_10m, condition, icon, cloudcover };
applyWeatherToScene(weatherState);
const cloudOpacity = 0.05 + (cloudcover / 100) * 0.55;
cloudMaterial.uniforms.uDensity.value = 0.3 + (cloudcover / 100) * 0.7;
const wx = await fetchWeatherData();
weatherState = wx;
applyWeatherToScene(wx);
const cloudOpacity = 0.05 + (wx.cloudcover / 100) * 0.55;
cloudMaterial.uniforms.uDensity.value = 0.3 + (wx.cloudcover / 100) * 0.7;
cloudMaterial.opacity = cloudOpacity;
updateWeatherHUD(weatherState);
updateWeatherHUD(wx);
} catch {
const descEl = document.getElementById('weather-desc');
if (descEl) descEl.textContent = 'Lempster NH';