clawmagic 1.0.6 → 1.0.8

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/web/index.html +159 -29
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmagic",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "OpenClaw, Configured Automagically. Transform a fresh OpenClaw install into production-ready setup.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -398,36 +398,37 @@ a:hover { text-decoration: underline; }
398
398
  <div class="step" id="step-5">
399
399
  <div class="text-center">
400
400
  <div class="success-check">✓</div>
401
- <h1>You're all set!</h1>
402
- <p class="subtitle">OpenClaw is production-ready.</p>
401
+ <h1 id="s-title">You're all set!</h1>
402
+ <p class="subtitle" id="s-subtitle">OpenClaw is production-ready.</p>
403
403
  </div>
404
+
404
405
  <div class="score-gauge">
405
406
  <span class="old" id="s-before">0</span>
406
407
  <span class="arrow">→</span>
407
408
  <span class="new" id="s-after">0</span>
408
- <span style="font-size:13px; color: var(--text-dim);">security score</span>
409
+ <span style="font-size:13px; color: var(--text-dim);">configuration score</span>
409
410
  </div>
411
+
410
412
  <div class="stats-row" id="success-stats"></div>
411
- <div class="next-steps">
412
- <h2>What's next</h2>
413
- <div class="next-step">
414
- <div class="step-num">1</div>
415
- <div class="step-content">
416
- <p>Restart your gateway</p>
417
- <code>openclaw gateway restart <button class="copy-btn" onclick="copyText('openclaw gateway restart')">📋</button></code>
418
- </div>
419
- </div>
420
- <div class="next-step">
421
- <div class="step-num">2</div>
422
- <div class="step-content"><p>Send a test message to your agent</p></div>
423
- </div>
424
- <div class="next-step">
425
- <div class="step-num">3</div>
426
- <div class="step-content"><p>Join our Discord: <a href="https://discord.gg/clawd" target="_blank">discord.gg/clawd</a></p></div>
427
- </div>
413
+
414
+ <!-- Score breakdown -->
415
+ <div id="score-breakdown" style="max-width:480px; margin:24px auto 0; text-align:left;"></div>
416
+
417
+ <!-- What's included -->
418
+ <div id="install-includes" style="max-width:480px; margin:24px auto 0; padding:20px; background:var(--bg-card); border:1px solid var(--border); border-radius:var(--radius);"></div>
419
+
420
+ <!-- Gateway status + dashboard -->
421
+ <div id="gateway-section" style="max-width:480px; margin:24px auto 0; text-align:center;">
422
+ <div id="gw-status" style="margin-bottom:16px;"></div>
423
+ <div id="gw-actions" style="display:flex; gap:12px; justify-content:center; flex-wrap:wrap;"></div>
424
+ </div>
425
+
426
+ <div style="max-width:480px; margin:20px auto 0; text-align:center;">
427
+ <p style="font-size:13px; color:var(--text-muted);">Need help? <a href="https://discord.gg/clawd" target="_blank" style="color:var(--accent);">discord.gg/clawd</a></p>
428
428
  </div>
429
+
429
430
  <div class="text-center mt-24">
430
- <button class="btn btn-primary btn-big" onclick="shutdown()">Close</button>
431
+ <button class="btn btn-primary btn-big" onclick="shutdown()">Close ClawMagic</button>
431
432
  </div>
432
433
  </div>
433
434
 
@@ -637,12 +638,56 @@ function renderReview() {
637
638
  return providerNames[id] + ' ⏭️';
638
639
  }).join('<br>');
639
640
 
