nothumanallowed 13.2.27 β 13.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/commands/ui.mjs +121 -102
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +43 -40
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.2.
|
|
3
|
+
"version": "13.2.29",
|
|
4
4
|
"description": "NotHumanAllowed β 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/commands/ui.mjs
CHANGED
|
@@ -2586,12 +2586,14 @@ Example output:
|
|
|
2586
2586
|
const hasCalendar = /calendar|agenda|calendari/i.test(task);
|
|
2587
2587
|
const hasSearch = /cerca|search|notizie|news/i.test(task);
|
|
2588
2588
|
const hasCanvas = /html|dashboard|visua|report/i.test(task);
|
|
2589
|
+
// Extract a short search query from the task (take key noun phrases, max 80 chars)
|
|
2590
|
+
const searchQueryFallback = task.replace(/^[^:]+:\s*/,'').split(/[,\n]/)[0].slice(0,80).trim() || task.slice(0,80);
|
|
2589
2591
|
steps = [];
|
|
2590
|
-
if (hasEmail) steps.push({icon:'
|
|
2591
|
-
if (hasCalendar) steps.push({icon:'
|
|
2592
|
-
if (hasSearch || steps.length === 0) steps.push({icon:'
|
|
2593
|
-
steps.push({icon:'
|
|
2594
|
-
if (hasCanvas) steps.push({icon:'
|
|
2592
|
+
if (hasEmail) steps.push({icon:'\u{1F4E7}',agent:'EmailAgent',label:'Controlla email',prompt:'Leggi le ultime email non lette e identifica elementi urgenti'});
|
|
2593
|
+
if (hasCalendar) steps.push({icon:'\u{1F4C5}',agent:'CalendarAgent',label:'Rivedi calendario',prompt:'Controlla gli eventi di oggi e identifica eventuali conflitti'});
|
|
2594
|
+
if (hasSearch || steps.length === 0) steps.push({icon:'\u{1F50D}',agent:'WebSearchAgent',label:'Ricerca web',prompt:searchQueryFallback});
|
|
2595
|
+
steps.push({icon:'\u{1F4F0}',agent:'HERALD',label:'Analisi e briefing',prompt:'Analizza tutti i dati forniti e scrivi un briefing esecutivo dettagliato con priorit\u00e0 e raccomandazioni'});
|
|
2596
|
+
if (hasCanvas) steps.push({icon:'\u{1F4CA}',agent:'CanvasAgent',label:'Dashboard HTML',prompt:'Crea una dashboard HTML visuale con i dati del briefing'});
|
|
2595
2597
|
}
|
|
2596
2598
|
if (!Array.isArray(steps) || !steps.length) {
|
|
2597
2599
|
sendJSON(res, 500, { error: 'Empty workflow plan' });
|
|
@@ -2661,9 +2663,24 @@ Example output:
|
|
|
2661
2663
|
} catch (e) { toolData = `Calendar read failed: ${e.message}`; }
|
|
2662
2664
|
|
|
2663
2665
|
} else if (agent === 'WebSearchAgent' || agent === 'ResearchAgent') {
|
|
2664
|
-
sendToken('[Searching the web...] ');
|
|
2666
|
+
sendToken('[Searching the web and reading pages...] ');
|
|
2665
2667
|
try {
|
|
2666
|
-
|
|
2668
|
+
// Extract a concise search query from the step prompt (avoid sending the whole task as query)
|
|
2669
|
+
// The planner should provide a short query, but if not, extract key terms
|
|
2670
|
+
let searchQuery = stepPrompt;
|
|
2671
|
+
// If the prompt is very long (> 120 chars), extract the core search terms
|
|
2672
|
+
if (searchQuery.length > 120) {
|
|
2673
|
+
// Try to extract a meaningful short query
|
|
2674
|
+
const keywordMatch = searchQuery.match(/(?:cerca|search|find|ricerca|notizie su|news about|latest on|aggiornamenti su)\s+(.{5,80}?)(?:\s+(?:e|and|per|for|poi|then)|$)/i);
|
|
2675
|
+
if (keywordMatch) {
|
|
2676
|
+
searchQuery = keywordMatch[1].trim();
|
|
2677
|
+
} else {
|
|
2678
|
+
// Take first meaningful clause before comma/period
|
|
2679
|
+
searchQuery = searchQuery.split(/[,\.\n]/)[0].slice(0, 100).trim();
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
// Use deep search: fetches and reads top 3 pages for real content
|
|
2683
|
+
const searchResult = await withTimeout(executeTool('web_search', { query: searchQuery, deep: true }, config), 25000);
|
|
2667
2684
|
toolData = typeof searchResult === 'string' ? searchResult : JSON.stringify(searchResult);
|
|
2668
2685
|
} catch (e) { toolData = `Web search failed: ${e.message}`; }
|
|
2669
2686
|
|
|
@@ -2725,128 +2742,130 @@ Example output:
|
|
|
2725
2742
|
// Tool-data agents: fetch real live data and use buildSystemPrompt (tool calls allowed)
|
|
2726
2743
|
const isLiveDataAgent = ['CalendarAgent','EmailAgent','GitHubAgent','NotionAgent','SlackAgent','DriveAgent','BrowserAgent','WebSearchAgent','ResearchAgent'].includes(agent);
|
|
2727
2744
|
|
|
2728
|
-
const canvasSystemPrompt = `You are an HTML report
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
-
|
|
2732
|
-
-
|
|
2733
|
-
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2745
|
+
const canvasSystemPrompt = `You are an expert HTML report designer. Output ONLY a complete HTML document in ${language}. Start immediately with <!DOCTYPE html>. No markdown, no explanation.
|
|
2746
|
+
|
|
2747
|
+
FORMATTING RULES β use ALL of these in the report:
|
|
2748
|
+
- <strong> for bold key terms and important values
|
|
2749
|
+
- <em> for emphasis and technical terms
|
|
2750
|
+
- <u> for critical warnings or deadlines
|
|
2751
|
+
- <ul><li> for bullet lists, <ol><li> for numbered/priority lists
|
|
2752
|
+
- <a href="URL" target="_blank" style="color:#22d3ee;text-decoration:underline"> for ALL source URLs β ALWAYS make URLs clickable hyperlinks, never plain text
|
|
2753
|
+
- Bar charts: use CSS width% on colored divs to visualize percentages/scores
|
|
2754
|
+
- Use <span class="badge-high">, <span class="badge-med">, <span class="badge-low"> for priority labels
|
|
2755
|
+
|
|
2756
|
+
CONTENT RULES:
|
|
2757
|
+
- ALL text must be in ${language}
|
|
2758
|
+
- Include ALL real content from the data: titles, descriptions, URLs, key findings
|
|
2759
|
+
- Do NOT summarize β include specific details, names, numbers, dates from the source data
|
|
2760
|
+
- For each news item/source: show title as <strong>, URL as clickable <a href>, and a real summary paragraph
|
|
2761
|
+
- Use <blockquote> for direct quotes or key excerpts
|
|
2762
|
+
|
|
2763
|
+
USE EXACTLY THIS CSS (do not change it, only add content):
|
|
2736
2764
|
<!DOCTYPE html>
|
|
2737
2765
|
<html lang="${language.slice(0,2).toLowerCase()}">
|
|
2738
2766
|
<head>
|
|
2739
2767
|
<meta charset="UTF-8">
|
|
2740
|
-
<meta name="viewport" content="width=device-width,
|
|
2741
|
-
<title>
|
|
2768
|
+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
2769
|
+
<title>NHA Studio Report</title>
|
|
2742
2770
|
<style>
|
|
2743
2771
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
2744
|
-
body{font-family:'Inter',system-ui,sans-serif;background:#0d0d14;color:#f0f0f5;min-height:100vh;padding:
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
.
|
|
2751
|
-
.
|
|
2752
|
-
.
|
|
2753
|
-
.
|
|
2754
|
-
.
|
|
2755
|
-
.
|
|
2756
|
-
.card
|
|
2757
|
-
.card
|
|
2758
|
-
.
|
|
2759
|
-
.
|
|
2760
|
-
.
|
|
2761
|
-
.
|
|
2762
|
-
.
|
|
2763
|
-
.section{
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2772
|
+
body{font-family:'Inter',system-ui,sans-serif;background:#0d0d14;color:#f0f0f5;min-height:100vh;padding:20px;font-size:14px;line-height:1.65}
|
|
2773
|
+
a{color:#22d3ee;text-decoration:underline}a:hover{color:#6366f1}
|
|
2774
|
+
strong{color:#f0f0f5;font-weight:700}
|
|
2775
|
+
em{color:#a5b4fc;font-style:italic}
|
|
2776
|
+
u{text-decoration-color:#ef4444}
|
|
2777
|
+
blockquote{border-left:3px solid #6366f1;padding:8px 16px;margin:10px 0;background:#15151f;border-radius:0 8px 8px 0;color:#8b8b9e;font-style:italic}
|
|
2778
|
+
.header{background:linear-gradient(135deg,#4f46e5 0%,#06b6d4 100%);border-radius:16px;padding:28px 36px;margin-bottom:20px}
|
|
2779
|
+
.header h1{font-size:26px;font-weight:800;color:#fff;margin-bottom:6px}
|
|
2780
|
+
.header p{font-size:13px;color:rgba(255,255,255,0.85);margin:0}
|
|
2781
|
+
.meta{display:flex;gap:10px;margin-top:14px;flex-wrap:wrap}
|
|
2782
|
+
.meta span{background:rgba(255,255,255,0.18);border-radius:20px;padding:3px 12px;font-size:11px;color:#fff;font-weight:500}
|
|
2783
|
+
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px;margin-bottom:20px}
|
|
2784
|
+
.card{background:#15151f;border:1px solid #2a2a38;border-radius:12px;padding:18px}
|
|
2785
|
+
.card-label{font-size:10px;text-transform:uppercase;letter-spacing:1.5px;color:#6366f1;font-weight:700;margin-bottom:8px}
|
|
2786
|
+
.card h3{font-size:18px;font-weight:700;color:#f0f0f5;margin-bottom:4px}
|
|
2787
|
+
.card p{font-size:12px;color:#8b8b9e;margin:0}
|
|
2788
|
+
.section{background:#15151f;border:1px solid #2a2a38;border-radius:12px;padding:22px;margin-bottom:16px}
|
|
2789
|
+
.section-title{font-size:10px;text-transform:uppercase;letter-spacing:1.5px;color:#22d3ee;font-weight:700;margin-bottom:16px}
|
|
2790
|
+
.section h3{font-size:15px;font-weight:600;color:#f0f0f5;margin-bottom:6px;margin-top:14px}
|
|
2791
|
+
.section p{font-size:13px;color:#8b8b9e;line-height:1.7;margin-bottom:10px}
|
|
2792
|
+
ul{list-style:none;padding:0;margin:8px 0}
|
|
2793
|
+
ul li{padding:4px 0 4px 18px;position:relative;font-size:13px;color:#8b8b9e}
|
|
2794
|
+
ul li::before{content:'βΊ';position:absolute;left:0;color:#6366f1;font-weight:700}
|
|
2795
|
+
ol{padding-left:20px;margin:8px 0}
|
|
2796
|
+
ol li{padding:4px 0;font-size:13px;color:#8b8b9e;line-height:1.6}
|
|
2797
|
+
.priority-list{display:flex;flex-direction:column;gap:8px}
|
|
2768
2798
|
.priority-item{display:flex;align-items:flex-start;gap:12px;padding:12px;background:#1c1c28;border-radius:8px}
|
|
2769
|
-
.priority-num{width:
|
|
2770
|
-
.priority-item h4{font-size:13px;font-weight:600;color:#f0f0f5;margin-bottom:
|
|
2799
|
+
.priority-num{width:26px;height:26px;border-radius:50%;background:#6366f1;color:#fff;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1px}
|
|
2800
|
+
.priority-item h4{font-size:13px;font-weight:600;color:#f0f0f5;margin-bottom:3px}
|
|
2771
2801
|
.priority-item p{font-size:12px;color:#8b8b9e;line-height:1.5;margin:0}
|
|
2772
|
-
.
|
|
2802
|
+
.source-item{padding:14px;background:#1c1c28;border-radius:8px;margin-bottom:10px;border-left:3px solid #6366f1}
|
|
2803
|
+
.source-item h4{font-size:13px;font-weight:600;color:#f0f0f5;margin-bottom:4px}
|
|
2804
|
+
.source-item p{font-size:12px;color:#8b8b9e;line-height:1.6;margin:4px 0}
|
|
2805
|
+
.source-item a{font-size:11px}
|
|
2806
|
+
.bar-row{margin-bottom:10px}
|
|
2807
|
+
.bar-label{font-size:12px;color:#8b8b9e;margin-bottom:4px;display:flex;justify-content:space-between}
|
|
2808
|
+
.bar-track{background:#1c1c28;border-radius:4px;height:8px;overflow:hidden}
|
|
2809
|
+
.bar-fill{height:100%;border-radius:4px;background:linear-gradient(90deg,#6366f1,#22d3ee)}
|
|
2810
|
+
.badge-high{display:inline-block;background:#7f1d1d;color:#ef4444;border-radius:12px;padding:2px 10px;font-size:10px;font-weight:700;margin-right:4px}
|
|
2811
|
+
.badge-med{display:inline-block;background:#713f12;color:#f59e0b;border-radius:12px;padding:2px 10px;font-size:10px;font-weight:700;margin-right:4px}
|
|
2812
|
+
.badge-low{display:inline-block;background:#14532d;color:#34d399;border-radius:12px;padding:2px 10px;font-size:10px;font-weight:700;margin-right:4px}
|
|
2813
|
+
.badge-info{display:inline-block;background:#1e1b4b;color:#a5b4fc;border-radius:12px;padding:2px 10px;font-size:10px;font-weight:700;margin-right:4px}
|
|
2814
|
+
.divider{border:none;border-top:1px solid #2a2a38;margin:16px 0}
|
|
2815
|
+
.footer{text-align:center;padding:18px;font-size:11px;color:#4a4a5e;margin-top:8px}
|
|
2773
2816
|
</style>
|
|
2774
2817
|
</head>
|
|
2775
2818
|
<body>
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
</div>
|
|
2785
|
-
</div>
|
|
2786
|
-
|
|
2787
|
-
<!-- STATS GRID: 3-4 cards with key numbers/stats -->
|
|
2788
|
-
<div class="grid">
|
|
2789
|
-
<div class="card">
|
|
2790
|
-
<h2>LABEL 1</h2>
|
|
2791
|
-
<h3>STAT OR TITLE</h3>
|
|
2792
|
-
<p>DESCRIPTION</p>
|
|
2793
|
-
</div>
|
|
2794
|
-
<!-- Add more cards for other stats -->
|
|
2795
|
-
</div>
|
|
2796
|
-
|
|
2797
|
-
<!-- MAIN SECTIONS: 2-4 sections with content -->
|
|
2798
|
-
<div class="section">
|
|
2799
|
-
<h2>SECTION LABEL</h2>
|
|
2800
|
-
<div class="priority-list">
|
|
2801
|
-
<div class="priority-item">
|
|
2802
|
-
<div class="priority-num">1</div>
|
|
2803
|
-
<div><h4>ITEM TITLE</h4><p>ITEM DESCRIPTION</p></div>
|
|
2804
|
-
</div>
|
|
2805
|
-
<!-- Add more priority items -->
|
|
2806
|
-
</div>
|
|
2807
|
-
</div>
|
|
2808
|
-
|
|
2809
|
-
<div class="footer">Generated by NHA Studio Β· ${today}</div>
|
|
2810
|
-
</body>
|
|
2811
|
-
</html>
|
|
2812
|
-
|
|
2813
|
-
Fill ALL placeholder text with the actual content from the data provided. Keep ALL CSS exactly as above. Output ONLY the HTML.`;
|
|
2819
|
+
|
|
2820
|
+
[HEADER β gradient card with h1 title, subtitle p, and .meta spans for date/stats]
|
|
2821
|
+
[GRID β 3-4 .card stat boxes with real numbers from the data]
|
|
2822
|
+
[SECTIONS β use .section with .section-title, then real content with h3, p, ul/ol, .source-item for URLs, .priority-list for ranked items, .bar-row for visual charts]
|
|
2823
|
+
[For every URL in the data: wrap in <a href="..." target="_blank"> as a clickable hyperlink]
|
|
2824
|
+
[FOOTER β "NHA Studio Β· ${today}"]
|
|
2825
|
+
|
|
2826
|
+
Output ONLY the full HTML. Replace all bracketed instructions above with real HTML content.`;
|
|
2814
2827
|
|
|
2815
2828
|
let sysPrompt, userMsg;
|
|
2816
2829
|
|
|
2817
2830
|
if (isCanvasAgent) {
|
|
2818
2831
|
sysPrompt = canvasSystemPrompt;
|
|
2819
|
-
userMsg = `Generate a beautiful HTML dashboard report for this content. Start immediately with <!DOCTYPE html>:\n\n${context.slice(0,
|
|
2832
|
+
userMsg = `Generate a beautiful HTML dashboard report for this content. Start immediately with <!DOCTYPE html>:\n\n${context.slice(0, 10000)}`;
|
|
2820
2833
|
} else if (isLiveDataAgent) {
|
|
2821
|
-
// These agents fetched real data β use
|
|
2822
|
-
const agentInstruction = `You are ${agent}, a specialist AI agent inside NHA Studio.
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2834
|
+
// These agents fetched real data β use a focused prompt (no tool definitions to avoid JSON output)
|
|
2835
|
+
const agentInstruction = `You are ${agent}, a specialist AI agent inside NHA Studio. Today is ${today}. Respond entirely in ${language}.
|
|
2836
|
+
|
|
2837
|
+
CRITICAL: Do NOT invent, hallucinate, or add any data not present in the DATA sections below. ONLY use the exact data provided.
|
|
2838
|
+
Do NOT output JSON, tool calls, or code blocks. Write in plain text with markdown headers.
|
|
2839
|
+
|
|
2840
|
+
${toolData ? `## DATA FROM TOOLS:\n${toolData.slice(0, 6000)}\n` : '## DATA: No data was retrieved by this agent.\n'}
|
|
2841
|
+
${context ? `## OUTPUT FROM PREVIOUS AGENTS:\n${context.slice(0, 4000)}\n` : ''}
|
|
2842
|
+
|
|
2843
|
+
Your task: ${stepPrompt}`;
|
|
2844
|
+
sysPrompt = agentInstruction;
|
|
2827
2845
|
userMsg = toolData
|
|
2828
|
-
? `Summarize the data above
|
|
2846
|
+
? `Summarize and analyze the REAL data above. Do not add anything not present in the data.`
|
|
2829
2847
|
: context
|
|
2830
|
-
? `Based on the previous
|
|
2848
|
+
? `Based ONLY on the previous agent outputs above, complete: ${stepPrompt}`
|
|
2831
2849
|
: stepPrompt;
|
|
2832
2850
|
} else {
|
|
2833
2851
|
// All other agents (WriterAgent, DataAnalystAgent, specialist agents, etc.)
|
|
2834
2852
|
// Use a focused prompt with NO TOOL_DEFINITIONS to prevent JSON/tool-call output
|
|
2853
|
+
const hasRealData = !!(toolData || context);
|
|
2835
2854
|
sysPrompt = `You are ${agent}, a specialist AI agent inside NHA Studio. Today is ${today}. You MUST respond entirely in ${language}.
|
|
2836
2855
|
|
|
2837
2856
|
CRITICAL RULES:
|
|
2838
2857
|
- Do NOT output JSON, tool calls, function calls, or code blocks
|
|
2839
|
-
-
|
|
2840
|
-
-
|
|
2841
|
-
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
? `
|
|
2849
|
-
: stepPrompt
|
|
2858
|
+
- NEVER invent, fabricate, or hallucinate data, events, emails, meetings, or news
|
|
2859
|
+
- ONLY use the EXACT data provided in the DATA sections below β if no data is provided, say so clearly
|
|
2860
|
+
- Do NOT add fictional examples, placeholder content, or generic suggestions not grounded in the data
|
|
2861
|
+
- Write in plain prose, structured with markdown headers (##) and bullet points (-)
|
|
2862
|
+
- Be thorough and specific β this is for an executive briefing based on REAL data only
|
|
2863
|
+
|
|
2864
|
+
${toolData ? `## LIVE DATA FROM TOOLS:\n${toolData.slice(0, 6000)}\n` : '## LIVE DATA: No tool data was fetched for this step.\n'}
|
|
2865
|
+
${context ? `## OUTPUT FROM PREVIOUS AGENTS:\n${context.slice(0, 6000)}\n` : ''}`;
|
|
2866
|
+
userMsg = hasRealData
|
|
2867
|
+
? `Based ONLY on the real data above, complete this task: ${stepPrompt}`
|
|
2868
|
+
: `No real data is available. State clearly that no data was retrieved and explain what would be needed: ${stepPrompt}`;
|
|
2850
2869
|
}
|
|
2851
2870
|
|
|
2852
2871
|
// ββ Stream LLM response βββββββββββββββββββββββββββββββββββββββ
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '13.2.
|
|
8
|
+
export const VERSION = '13.2.29';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
package/src/services/web-ui.mjs
CHANGED
|
@@ -2975,7 +2975,10 @@ function renderStudioResult() {
|
|
|
2975
2975
|
var body = isHtml
|
|
2976
2976
|
? '<div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap"><span style="color:var(--dim);font-size:13px">✓ ' + t('canvas_generated') + '</span><button onclick="openCanvasPanel()" style="padding:6px 14px;background:var(--greendim);border:1px solid var(--green3);border-radius:8px;color:var(--green);font-size:12px;cursor:pointer;font-weight:700">▣ ' + t('canvas_open') + '</button></div>'
|
|
2977
2977
|
: '<div class="md-body">' + renderMd(studioState.result) + '</div>';
|
|
2978
|
-
el.innerHTML = '<div class="studio-result__title">✓
|
|
2978
|
+
el.innerHTML = '<div class="studio-result__title">✓ ' + t('workflow_complete') + '</div>' + body;
|
|
2979
|
+
// Show/hide persistent canvas button in toolbar
|
|
2980
|
+
var canvasBtn = document.getElementById('studioCanvasBtn');
|
|
2981
|
+
if (canvasBtn) canvasBtn.style.display = isHtml ? '' : 'none';
|
|
2979
2982
|
}
|
|
2980
2983
|
|
|
2981
2984
|
function studioSetNodeStatus(idx, status) {
|
|
@@ -3295,44 +3298,44 @@ function renderStudio(el) {
|
|
|
3295
3298
|
|
|
3296
3299
|
// 38 specialist agents sidebar
|
|
3297
3300
|
var SPECIALIST_AGENTS = [
|
|
3298
|
-
{icon:'
|
|
3299
|
-
{icon:'
|
|
3300
|
-
{icon:'
|
|
3301
|
-
{icon:'
|
|
3302
|
-
{icon:'
|
|
3303
|
-
{icon:'
|
|
3304
|
-
{icon:'
|
|
3305
|
-
{icon:'
|
|
3306
|
-
{icon:'
|
|
3307
|
-
{icon:'
|
|
3308
|
-
{icon:'
|
|
3309
|
-
{icon:'
|
|
3310
|
-
{icon:'
|
|
3311
|
-
{icon:'
|
|
3312
|
-
{icon:'
|
|
3313
|
-
{icon:'
|
|
3314
|
-
{icon:'
|
|
3315
|
-
{icon:'
|
|
3316
|
-
{icon:'
|
|
3317
|
-
{icon:'
|
|
3318
|
-
{icon:'
|
|
3319
|
-
{icon:'
|
|
3320
|
-
{icon:'
|
|
3321
|
-
{icon:'
|
|
3322
|
-
{icon:'
|
|
3323
|
-
{icon:'
|
|
3324
|
-
{icon:'
|
|
3325
|
-
{icon:'
|
|
3326
|
-
{icon:'
|
|
3327
|
-
{icon:'
|
|
3328
|
-
{icon:'
|
|
3329
|
-
{icon:'
|
|
3330
|
-
{icon:'
|
|
3331
|
-
{icon:'
|
|
3332
|
-
{icon:'
|
|
3333
|
-
{icon:'
|
|
3334
|
-
{icon:'
|
|
3335
|
-
{icon:'
|
|
3301
|
+
{icon:'\u{1F6E1}',name:'saber',desc:'Security audits, pentest, OWASP'},
|
|
3302
|
+
{icon:'\u{1F50D}',name:'zero',desc:'Vulnerability & dependency audit'},
|
|
3303
|
+
{icon:'\u2713',name:'veritas',desc:'Fact-checking & hallucination detection'},
|
|
3304
|
+
{icon:'\u{1F52C}',name:'ade',desc:'Full security review, forensics'},
|
|
3305
|
+
{icon:'\u{1F512}',name:'heimdall',desc:'OAuth, JWT, RBAC design'},
|
|
3306
|
+
{icon:'\u{1F4BB}',name:'jarvis',desc:'Full-stack architecture & API'},
|
|
3307
|
+
{icon:'\u2699',name:'forge',desc:'CI/CD, deployment, infra'},
|
|
3308
|
+
{icon:'\u{1F527}',name:'pipe',desc:'Build systems, Airflow, automation'},
|
|
3309
|
+
{icon:'\u{1F4DF}',name:'shell',desc:'Shell scripts, CLI tools'},
|
|
3310
|
+
{icon:'\u{1F41B}',name:'glitch',desc:'Debugging & root cause'},
|
|
3311
|
+
{icon:'\u{1F4CA}',name:'oracle',desc:'Data analysis, stats, ML'},
|
|
3312
|
+
{icon:'\u{1F9EE}',name:'logos',desc:'Logic, proofs, formal reasoning'},
|
|
3313
|
+
{icon:'\u{1F5FA}',name:'atlas',desc:'Terraform, CloudFormation, IaC'},
|
|
3314
|
+
{icon:'\u{1F30D}',name:'cartographer',desc:'Geo data, mapping, routing'},
|
|
3315
|
+
{icon:'\u270D',name:'scheherazade',desc:'Docs, tutorials, blog posts'},
|
|
3316
|
+
{icon:'\u{1F4DD}',name:'quill',desc:'Posts, summaries, abstracts'},
|
|
3317
|
+
{icon:'\u{1F3A8}',name:'muse',desc:'Creative brainstorming & ideation'},
|
|
3318
|
+
{icon:'\u{1F58C}',name:'murasaki',desc:'UI/UX design, accessibility'},
|
|
3319
|
+
{icon:'\u{1F517}',name:'hermes',desc:'Kafka, RabbitMQ, event-driven'},
|
|
3320
|
+
{icon:'\u{1F50C}',name:'link',desc:'Community, reputation, engagement'},
|
|
3321
|
+
{icon:'\u{1F310}',name:'mercury',desc:'Finance, market, ROI analysis'},
|
|
3322
|
+
{icon:'\u2638',name:'shogun',desc:'Kubernetes, Helm, pod security'},
|
|
3323
|
+
{icon:'\u{1F504}',name:'flux',desc:'GitOps, rollback planning'},
|
|
3324
|
+
{icon:'\u23F0',name:'cron',desc:'GitHub Actions, GitLab CI'},
|
|
3325
|
+
{icon:'\u{1F30E}',name:'babel',desc:'API integration, microservices'},
|
|
3326
|
+
{icon:'\u{1F5E3}',name:'polyglot',desc:'i18n, localization, translation'},
|
|
3327
|
+
{icon:'\u{1F4E2}',name:'herald',desc:'News analysis, trend detection'},
|
|
3328
|
+
{icon:'\u{1F4E1}',name:'echo',desc:'Content repurposing: blog\u2192social'},
|
|
3329
|
+
{icon:'\u26A1',name:'macro',desc:'Batch processing, data migration'},
|
|
3330
|
+
{icon:'\u{1F525}',name:'prometheus',desc:'Strategy, architecture trade-offs'},
|
|
3331
|
+
{icon:'\u26A0',name:'cassandra',desc:'Risk prediction, worst-case analysis'},
|
|
3332
|
+
{icon:'\u{1F9E0}',name:'athena',desc:'Tech evaluation, benchmarks'},
|
|
3333
|
+
{icon:'\u{1F441}',name:'sauron',desc:'Performance profiling, bottlenecks'},
|
|
3334
|
+
{icon:'\u{1F3BC}',name:'conductor',desc:'Workflow orchestration'},
|
|
3335
|
+
{icon:'\u{1F9ED}',name:'navi',desc:'Data profiling, schema inference'},
|
|
3336
|
+
{icon:'\u{1F4C8}',name:'edi',desc:'A/B testing, hypothesis testing'},
|
|
3337
|
+
{icon:'\u26C8',name:'tempest',desc:'Climate, weather, environmental'},
|
|
3338
|
+
{icon:'\u{1F37D}',name:'epicure',desc:'Recipes, nutrition, dietary'},
|
|
3336
3339
|
];
|
|
3337
3340
|
var specialistHtml = SPECIALIST_AGENTS.map(function(t){
|
|
3338
3341
|
var ic = t.icon;
|
|
@@ -3389,7 +3392,7 @@ function renderStudio(el) {
|
|
|
3389
3392
|
|
|
3390
3393
|
'<div style="display:flex;align-items:center;gap:8px;margin:8px 0">' +
|
|
3391
3394
|
'<div id="studioTokenBar" style="font-size:10px;color:var(--dim);font-family:var(--mono);flex:1"></div>' +
|
|
3392
|
-
'<button id="studioCanvasBtn" onclick="
|
|
3395
|
+
'<button id="studioCanvasBtn" onclick="openCanvasPanel()" style="display:none;font-size:12px;padding:5px 14px;background:var(--greendim);border:1px solid var(--green3);border-radius:6px;color:var(--green);cursor:pointer;font-weight:700">■ ' + t('canvas_open') + '</button>' +
|
|
3393
3396
|
'</div>' +
|
|
3394
3397
|
'<div class="studio-canvas" id="studioNodes"></div>' +
|
|
3395
3398
|
'<div class="studio-log" id="studioLog" style="display:none"></div>' +
|