Add Ralph skill for autonomous PRD creation and implementation

This commit is contained in:
Echo
2026-02-09 08:56:16 +00:00
parent 59abff1bce
commit e82a786885
27 changed files with 2673 additions and 67 deletions

View File

@@ -3,11 +3,11 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg+xml" href="favicon.svg">
<link rel="icon" type="image/svg+xml" href="/echo/favicon.svg">
<title>Echo · Dashboard</title>
<link rel="stylesheet" href="common.css">
<link rel="stylesheet" href="/echo/common.css">
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
<script src="swipe-nav.js"></script>
<script src="/echo/swipe-nav.js"></script>
<style>
.main {
max-width: 1400px;
@@ -1054,20 +1054,20 @@
</head>
<body>
<header class="header">
<a href="index.html" class="logo">
<a href="/echo/index.html" class="logo">
<i data-lucide="circle-dot"></i>
Echo
</a>
<nav class="nav">
<a href="index.html" class="nav-item active">
<a href="/echo/index.html" class="nav-item active">
<i data-lucide="layout-dashboard"></i>
<span>Dashboard</span>
</a>
<a href="notes.html" class="nav-item">
<a href="/echo/notes.html" class="nav-item">
<i data-lucide="file-text"></i>
<span>KB</span>
</a>
<a href="files.html" class="nav-item">
<a href="/echo/files.html" class="nav-item">
<i data-lucide="folder"></i>
<span>Files</span>
</a>
@@ -1526,7 +1526,7 @@
async function loadGitStatus() {
try {
const response = await fetch('./api/git?' + Date.now());
const response = await fetch('/echo/api/git?' + Date.now());
if (!response.ok) throw new Error('API error');
const git = await response.json();
@@ -1560,7 +1560,7 @@
const more = git.uncommittedCount > 3 ? ` +${git.uncommittedCount - 3}` : '';
html += `<div class="status-detail-item uncommitted">
<i data-lucide="alert-circle"></i>
<span><a href="files.html?git=1" style="color:var(--warning)"><strong>${git.uncommittedCount}</strong> necomise</a>: ${files}${more}</span>
<span><a href="/echo/files.html?git=1" style="color:var(--warning)"><strong>${git.uncommittedCount}</strong> necomise</a>: ${files}${more}</span>
</div>`;
}
@@ -1582,7 +1582,7 @@
async function loadAnafStatus() {
try {
const response = await fetch('status.json?' + Date.now());
const response = await fetch('/echo/status.json?' + Date.now());
if (!response.ok) throw new Error('No status.json');
const status = await response.json();
@@ -1610,7 +1610,7 @@
async function loadCronStatus() {
try {
const response = await fetch('./api/cron?' + Date.now());
const response = await fetch('/echo/api/cron?' + Date.now());
if (!response.ok) throw new Error('API error');
const data = await response.json();
@@ -1681,7 +1681,7 @@
async function loadAgentsStatus() {
try {
const response = await fetch('./api/agents?' + Date.now());
const response = await fetch('/echo/api/agents?' + Date.now());
if (!response.ok) throw new Error('API error');
const data = await response.json();
@@ -1737,7 +1737,7 @@
async function loadTodos() {
try {
const response = await fetch('todos.json?' + Date.now());
const response = await fetch('/echo/todos.json?' + Date.now());
if (response.ok) {
todosData = await response.json();
renderTodos();
@@ -1991,7 +1991,7 @@
// ===== ISSUES =====
async function loadIssues() {
try {
const response = await fetch('issues.json?' + Date.now());
const response = await fetch('/echo/issues.json?' + Date.now());
issuesData = await response.json();
populateProgramSelect();
renderIssues();
@@ -2017,7 +2017,7 @@
async function loadActivity() {
try {
// Fetch from unified activity API
const response = await fetch('./api/activity?t=' + Date.now());
const response = await fetch('/echo/api/activity?t=' + Date.now());
const data = await response.json();
if (data.error) throw new Error(data.error);