641
+ // Skill descriptions for display
642
+ const skillDescriptions = {
643
+ 'weather': '🌤 Weather — forecasts & conditions for any location',
644
+ 'web_search': '🔍 Web Search — search the internet in real time',
645
+ 'web_fetch': '📄 Web Fetch — extract content from any URL',
646
+ 'github': '🐙 GitHub — PRs, issues, CI runs, code review',
647
+ 'gog': '📧 Google Workspace — Gmail, Calendar, Drive, Docs',
648
+ 'nano-banana-pro': '🎨 Image Generation — create images with AI',
649
+ 'session-logs': '📋 Session Logs — search past conversations',
650
+ 'three-tier-memory': '🧠 Three-Tier Memory — knowledge graph + daily notes + long-term memory',
651
+ 'healthcheck': '🔒 Security Hardening — audits, firewall, SSH hardening',
652
+ 'tmux': '🖥 Tmux — remote terminal session control',
653
+ 'voice-call': '📞 Voice Calls — make and receive phone calls',
654
+ 'nano-pdf': '📑 PDF Editor — edit PDFs with natural language',
655
+ 'coding-agent': '🤖 Coding Agent — delegate code tasks to sub-agents',
656
+ 'gh-issues': '🐛 GitHub Issues — auto-implement fixes and open PRs',
657
+ 'mcporter': '🔌 MCP Servers — connect to any MCP tool server',
658
+ 'skill-creator': '🛠 Skill Creator — build new skills for your agent',
659
+ 'blogwatcher': '📰 Blog Watcher — monitor RSS feeds for updates',
660
+ 'video-frames': '🎬 Video Frames — extract frames from videos',
661
+ '1password': '🔐 1Password — secure secret management',
662
+ 'humanizer': '✍️ Humanizer — remove AI patterns from writing',
663
+ 'financial-analysis': '💰 Financial Analysis — statements, valuations, models',
664
+ };
665
+
666
+ const skillsList = (flavorInfo.skills || [])
667
+ .map(s => skillDescriptions[s] || `📦 ${s}`)
668
+ .map(s => `<div style="padding:4px 0; font-size:13px; border-bottom:1px solid rgba(255,255,255,0.04);">${s}</div>`)
669
+ .join('');
670
+
671
+ const featuresList = (flavorInfo.features || [])
672
+ .map(f => `<span style="display:inline-block; padding:4px 10px; margin:3px; background:var(--accent-glow); border:1px solid rgba(218,119,86,0.2); border-radius:20px; font-size:12px; color:var(--accent);">${f}</span>`)
673
+ .join('');
674
+
640
675
  document.getElementById('review-summary').innerHTML = `
641
676
  <div class="review-row"><span class="review-label">Flavor</span><span class="review-value">${flavorInfo.icon || ''} ${flavorInfo.name || state.flavor}</span></div>
642
- <div class="review-row"><span class="review-label">Skills</span><span class="review-value">${flavorInfo.skillCount || 0} active</span></div>
643
677
  <div class="review-row"><span class="review-label">Providers</span><span class="review-value" style="text-align:right">${providerList}</span></div>
644
- <div class="review-row"><span class="review-label">Security</span><span class="review-value">File permissions, auth hardening</span></div>
645
- <div class="review-row"><span class="review-label">Files</span><span class="review-value">openclaw.json, workspace files, memory dirs</span></div>
678
+ <div class="review-row"><span class="review-label">Security</span><span class="review-value">File permissions, auth hardening, gateway token</span></div>
679
+ <div class="review-row"><span class="review-label">Memory</span><span class="review-value">Three-tier system, daily notes, knowledge graph</span></div>
680
+ <div class="review-row"><span class="review-label">Automation</span><span class="review-value">Onboarding interview, daily check-in, weekly review</span></div>
681
+ ${featuresList ? `<div style="padding:16px 0 8px;"><span class="review-label">Highlights</span><div style="margin-top:8px;">${featuresList}</div></div>` : ''}
682
+ <div style="padding:12px 0 0;">
683
+ <div style="display:flex; align-items:center; justify-content:space-between; cursor:pointer;" onclick="this.parentElement.querySelector('.skill-list').style.display = this.parentElement.querySelector('.skill-list').style.display === 'none' ? 'block' : 'none'; this.querySelector('.arrow').textContent = this.parentElement.querySelector('.skill-list').style.display === 'none' ? '▶' : '▼';">
684
+ <span class="review-label">${flavorInfo.skillCount || 0} Skills Included</span>
685
+ <span class="arrow" style="font-size:11px; color:var(--text-dim);">▶</span>
686
+ </div>
687
+ <div class="skill-list" style="display:none; margin-top:8px; max-height:300px; overflow-y:auto;">
688
+ ${skillsList}
689
+ </div>
690
+ </div>
646
691
  `;
