vibespot 1.6.5 → 1.8.0

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 (40) hide show
  1. package/README.md +24 -3
  2. package/assets/whats-new.json +27 -0
  3. package/dist/index.js +579 -681
  4. package/dist/index.js.map +1 -1
  5. package/package.json +8 -5
  6. package/ui/chat.js +671 -9
  7. package/ui/dashboard.js +53 -12
  8. package/ui/docs/index.html +57 -2
  9. package/ui/email-preview.js +1 -5
  10. package/ui/escape-html.js +14 -0
  11. package/ui/field-editor.js +6 -12
  12. package/ui/field-save.js +82 -0
  13. package/ui/index.html +10 -4
  14. package/ui/inline-edit.js +116 -570
  15. package/ui/plan.js +22 -13
  16. package/ui/preview-agent.js +1050 -0
  17. package/ui/preview.js +248 -265
  18. package/ui/section-controls.js +16 -622
  19. package/ui/setup.js +73 -20
  20. package/ui/styles.css +424 -0
  21. package/ui/upload-panel.js +7 -8
  22. package/ui/whats-new.js +249 -0
  23. package/assets/readme/00-hero-banner.png +0 -0
  24. package/assets/readme/00-hero-banner.svg +0 -59
  25. package/assets/readme/01-vibe-coding-hero.png +0 -0
  26. package/assets/readme/02-plan-mode.png +0 -0
  27. package/assets/readme/03-figma-import.png +0 -0
  28. package/assets/readme/04-multi-page-sites.png +0 -0
  29. package/assets/readme/05-inline-wysiwyg.png +0 -0
  30. package/assets/readme/06-hubspot-upload.png +0 -0
  31. package/ui/docs/screenshots/brand-kit-preview.png +0 -0
  32. package/ui/docs/screenshots/content-type-dropdown.png +0 -0
  33. package/ui/docs/screenshots/editor-full-layout.png +0 -0
  34. package/ui/docs/screenshots/inline-wysiwyg-editing.png +0 -0
  35. package/ui/docs/screenshots/module-overview-slideout.png +0 -0
  36. package/ui/docs/screenshots/multi-page-tree.png +0 -0
  37. package/ui/docs/screenshots/onboarding-walkthrough.png +0 -0
  38. package/ui/docs/screenshots/split-pane-view.png +0 -0
  39. package/ui/docs/screenshots/visual-controls-toolbar.png +0 -0
  40. package/ui/docs/screenshots/workspace-tabs.png +0 -0
package/ui/plan.js CHANGED
@@ -36,7 +36,9 @@
36
36
  s
37
37
  .replace(/&/g, "&")
38
38
  .replace(/</g, "&lt;")
39
- .replace(/>/g, "&gt;");
39
+ .replace(/>/g, "&gt;")
40
+ .replace(/"/g, "&quot;")
41
+ .replace(/'/g, "&#39;");
40
42
 
41
43
  // Pull out fenced code blocks first so we don't process their contents.
42
44
  const fences = [];
@@ -61,9 +63,10 @@
61
63
  // Italic (*text* or _text_)
62
64
  s = s.replace(/(^|[^*])\*([^*]+)\*(?!\*)/g, "$1<em>$2</em>");
63
65
  s = s.replace(/(^|[^_])_([^_]+)_(?!_)/g, "$1<em>$2</em>");
64
- // Links [text](url)
66
+ // Links [text](url) — `u` was escaped above (incl. quotes), so it can't
67
+ // break out of the href attribute; the scheme check blocks javascript: etc.
65
68
  s = s.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, t, u) => {
66
- const safeUrl = /^(https?:|\/|#|mailto:)/i.test(u) ? u : "#";
69
+ const safeUrl = /^(https?:|\/|#|mailto:)/i.test(u.trim()) ? u.trim() : "#";
67
70
  return `<a href="${safeUrl}" target="_blank" rel="noopener noreferrer">${t}</a>`;
68
71
  });
69
72
  return s;
@@ -205,13 +208,7 @@
205
208
  }
206
209
  }
207
210
 
208
- function escapeHtml(s) {
209
- return String(s)
210
- .replace(/&/g, "&amp;")
211
- .replace(/</g, "&lt;")
212
- .replace(/>/g, "&gt;")
213
- .replace(/"/g, "&quot;");
214
- }
211
+ // escapeHtml comes from the shared ui/escape-html.js (VIB-1902).
215
212
 
216
213
  // Inline SVG icons keyed by the template's `icon` field. Anything else
217
214
  // falls back to a neutral document glyph so the picker still renders.
@@ -559,10 +556,20 @@
559
556
  alert("There's no plan to approve yet. Send a chat message first.");
560
557
  return;
561
558
  }
559
+ // Resolve the parked "plan" checkpoint — plan mode is unified onto the
560
+ // checkpoint primitive (VIB-1880). Server flips planMode off + builds.
561
+ // Only clear local UI state once the send actually went out — a throwing
562
+ // send would otherwise leave the server still parked while the UI thinks
563
+ // the plan was approved.
564
+ try {
565
+ ws.send(JSON.stringify({ type: "checkpoint_resolve", kind: "plan", action: "approve" }));
566
+ } catch (err) {
567
+ console.error("[plan] approve send failed", err);
568
+ alert("Connection lost — please refresh and approve again.");
569
+ return;
570
+ }
562
571
  // Collapse plan sidebar so user watches modules generate.
563
572
  hidePlanView();
564
- // Server flips planMode off + runs the agentic pipeline.
565
- ws.send(JSON.stringify({ type: "plan_approve" }));
566
573
  // Local state will be refreshed by the next init or modules_updated event.
567
574
  planModeActive = false;
568
575
  window.planModeActive = false;
@@ -573,7 +580,9 @@
573
580
  function discardPlan() {
574
581
  if (!confirm("Discard the current plan and exit plan mode?")) return;
575
582
  if (typeof ws !== "undefined" && ws && ws.readyState === 1) {
576
- ws.send(JSON.stringify({ type: "plan_discard" }));
583
+ // Cancel the parked "plan" checkpoint (VIB-1880); falls back to plan_discard
584
+ // semantics server-side. HTTP fallback below for a dropped socket.
585
+ ws.send(JSON.stringify({ type: "checkpoint_resolve", kind: "plan", action: "cancel" }));
577
586
  } else {
578
587
  // Fallback to HTTP
579
588
  fetch("/api/plan/discard", { method: "POST", headers: { "Content-Type": "application/json" }, body: "{}" });