bosia 0.7.0 → 0.7.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bosia",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "type": "module",
5
5
  "description": "A fast, batteries-included fullstack framework — SSR · Svelte 5 Runes · Bun · ElysiaJS. File-based routing inspired by SvelteKit. No Node.js, no Vite, no adapters.",
6
6
  "keywords": [
@@ -75,6 +75,50 @@ function chainString(el){
75
75
  return stack.concat(leaf).join(" → ");
76
76
  }
77
77
 
78
+ // ─── Structured AI payload helpers (alt+click flow) ──────────────
79
+ function isFrameworkFrame(f){return f.indexOf("node_modules/bosia")>=0}
80
+ function fileOf(frame){var m=/^(.+):\\d+:\\d+$/.exec(frame);return m?m[1]:frame}
81
+ function endsWith(s,suf){return s.length>=suf.length&&s.lastIndexOf(suf)===s.length-suf.length}
82
+ // Outer→leaf chain with framework (node_modules/bosia) frames removed.
83
+ function userFrames(el){
84
+ var leaf=el.getAttribute("data-bosia-loc")||"";
85
+ var all=collectStack(el).concat(leaf?[leaf]:[]);
86
+ var uf=[];
87
+ for(var i=0;i<all.length;i++)if(!isFrameworkFrame(all[i]))uf.push(all[i]);
88
+ return uf;
89
+ }
90
+ // Nearest-to-leaf +page.svelte (preferred) or +layout.svelte frame.
91
+ function findPageFile(frames){
92
+ var layoutHit=null;
93
+ for(var i=frames.length-1;i>=0;i--){
94
+ var f=fileOf(frames[i]);
95
+ if(endsWith(f,"+page.svelte"))return frames[i];
96
+ if(!layoutHit&&endsWith(f,"+layout.svelte"))layoutHit=frames[i];
97
+ }
98
+ return layoutHit;
99
+ }
100
+ // The clicked element's own direct text (not descendants), collapsed + capped.
101
+ function ownText(el){
102
+ var t="";
103
+ for(var i=0;i<el.childNodes.length;i++){var n=el.childNodes[i];if(n.nodeType===3)t+=n.nodeValue||""}
104
+ t=t.replace(/\\s+/g," ").trim();
105
+ if(t.length>80)t=t.slice(0,80)+"…";
106
+ return t;
107
+ }
108
+ function buildContext(el){
109
+ var leaf=el.getAttribute("data-bosia-loc")||"";
110
+ var frames=userFrames(el);
111
+ var pageFile=findPageFile(frames);
112
+ var lines=[];
113
+ lines.push("url: "+location.href);
114
+ if(pageFile)lines.push("pageFile: "+pageFile);
115
+ if(leaf&&leaf!==pageFile)lines.push("component: "+leaf);
116
+ var text=ownText(el);
117
+ if(text)lines.push('text: "'+text+'"');
118
+ if(frames.length>1)lines.push("tree: "+frames.join(" → "));
119
+ return lines.join("\\n");
120
+ }
121
+
78
122
  function toast(msg,err){
79
123
  var t=document.createElement("div");
80
124
  t.textContent=msg;
@@ -94,7 +138,7 @@ function send(payload,onOk,onErr){
94
138
  function closeForm(){if(form){form.remove();form=null}}
95
139
  function openForm(loc,el){
96
140
  closeForm();
97
- var chain=chainString(el);
141
+ var chain=userFrames(el).join(" → ");
98
142
  var r=el.getBoundingClientRect();
99
143
  form=document.createElement("div");
100
144
  form.style.cssText="position:fixed;left:"+r.left+"px;top:"+(r.bottom+6)+"px;background:#fff;color:#111;border:1px solid #d4d4d8;border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,.18);padding:10px;width:340px;z-index:2147483647;font:13px ui-sans-serif,system-ui,sans-serif";
@@ -112,8 +156,7 @@ function openForm(loc,el){
112
156
  var userComment=ta.value.trim();
113
157
  var payload={file:loc.file,line:loc.line,col:loc.col};
114
158
  if(userComment){
115
- var tree=chain.indexOf(" → ")>=0?("Component tree (outer → leaf): "+chain+"\\n\\n"):"";
116
- payload.comment=tree+userComment;
159
+ payload.comment=buildContext(el)+"\\n---\\n"+userComment;
117
160
  }
118
161
  send(payload,function(j){toast(j.mode==="ai"?"sent to AI":"opened "+loc.file+":"+loc.line)});
119
162
  closeForm();