nothumanallowed 13.2.93 → 13.2.94
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/constants.mjs +1 -1
- package/src/services/web-ui.mjs +135 -32
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.2.
|
|
3
|
+
"version": "13.2.94",
|
|
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/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.94';
|
|
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
|
@@ -3677,7 +3677,8 @@ function downloadStudioPDF() {
|
|
|
3677
3677
|
'</div>' +
|
|
3678
3678
|
'</body></html>';
|
|
3679
3679
|
|
|
3680
|
-
// Generate PDF
|
|
3680
|
+
// Generate PDF — injects print-safe CSS then uses html2canvas at 2.5x for crisp output.
|
|
3681
|
+
// Page breaks are avoided inside .section/.card/.priority-item by injecting break-inside:avoid.
|
|
3681
3682
|
var pdfFileName = (studioState.task || 'NHA Studio Report').slice(0, 60).replace(/[^a-z0-9\s]/gi,'').trim().replace(/\s+/g,'-') + '.pdf';
|
|
3682
3683
|
function doGeneratePdf() {
|
|
3683
3684
|
var btn2 = document.getElementById('studioInlinePdfBtn');
|
|
@@ -3687,33 +3688,67 @@ function downloadStudioPDF() {
|
|
|
3687
3688
|
if (dlBtn2) { dlBtn2.disabled = b; dlBtn2.textContent = b ? 'Generando PDF...' : '\u2913 Download PDF'; }
|
|
3688
3689
|
}
|
|
3689
3690
|
setBusy(true);
|
|
3690
|
-
|
|
3691
|
+
|
|
3692
|
+
// Inject page-break-safe CSS into the HTML before rendering
|
|
3693
|
+
var printCss = '<style>body{padding:20px!important;max-width:800px!important;margin:0 auto!important}' +
|
|
3694
|
+
'.section,.card,.priority-item,.source-item,.bar-row{break-inside:avoid;page-break-inside:avoid}' +
|
|
3695
|
+
'.header{break-after:avoid;page-break-after:avoid}' +
|
|
3696
|
+
'h1,h2,h3,h4{break-after:avoid;page-break-after:avoid}' +
|
|
3697
|
+
'@media print{body{background:#fff!important;color:#111!important}' +
|
|
3698
|
+
'.header{background:linear-gradient(135deg,#4f46e5,#06b6d4)!important;-webkit-print-color-adjust:exact}' +
|
|
3699
|
+
'.section{background:#f8f9fa!important;border:1px solid #e0e0e0!important}' +
|
|
3700
|
+
'.section-title{color:#4f46e5!important}}</style>';
|
|
3701
|
+
var pdfHtml = html.replace('</head>', printCss + '</head>');
|
|
3702
|
+
|
|
3703
|
+
// Build hidden iframe at 800px (A4 equivalent at 96dpi)
|
|
3691
3704
|
var iframe = document.createElement('iframe');
|
|
3692
|
-
iframe.style.cssText = 'position:fixed;left:-9999px;top:0;width:
|
|
3705
|
+
iframe.style.cssText = 'position:fixed;left:-9999px;top:0;width:800px;height:1px;border:none;visibility:hidden';
|
|
3693
3706
|
document.body.appendChild(iframe);
|
|
3694
3707
|
var ifrDoc = iframe.contentDocument || iframe.contentWindow.document;
|
|
3695
|
-
ifrDoc.open(); ifrDoc.write(
|
|
3708
|
+
ifrDoc.open(); ifrDoc.write(pdfHtml); ifrDoc.close();
|
|
3696
3709
|
iframe.onload = function() {
|
|
3697
3710
|
var body = ifrDoc.body;
|
|
3698
3711
|
var totalH = Math.max(body.scrollHeight, body.offsetHeight, ifrDoc.documentElement.scrollHeight);
|
|
3699
3712
|
iframe.style.height = totalH + 'px';
|
|
3713
|
+
// Render at 2.5x scale for crisp text
|
|
3700
3714
|
window.html2canvas(body, {
|
|
3701
|
-
scale:
|
|
3702
|
-
|
|
3715
|
+
scale: 2.5, useCORS: true, allowTaint: true,
|
|
3716
|
+
backgroundColor: '#0d0d14',
|
|
3717
|
+
width: 800, windowWidth: 800,
|
|
3703
3718
|
scrollX: 0, scrollY: 0,
|
|
3704
3719
|
ignoreElements: function(el){ return el.tagName === 'SCRIPT'; }
|
|
3705
3720
|
}).then(function(canvas) {
|
|
3706
|
-
var imgData = canvas.toDataURL('image/
|
|
3721
|
+
var imgData = canvas.toDataURL('image/png'); // PNG for crisp text
|
|
3707
3722
|
var pdf = new window.jspdf.jsPDF({orientation:'portrait', unit:'pt', format:'a4', compress:true});
|
|
3708
|
-
var pageW = pdf.internal.pageSize.getWidth();
|
|
3709
|
-
var pageH = pdf.internal.pageSize.getHeight();
|
|
3710
|
-
var
|
|
3711
|
-
var
|
|
3712
|
-
var
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3723
|
+
var pageW = pdf.internal.pageSize.getWidth(); // 595pt
|
|
3724
|
+
var pageH = pdf.internal.pageSize.getHeight(); // 842pt
|
|
3725
|
+
var margin = 24; // pt
|
|
3726
|
+
var usableW = pageW - margin * 2;
|
|
3727
|
+
var usableH = pageH - margin * 2;
|
|
3728
|
+
// Scale image to fit page width
|
|
3729
|
+
var imgW = usableW;
|
|
3730
|
+
var imgH = (canvas.height * usableW) / canvas.width;
|
|
3731
|
+
|
|
3732
|
+
// Smart paging: find safe cut points every ~usableH
|
|
3733
|
+
// Strategy: render slice by slice, each slice fits one page
|
|
3734
|
+
var sliceH = Math.floor(canvas.height * (usableH / imgH)); // canvas px per page
|
|
3735
|
+
var yCanvas = 0;
|
|
3736
|
+
var pageNum = 0;
|
|
3737
|
+
while (yCanvas < canvas.height) {
|
|
3738
|
+
if (pageNum > 0) pdf.addPage();
|
|
3739
|
+
var remaining = canvas.height - yCanvas;
|
|
3740
|
+
var thisSlice = Math.min(sliceH, remaining);
|
|
3741
|
+
// Create a temporary canvas for this slice
|
|
3742
|
+
var sliceCanvas = document.createElement('canvas');
|
|
3743
|
+
sliceCanvas.width = canvas.width;
|
|
3744
|
+
sliceCanvas.height = thisSlice;
|
|
3745
|
+
var ctx = sliceCanvas.getContext('2d');
|
|
3746
|
+
ctx.drawImage(canvas, 0, yCanvas, canvas.width, thisSlice, 0, 0, canvas.width, thisSlice);
|
|
3747
|
+
var sliceData = sliceCanvas.toDataURL('image/png');
|
|
3748
|
+
var sliceImgH = (thisSlice * usableW) / canvas.width;
|
|
3749
|
+
pdf.addImage(sliceData, 'PNG', margin, margin, usableW, sliceImgH, '', 'FAST');
|
|
3750
|
+
yCanvas += thisSlice;
|
|
3751
|
+
pageNum++;
|
|
3717
3752
|
}
|
|
3718
3753
|
pdf.save(pdfFileName);
|
|
3719
3754
|
document.body.removeChild(iframe);
|
|
@@ -3803,6 +3838,8 @@ async function runStudio() {
|
|
|
3803
3838
|
studioState.running = true;
|
|
3804
3839
|
studioState.planned = false;
|
|
3805
3840
|
// Keep attachmentContext — it was loaded before hitting Run
|
|
3841
|
+
var parlBlockEl = document.getElementById('studioParliamentBlock');
|
|
3842
|
+
if (parlBlockEl) parlBlockEl.style.display = 'none';
|
|
3806
3843
|
renderStudioNodes();
|
|
3807
3844
|
renderStudioLog();
|
|
3808
3845
|
renderStudioResult();
|
|
@@ -3929,6 +3966,38 @@ async function runStudio() {
|
|
|
3929
3966
|
var parlNodeIdx = studioState.nodes.length;
|
|
3930
3967
|
studioState.nodes.push({icon:\x27♖\x27, agent:\x27Parliament\x27, label:\x27Parlamento\x27, status:\x27running\x27, output:\x27\x27, _rendered:false});
|
|
3931
3968
|
renderStudioNodes();
|
|
3969
|
+
|
|
3970
|
+
// ── Parliament visual block ──────────────────────────────────────
|
|
3971
|
+
// Track active R2 agent for visual block
|
|
3972
|
+
var parlActiveAgent = null;
|
|
3973
|
+
var parlDoneAgents = {};
|
|
3974
|
+
|
|
3975
|
+
function renderParlBlock(phase, activeLabel, convergence) {
|
|
3976
|
+
var pb = document.getElementById(\x27studioParliamentBlock\x27);
|
|
3977
|
+
if (!pb) return;
|
|
3978
|
+
pb.style.display = \x27block\x27;
|
|
3979
|
+
var agentCircles = proposals.map(function(p) {
|
|
3980
|
+
var lbl = p.label || p.agent;
|
|
3981
|
+
var isDone = !!parlDoneAgents[lbl];
|
|
3982
|
+
var isActive = lbl === activeLabel;
|
|
3983
|
+
var circCls = \x27studio-parliament__agent-circle\x27 + (isActive ? \x27 studio-parliament__agent-circle--reading\x27 : isDone ? \x27 studio-parliament__agent-circle--done\x27 : \x27\x27);
|
|
3984
|
+
var readingTxt = isActive
|
|
3985
|
+
? (\x27<div class="studio-parliament__reading">\u21c4 legge ' + proposals.filter(function(x){return (x.label||x.agent)!==lbl;}).map(function(x){return x.label||x.agent;}).slice(0,2).join(\x27, \x27) + \x27</div>\x27)
|
|
3986
|
+
: \x27\x27;
|
|
3987
|
+
return \x27<div class="studio-parliament__agent"><div class="\x27 + circCls + \x27">\x27 + esc(p.icon||String.fromCharCode(9632)) + \x27</div><div class="studio-parliament__agent-label">\x27 + esc(lbl.slice(0,14)) + \x27</div>\x27 + readingTxt + \x27</div>\x27;
|
|
3988
|
+
}).join(\x27<div class="studio-parliament__bidir">\u21c4</div>\x27);
|
|
3989
|
+
|
|
3990
|
+
var phaseLabel = phase === \x27r1\x27 ? \x27Round 1\x27 : phase === \x27r2\x27 ? \x27Round 2 — Cross-reading\x27 : phase === \x27r3\x27 ? \x27Round 3 — Mediazione\x27 : \x27Completato\x27;
|
|
3991
|
+
var roundEl = convergence != null
|
|
3992
|
+
? \x27<div class="studio-parliament__convergence">✔ Convergenza: \x27 + convergence + \x27% — deliberazione completata</div>\x27
|
|
3993
|
+
: \x27<span class="studio-parliament__round">\x27 + phaseLabel + \x27</span>\x27;
|
|
3994
|
+
|
|
3995
|
+
pb.innerHTML = \x27<div class="studio-parliament"><div class="studio-parliament__header"><div class="studio-parliament__master"><span class="studio-parliament__master-icon">♦</span><span>MASTER AGENT — Orchestrazione</span></div><div class="studio-parliament__title">♖ PARLIAMENT</div>\x27 + (convergence == null ? roundEl : \x27\x27) + \x27</div><div class="studio-parliament__agents">\x27 + agentCircles + \x27</div>\x27 + (convergence != null ? roundEl : \x27\x27) + \x27</div>\x27;
|
|
3996
|
+
}
|
|
3997
|
+
|
|
3998
|
+
// Show initial R1 block
|
|
3999
|
+
renderParlBlock(\x27r1\x27, null, null);
|
|
4000
|
+
|
|
3932
4001
|
var deliberateBody = JSON.stringify({task: task, proposals: proposals, language: document.getElementById(\x27langSelect\x27) ? document.getElementById(\x27langSelect\x27).value : \x27it\x27});
|
|
3933
4002
|
try {
|
|
3934
4003
|
var delRes = await fetch(\x27/api/studio/deliberate\x27, {method:\x27POST\x27, headers:{\x27Content-Type\x27:\x27application/json\x27}, body: deliberateBody, signal: studioAbortController ? studioAbortController.signal : undefined});
|
|
@@ -3950,12 +4019,11 @@ async function runStudio() {
|
|
|
3950
4019
|
try {
|
|
3951
4020
|
var dev = JSON.parse(dd);
|
|
3952
4021
|
if (dev.token) {
|
|
3953
|
-
// Status tokens — check for Round 2 start to add new animated log entry
|
|
3954
4022
|
var r2StartM = dev.token.match(/^\\[Round 2: (.+?)\\]\\s*$/);
|
|
3955
4023
|
var r2LiveM = dev.token.match(/^\\[Round 2 (.+?): (\\d+) token\\]\\s*$/);
|
|
3956
4024
|
if (r2StartM) {
|
|
3957
|
-
// New R2 agent starting — add a new log entry with thinking animation
|
|
3958
4025
|
var r2Label = r2StartM[1];
|
|
4026
|
+
parlActiveAgent = r2Label;
|
|
3959
4027
|
studioLog(r2Label, \x27♖\x27, \x27\x27, \x27agent\x27, false);
|
|
3960
4028
|
var delEnts2 = document.querySelectorAll(\x27.studio-log-entry\x27);
|
|
3961
4029
|
var delL2 = delEnts2[delEnts2.length - 1];
|
|
@@ -3964,7 +4032,7 @@ async function runStudio() {
|
|
|
3964
4032
|
var delTb2 = delL2.querySelector(\x27.studio-log-entry__text\x27);
|
|
3965
4033
|
if (delTb2) delTb2.innerHTML = \x27<span style="color:var(--green);font-family:var(--mono);font-size:10px">♖ Deliberando Round 2<span class="thinking-dots"><span></span><span></span><span></span></span></span>\x27;
|
|
3966
4034
|
}
|
|
3967
|
-
|
|
4035
|
+
renderParlBlock(\x27r2\x27, r2Label, null);
|
|
3968
4036
|
if (studioState.nodes[parlNodeIdx]) {
|
|
3969
4037
|
var otherLabels = proposals.filter(function(p){ return (p.label || p.agent) !== r2Label; }).map(function(p){ return p.label || p.agent; });
|
|
3970
4038
|
var readingStr = otherLabels.slice(0,2).join(\x27 + \x27) + (otherLabels.length > 2 ? \x27 +\x27 + (otherLabels.length-2) : \x27\x27);
|
|
@@ -3973,7 +4041,6 @@ async function runStudio() {
|
|
|
3973
4041
|
renderStudioNodes();
|
|
3974
4042
|
}
|
|
3975
4043
|
} else if (r2LiveM) {
|
|
3976
|
-
// Live token count update for the current R2 agent
|
|
3977
4044
|
var r2AgentName = r2LiveM[1];
|
|
3978
4045
|
var r2Toks = parseInt(r2LiveM[2], 10);
|
|
3979
4046
|
var delAllEnts = document.querySelectorAll(\x27[data-r2-agent]\x27);
|
|
@@ -3981,35 +4048,31 @@ async function runStudio() {
|
|
|
3981
4048
|
for (var rei = delAllEnts.length - 1; rei >= 0; rei--) {
|
|
3982
4049
|
if (delAllEnts[rei].getAttribute(\x27data-r2-agent\x27) === r2AgentName) { r2Entry = delAllEnts[rei]; break; }
|
|
3983
4050
|
}
|
|
3984
|
-
if (!r2Entry) {
|
|
3985
|
-
var delAllE = document.querySelectorAll(\x27.studio-log-entry\x27);
|
|
3986
|
-
r2Entry = delAllE[delAllE.length - 1];
|
|
3987
|
-
}
|
|
4051
|
+
if (!r2Entry) { var delAllE = document.querySelectorAll(\x27.studio-log-entry\x27); r2Entry = delAllE[delAllE.length - 1]; }
|
|
3988
4052
|
if (r2Entry) {
|
|
3989
4053
|
var r2Tb = r2Entry.querySelector(\x27.studio-log-entry__text\x27);
|
|
3990
4054
|
if (r2Tb) r2Tb.innerHTML = \x27<span style="color:var(--green);font-family:var(--mono);font-size:10px">♖ Deliberando Round 2 \u2014 \x27 + r2Toks + \x27 token<span class="thinking-dots"><span></span><span></span><span></span></span></span>\x27;
|
|
3991
4055
|
}
|
|
3992
|
-
studioAddTokens(0, 20);
|
|
4056
|
+
studioAddTokens(0, 20);
|
|
3993
4057
|
} else {
|
|
3994
|
-
// Other status tokens — update last log entry
|
|
3995
4058
|
var delEntries = document.querySelectorAll(\x27.studio-log-entry\x27);
|
|
3996
4059
|
var delLast = delEntries[delEntries.length - 1];
|
|
3997
4060
|
if (delLast) { var delTb = delLast.querySelector(\x27.studio-log-entry__text\x27); if (delTb) delTb.textContent = dev.token.replace(new RegExp(\x27[\\r\\n]+\x27,\x27g\x27),\x27 \x27); }
|
|
3998
4061
|
}
|
|
3999
4062
|
} else if (dev.deliberation_r2) {
|
|
4000
4063
|
var r2d = dev.deliberation_r2;
|
|
4001
|
-
// Full output in log — no truncation
|
|
4002
4064
|
studioLog(r2d.label || r2d.agent, \x27♖\x27, \x27[R2] \x27 + (r2d.output || \x27\x27), \x27agent\x27, true);
|
|
4003
4065
|
var ni2 = studioState.nodes.findIndex(function(x){return x.agent===r2d.agent;});
|
|
4004
|
-
if (ni2 >= 0) {
|
|
4005
|
-
studioState.nodes[ni2].output = r2d.output;
|
|
4006
|
-
studioState.nodes[ni2].status = \x27done\x27;
|
|
4007
|
-
}
|
|
4008
|
-
// Estimate tokens for R2 (approx 1 token ≈ 4 chars)
|
|
4066
|
+
if (ni2 >= 0) { studioState.nodes[ni2].output = r2d.output; studioState.nodes[ni2].status = \x27done\x27; }
|
|
4009
4067
|
studioAddTokens(0, Math.ceil((r2d.output||'').length / 4));
|
|
4068
|
+
// Mark this agent done in parliament block
|
|
4069
|
+
parlDoneAgents[r2d.label || r2d.agent] = true;
|
|
4070
|
+
parlActiveAgent = null;
|
|
4071
|
+
renderParlBlock(\x27r2\x27, null, null);
|
|
4010
4072
|
renderStudioNodes();
|
|
4011
4073
|
context = r2d.output || context;
|
|
4012
4074
|
} else if (dev.deliberation_r3) {
|
|
4075
|
+
renderParlBlock(\x27r3\x27, null, null);
|
|
4013
4076
|
studioLog(\x27HERALD\x27, \x27🔧\x27, \x27[Mediazione] \x27 + (dev.deliberation_r3.output || \x27\x27), \x27system\x27, true);
|
|
4014
4077
|
studioAddTokens(0, Math.ceil((dev.deliberation_r3.output||'').length / 4));
|
|
4015
4078
|
context = dev.deliberation_r3.output || context;
|
|
@@ -4017,6 +4080,7 @@ async function runStudio() {
|
|
|
4017
4080
|
var r2Conv = Math.round((dev.r2_convergence || 0) * 100);
|
|
4018
4081
|
studioLog(\x27Parlamento\x27, \x27♖\x27, \x27Deliberazione completa — convergenza R2: \x27 + r2Conv + \x27%\x27, \x27system\x27);
|
|
4019
4082
|
if (dev.mediation) { context = dev.mediation; }
|
|
4083
|
+
renderParlBlock(\x27done\x27, null, r2Conv);
|
|
4020
4084
|
if (studioState.nodes[parlNodeIdx]) {
|
|
4021
4085
|
studioState.nodes[parlNodeIdx].status = \x27done\x27;
|
|
4022
4086
|
studioState.nodes[parlNodeIdx].label = \x27Parlamento (\x27 + r2Conv + \x27%)\x27;
|
|
@@ -4033,6 +4097,7 @@ async function runStudio() {
|
|
|
4033
4097
|
} catch(e3) {
|
|
4034
4098
|
if (e3.name !== \x27AbortError\x27) {
|
|
4035
4099
|
studioLog(\x27Parlamento\x27, \x27♖\x27, \x27Deliberazione non disponibile: \x27 + (e3.message || String(e3)), \x27error\x27);
|
|
4100
|
+
var pb2 = document.getElementById(\x27studioParliamentBlock\x27); if (pb2) pb2.style.display = \x27none\x27;
|
|
4036
4101
|
}
|
|
4037
4102
|
}
|
|
4038
4103
|
}
|
|
@@ -4068,6 +4133,7 @@ function saveStudioSession(task, nodes, log, result) {
|
|
|
4068
4133
|
task: task,
|
|
4069
4134
|
nodes: nodes.map(function(n){return {label:n.label,icon:n.icon,agent:n.agent};}),
|
|
4070
4135
|
result: result,
|
|
4136
|
+
canvas: studioState.canvas || null,
|
|
4071
4137
|
log: log.map(function(e){return {agent:e.agent,icon:e.icon,text:e.text,type:e.type,time:e.time};}),
|
|
4072
4138
|
ts: new Date().toLocaleString()
|
|
4073
4139
|
});
|
|
@@ -4111,10 +4177,28 @@ function restoreStudioSession(idx) {
|
|
|
4111
4177
|
studioState.nodes = s.nodes.map(function(n){return {icon:n.icon,agent:n.agent,label:n.label,status:'done'};});
|
|
4112
4178
|
studioState.log = s.log;
|
|
4113
4179
|
studioState.result = s.result;
|
|
4180
|
+
studioState.canvas = s.canvas || null;
|
|
4114
4181
|
studioState.running = false;
|
|
4115
4182
|
var ta = document.getElementById('studioTaskInput');
|
|
4116
4183
|
if (ta) ta.value = s.task;
|
|
4117
4184
|
renderStudioNodes(); renderStudioLog(); renderStudioResult();
|
|
4185
|
+
// Restore canvas if present
|
|
4186
|
+
if (s.canvas) {
|
|
4187
|
+
var cf = document.getElementById('canvasFrame');
|
|
4188
|
+
var cp = document.getElementById('canvasPanel');
|
|
4189
|
+
if (cf) cf.srcdoc = s.canvas;
|
|
4190
|
+
if (cp) cp.classList.add('open');
|
|
4191
|
+
var ct = document.getElementById('canvasTitle');
|
|
4192
|
+
if (ct) ct.textContent = 'Studio Report';
|
|
4193
|
+
var scb = document.getElementById('studioCanvasBtn');
|
|
4194
|
+
if (scb) scb.style.display = '';
|
|
4195
|
+
// Also store in allCanvasData so canvas panel nav works
|
|
4196
|
+
var convId = activeConvId || 'studio';
|
|
4197
|
+
if (!allCanvasData[convId]) allCanvasData[convId] = {canvases:[], browsers:[]};
|
|
4198
|
+
allCanvasData[convId].canvases.push({html: s.canvas, title: s.task.slice(0,60), ts: s.ts});
|
|
4199
|
+
canvasIdx = allCanvasData[convId].canvases.length - 1;
|
|
4200
|
+
canvasMode = 'canvas';
|
|
4201
|
+
}
|
|
4118
4202
|
showToast('success', 'Session restored', s.task.slice(0, 60), 3000);
|
|
4119
4203
|
}
|
|
4120
4204
|
|
|
@@ -4417,6 +4501,7 @@ function renderStudio(el) {
|
|
|
4417
4501
|
'<button id="studioCanvasBtn" onclick="openCanvasPanel()" title="' + t('canvas_open') + '" style="font-size:12px;padding:5px 14px;background:none;border:1px solid var(--border);border-radius:6px;color:var(--dim);cursor:pointer;font-weight:700;transition:all .2s">■ Canvas</button>' +
|
|
4418
4502
|
'</div>' +
|
|
4419
4503
|
'<div class="studio-canvas" id="studioNodes"></div>' +
|
|
4504
|
+
'<div id="studioParliamentBlock" style="display:none"></div>' +
|
|
4420
4505
|
'<div class="studio-log" id="studioLog" style="display:none"></div>' +
|
|
4421
4506
|
'<div id="studioResult"></div>' +
|
|
4422
4507
|
'<div id="studioSessionsBar" style="margin-top:16px;display:none"></div>' +
|
|
@@ -4962,6 +5047,24 @@ input:focus,textarea:focus{border-color:var(--green3)}
|
|
|
4962
5047
|
.studio-arrow{display:flex;align-items:center;color:var(--border2);font-size:18px;padding:0 8px;flex-shrink:0;margin-bottom:30px;transition:color .4s}
|
|
4963
5048
|
.studio-arrow--active{color:var(--green3);animation:stFlow .5s ease-in-out infinite alternate}
|
|
4964
5049
|
.studio-arrow--done{color:#22c55e}
|
|
5050
|
+
.studio-parliament{background:linear-gradient(135deg,#0e0e1c 0%,#12122a 100%);border:1.5px solid #6366f1;border-radius:12px;padding:18px 20px;margin-bottom:16px;animation:stNodeIn .4s ease forwards}
|
|
5051
|
+
.studio-parliament__header{display:flex;align-items:center;gap:10px;margin-bottom:14px;padding-bottom:10px;border-bottom:1px solid #6366f133}
|
|
5052
|
+
.studio-parliament__master{display:flex;align-items:center;gap:8px;background:linear-gradient(90deg,#4f46e5,#7c3aed);border-radius:8px;padding:7px 12px;font-size:11px;font-weight:700;color:#fff;letter-spacing:.5px}
|
|
5053
|
+
.studio-parliament__master-icon{font-size:18px}
|
|
5054
|
+
.studio-parliament__title{font-size:10px;color:#a5b4fc;text-transform:uppercase;letter-spacing:1.2px;font-weight:700;margin-left:auto}
|
|
5055
|
+
.studio-parliament__round{font-size:10px;color:#6366f1;background:rgba(99,102,241,.12);border-radius:20px;padding:3px 10px;font-weight:700;animation:stPulse .9s ease-in-out infinite}
|
|
5056
|
+
.studio-parliament__agents{display:flex;align-items:center;justify-content:center;gap:8px;flex-wrap:wrap;padding:4px 0}
|
|
5057
|
+
.studio-parliament__agent{display:flex;flex-direction:column;align-items:center;gap:5px;min-width:80px}
|
|
5058
|
+
.studio-parliament__agent-circle{width:44px;height:44px;border-radius:10px;border:1.5px solid #6366f1;background:#1a1a2e;display:flex;align-items:center;justify-content:center;font-size:18px;transition:all .3s}
|
|
5059
|
+
.studio-parliament__agent-circle--reading{border-color:#22d3ee;box-shadow:0 0 0 6px rgba(34,211,238,.15),0 0 16px rgba(34,211,238,.2);animation:stRing 1.4s ease-out infinite}
|
|
5060
|
+
.studio-parliament__agent-circle--done{border-color:#22c55e;background:rgba(34,197,94,.08)}
|
|
5061
|
+
.studio-parliament__agent-label{font-size:9px;color:#a5b4fc;text-align:center;font-weight:600;max-width:80px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
5062
|
+
.studio-parliament__conn{display:flex;flex-direction:column;align-items:center;gap:2px;margin-bottom:16px}
|
|
5063
|
+
.studio-parliament__conn-line{width:2px;height:18px;background:linear-gradient(180deg,#6366f1,#22d3ee);border-radius:2px;animation:stFlow .7s ease-in-out infinite alternate}
|
|
5064
|
+
.studio-parliament__bidir{color:#6366f1;font-size:14px;animation:stPulse .6s ease-in-out infinite}
|
|
5065
|
+
.studio-parliament__reading{font-size:9px;color:#22d3ee;text-align:center;margin-top:6px;font-family:var(--mono);background:rgba(34,211,238,.07);border-radius:6px;padding:3px 8px}
|
|
5066
|
+
.studio-parliament__convergence{text-align:center;margin-top:12px;padding:8px;background:rgba(34,197,94,.07);border:1px solid rgba(34,197,94,.2);border-radius:8px;font-size:11px;color:#22c55e;font-weight:700}
|
|
5067
|
+
@keyframes stOrbit{0%{transform:translateX(0) scale(1)}50%{transform:translateX(4px) scale(1.04)}100%{transform:translateX(0) scale(1)}}
|
|
4965
5068
|
.studio-log{background:var(--bg2);border:1px solid var(--border);border-radius:10px;padding:16px;max-height:380px;overflow-y:auto;font-size:11.5px;line-height:1.65}
|
|
4966
5069
|
.studio-log-entry{margin-bottom:12px;padding:10px 12px;border-radius:8px;background:var(--bg3);border:1px solid var(--border)}
|
|
4967
5070
|
.studio-log-entry:last-child{margin-bottom:0}
|