647
692
  }
648
693
 
@@ -703,19 +748,79 @@ async function runConfigure() {
703
748
  await sleep(600);
704
749
 
705
750
  // Populate success page
706
- document.getElementById('s-before').textContent = (state.report.beforeScore || 0) + '/100';
707
- document.getElementById('s-after').textContent = (state.report.afterScore || 0) + '/100';
751
+ const r = state.report;
752
+ const flavorName = r.flavorName || 'Standard';
753
+
754
+ document.getElementById('s-title').textContent = `${flavorName} Configuration Installed`;
755
+ document.getElementById('s-subtitle').textContent = r.gatewayStarted
756
+ ? 'Your agent is running and ready to chat.'
757
+ : 'Configuration complete. Start your gateway to begin.';
758
+
759
+ document.getElementById('s-before').textContent = (r.beforeScore || 0) + '/100';
760
+ document.getElementById('s-after').textContent = (r.afterScore || 0) + '/100';
708
761
 
709
762
  const validProviders = apiKeys.length;
710
- const skillsActivated = state.report.skillsActivated || 0;
711
- const filesCreated = (state.report.filesCreated || []).length;
763
+ const skillsActivated = r.skillsActivated || 0;
764
+ const filesCreated = (r.filesCreated || []).length;
765
+ const cronJobs = r.cronJobs || 0;
712
766
 
713
767
  document.getElementById('success-stats').innerHTML = `
714
768
  <div class="stat-card"><div class="val">${validProviders}</div><div class="label">Providers</div></div>
715
769
  <div class="stat-card"><div class="val">${skillsActivated}</div><div class="label">Skills</div></div>
716
- <div class="stat-card"><div class="val">${filesCreated}</div><div class="label">Files Created</div></div>
770
+ <div class="stat-card"><div class="val">${filesCreated}</div><div class="label">Files</div></div>
771
+ <div class="stat-card"><div class="val">${cronJobs}</div><div class="label">Auto Tasks</div></div>
772
+ `;
773
+
774
+ // Score breakdown
775
+ const scoreItems = r.scoreItems || [];
776
+ if (scoreItems.length > 0) {
777
+ const bd = document.getElementById('score-breakdown');
778
+ bd.innerHTML = '<h3 style="font-size:14px; color:var(--text-dim); margin-bottom:12px; text-transform:uppercase; letter-spacing:0.05em;">Configuration Report</h3>' +
779
+ scoreItems.map(item => {
780
+ const icon = item.status === 'pass' ? '✅' : item.status === 'partial' ? '🟡' : '❌';
781
+ return `<div style="display:flex; align-items:center; gap:8px; padding:6px 0; border-bottom:1px solid var(--border);">
782
+ <span>${icon}</span>
783
+ <span style="flex:1; font-size:14px;">${item.name}</span>
784
+ <span style="font-size:13px; color:var(--text-dim);">${item.points}/${item.maxPoints}</span>
785
+ </div>` + (item.detail ? `<div style="padding:2px 0 6px 30px; font-size:12px; color:var(--text-muted);">${item.detail}</div>` : '');
786
+ }).join('');
787
+ }
788
+
789
+ // What's included
790
+ const inc = document.getElementById('install-includes');
791
+ inc.innerHTML = `
792
+ <h3 style="font-size:14px; color:var(--accent); margin-bottom:12px;">Your ${flavorName} Install Includes</h3>
793
+ <div style="font-size:14px; line-height:1.8; color:var(--text);">
794
+ ✦ ${skillsActivated} skills active<br>
795
+ ✦ ${cronJobs} automated tasks (including onboarding interview)<br>
796
+ ✦ Three-tier memory system<br>
797
+ ✦ Heartbeat monitoring (every 30 min)<br>
798
+ ✦ ${validProviders} AI provider${validProviders !== 1 ? 's' : ''} configured<br>
799
+ ✦ Security-hardened file permissions
800
+ </div>
717
801
  `;
718
802
 
803
+ // Gateway section
804
+ const gwStatus = document.getElementById('gw-status');
805
+ const gwActions = document.getElementById('gw-actions');
806
+ if (r.gatewayStarted && r.dashboardUrl) {
807
+ gwStatus.innerHTML = '<p style="color:var(--green); font-size:15px; font-weight:600;">✅ Gateway running</p>';
808
+ gwActions.innerHTML = `
809
+ <button class="btn btn-primary btn-big" onclick="window.open('${r.dashboardUrl}', '_blank')" style="font-size:16px;">
810
+ 🚀 Open Dashboard — Say Hello
811
+ </button>
812
+ `;
813
+ } else if (r.gatewayStarted) {
814
+ gwStatus.innerHTML = '<p style="color:var(--green); font-size:14px;">✅ Gateway running</p>';
815
+ gwActions.innerHTML = '<p style="font-size:13px; color:var(--text-dim);">Open your terminal and run: <code style="color:var(--accent);">openclaw</code></p>';
816
+ } else {
817
+ gwStatus.innerHTML = '<p style="color:var(--yellow); font-size:14px;">⚠️ Gateway not started</p>';
818
+ gwActions.innerHTML = `
819
+ <button class="btn btn-primary" id="btn-restart-gw" onclick="restartGateway()">Start Gateway</button>
820
+ <p style="font-size:12px; color:var(--text-muted); width:100%; margin-top:8px;">Or run: <code style="color:var(--accent);">openclaw gateway start</code></p>
821
+ `;
822
+ }
823
+
719
824
  goTo(5);
720
825
  } catch (err) {
721
826
  btn.disabled = false;
@@ -734,6 +839,31 @@ function copyText(text) {
734
839
  }).catch(() => {});
