capsule-ai-cli
Version:
The AI Model Orchestrator - Intelligent multi-model workflows with device-locked licensing
214 lines • 10.7 kB
JavaScript
import React, { useState, useEffect } from 'react';
import { Box, Text, useStdout } from 'ink';
import chalk from 'chalk';
export const MatrixStartup = ({ onComplete }) => {
const { stdout } = useStdout();
const [grid, setGrid] = useState([]);
const [columns, setColumns] = useState([]);
const [phase, setPhase] = useState('rain');
const [frame, setFrame] = useState(0);
const width = Math.min(stdout.columns || 80, 100);
const height = Math.min(stdout.rows || 24, 30);
const matrixChars = "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン0123456789!@#$%^&*()_+-=[]{}|;:,.<>?";
const logoLines = [
'[▓███] [▓██▓] [▓██▓] [▓███] █ █ █ [▓███]',
'█ █ █ █ █ ▒███░ █ █ █ █░░░░',
'█ █▓▓▓█ █▓▓▓█ ░███▓ █ █ █ █▓▓▓▓',
'█ █ █ █ ░███░ █ █ █ █░░░░',
'[▓███] █ █ █ [▓███] [▓██▓] [▓███] [▓███]'
];
const logoWidth = logoLines[0].length;
const logoHeight = logoLines.length;
const logoStartX = Math.floor((width - logoWidth) / 2);
const logoStartY = Math.floor((height - logoHeight) / 2) - 2;
useEffect(() => {
const initialGrid = [];
const initialColumns = [];
for (let x = 0; x < width; x += 3) {
if (Math.random() < 0.8) {
initialColumns.push({
position: Math.floor(Math.random() * height) - height,
speed: 0.3 + Math.random() * 0.7,
length: 5 + Math.floor(Math.random() * 15),
chars: Array.from({ length: 20 }, () => matrixChars[Math.floor(Math.random() * matrixChars.length)])
});
}
}
setColumns(initialColumns);
for (let y = 0; y < height; y++) {
const row = [];
for (let x = 0; x < width; x++) {
const logoX = x - logoStartX;
const logoY = y - logoStartY;
const isLogoPos = logoX >= 0 && logoX < logoWidth &&
logoY >= 0 && logoY < logoHeight;
const targetChar = isLogoPos ? logoLines[logoY][logoX] : ' ';
row.push({
char: matrixChars[Math.floor(Math.random() * matrixChars.length)],
brightness: Math.random() * 0.5,
isLogo: isLogoPos && targetChar !== ' ',
targetChar: targetChar,
materializing: false,
column: x
});
}
initialGrid.push(row);
}
setGrid(initialGrid);
}, [width, height]);
useEffect(() => {
const interval = setInterval(() => {
setFrame(prev => {
const next = prev + 1;
if (next === 30)
setPhase('materialize');
if (next === 80)
setPhase('glow');
if (next === 100) {
setPhase('complete');
setTimeout(onComplete, 800);
}
return next;
});
setColumns(currentColumns => currentColumns.map(col => ({
...col,
position: col.position + col.speed,
...(col.position > height ? {
position: -col.length,
speed: 0.3 + Math.random() * 0.7,
chars: Array.from({ length: 20 }, () => matrixChars[Math.floor(Math.random() * matrixChars.length)])
} : {})
})));
setGrid(currentGrid => {
const newGrid = currentGrid.map((row, y) => row.map((cell, x) => {
let inColumn = false;
let columnIndex = 0;
for (const col of columns) {
if (x === columnIndex * 3) {
const relativeY = y - Math.floor(col.position);
if (relativeY >= 0 && relativeY < col.length) {
const brightness = 1 - (relativeY / col.length);
inColumn = true;
if (!cell.isLogo || phase === 'rain') {
return {
...cell,
char: col.chars[relativeY % col.chars.length],
brightness: brightness
};
}
}
}
columnIndex++;
}
if (!inColumn && !cell.isLogo) {
if (cell.brightness > 0) {
return { ...cell, brightness: Math.max(0, cell.brightness - 0.1) };
}
if (Math.random() < 0.001) {
return {
...cell,
char: matrixChars[Math.floor(Math.random() * matrixChars.length)],
brightness: 0.3
};
}
}
if (phase === 'materialize' && cell.isLogo && !cell.materializing) {
const centerX = width / 2;
const centerY = height / 2;
const dist = Math.sqrt(Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2));
const maxDist = Math.sqrt(Math.pow(centerX, 2) + Math.pow(centerY, 2));
const normalizedDist = dist / maxDist;
const delay = normalizedDist * 20;
if (frame > 30 + delay) {
return { ...cell, materializing: true, brightness: 1 };
}
}
if (cell.materializing && cell.targetChar) {
const materializeProgress = (frame - 30) / 50;
const threshold = 0.1 + materializeProgress * 0.8;
if (Math.random() < threshold) {
return { ...cell, char: cell.targetChar, brightness: 1 };
}
else if (cell.char !== cell.targetChar) {
const glitchChar = Math.random() < 0.3 ?
'█▓▒░'[Math.floor(Math.random() * 4)] :
matrixChars[Math.floor(Math.random() * matrixChars.length)];
return {
...cell,
char: glitchChar,
brightness: 0.5 + Math.random() * 0.5
};
}
}
return cell;
}));
return newGrid;
});
}, 50);
return () => clearInterval(interval);
}, [frame, phase, onComplete]);
const renderGrid = () => {
return grid.map((row, y) => {
const line = row.map((cell, x) => {
if (phase === 'glow' && cell.isLogo && cell.char === cell.targetChar) {
const pulse = Math.sin(frame * 0.1) * 0.5 + 0.5;
const flicker = Math.random() > 0.95;
if (flicker) {
return chalk.white.bold(cell.char);
}
if ('[]'.includes(cell.char)) {
return chalk.cyan.bold(cell.char);
}
if ('▓█'.includes(cell.char)) {
const greenValue = Math.floor(200 + pulse * 55);
return chalk.rgb(0, greenValue, 0).bold(cell.char);
}
if ('▒░'.includes(cell.char)) {
return chalk.rgb(0, 150, 0)(cell.char);
}
if ('░▒▓█'.includes(cell.char) && cell.char === '░') {
return chalk.rgb(0, 100, 0)(cell.char);
}
const greenValue = Math.floor(180 + pulse * 75);
return chalk.rgb(0, greenValue, 0)(cell.char);
}
else if (cell.materializing && cell.char === cell.targetChar) {
const flicker = Math.random() > 0.9;
return flicker ? chalk.white.bold(cell.char) : chalk.rgb(57, 255, 20)(cell.char);
}
else if (cell.materializing && cell.char !== cell.targetChar) {
return chalk.rgb(Math.floor(Math.random() * 100 + 155), Math.floor(Math.random() * 100 + 155), Math.floor(Math.random() * 100 + 155))(cell.char);
}
else if (cell.brightness > 0.8) {
return chalk.white(cell.char);
}
else if (cell.brightness > 0.5) {
return chalk.green(cell.char);
}
else if (cell.brightness > 0.3) {
return chalk.greenBright(cell.char);
}
else {
return chalk.gray(cell.char);
}
}).join('');
return React.createElement(Text, { key: y }, line);
});
};
const taglineText = '< AI-POWERED SOFTWARE ENGINEERING />';
const taglineProgress = phase === 'glow' ? Math.min((frame - 80) / 20, 1) : 0;
const visibleTagline = taglineText.slice(0, Math.floor(taglineProgress * taglineText.length));
const tagline = phase === 'glow' && visibleTagline ? (React.createElement(Box, { justifyContent: "center", marginTop: 1 },
React.createElement(Text, null,
visibleTagline.split('').map((char, i) => {
if ('<>/'.includes(char)) {
return chalk.cyan.bold(char);
}
return chalk.green(char);
}).join(''),
taglineProgress < 1 && chalk.green.bold('█')))) : null;
return (React.createElement(Box, { flexDirection: "column", width: width, height: height },
React.createElement(Box, { flexDirection: "column" }, renderGrid()),
tagline));
};
//# sourceMappingURL=MatrixStartup.js.map