Add Ralph skill for autonomous PRD creation and implementation
This commit is contained in:
@@ -862,7 +862,7 @@ def clean_vtt(content):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
port = 8080
|
||||
port = 8088
|
||||
os.chdir(KANBAN_DIR)
|
||||
|
||||
print(f"Starting Echo Task Board API on port {port}")
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<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 · Files</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="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
|
||||
<script src="swipe-nav.js"></script>
|
||||
<script src="/echo/swipe-nav.js"></script>
|
||||
<style>
|
||||
.main {
|
||||
display: flex;
|
||||
@@ -829,20 +829,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">
|
||||
<a href="/echo/index.html" class="nav-item">
|
||||
<i data-lucide="layout-list"></i>
|
||||
<span>Tasks</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 active">
|
||||
<a href="/echo/files.html" class="nav-item active">
|
||||
<i data-lucide="folder"></i>
|
||||
<span>Files</span>
|
||||
</a>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Echo · Grup Sprijin</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>
|
||||
<style>
|
||||
.main {
|
||||
@@ -233,24 +233,24 @@
|
||||
</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">
|
||||
<a href="/echo/index.html" class="nav-item">
|
||||
<i data-lucide="layout-list"></i>
|
||||
<span>Tasks</span>
|
||||
</a>
|
||||
<a href="notes.html" class="nav-item">
|
||||
<a href="/echo/notes.html" class="nav-item">
|
||||
<i data-lucide="file-text"></i>
|
||||
<span>Notes</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>
|
||||
<a href="grup-sprijin.html" class="nav-item active">
|
||||
<a href="/echo/grup-sprijin.html" class="nav-item active">
|
||||
<i data-lucide="heart-handshake"></i>
|
||||
<span>Grup</span>
|
||||
</a>
|
||||
@@ -476,7 +476,7 @@
|
||||
if (fise.length > 0) {
|
||||
document.getElementById('fiseSection').style.display = 'block';
|
||||
document.getElementById('fiseList').innerHTML = fise.map(f => `
|
||||
<a href="files.html#kanban/grup-sprijin/${f.name}" class="filter-btn" style="text-decoration: none;">
|
||||
<a href="/echo/files.html#kanban/grup-sprijin/${f.name}" class="filter-btn" style="text-decoration: none;">
|
||||
${f.name.replace('fisa-', '').replace('.md', '')}
|
||||
</a>
|
||||
`).join('');
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 · KB</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>
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<style>
|
||||
.main {
|
||||
@@ -679,20 +679,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">
|
||||
<a href="/echo/index.html" class="nav-item">
|
||||
<i data-lucide="layout-list"></i>
|
||||
<span>Tasks</span>
|
||||
</a>
|
||||
<a href="notes.html" class="nav-item active">
|
||||
<a href="/echo/notes.html" class="nav-item active">
|
||||
<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>
|
||||
@@ -1172,7 +1172,7 @@
|
||||
<div class="note-card" onclick="openNote('${note.file}')">
|
||||
<div class="note-title">
|
||||
${note.title}
|
||||
<a href="files.html#${filesPath}" class="note-file-link" onclick="event.stopPropagation()" title="${filesPath}">
|
||||
<a href="/echo/files.html#${filesPath}" class="note-file-link" onclick="event.stopPropagation()" title="${filesPath}">
|
||||
<i data-lucide="external-link"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"ok": true,
|
||||
"status": "OK",
|
||||
"message": "Nicio modificare detectată",
|
||||
"lastCheck": "06 Feb 2026, 14:00",
|
||||
"lastCheck": "09 Feb 2026, 08:00",
|
||||
"changesCount": 0
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"lastUpdated": "2026-02-08T07:00:00.000Z",
|
||||
"lastUpdated": "2026-02-08T14:32:35.511Z",
|
||||
"items": [
|
||||
{
|
||||
"id": "prov-2026-02-08",
|
||||
@@ -8,8 +8,8 @@
|
||||
"example": "Scenariul tău real: Într-un exercițiu NLP, partenerul te blochează sau critică. În loc să rămâi în defensivă ('e greu') → aplici pattern interrupt din Tony Robbins: observi fiziologia (umeri contractați?), schimbi focusul (ce pot învăța despre cum reacționez?), schimbi limbajul ('e provocator' în loc de 'e greu'). Exercițiul devine mirror pentru tiparele tale în relații/business - exact cum reacționezi când angajatul nu înțelege sau când clientul critică.",
|
||||
"domain": "self",
|
||||
"dueDate": "2026-02-08",
|
||||
"done": false,
|
||||
"doneAt": null,
|
||||
"done": true,
|
||||
"doneAt": "2026-02-08T14:32:35.511Z",
|
||||
"source": "Tony Robbins - The Secret to an Extraordinary Life + Monica Ion - Legea Fractalilor",
|
||||
"sourceUrl": "https://moltbot.tailf7372d.ts.net/echo/files.html#memory/kb/coaching/2026-02-08-dimineata.md",
|
||||
"createdAt": "2026-02-08T07:00:00.000Z"
|
||||
|
||||
Reference in New Issue
Block a user