735
840
  }
736
841
 
842
+ async function restartGateway() {
843
+ const btn = document.getElementById('btn-restart-gw');
844
+ if (btn) { btn.disabled = true; btn.textContent = 'Starting...'; }
845
+ try {
846
+ const res = await fetch(API + '/api/restart-gateway', { method: 'POST' });
847
+ const data = await res.json();
848
+ const gwStatus = document.getElementById('gw-status');
849
+ const gwActions = document.getElementById('gw-actions');
850
+ if (data.success && data.dashboardUrl) {
851
+ gwStatus.innerHTML = '<p style="color:var(--green); font-size:15px; font-weight:600;">✅ Gateway running</p>';
852
+ gwActions.innerHTML = `
853
+ <button class="btn btn-primary btn-big" onclick="window.open('${data.dashboardUrl}', '_blank')" style="font-size:16px;">
854
+ 🚀 Open Dashboard — Say Hello
855
+ </button>
856
+ `;
857
+ } else {
858
+ gwStatus.innerHTML = '<p style="color:var(--red); font-size:14px;">❌ Could not start gateway</p>';
859
+ gwActions.innerHTML = `<p style="font-size:13px; color:var(--text-dim);">Run manually: <code style="color:var(--accent);">openclaw gateway start</code></p>`;
860
+ }
861
+ } catch (err) {
862
+ const gwStatus = document.getElementById('gw-status');
863
+ if (gwStatus) gwStatus.innerHTML = '<p style="color:var(--red); font-size:14px;">❌ Error: ' + (err.message || 'Unknown') + '</p>';
864
+ }
865
+ }
866
+
737
867
  async function shutdown() {
738
868
  try { await fetch(API + '/api/shutdown', { method: 'POST' }); } catch {}
739
869
  document.body.innerHTML = '<div style="display:flex;align-items:center;justify-content:center;height:100vh;color:#888;font-family:sans-serif;"><p>ClawMagic closed. You can close this tab.</p></div>';