vibeteam 0.6.1 → 0.6.3
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/dist/server/server/index.js +58 -2
- package/package.json +1 -1
- package/public/assets/{ActivityFeedPanel-DurVWYkA.js → ActivityFeedPanel-BFyTsO8A.js} +1 -1
- package/public/assets/{GitPanel-B44UP-is.js → GitPanel-C15v1odz.js} +1 -1
- package/public/assets/{IdeationPanel-C2PE8iDm.js → IdeationPanel-DcPgIzA0.js} +1 -1
- package/public/assets/KanbanPanel-D-qd8s_O.js +20 -0
- package/public/assets/{ProjectStatePanel-DbnEku2A.js → ProjectStatePanel-lPRi78lJ.js} +1 -1
- package/public/assets/index-BEbScO5K.js +86 -0
- package/public/index.html +1 -1
- package/public/assets/KanbanPanel-BFZE5jJP.js +0 -33
- package/public/assets/index-CM1T9m8S.js +0 -41
|
@@ -124,12 +124,27 @@ function isOriginAllowed(origin) {
|
|
|
124
124
|
return false;
|
|
125
125
|
try {
|
|
126
126
|
const url = new URL(origin);
|
|
127
|
+
const h = url.hostname;
|
|
127
128
|
// Allow any port on localhost/127.0.0.1 (local development)
|
|
128
|
-
if (
|
|
129
|
+
if (h === 'localhost' || h === '127.0.0.1' || h === '0.0.0.0') {
|
|
129
130
|
return true;
|
|
130
131
|
}
|
|
132
|
+
// Allow LAN/Tailscale origins for dev — phone or another laptop on the
|
|
133
|
+
// same network connecting to this host's vite dev server.
|
|
134
|
+
if (/^192\.168\./.test(h)) return true;
|
|
135
|
+
if (/^10\./.test(h)) return true;
|
|
136
|
+
const m172 = h.match(/^172\.(\d{1,3})\./);
|
|
137
|
+
if (m172) { const x = parseInt(m172[1], 10); if (x >= 16 && x <= 31) return true; }
|
|
138
|
+
const m100 = h.match(/^100\.(\d{1,3})\./);
|
|
139
|
+
if (m100) { const x = parseInt(m100[1], 10); if (x >= 64 && x <= 127) return true; } // Tailscale CGNAT
|
|
140
|
+
if (/^169\.254\./.test(h)) return true; // link-local
|
|
141
|
+
if (h.endsWith('.ts.net')) return true; // Tailscale MagicDNS
|
|
142
|
+
if (h.endsWith('.local')) return true; // mDNS / Bonjour
|
|
143
|
+
// Single-label LAN hostname (no dots) — browser only resolves these
|
|
144
|
+
// through DNS/mDNS, so they're safe to allow
|
|
145
|
+
if (!h.includes('.') && h !== 'localhost') return true;
|
|
131
146
|
// Production: exact hostname match with HTTPS required
|
|
132
|
-
if ((
|
|
147
|
+
if ((h === 'vibeteam.sh' || h === 'vibing.team' || h === 'www.vibing.team') && url.protocol === 'https:') {
|
|
133
148
|
return true;
|
|
134
149
|
}
|
|
135
150
|
return false;
|
|
@@ -6180,6 +6195,7 @@ const RELAY_PATH_ALLOWLIST = [
|
|
|
6180
6195
|
/^\/themes(\/|\?|$)/,
|
|
6181
6196
|
/^\/settings(\/|\?|$)/,
|
|
6182
6197
|
/^\/usage(\/|\?|$)/,
|
|
6198
|
+
/^\/ideation(\/|\?|$)/,
|
|
6183
6199
|
/^\/health$/,
|
|
6184
6200
|
];
|
|
6185
6201
|
|
|
@@ -8212,6 +8228,46 @@ async function handleHttpRequest(req, res) {
|
|
|
8212
8228
|
});
|
|
8213
8229
|
return;
|
|
8214
8230
|
}
|
|
8231
|
+
// GET /sessions/:id/terminal - Raw tmux pane content (source of truth).
|
|
8232
|
+
// Used by mobile to display the actual terminal output reliably,
|
|
8233
|
+
// bypassing the parsed message/event stream that can drop chunks
|
|
8234
|
+
// through the relay.
|
|
8235
|
+
if (req.method === 'GET' && action && action.startsWith('terminal')) {
|
|
8236
|
+
const session = getSession(sessionId);
|
|
8237
|
+
if (!session) {
|
|
8238
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
8239
|
+
res.end(JSON.stringify({ ok: false, error: 'Session not found' }));
|
|
8240
|
+
return;
|
|
8241
|
+
}
|
|
8242
|
+
try {
|
|
8243
|
+
validateTmuxSession(session.tmuxSession);
|
|
8244
|
+
} catch {
|
|
8245
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
8246
|
+
res.end(JSON.stringify({ ok: false, error: 'Invalid tmux session name' }));
|
|
8247
|
+
return;
|
|
8248
|
+
}
|
|
8249
|
+
// Parse ?lines= (default 500, cap 5000)
|
|
8250
|
+
let lines = 500;
|
|
8251
|
+
try {
|
|
8252
|
+
const u = new URL(req.url, 'http://localhost');
|
|
8253
|
+
const raw = parseInt(u.searchParams.get('lines') || '500', 10);
|
|
8254
|
+
if (!isNaN(raw) && raw > 0) lines = Math.min(raw, 5000);
|
|
8255
|
+
} catch { /* default */ }
|
|
8256
|
+
cachedCaptureTmuxPane(session.tmuxSession, `-${lines}`).then((output) => {
|
|
8257
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
8258
|
+
res.end(JSON.stringify({
|
|
8259
|
+
ok: true,
|
|
8260
|
+
sessionId,
|
|
8261
|
+
tmuxSession: session.tmuxSession,
|
|
8262
|
+
capturedAt: Date.now(),
|
|
8263
|
+
content: output || '',
|
|
8264
|
+
}));
|
|
8265
|
+
}).catch((err) => {
|
|
8266
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
8267
|
+
res.end(JSON.stringify({ ok: false, error: err.message }));
|
|
8268
|
+
});
|
|
8269
|
+
return;
|
|
8270
|
+
}
|
|
8215
8271
|
// POST /sessions/:id/cancel - Send Ctrl+C to specific session
|
|
8216
8272
|
if (req.method === 'POST' && action === 'cancel') {
|
|
8217
8273
|
const session = getSession(sessionId);
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as E,r as s,
|
|
1
|
+
import{u as E,r as s,C as B,j as t,D as H}from"./index-BEbScO5K.js";const L="vibeteam-activity-filters",J=[{value:"tool_use",label:"Tool Use"},{value:"prompt",label:"Prompts"},{value:"permission",label:"Permissions"},{value:"session_end",label:"Session End"},{value:"error",label:"Errors"}],K=[{value:"5m",label:"5m"},{value:"15m",label:"15m"},{value:"1h",label:"1h"},{value:"all",label:"All"}],W=["tool_use","prompt","status_change","permission","error","session_end"],q=["5m","15m","1h","all"];function Q(){try{const a=localStorage.getItem(L);if(!a)return{selectedTypes:[],timeRange:"all"};const l=JSON.parse(a),g=Array.isArray(l.selectedTypes)?l.selectedTypes.filter(p=>W.includes(p)):[],y=q.includes(l.timeRange)?l.timeRange:"all";return{selectedTypes:g,timeRange:y}}catch{return{selectedTypes:[],timeRange:"all"}}}function X(a,l){try{localStorage.setItem(L,JSON.stringify({selectedTypes:a,timeRange:l}))}catch{}}function Z(a){switch(a){case"5m":return 300*1e3;case"15m":return 900*1e3;case"1h":return 3600*1e3;case"all":return 1/0}}function ee(a){const l=Date.now()-a;return l<5e3?"just now":l<6e4?`${Math.floor(l/1e3)}s ago`:l<36e5?`${Math.floor(l/6e4)}m ago`:l<864e5?`${Math.floor(l/36e5)}h ago`:`${Math.floor(l/864e5)}d ago`}function te(a){switch(a.type){case"tool_use":return a.tool?H(a.tool):"🔧";case"prompt":return"💬";case"permission":return"⚠️";case"session_end":return"✅";case"error":return"❌";case"status_change":return"🔄";default:return"📌"}}function se(a,l){return a.length<=l?a:a.slice(0,l)+"..."}function ae(){const a=E(e=>e.activityEvents),l=E(e=>e.resetActivityUnread),g=E(e=>e.agents),y=E(e=>e.selectAgent),p=s.useMemo(()=>Q(),[]),[u,A]=s.useState([]),[r,I]=s.useState(p.selectedTypes),[m,O]=s.useState(p.timeRange),[x,S]=s.useState(!1),[N,w]=s.useState(!1),[i,j]=s.useState(!1),[,D]=s.useState(0),b=s.useRef(null),v=s.useRef(!0),h=s.useRef(0),_=s.useRef(0),[R,T]=s.useState(0),F=s.useRef(null),M=s.useRef(null),C=s.useRef(0);s.useEffect(()=>{X(r,m)},[r,m]),s.useEffect(()=>{if(!x&&!N)return;const e=n=>{const c=n.target;F.current?.contains(c)||M.current?.contains(c)||(S(!1),w(!1))};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[x,N]),s.useEffect(()=>{const e=setInterval(()=>D(n=>n+1),6e4);return()=>clearInterval(e)},[]),s.useEffect(()=>{v.current&&!i&&(l(),h.current=0,T(0))},[a.length,l,i]);const V=s.useCallback(()=>{if(!b.current)return;const{scrollTop:e,scrollHeight:n,clientHeight:c}=b.current,f=n-e-c<40;v.current=f,f&&(h.current=0,T(0),l(),i&&j(!1))},[l,i]),z=s.useCallback(e=>{e.agentId&&e.agentId!=="unknown"&&y(e.agentId)},[y]),Y=s.useCallback(e=>{A(n=>n.includes(e)?n.filter(c=>c!==e):[...n,e])},[]),G=s.useCallback(e=>{I(n=>n.includes(e)?n.filter(c=>c!==e):[...n,e])},[]),U=s.useCallback(()=>{j(e=>e?!1:(C.current=a.length,!0))},[a.length]),k=i?a.length-C.current:0,o=s.useMemo(()=>{const e=Date.now(),n=Z(m);return(i?a.slice(0,C.current):a).filter(f=>!(u.length>0&&!u.includes(f.agentId)||r.length>0&&!r.includes(f.type)||n!==1/0&&e-f.timestamp>n))},[a,u,r,m,i]),d=B({count:o.length,getScrollElement:()=>b.current,estimateSize:()=>28,overscan:10});s.useEffect(()=>{const e=a.length>_.current;_.current=a.length,!i&&v.current&&o.length>0?d.scrollToIndex(o.length-1,{align:"end"}):!i&&e&&(h.current++,T(h.current))},[a.length,i,o.length,d]);const P=s.useCallback(()=>{o.length>0&&d.scrollToIndex(o.length-1,{align:"end"}),v.current=!0,h.current=0,T(0),l(),j(!1)},[l,o.length,d]),$=s.useMemo(()=>{const e=new Map;for(const[n,c]of g)e.set(n,{id:n,name:c.name,color:c.color});return Array.from(e.values())},[g]);return t.jsxs("div",{className:"activity-feed-panel",children:[t.jsxs("div",{className:"activity-filter-bar",children:[t.jsxs("div",{className:"activity-filter-group",children:[t.jsxs("div",{className:"activity-filter-dropdown-wrapper",ref:F,children:[t.jsxs("button",{className:`activity-filter-btn ${u.length>0?"active":""}`,onClick:()=>{S(!x),w(!1)},children:["Agent",u.length>0?` (${u.length})`:""]}),x&&t.jsxs("div",{className:"activity-filter-dropdown",children:[$.length===0?t.jsx("div",{className:"activity-filter-empty",children:"No agents"}):$.map(e=>t.jsxs("label",{className:"activity-filter-option",children:[t.jsx("input",{type:"checkbox",checked:u.includes(e.id),onChange:()=>Y(e.id)}),t.jsx("span",{className:"activity-agent-dot",style:{background:e.color}}),t.jsx("span",{children:e.name})]},e.id)),u.length>0&&t.jsx("button",{className:"activity-filter-clear",onClick:()=>A([]),children:"Clear"})]})]}),t.jsxs("div",{className:"activity-filter-dropdown-wrapper",ref:M,children:[t.jsxs("button",{className:`activity-filter-btn ${r.length>0?"active":""}`,onClick:()=>{w(!N),S(!1)},children:["Type",r.length>0?` (${r.length})`:""]}),N&&t.jsxs("div",{className:"activity-filter-dropdown",children:[J.map(e=>t.jsxs("label",{className:"activity-filter-option",children:[t.jsx("input",{type:"checkbox",checked:r.includes(e.value),onChange:()=>G(e.value)}),t.jsx("span",{children:e.label})]},e.value)),r.length>0&&t.jsx("button",{className:"activity-filter-clear",onClick:()=>I([]),children:"Clear"})]})]}),t.jsx("button",{className:`activity-pause-btn ${i?"paused":""}`,onClick:U,title:i?"Resume feed":"Pause feed",children:i?"▶":"⏸"})]}),t.jsx("div",{className:"activity-time-range",children:K.map(e=>t.jsx("button",{className:`activity-time-btn ${m===e.value?"active":""}`,onClick:()=>O(e.value),children:e.label},e.value))})]}),i&&t.jsxs("div",{className:"activity-paused-banner",children:["Paused ",k>0?`- ${k} new event${k!==1?"s":""}`:"",t.jsx("button",{className:"activity-paused-resume",onClick:()=>{j(!1),P()},children:"Resume"})]}),t.jsx("div",{className:"activity-event-list",ref:b,onScroll:V,children:o.length===0?t.jsxs("div",{className:"activity-empty-state",children:[t.jsx("div",{className:"activity-empty-icon",children:"📋"}),t.jsx("div",{className:"activity-empty-text",children:"No activity yet"}),t.jsx("div",{className:"activity-empty-hint",children:"Spawn an agent to get started"})]}):t.jsx("div",{className:"activity-event-list-virtual",style:{height:d.getTotalSize()},children:d.getVirtualItems().map(e=>{const n=o[e.index];return t.jsx("div",{className:"activity-event-card-wrapper",style:{transform:`translateY(${e.start}px)`},children:t.jsxs("div",{className:"activity-event-card",onClick:()=>z(n),title:n.description,children:[t.jsx("span",{className:"activity-event-time",children:ee(n.timestamp)}),t.jsx("span",{className:"activity-agent-dot",style:{background:n.agentColor}}),t.jsx("span",{className:"activity-event-agent",children:n.agentName}),t.jsx("span",{className:"activity-event-icon",children:te(n)}),t.jsx("span",{className:"activity-event-desc",children:se(n.description,80)})]})},n.id)})})}),!i&&R>0&&!v.current&&t.jsxs("button",{className:"activity-new-events",onClick:P,children:[R," new event",R!==1?"s":""]})]})}export{ae as ActivityFeedPanel};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as h,c as _,j as t,u as S}from"./index-CM1T9m8S.js";const $=20,A=500,x={files:[],commits:[],hasMoreCommits:!1,incoming:[],loading:!1,loadingMore:!1,fetching:!1,error:null,fetchError:null};async function E(e){try{const s=await e.json();if(s&&typeof s.error=="string")return s.error}catch{}return e.status===503?"git_unavailable":e.status===404?"not_tracked":e.status===400?"invalid_sha":"git_error"}function T(e,s){const[a,r]=h.useState(x),d=h.useRef(new Map),c=h.useRef(null);h.useEffect(()=>{c.current!==e&&(d.current=new Map,c.current=e)},[e]);const i=_(),m=h.useCallback(async(o,l)=>{r(u=>({...u,loading:!0,error:null}));try{const[u,g,b]=await Promise.all([fetch(`${i}/sessions/${o}/git/files`,{signal:l}),fetch(`${i}/sessions/${o}/git/commits?limit=${$}`,{signal:l}),fetch(`${i}/sessions/${o}/git/incoming?limit=${$}`,{signal:l}).catch(()=>null)]);if(!u.ok){const f=await E(u);if(l.aborted)return;r(j=>({...x,fetchError:j.fetchError,error:f}));return}if(!g.ok){const f=await E(g);if(l.aborted)return;r(j=>({...x,fetchError:j.fetchError,error:f}));return}const w=await u.json(),M=await g.json(),k=b&&b.ok?await b.json().catch(()=>null):null;if(l.aborted)return;r(f=>({...x,fetchError:f.fetchError,files:w.files||[],commits:M.commits||[],hasMoreCommits:!!M.hasMore,incoming:k?.commits||[],loading:!1}))}catch(u){if(l.aborted||u instanceof DOMException&&u.name==="AbortError")return;r(g=>({...x,fetchError:g.fetchError,error:"network_error"}))}},[i]);h.useEffect(()=>{if(!e){r(x);return}const o=new AbortController,l=setTimeout(()=>{m(e,o.signal)},A);return()=>{clearTimeout(l),o.abort()}},[e,s,m]);const n=h.useCallback(()=>{if(!e)return;const o=new AbortController;m(e,o.signal)},[e,m]),p=h.useCallback(async()=>{if(!e||a.loadingMore||!a.hasMoreCommits)return;const o=a.commits[a.commits.length-1];if(o){r(l=>({...l,loadingMore:!0}));try{const l=await fetch(`${i}/sessions/${e}/git/commits?limit=${$}&before=${o.hash}`);if(!l.ok){r(g=>({...g,loadingMore:!1}));return}const u=await l.json();r(g=>({...g,commits:[...g.commits,...u.commits||[]],hasMoreCommits:!!u.hasMore,loadingMore:!1}))}catch{r(l=>({...l,loadingMore:!1}))}}},[e,i,a.commits,a.hasMoreCommits,a.loadingMore]),N=h.useCallback(async o=>{if(!e)return null;const l=d.current.get(o);if(l)return l;try{const u=await fetch(`${i}/sessions/${e}/git/commits/${o}`);if(!u.ok)return null;const g=await u.json();return g&&g.commit?(d.current.set(o,g.commit),g.commit):null}catch{return null}},[e,i]),y=h.useCallback(async()=>{if(e){try{await fetch(`${i}/sessions/${e}/git/refresh`,{method:"POST"})}catch{}n()}},[e,i,n]),v=h.useCallback(async()=>{if(e){r(o=>({...o,fetching:!0,fetchError:null}));try{const o=await fetch(`${i}/sessions/${e}/git/fetch`,{method:"POST"});if(!o.ok){const l=await E(o);r(u=>({...u,fetching:!1,fetchError:l}));return}}catch{r(o=>({...o,fetching:!1,fetchError:"network_error"}));return}r(o=>({...o,fetching:!1,fetchError:null})),n()}},[e,i,n]);return h.useMemo(()=>({files:a.files,commits:a.commits,hasMoreCommits:a.hasMoreCommits,incoming:a.incoming,loading:a.loading,loadingMore:a.loadingMore,fetching:a.fetching,error:a.error,fetchError:a.fetchError,refetch:n,loadMore:p,getCommitDetail:N,triggerServerRefresh:y,triggerFetch:v}),[a,n,p,N,y,v])}function D(e){return e?[e.branch??"",e.ahead??0,e.behind??0,e.totalFiles??0,e.linesAdded??0,e.linesRemoved??0,e.lastCommitTime??0].join("|"):"none"}function F(e,s){if(s==="untracked")return{code:"?",modifier:"untracked"};const a=s==="staged"?e.statusStaged:e.statusUnstaged;switch(a){case"M":return{code:"M",modifier:"m"};case"A":return{code:"A",modifier:"a"};case"D":return{code:"D",modifier:"d"};case"R":return{code:"R",modifier:"r"};case"C":return{code:"C",modifier:"r"};case"T":return{code:"T",modifier:"m"};case"U":return{code:"U",modifier:"d"};default:return{code:a.trim()||"·",modifier:"m"}}}function U(e){const s=e.lastIndexOf("/");return s<0?{dir:"",base:e}:{dir:e.slice(0,s+1),base:e.slice(s+1)}}function L({file:e,kind:s}){const a=F(e,s),{dir:r,base:d}=U(e.path);return t.jsxs("div",{className:"git-file-row",title:e.path,children:[t.jsx("span",{className:`git-status-badge git-status-badge--${a.modifier}`,children:a.code}),t.jsxs("span",{className:"git-file-path",children:[r&&t.jsx("span",{className:"git-file-dir",children:r}),t.jsx("span",{className:"git-file-base",children:d}),e.oldPath&&e.oldPath!==e.path&&t.jsxs("span",{className:"git-file-rename",children:[" ← ",e.oldPath]})]}),(e.linesAdded!=null||e.linesRemoved!=null)&&t.jsxs("span",{className:"git-file-stat",children:[e.linesAdded?t.jsxs("span",{className:"git-stat-added",children:["+",e.linesAdded]}):null,e.linesRemoved?t.jsxs("span",{className:"git-stat-removed",children:["−",e.linesRemoved]}):null]})]})}function P({files:e}){const[s,a]=h.useState({staged:!1,unstaged:!1,untracked:!0}),r=h.useMemo(()=>{const c=[],i=[],m=[];for(const n of e){if(n.isUntracked){m.push(n);continue}n.statusStaged&&n.statusStaged!==" "&&c.push(n),n.statusUnstaged&&n.statusUnstaged!==" "&&i.push(n)}return[{key:"staged",label:"Staged",entries:c},{key:"unstaged",label:"Unstaged",entries:i},{key:"untracked",label:"Untracked",entries:m}]},[e]);return r.reduce((c,i)=>c+i.entries.length,0)===0?t.jsx("div",{className:"git-empty git-empty--small",children:"No changes"}):t.jsx("div",{className:"git-file-list",children:r.map(c=>c.entries.length===0?null:t.jsxs("div",{className:"git-file-section",children:[t.jsxs("button",{type:"button",className:"git-section-header",onClick:()=>a(i=>({...i,[c.key]:!i[c.key]})),children:[t.jsx("span",{className:"git-section-caret",children:s[c.key]?"▶":"▼"}),t.jsx("span",{className:"git-section-label",children:c.label}),t.jsxs("span",{className:"git-section-count",children:["(",c.entries.length,")"]})]}),!s[c.key]&&t.jsx("div",{className:"git-section-body",children:c.entries.map(i=>t.jsx(L,{file:i,kind:c.key},`${c.key}:${i.path}`))})]},c.key))})}function G(e){if(!e)return"";const s=Math.floor(Date.now()/1e3)-e;return s<60?`${Math.max(1,s)}s ago`:s<3600?`${Math.floor(s/60)}m ago`:s<86400?`${Math.floor(s/3600)}h ago`:s<86400*30?`${Math.floor(s/86400)}d ago`:s<86400*365?`${Math.floor(s/(86400*30))}mo ago`:`${Math.floor(s/(86400*365))}y ago`}function O({commit:e,expanded:s,onToggle:a,getDetail:r}){const[d,c]=h.useState(null),[i,m]=h.useState(!1);return h.useEffect(()=>{if(!s)return;let n=!1;return m(!0),r(e.hash).then(p=>{n||(c(p),m(!1))}),()=>{n=!0}},[s,e.hash,r]),t.jsxs("div",{className:`git-commit-row${s?" git-commit-row--expanded":""}`,children:[t.jsxs("button",{type:"button",className:"git-commit-header",onClick:a,children:[t.jsx("span",{className:"git-section-caret",children:s?"▼":"▶"}),t.jsx("span",{className:"git-commit-hash",children:e.shortHash}),t.jsx("span",{className:"git-commit-subject",title:e.subject,children:e.subject})]}),t.jsxs("div",{className:"git-commit-meta",children:[t.jsx("span",{children:e.authorName}),t.jsx("span",{className:"git-commit-meta-dot",children:"·"}),t.jsx("span",{children:G(e.timestamp)})]}),s&&t.jsxs("div",{className:"git-commit-detail",children:[i&&t.jsx("div",{className:"git-empty git-empty--small",children:"Loading…"}),!i&&!d&&t.jsx("div",{className:"git-empty git-empty--small",children:"Could not load commit."}),d&&t.jsxs(t.Fragment,{children:[d.body&&t.jsx("pre",{className:"git-commit-body",children:d.body}),d.parents.length>0&&t.jsxs("div",{className:"git-commit-parents",children:["Parents: ",d.parents.map(n=>n.slice(0,7)).join(", ")]}),d.files.length>0&&t.jsx("div",{className:"git-commit-files",children:d.files.map(n=>t.jsxs("div",{className:"git-commit-file",title:n.path,children:[t.jsx("span",{className:"git-commit-file-path",children:n.path}),t.jsxs("span",{className:"git-file-stat",children:[n.linesAdded?t.jsxs("span",{className:"git-stat-added",children:["+",n.linesAdded]}):null,n.linesRemoved?t.jsxs("span",{className:"git-stat-removed",children:["−",n.linesRemoved]}):null]})]},n.path))})]})]})]})}function R({commits:e,hasMore:s,loadingMore:a,expandedSha:r,onToggle:d,onLoadMore:c,getDetail:i}){return e.length===0?t.jsx("div",{className:"git-empty git-empty--small",children:"No commits yet"}):t.jsxs("div",{className:"git-commit-list",children:[e.map(m=>t.jsx(O,{commit:m,expanded:r===m.hash,onToggle:()=>d(r===m.hash?null:m.hash),getDetail:i},m.hash)),s&&t.jsx("button",{type:"button",className:"git-load-more",onClick:c,disabled:a,children:a?"Loading…":"Load 20 more"})]})}function B(e,s){switch(e){case"not_tracked":return"This agent is not being tracked by git status.";case"path_missing":return"Worktree no longer exists on disk.";case"not_a_repo":return`Not a git repository${s?`: ${s}`:""}.`;case"not_found":return"Commit not found.";case"invalid_sha":return"Invalid commit reference.";case"git_unavailable":return"Git is not available on this machine.";case"network_error":return"Could not reach the backend.";case"git_error":return"Git ran into an error.";default:return"Could not load git data."}}function H(e){if(!e)return null;switch(e){case"network_error":return"Couldn't reach remote (network error).";case"auth_error":return"Authentication failed — check your git credentials.";case"git_unavailable":return"Git is not available.";case"path_missing":return"Worktree path is missing.";default:return"Fetch failed."}}function W(e){if(!e)return null;const s=e.ahead||0,a=e.behind||0;return s===0&&a===0?t.jsx("span",{className:"git-sync git-sync--synced",children:"in sync"}):t.jsxs("span",{className:"git-sync",children:[s>0&&t.jsxs("span",{className:"git-sync-ahead",children:["↑",s]}),a>0&&t.jsxs("span",{className:"git-sync-behind",children:["↓",a]})]})}function V(e){if(!e)return"";const s=Math.floor((Date.now()-e)/1e3);return s<5?"just now":s<60?`${s}s ago`:s<3600?`${Math.floor(s/60)}m ago`:s<86400?`${Math.floor(s/3600)}h ago`:`${Math.floor(s/86400)}d ago`}function q(){const e=S(C=>C.activeTabId),s=S(C=>e?C.agents.get(e):void 0),a=h.useMemo(()=>D(s?.gitStatus),[s?.gitStatus]),{files:r,commits:d,hasMoreCommits:c,incoming:i,loading:m,loadingMore:n,fetching:p,error:N,fetchError:y,loadMore:v,getCommitDetail:o,triggerServerRefresh:l,triggerFetch:u}=T(e,a),[g,b]=h.useState(null),[w,M]=h.useState(null);if(!e||!s)return t.jsx("div",{className:"git-panel",children:t.jsx("div",{className:"git-empty",children:"Select an agent to see git status."})});if(!s.cwd)return t.jsx("div",{className:"git-panel",children:t.jsx("div",{className:"git-empty",children:"No working directory for this agent."})});if(s.gitStatus&&s.gitStatus.isRepo===!1)return t.jsx("div",{className:"git-panel",children:t.jsxs("div",{className:"git-empty",children:["Not a git repository.",t.jsx("div",{className:"git-empty-path",children:s.cwd})]})});const k=s.gitStatus?.branch||s.worktree?.branch||"",f=s.gitStatus?.lastFetched??null,j=H(y);return t.jsxs("div",{className:"git-panel",children:[t.jsxs("header",{className:"git-panel-header",children:[t.jsxs("div",{className:"git-panel-branch",title:k,children:[t.jsx("span",{className:"git-branch-icon",children:"⎇"}),t.jsx("span",{className:"git-branch-name",children:k||"—"}),W(s.gitStatus)]}),t.jsxs("div",{className:"git-panel-actions",children:[t.jsx("button",{type:"button",className:"git-action-btn git-action-btn--primary",onClick:u,disabled:p,title:"Fetch from remote",children:p?"…":"↓ Fetch"}),t.jsx("button",{type:"button",className:"git-action-btn",onClick:l,disabled:m,title:"Refresh status","aria-label":"Refresh git status",children:"↻"})]})]}),t.jsx("div",{className:"git-panel-meta",children:j?t.jsx("span",{className:"git-panel-meta-error",children:j}):f?t.jsxs("span",{children:["fetched ",V(f)]}):t.jsx("span",{className:"git-panel-meta-dim",children:"never fetched in this session"})}),N&&t.jsx("div",{className:"git-panel-error",children:B(N,s.cwd)}),i.length>0&&t.jsxs("section",{className:"git-panel-section git-panel-section--incoming",children:[t.jsxs("h4",{className:"git-panel-heading",children:["Incoming ",t.jsxs("span",{className:"git-panel-heading-count",children:["(",i.length,")"]})]}),t.jsx("p",{className:"git-panel-hint",children:"Commits on the upstream that aren't in this branch yet — pull or merge to bring them in."}),t.jsx(R,{commits:i,hasMore:!1,loadingMore:!1,expandedSha:w,onToggle:M,onLoadMore:()=>{},getDetail:o})]}),t.jsxs("section",{className:"git-panel-section",children:[t.jsx("h4",{className:"git-panel-heading",children:"Changes"}),m&&r.length===0?t.jsx("div",{className:"git-empty git-empty--small",children:"Loading…"}):t.jsx(P,{files:r})]}),t.jsxs("section",{className:"git-panel-section",children:[t.jsx("h4",{className:"git-panel-heading",children:"Recent commits"}),m&&d.length===0?t.jsx("div",{className:"git-empty git-empty--small",children:"Loading…"}):t.jsx(R,{commits:d,hasMore:c,loadingMore:n,expandedSha:g,onToggle:b,onLoadMore:v,getDetail:o})]})]})}export{q as GitPanel,q as default};
|
|
1
|
+
import{r as h,z as _,j as t,u as S}from"./index-BEbScO5K.js";const $=20,A=500,x={files:[],commits:[],hasMoreCommits:!1,incoming:[],loading:!1,loadingMore:!1,fetching:!1,error:null,fetchError:null};async function E(e){try{const s=await e.json();if(s&&typeof s.error=="string")return s.error}catch{}return e.status===503?"git_unavailable":e.status===404?"not_tracked":e.status===400?"invalid_sha":"git_error"}function T(e,s){const[a,r]=h.useState(x),d=h.useRef(new Map),c=h.useRef(null);h.useEffect(()=>{c.current!==e&&(d.current=new Map,c.current=e)},[e]);const i=_(),m=h.useCallback(async(o,l)=>{r(u=>({...u,loading:!0,error:null}));try{const[u,g,b]=await Promise.all([fetch(`${i}/sessions/${o}/git/files`,{signal:l}),fetch(`${i}/sessions/${o}/git/commits?limit=${$}`,{signal:l}),fetch(`${i}/sessions/${o}/git/incoming?limit=${$}`,{signal:l}).catch(()=>null)]);if(!u.ok){const f=await E(u);if(l.aborted)return;r(j=>({...x,fetchError:j.fetchError,error:f}));return}if(!g.ok){const f=await E(g);if(l.aborted)return;r(j=>({...x,fetchError:j.fetchError,error:f}));return}const w=await u.json(),M=await g.json(),k=b&&b.ok?await b.json().catch(()=>null):null;if(l.aborted)return;r(f=>({...x,fetchError:f.fetchError,files:w.files||[],commits:M.commits||[],hasMoreCommits:!!M.hasMore,incoming:k?.commits||[],loading:!1}))}catch(u){if(l.aborted||u instanceof DOMException&&u.name==="AbortError")return;r(g=>({...x,fetchError:g.fetchError,error:"network_error"}))}},[i]);h.useEffect(()=>{if(!e){r(x);return}const o=new AbortController,l=setTimeout(()=>{m(e,o.signal)},A);return()=>{clearTimeout(l),o.abort()}},[e,s,m]);const n=h.useCallback(()=>{if(!e)return;const o=new AbortController;m(e,o.signal)},[e,m]),p=h.useCallback(async()=>{if(!e||a.loadingMore||!a.hasMoreCommits)return;const o=a.commits[a.commits.length-1];if(o){r(l=>({...l,loadingMore:!0}));try{const l=await fetch(`${i}/sessions/${e}/git/commits?limit=${$}&before=${o.hash}`);if(!l.ok){r(g=>({...g,loadingMore:!1}));return}const u=await l.json();r(g=>({...g,commits:[...g.commits,...u.commits||[]],hasMoreCommits:!!u.hasMore,loadingMore:!1}))}catch{r(l=>({...l,loadingMore:!1}))}}},[e,i,a.commits,a.hasMoreCommits,a.loadingMore]),N=h.useCallback(async o=>{if(!e)return null;const l=d.current.get(o);if(l)return l;try{const u=await fetch(`${i}/sessions/${e}/git/commits/${o}`);if(!u.ok)return null;const g=await u.json();return g&&g.commit?(d.current.set(o,g.commit),g.commit):null}catch{return null}},[e,i]),y=h.useCallback(async()=>{if(e){try{await fetch(`${i}/sessions/${e}/git/refresh`,{method:"POST"})}catch{}n()}},[e,i,n]),v=h.useCallback(async()=>{if(e){r(o=>({...o,fetching:!0,fetchError:null}));try{const o=await fetch(`${i}/sessions/${e}/git/fetch`,{method:"POST"});if(!o.ok){const l=await E(o);r(u=>({...u,fetching:!1,fetchError:l}));return}}catch{r(o=>({...o,fetching:!1,fetchError:"network_error"}));return}r(o=>({...o,fetching:!1,fetchError:null})),n()}},[e,i,n]);return h.useMemo(()=>({files:a.files,commits:a.commits,hasMoreCommits:a.hasMoreCommits,incoming:a.incoming,loading:a.loading,loadingMore:a.loadingMore,fetching:a.fetching,error:a.error,fetchError:a.fetchError,refetch:n,loadMore:p,getCommitDetail:N,triggerServerRefresh:y,triggerFetch:v}),[a,n,p,N,y,v])}function D(e){return e?[e.branch??"",e.ahead??0,e.behind??0,e.totalFiles??0,e.linesAdded??0,e.linesRemoved??0,e.lastCommitTime??0].join("|"):"none"}function F(e,s){if(s==="untracked")return{code:"?",modifier:"untracked"};const a=s==="staged"?e.statusStaged:e.statusUnstaged;switch(a){case"M":return{code:"M",modifier:"m"};case"A":return{code:"A",modifier:"a"};case"D":return{code:"D",modifier:"d"};case"R":return{code:"R",modifier:"r"};case"C":return{code:"C",modifier:"r"};case"T":return{code:"T",modifier:"m"};case"U":return{code:"U",modifier:"d"};default:return{code:a.trim()||"·",modifier:"m"}}}function U(e){const s=e.lastIndexOf("/");return s<0?{dir:"",base:e}:{dir:e.slice(0,s+1),base:e.slice(s+1)}}function L({file:e,kind:s}){const a=F(e,s),{dir:r,base:d}=U(e.path);return t.jsxs("div",{className:"git-file-row",title:e.path,children:[t.jsx("span",{className:`git-status-badge git-status-badge--${a.modifier}`,children:a.code}),t.jsxs("span",{className:"git-file-path",children:[r&&t.jsx("span",{className:"git-file-dir",children:r}),t.jsx("span",{className:"git-file-base",children:d}),e.oldPath&&e.oldPath!==e.path&&t.jsxs("span",{className:"git-file-rename",children:[" ← ",e.oldPath]})]}),(e.linesAdded!=null||e.linesRemoved!=null)&&t.jsxs("span",{className:"git-file-stat",children:[e.linesAdded?t.jsxs("span",{className:"git-stat-added",children:["+",e.linesAdded]}):null,e.linesRemoved?t.jsxs("span",{className:"git-stat-removed",children:["−",e.linesRemoved]}):null]})]})}function P({files:e}){const[s,a]=h.useState({staged:!1,unstaged:!1,untracked:!0}),r=h.useMemo(()=>{const c=[],i=[],m=[];for(const n of e){if(n.isUntracked){m.push(n);continue}n.statusStaged&&n.statusStaged!==" "&&c.push(n),n.statusUnstaged&&n.statusUnstaged!==" "&&i.push(n)}return[{key:"staged",label:"Staged",entries:c},{key:"unstaged",label:"Unstaged",entries:i},{key:"untracked",label:"Untracked",entries:m}]},[e]);return r.reduce((c,i)=>c+i.entries.length,0)===0?t.jsx("div",{className:"git-empty git-empty--small",children:"No changes"}):t.jsx("div",{className:"git-file-list",children:r.map(c=>c.entries.length===0?null:t.jsxs("div",{className:"git-file-section",children:[t.jsxs("button",{type:"button",className:"git-section-header",onClick:()=>a(i=>({...i,[c.key]:!i[c.key]})),children:[t.jsx("span",{className:"git-section-caret",children:s[c.key]?"▶":"▼"}),t.jsx("span",{className:"git-section-label",children:c.label}),t.jsxs("span",{className:"git-section-count",children:["(",c.entries.length,")"]})]}),!s[c.key]&&t.jsx("div",{className:"git-section-body",children:c.entries.map(i=>t.jsx(L,{file:i,kind:c.key},`${c.key}:${i.path}`))})]},c.key))})}function G(e){if(!e)return"";const s=Math.floor(Date.now()/1e3)-e;return s<60?`${Math.max(1,s)}s ago`:s<3600?`${Math.floor(s/60)}m ago`:s<86400?`${Math.floor(s/3600)}h ago`:s<86400*30?`${Math.floor(s/86400)}d ago`:s<86400*365?`${Math.floor(s/(86400*30))}mo ago`:`${Math.floor(s/(86400*365))}y ago`}function O({commit:e,expanded:s,onToggle:a,getDetail:r}){const[d,c]=h.useState(null),[i,m]=h.useState(!1);return h.useEffect(()=>{if(!s)return;let n=!1;return m(!0),r(e.hash).then(p=>{n||(c(p),m(!1))}),()=>{n=!0}},[s,e.hash,r]),t.jsxs("div",{className:`git-commit-row${s?" git-commit-row--expanded":""}`,children:[t.jsxs("button",{type:"button",className:"git-commit-header",onClick:a,children:[t.jsx("span",{className:"git-section-caret",children:s?"▼":"▶"}),t.jsx("span",{className:"git-commit-hash",children:e.shortHash}),t.jsx("span",{className:"git-commit-subject",title:e.subject,children:e.subject})]}),t.jsxs("div",{className:"git-commit-meta",children:[t.jsx("span",{children:e.authorName}),t.jsx("span",{className:"git-commit-meta-dot",children:"·"}),t.jsx("span",{children:G(e.timestamp)})]}),s&&t.jsxs("div",{className:"git-commit-detail",children:[i&&t.jsx("div",{className:"git-empty git-empty--small",children:"Loading…"}),!i&&!d&&t.jsx("div",{className:"git-empty git-empty--small",children:"Could not load commit."}),d&&t.jsxs(t.Fragment,{children:[d.body&&t.jsx("pre",{className:"git-commit-body",children:d.body}),d.parents.length>0&&t.jsxs("div",{className:"git-commit-parents",children:["Parents: ",d.parents.map(n=>n.slice(0,7)).join(", ")]}),d.files.length>0&&t.jsx("div",{className:"git-commit-files",children:d.files.map(n=>t.jsxs("div",{className:"git-commit-file",title:n.path,children:[t.jsx("span",{className:"git-commit-file-path",children:n.path}),t.jsxs("span",{className:"git-file-stat",children:[n.linesAdded?t.jsxs("span",{className:"git-stat-added",children:["+",n.linesAdded]}):null,n.linesRemoved?t.jsxs("span",{className:"git-stat-removed",children:["−",n.linesRemoved]}):null]})]},n.path))})]})]})]})}function R({commits:e,hasMore:s,loadingMore:a,expandedSha:r,onToggle:d,onLoadMore:c,getDetail:i}){return e.length===0?t.jsx("div",{className:"git-empty git-empty--small",children:"No commits yet"}):t.jsxs("div",{className:"git-commit-list",children:[e.map(m=>t.jsx(O,{commit:m,expanded:r===m.hash,onToggle:()=>d(r===m.hash?null:m.hash),getDetail:i},m.hash)),s&&t.jsx("button",{type:"button",className:"git-load-more",onClick:c,disabled:a,children:a?"Loading…":"Load 20 more"})]})}function B(e,s){switch(e){case"not_tracked":return"This agent is not being tracked by git status.";case"path_missing":return"Worktree no longer exists on disk.";case"not_a_repo":return`Not a git repository${s?`: ${s}`:""}.`;case"not_found":return"Commit not found.";case"invalid_sha":return"Invalid commit reference.";case"git_unavailable":return"Git is not available on this machine.";case"network_error":return"Could not reach the backend.";case"git_error":return"Git ran into an error.";default:return"Could not load git data."}}function H(e){if(!e)return null;switch(e){case"network_error":return"Couldn't reach remote (network error).";case"auth_error":return"Authentication failed — check your git credentials.";case"git_unavailable":return"Git is not available.";case"path_missing":return"Worktree path is missing.";default:return"Fetch failed."}}function W(e){if(!e)return null;const s=e.ahead||0,a=e.behind||0;return s===0&&a===0?t.jsx("span",{className:"git-sync git-sync--synced",children:"in sync"}):t.jsxs("span",{className:"git-sync",children:[s>0&&t.jsxs("span",{className:"git-sync-ahead",children:["↑",s]}),a>0&&t.jsxs("span",{className:"git-sync-behind",children:["↓",a]})]})}function z(e){if(!e)return"";const s=Math.floor((Date.now()-e)/1e3);return s<5?"just now":s<60?`${s}s ago`:s<3600?`${Math.floor(s/60)}m ago`:s<86400?`${Math.floor(s/3600)}h ago`:`${Math.floor(s/86400)}d ago`}function Z(){const e=S(C=>C.activeTabId),s=S(C=>e?C.agents.get(e):void 0),a=h.useMemo(()=>D(s?.gitStatus),[s?.gitStatus]),{files:r,commits:d,hasMoreCommits:c,incoming:i,loading:m,loadingMore:n,fetching:p,error:N,fetchError:y,loadMore:v,getCommitDetail:o,triggerServerRefresh:l,triggerFetch:u}=T(e,a),[g,b]=h.useState(null),[w,M]=h.useState(null);if(!e||!s)return t.jsx("div",{className:"git-panel",children:t.jsx("div",{className:"git-empty",children:"Select an agent to see git status."})});if(!s.cwd)return t.jsx("div",{className:"git-panel",children:t.jsx("div",{className:"git-empty",children:"No working directory for this agent."})});if(s.gitStatus&&s.gitStatus.isRepo===!1)return t.jsx("div",{className:"git-panel",children:t.jsxs("div",{className:"git-empty",children:["Not a git repository.",t.jsx("div",{className:"git-empty-path",children:s.cwd})]})});const k=s.gitStatus?.branch||s.worktree?.branch||"",f=s.gitStatus?.lastFetched??null,j=H(y);return t.jsxs("div",{className:"git-panel",children:[t.jsxs("header",{className:"git-panel-header",children:[t.jsxs("div",{className:"git-panel-branch",title:k,children:[t.jsx("span",{className:"git-branch-icon",children:"⎇"}),t.jsx("span",{className:"git-branch-name",children:k||"—"}),W(s.gitStatus)]}),t.jsxs("div",{className:"git-panel-actions",children:[t.jsx("button",{type:"button",className:"git-action-btn git-action-btn--primary",onClick:u,disabled:p,title:"Fetch from remote",children:p?"…":"↓ Fetch"}),t.jsx("button",{type:"button",className:"git-action-btn",onClick:l,disabled:m,title:"Refresh status","aria-label":"Refresh git status",children:"↻"})]})]}),t.jsx("div",{className:"git-panel-meta",children:j?t.jsx("span",{className:"git-panel-meta-error",children:j}):f?t.jsxs("span",{children:["fetched ",z(f)]}):t.jsx("span",{className:"git-panel-meta-dim",children:"never fetched in this session"})}),N&&t.jsx("div",{className:"git-panel-error",children:B(N,s.cwd)}),i.length>0&&t.jsxs("section",{className:"git-panel-section git-panel-section--incoming",children:[t.jsxs("h4",{className:"git-panel-heading",children:["Incoming ",t.jsxs("span",{className:"git-panel-heading-count",children:["(",i.length,")"]})]}),t.jsx("p",{className:"git-panel-hint",children:"Commits on the upstream that aren't in this branch yet — pull or merge to bring them in."}),t.jsx(R,{commits:i,hasMore:!1,loadingMore:!1,expandedSha:w,onToggle:M,onLoadMore:()=>{},getDetail:o})]}),t.jsxs("section",{className:"git-panel-section",children:[t.jsx("h4",{className:"git-panel-heading",children:"Changes"}),m&&r.length===0?t.jsx("div",{className:"git-empty git-empty--small",children:"Loading…"}):t.jsx(P,{files:r})]}),t.jsxs("section",{className:"git-panel-section",children:[t.jsx("h4",{className:"git-panel-heading",children:"Recent commits"}),m&&d.length===0?t.jsx("div",{className:"git-empty git-empty--small",children:"Loading…"}):t.jsx(R,{commits:d,hasMore:c,loadingMore:n,expandedSha:g,onToggle:b,onLoadMore:v,getDetail:o})]})]})}export{Z as GitPanel,Z as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{h as ee,r as n,j as e,c as se,l as te,i as Z}from"./index-CM1T9m8S.js";const Y=["#4ade80","#60a5fa","#f87171","#fbbf24","#a78bfa","#22d3d8","#a855f7","#fb923c","#f472b6","#34d399","#818cf8","#e879f9"],I=["🔧","🎨","🔒","⚡","📝","✨","🚀","🧪","📊","🔍","🛡️","🎯","📦","🔗","💬","🏗️","🧹","♿","🌐","📱"];function de({onGenerate:s,onCancel:r,initialCategories:x,createCategory:p,updateCategory:u,deleteCategory:d,suggestCategories:N,projectId:w,projectPath:f}){const C=ee(t=>t.categories),[g,k]=n.useState(()=>new Set(x||C.map(t=>t.id))),[z,$]=n.useState(!1),[o,_]=n.useState(""),[S,P]=n.useState(Y[0]),[v,D]=n.useState(I[0]),[y,E]=n.useState(!1),[R,O]=n.useState(null),[c,L]=n.useState(""),[U,b]=n.useState(""),[M,F]=n.useState(""),[K,B]=n.useState(!1),[W,A]=n.useState([]),X=t=>{k(l=>{const h=new Set(l);return h.has(t)?h.delete(t):h.add(t),h})},q=()=>k(new Set(C.map(t=>t.id))),J=()=>k(new Set),G=async()=>{if(!p||!o.trim())return;E(!0);const t=await p({label:o.trim(),color:S,icon:v});E(!1),t.ok&&t.category&&(k(l=>new Set([...l,t.category.id])),_(""),P(Y[0]),D(I[0]),$(!1))},V=t=>{O(t.id),L(t.label),b(t.color),F(t.icon)},i=async()=>{!u||!R||!c.trim()||(await u(R,{label:c.trim(),color:U,icon:M}),O(null))},T=()=>{O(null)},a=async t=>{d&&(await d(t),k(l=>{const h=new Set(l);return h.delete(t),h}))},m=async()=>{if(!N||!w||!f)return;B(!0),A([]);const t=await N(w,f);if(B(!1),t.ok&&t.categories){const l=new Set(C.map(H=>H.id)),h=t.categories.filter(H=>!l.has(H.id));A(h)}},j=async t=>{if(!p)return;const l=await p({label:t.label,color:t.color,icon:t.icon});l.ok&&l.category&&(k(h=>new Set([...h,l.category.id])),A(h=>h.filter(H=>H.id!==t.id)))};return e.jsx("div",{className:"ideation-config-overlay",onClick:r,children:e.jsxs("div",{className:"ideation-config-dialog",onClick:t=>t.stopPropagation(),children:[e.jsxs("div",{className:"ideation-config-header",children:[e.jsx("h3",{children:"Configure Ideation"}),e.jsx("p",{children:"Select the categories to analyze"})]}),e.jsxs("div",{className:"ideation-config-toggles",children:[e.jsx("button",{className:"ideation-config-toggle-btn",onClick:q,children:"Select All"}),e.jsx("button",{className:"ideation-config-toggle-btn",onClick:J,children:"Deselect All"})]}),e.jsx("div",{className:"ideation-config-categories",children:C.map(t=>e.jsx("div",{className:"ideation-config-category-row",children:R===t.id?e.jsxs("div",{className:"ideation-config-edit-row",children:[e.jsx("input",{type:"text",value:c,onChange:l=>L(l.target.value),className:"ideation-config-edit-input",autoFocus:!0,onKeyDown:l=>{l.key==="Enter"&&i(),l.key==="Escape"&&T()}}),e.jsx("div",{className:"ideation-config-picker-row",children:I.slice(0,10).map(l=>e.jsx("button",{className:`ideation-config-icon-btn ${M===l?"selected":""}`,onClick:()=>F(l),children:l},l))}),e.jsx("div",{className:"ideation-config-picker-row",children:Y.map(l=>e.jsx("button",{className:`ideation-config-color-btn ${U===l?"selected":""}`,style:{backgroundColor:l},onClick:()=>b(l)},l))}),e.jsxs("div",{className:"ideation-config-edit-actions",children:[e.jsx("button",{className:"ideation-config-toggle-btn",onClick:i,children:"Save"}),e.jsx("button",{className:"ideation-config-toggle-btn",onClick:T,children:"Cancel"})]})]}):e.jsxs("label",{className:"ideation-config-category",children:[e.jsx("input",{type:"checkbox",checked:g.has(t.id),onChange:()=>X(t.id)}),e.jsx("span",{className:"ideation-config-category-icon",children:t.icon}),e.jsx("span",{className:"ideation-config-category-label",children:t.label}),e.jsx("span",{className:"ideation-config-category-color",style:{backgroundColor:t.color}}),t.isCustom&&e.jsxs("span",{className:"ideation-config-category-actions",children:[e.jsx("button",{className:"ideation-config-cat-btn edit",onClick:l=>{l.preventDefault(),V(t)},title:"Edit category",children:e.jsx("svg",{viewBox:"0 0 16 16",width:"12",height:"12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e.jsx("path",{d:"M11.5 1.5l3 3-9 9H2.5v-3l9-9z"})})}),e.jsx("button",{className:"ideation-config-cat-btn delete",onClick:l=>{l.preventDefault(),a(t.id)},title:"Delete category",children:e.jsx("svg",{viewBox:"0 0 16 16",width:"12",height:"12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e.jsx("path",{d:"M3 4h10M5.5 4V3a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v1M6.5 7v5M9.5 7v5M4.5 4l.5 9a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1l.5-9"})})})]})]})},t.id))}),z?e.jsxs("div",{className:"ideation-config-create-form",children:[e.jsx("div",{className:"ideation-config-create-field",children:e.jsx("input",{type:"text",value:o,onChange:t=>_(t.target.value),placeholder:"Category name",className:"ideation-config-edit-input",autoFocus:!0,onKeyDown:t=>{t.key==="Enter"&&o.trim()&&G(),t.key==="Escape"&&$(!1)}})}),e.jsxs("div",{className:"ideation-config-create-field",children:[e.jsx("span",{className:"ideation-config-create-label",children:"Icon"}),e.jsx("div",{className:"ideation-config-picker-row",children:I.map(t=>e.jsx("button",{className:`ideation-config-icon-btn ${v===t?"selected":""}`,onClick:()=>D(t),children:t},t))})]}),e.jsxs("div",{className:"ideation-config-create-field",children:[e.jsx("span",{className:"ideation-config-create-label",children:"Color"}),e.jsx("div",{className:"ideation-config-picker-row",children:Y.map(t=>e.jsx("button",{className:`ideation-config-color-btn ${S===t?"selected":""}`,style:{backgroundColor:t},onClick:()=>P(t)},t))})]}),e.jsxs("div",{className:"ideation-config-create-actions",children:[e.jsx("button",{className:"ideation-config-toggle-btn",onClick:G,disabled:!o.trim()||y,children:y?"Creating...":"Add Category"}),e.jsx("button",{className:"ideation-config-toggle-btn",onClick:()=>$(!1),children:"Cancel"})]})]}):e.jsxs("div",{className:"ideation-config-add-row",children:[p&&e.jsx("button",{className:"ideation-config-toggle-btn",onClick:()=>$(!0),children:"+ Add Custom Category"}),N&&w&&f&&e.jsx("button",{className:"ideation-config-toggle-btn suggest",onClick:m,disabled:K,children:K?"Suggesting...":"Suggest Categories"})]}),W.length>0&&e.jsxs("div",{className:"ideation-config-suggestions",children:[e.jsx("span",{className:"ideation-config-suggestions-title",children:"AI Suggestions"}),W.map(t=>e.jsxs("div",{className:"ideation-config-suggestion",children:[e.jsx("span",{className:"ideation-config-category-icon",children:t.icon}),e.jsx("span",{className:"ideation-config-category-label",children:t.label}),e.jsx("span",{className:"ideation-config-category-color",style:{backgroundColor:t.color}}),e.jsx("button",{className:"ideation-config-toggle-btn",onClick:()=>j(t),children:"+ Add"})]},t.id))]}),e.jsxs("div",{className:"ideation-config-actions",children:[e.jsx("button",{className:"ideation-config-cancel",onClick:r,children:"Cancel"}),e.jsxs("button",{className:"ideation-config-generate",onClick:()=>s(Array.from(g)),disabled:g.size===0,children:["Generate Ideas (",g.size," categories)"]})]})]})})}const ie=6,me=10*1024*1024;function he({projectId:s,editingIdea:r,onSave:x,onCancel:p}){const[u,d]=n.useState(r?.title||""),[N,w]=n.useState(r?.description||""),[f,C]=n.useState(r?.category||"new_features"),[g,k]=n.useState(r?.effort||"medium"),[z,$]=n.useState(r?.impact||"medium"),[o,_]=n.useState(r?.images||[]),[S,P]=n.useState(r?.links||[]),[v,D]=n.useState(""),[y,E]=n.useState(""),[R,O]=n.useState(!1),[c,L]=n.useState(null),[U,b]=n.useState(!1),M=n.useRef(0),F=n.useRef(null),K=ee(a=>a.categories),B=!!r,W=n.useCallback(async a=>{if(!a.type.startsWith("image/")){L("Only image files are supported");return}if(a.size>me){L("Image must be under 10MB");return}if(o.length>=ie){L(`Maximum ${ie} images`);return}L(null),O(!0);try{const m=await new Promise((ae,ce)=>{const Q=new FileReader;Q.onload=()=>ae(Q.result),Q.onerror=()=>ce(new Error("Failed to read image file")),Q.readAsDataURL(a)}),j=se(te()),l=await(await fetch(`${j}/kanban/images`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:m,projectId:s})})).json();if(!l.ok)throw new Error(l.error||"Failed to upload image");const h=l.attachment,H={id:`img-${Date.now()}-${Math.random().toString(16).slice(2,10)}`,filename:h.filename||a.name,path:h.path||h.url||"",size:a.size,mimeType:a.type,createdAt:Date.now()};_(ae=>[...ae,H])}catch(m){L(m instanceof Error?m.message:"Failed to upload image")}finally{O(!1)}},[o.length,s]),A=n.useCallback(a=>{Array.from(a).forEach(m=>W(m))},[W]),X=n.useCallback(a=>{a.preventDefault(),a.stopPropagation(),b(!1),M.current=0,a.dataTransfer.files.length>0&&A(a.dataTransfer.files)},[A]),q=n.useCallback(a=>{const m=a.clipboardData?.items;if(!m)return;const j=[];for(let t=0;t<m.length;t++)if(m[t].type.startsWith("image/")){const l=m[t].getAsFile();l&&j.push(l)}j.length>0&&(a.preventDefault(),A(j))},[A]),J=n.useCallback(a=>{_(m=>m.filter(j=>j.id!==a))},[]),G=n.useCallback(()=>{const a=v.trim();if(!a)return;const m={id:`ref-${Date.now()}-${Math.random().toString(16).slice(2,10)}`,url:a,title:y.trim()||a};P(j=>[...j,m]),D(""),E("")},[v,y]),V=n.useCallback(a=>{P(m=>m.filter(j=>j.id!==a))},[]),i=()=>{u.trim()&&x({title:u.trim(),description:N.trim(),category:f,effort:g,impact:z,images:o,links:S})},T=a=>{try{return new URL(a).hostname}catch{return a}};return e.jsx("div",{className:"idea-creator-overlay",onClick:p,children:e.jsxs("div",{className:"idea-creator-dialog",onClick:a=>a.stopPropagation(),onPaste:q,children:[e.jsxs("div",{className:"idea-creator-header",children:[e.jsx("h3",{children:B?"Edit Idea":"New Idea"}),e.jsx("p",{children:B?"Update your idea details":"Add your own improvement idea with references"})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Title *"}),e.jsx("input",{type:"text",value:u,onChange:a=>d(a.target.value),placeholder:"What's the idea?",autoFocus:!0,className:"idea-creator-input"})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Description"}),e.jsx("textarea",{value:N,onChange:a=>w(a.target.value),placeholder:"Describe the improvement...",rows:4,className:"idea-creator-textarea"})]}),e.jsxs("div",{className:"idea-creator-selects-row",children:[e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Category"}),e.jsx("select",{value:f,onChange:a=>C(a.target.value),className:"idea-creator-select",children:K.map(a=>e.jsxs("option",{value:a.id,children:[a.icon," ",a.label]},a.id))})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Effort"}),e.jsxs("select",{value:g,onChange:a=>k(a.target.value),className:"idea-creator-select",children:[e.jsx("option",{value:"trivial",children:"Trivial"}),e.jsx("option",{value:"small",children:"Small"}),e.jsx("option",{value:"medium",children:"Medium"}),e.jsx("option",{value:"large",children:"Large"}),e.jsx("option",{value:"complex",children:"Complex"})]})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Impact"}),e.jsxs("select",{value:z,onChange:a=>$(a.target.value),className:"idea-creator-select",children:[e.jsx("option",{value:"low",children:"Low"}),e.jsx("option",{value:"medium",children:"Medium"}),e.jsx("option",{value:"high",children:"High"}),e.jsx("option",{value:"critical",children:"Critical"})]})]})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Images"}),e.jsxs("div",{className:`idea-creator-dropzone ${U?"drag-over":""}`,onDragEnter:a=>{a.preventDefault(),a.stopPropagation(),M.current++,a.dataTransfer.types.includes("Files")&&b(!0)},onDragLeave:a=>{a.preventDefault(),a.stopPropagation(),M.current--,M.current===0&&b(!1)},onDragOver:a=>{a.preventDefault(),a.stopPropagation()},onDrop:X,onClick:()=>F.current?.click(),children:[e.jsx("input",{ref:F,type:"file",accept:"image/*",multiple:!0,style:{display:"none"},onChange:a=>{a.target.files&&A(a.target.files),a.target.value=""}}),R?e.jsx("span",{className:"idea-creator-dropzone-text",children:"Uploading..."}):e.jsx("span",{className:"idea-creator-dropzone-text",children:"Drop images here, paste, or click to browse"})]}),c&&e.jsx("div",{className:"idea-creator-upload-error",children:c}),o.length>0&&e.jsx("div",{className:"idea-creator-image-grid",children:o.map(a=>e.jsxs("div",{className:"idea-creator-image-thumb",children:[e.jsx("img",{src:`${se(te())}/kanban/images/${a.filename||a.path.split("/").pop()}`,alt:a.filename}),e.jsx("button",{className:"idea-creator-image-remove",onClick:()=>J(a.id),title:"Remove image",children:"×"})]},a.id))})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Reference Links"}),e.jsxs("div",{className:"idea-creator-link-input-row",children:[e.jsx("input",{type:"text",value:v,onChange:a=>D(a.target.value),placeholder:"https://...",className:"idea-creator-input",onKeyDown:a=>{a.key==="Enter"&&(a.preventDefault(),G())}}),e.jsx("input",{type:"text",value:y,onChange:a=>E(a.target.value),placeholder:"Title (optional)",className:"idea-creator-input",style:{flex:"0 0 140px"},onKeyDown:a=>{a.key==="Enter"&&(a.preventDefault(),G())}}),e.jsx("button",{className:"ideation-btn secondary",onClick:G,disabled:!v.trim(),children:"Add"})]}),S.length>0&&e.jsx("div",{className:"idea-creator-link-list",children:S.map(a=>e.jsxs("div",{className:"idea-creator-link-item",children:[e.jsx("span",{className:"idea-creator-link-icon",children:e.jsx("svg",{viewBox:"0 0 16 16",width:"12",height:"12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e.jsx("path",{d:"M6.5 9.5l3-3M9 7l1.5-1.5a2.12 2.12 0 0 0-3-3L6 4M7 9l-1.5 1.5a2.12 2.12 0 0 1-3-3L4 6"})})}),e.jsx("span",{className:"idea-creator-link-title",children:a.title||T(a.url)}),e.jsx("button",{className:"idea-creator-link-remove",onClick:()=>V(a.id),title:"Remove link",children:"×"})]},a.id))})]}),e.jsxs("div",{className:"idea-creator-actions",children:[e.jsx("button",{className:"ideation-config-cancel",onClick:p,children:"Cancel"}),e.jsx("button",{className:"ideation-config-generate",onClick:i,disabled:!u.trim()||R,children:B?"Save Changes":"Create Idea"})]})]})})}function ge(s){switch(s){case"critical":return"urgent";case"high":return"high";case"medium":return"medium";case"low":return"low";default:return"medium"}}function ue(s){const r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(s);return r?`${parseInt(r[1],16)}, ${parseInt(r[2],16)}, ${parseInt(r[3],16)}`:"255, 255, 255"}const ne={trivial:"#4ade80",small:"#60a5fa",medium:"#fbbf24",large:"#f97316",complex:"#f87171"},le={low:"#888",medium:"#fbbf24",high:"#f97316",critical:"#f87171"};function oe(s){const r=se(te()),x=s.filename||s.path.split("/").pop()||"";return`${r}/kanban/images/${x}`}function re(s){try{return new URL(s).hostname}catch{return s}}function fe({idea:s,onDismiss:r,onDelete:x,onConvertToTask:p,onEdit:u}){const[d,N]=n.useState(!1),[w,f]=n.useState(null),g=ee(o=>o.categories).find(o=>o.id===s.category),k=s.images&&s.images.length>0,z=s.links&&s.links.length>0,$=d?s.images:s.images?.slice(0,3)||[];return e.jsxs("div",{className:`idea-card ${s.convertedToTaskId?"converted":""} ${d?"expanded":""}`,children:[e.jsxs("div",{className:"idea-card-header",children:[e.jsx("span",{className:"idea-card-category-icon",title:g?.label,children:g?.icon||"?"}),e.jsxs("h4",{className:"idea-card-title",onClick:()=>N(!d),children:[s.title,s.isManual&&e.jsx("span",{className:"idea-card-manual-badge",title:"Manual idea",children:"M"}),e.jsx("span",{className:"idea-card-expand-hint",children:d?"▾":"▸"})]}),e.jsx("div",{className:"idea-card-actions",children:s.convertedToTaskId?e.jsxs("span",{className:"idea-card-converted-badge",title:"Converted to task",children:[e.jsx("svg",{viewBox:"0 0 16 16",width:"14",height:"14",fill:"currentColor",children:e.jsx("path",{d:"M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zm3.78-9.72a.75.75 0 0 0-1.06-1.06L6.75 9.19 5.28 7.72a.75.75 0 0 0-1.06 1.06l2 2a.75.75 0 0 0 1.06 0l4.5-4.5z"})}),e.jsx("span",{style:{fontSize:11,marginLeft:4},children:"Task created"})]}):e.jsxs(e.Fragment,{children:[s.isManual&&u&&e.jsx("button",{className:"idea-card-action-btn edit",onClick:u,title:"Edit idea",children:"✏️"}),x&&e.jsx("button",{className:"idea-card-action-btn delete",onClick:x,title:"Delete idea permanently",children:"🗑️"}),e.jsx("button",{className:"idea-card-action-btn dismiss",onClick:r,title:"Dismiss idea (hide)",children:"✕"})]})})]}),e.jsx("p",{className:`idea-card-description ${d?"expanded":""}`,children:s.description}),k&&e.jsxs("div",{className:`idea-card-images ${d?"expanded":""}`,children:[$.map(o=>e.jsx("div",{className:`idea-card-thumbnail ${d?"large":""}`,onClick:()=>f(oe(o)),title:o.filename,children:e.jsx("img",{src:oe(o),alt:o.filename})},o.id)),!d&&s.images.length>3&&e.jsxs("span",{className:"idea-card-images-overflow",onClick:()=>N(!0),children:["+",s.images.length-3]})]}),z&&e.jsx("div",{className:"idea-card-links",children:s.links.map(o=>e.jsxs("a",{className:`idea-card-link-pill ${d?"expanded":""}`,href:o.url,target:"_blank",rel:"noopener noreferrer",title:o.url,children:[e.jsx("svg",{viewBox:"0 0 16 16",width:"10",height:"10",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e.jsx("path",{d:"M6.5 9.5l3-3M9 7l1.5-1.5a2.12 2.12 0 0 0-3-3L6 4M7 9l-1.5 1.5a2.12 2.12 0 0 1-3-3L4 6"})}),d?o.title?`${o.title} — ${re(o.url)}`:o.url:o.title||re(o.url)]},o.id))}),d&&e.jsxs("div",{className:"idea-card-meta",children:[e.jsx("span",{className:"idea-card-meta-category",style:{color:g?.color},children:g?.label}),e.jsx("span",{className:"idea-card-meta-date",children:new Date(s.createdAt).toLocaleDateString()})]}),e.jsxs("div",{className:"idea-card-footer",children:[e.jsxs("div",{className:"idea-card-badges",children:[e.jsx("span",{className:"idea-badge effort",style:{borderColor:ne[s.effort]||"#888",color:ne[s.effort]||"#888"},children:s.effort}),e.jsxs("span",{className:"idea-badge impact",style:{borderColor:le[s.impact]||"#888",color:le[s.impact]||"#888"},children:[s.impact," impact"]})]}),!s.convertedToTaskId&&e.jsx("button",{className:"idea-card-create-task-btn",onClick:p,title:"Create Kanban task from this idea",children:"+ Create Task"})]}),w&&e.jsx("div",{className:"idea-card-image-preview",onClick:()=>f(null),children:e.jsx("img",{src:w,alt:"Preview"})})]})}function pe({projectId:s,projectPath:r,generateIdeas:x,dismissIdea:p,deleteIdea:u,deleteIdeationSession:d,createKanbanTask:N,convertIdeaToTask:w,createManualIdea:f,updateManualIdea:C,getIdeationSession:g,createCategory:k,updateCategory:z,deleteCategory:$,suggestCategories:o}){const[_,S]=n.useState(!1),[P,v]=n.useState(!1),[D,y]=n.useState(),E=Z(i=>i.selectedCategory),R=Z(i=>i.setSelectedCategory),O=ee(i=>i.categories),c=Z(i=>s?i.sessions.get(s):void 0),L=Z(i=>i.getIdeasByCategory);n.useEffect(()=>{s&&g&&!c&&g(s)},[s,g,c]);const U=s?L(s,E):[],b=c?.status==="generating"||c?.status==="streaming",M=c?.status==="error",F=c?.ideas.filter(i=>!i.dismissed).length||0,K=n.useCallback(async i=>{!s||!r||(S(!1),await x(s,r,i))},[s,r,x]),B=n.useCallback(async()=>{if(!s||!r)return;const i=c?.enabledCategories;await x(s,r,i,!0)},[s,r,c,x]),W=n.useCallback(async i=>{s&&await p(i,s)},[s,p]),A=n.useCallback(async i=>{!s||!u||await u(i,s)},[s,u]),X=n.useCallback(async i=>{if(!s)return;const T=await N(s,{title:i.title,description:i.description,priority:ge(i.impact),columnId:"ideas",tags:[i.category]});T&&(Z.getState().updateIdea(s,i.id,{convertedToTaskId:T.id}),w(i.id,s,T.id))},[s,N,w]),q=n.useCallback(async()=>{s&&await d(s)},[s,d]),J=n.useCallback(async i=>{!s||!f||(await f(s,i),v(!1),y(void 0))},[s,f]),G=n.useCallback(async i=>{!s||!D||!C||(await C(D.id,s,i),v(!1),y(void 0))},[s,D,C]),V=n.useCallback(i=>{y(i),v(!0)},[]);return s?e.jsxs("div",{className:"ideation-panel",children:[e.jsxs("div",{className:"ideation-header",children:[e.jsx("div",{className:"ideation-header-left",children:b&&e.jsxs("div",{className:"ideation-generating",children:[e.jsxs("span",{className:"ideation-generating-dots",children:[e.jsx("span",{}),e.jsx("span",{}),e.jsx("span",{})]}),e.jsx("span",{className:"ideation-generating-text",children:F>0?`${F} ideas found...`:"Analyzing codebase..."})]})}),e.jsxs("div",{className:"ideation-header-actions",children:[f&&e.jsx("button",{className:"ideation-btn secondary",onClick:()=>{y(void 0),v(!0)},title:"Add your own idea",children:"+ New Idea"}),c&&!b&&e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"ideation-btn secondary",onClick:B,title:"Add more ideas to current session",children:"+ Add More"}),e.jsx("button",{className:"ideation-btn secondary",onClick:q,title:"Clear all ideas",children:"Clear"})]}),e.jsx("button",{className:"ideation-btn secondary",onClick:()=>S(!0),title:"Configure categories",disabled:b,children:e.jsxs("svg",{viewBox:"0 0 16 16",width:"14",height:"14",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[e.jsx("circle",{cx:"8",cy:"8",r:"3"}),e.jsx("path",{d:"M8 1v2M8 13v2M1 8h2M13 8h2M3.05 3.05l1.41 1.41M11.54 11.54l1.41 1.41M3.05 12.95l1.41-1.41M11.54 4.46l1.41-1.41"})]})}),!b&&e.jsx("button",{className:"ideation-btn primary",onClick:()=>S(!0),disabled:!r,title:r?"Generate improvement ideas":"Project path required",children:M?"Retry":c?"Regenerate":"Generate Ideas"})]})]}),M&&c?.error&&e.jsxs("div",{className:"ideation-error",children:[e.jsx("span",{className:"ideation-error-icon",children:"⚠️"}),e.jsx("span",{children:c.error})]}),c&&c.ideas.length>0&&e.jsxs("div",{className:"ideation-category-tabs",children:[e.jsxs("button",{className:`ideation-category-tab ${E===null?"active":""}`,onClick:()=>R(null),children:["All (",F,")"]}),O.map(i=>{const T=c.ideas.filter(a=>!a.dismissed&&a.category===i.id).length;return T===0?null:e.jsxs("button",{className:`ideation-category-tab ${E===i.id?"active":""}`,onClick:()=>R(i.id),style:{"--tab-color":i.color,"--tab-color-rgb":ue(i.color)},children:[i.icon," ",i.label," (",T,")"]},i.id)})]}),e.jsx("div",{className:"ideation-ideas-list",children:U.length>0?U.map(i=>e.jsx(fe,{idea:i,onDismiss:()=>W(i.id),onDelete:u?()=>A(i.id):void 0,onConvertToTask:()=>X(i),onEdit:i.isManual&&C?()=>V(i):void 0},i.id)):!b&&!c?e.jsxs("div",{className:"ideation-empty-state",children:[e.jsx("span",{className:"ideation-empty-icon",children:"💡"}),e.jsx("h3",{children:"Discover Improvements"}),e.jsx("p",{children:'Click "Generate Ideas" to AI-analyze your codebase, or "+ New Idea" to add your own inspiration with images and reference links.'})]}):!b&&!M&&c&&U.length===0?e.jsxs("div",{className:"ideation-empty-state",children:[e.jsx("span",{className:"ideation-empty-icon",children:E?"🔍":"✅"}),e.jsx("p",{children:E?"No ideas in this category":"No ideas found. Try generating with different categories or add your own."})]}):null}),_&&e.jsx(de,{onGenerate:K,onCancel:()=>S(!1),initialCategories:c?.enabledCategories,createCategory:k,updateCategory:z,deleteCategory:$,suggestCategories:o,projectId:s,projectPath:r}),P&&s&&e.jsx(he,{projectId:s,editingIdea:D,onSave:D?G:J,onCancel:()=>{v(!1),y(void 0)}})]}):e.jsx("div",{className:"ideation-panel",children:e.jsxs("div",{className:"ideation-empty-state",children:[e.jsx("span",{className:"ideation-empty-icon",children:"💡"}),e.jsx("p",{children:"Select a project to generate improvement ideas"})]})})}export{pe as IdeationPanel};
|
|
1
|
+
import{F as ee,r as n,j as e,z as se,A as te,G as Z}from"./index-BEbScO5K.js";const Y=["#4ade80","#60a5fa","#f87171","#fbbf24","#a78bfa","#22d3d8","#a855f7","#fb923c","#f472b6","#34d399","#818cf8","#e879f9"],I=["🔧","🎨","🔒","⚡","📝","✨","🚀","🧪","📊","🔍","🛡️","🎯","📦","🔗","💬","🏗️","🧹","♿","🌐","📱"];function de({onGenerate:s,onCancel:r,initialCategories:x,createCategory:p,updateCategory:u,deleteCategory:d,suggestCategories:N,projectId:w,projectPath:f}){const C=ee(t=>t.categories),[g,k]=n.useState(()=>new Set(x||C.map(t=>t.id))),[z,$]=n.useState(!1),[o,_]=n.useState(""),[S,P]=n.useState(Y[0]),[v,D]=n.useState(I[0]),[y,E]=n.useState(!1),[R,O]=n.useState(null),[c,L]=n.useState(""),[U,b]=n.useState(""),[A,F]=n.useState(""),[K,B]=n.useState(!1),[W,M]=n.useState([]),X=t=>{k(l=>{const h=new Set(l);return h.has(t)?h.delete(t):h.add(t),h})},q=()=>k(new Set(C.map(t=>t.id))),J=()=>k(new Set),G=async()=>{if(!p||!o.trim())return;E(!0);const t=await p({label:o.trim(),color:S,icon:v});E(!1),t.ok&&t.category&&(k(l=>new Set([...l,t.category.id])),_(""),P(Y[0]),D(I[0]),$(!1))},V=t=>{O(t.id),L(t.label),b(t.color),F(t.icon)},i=async()=>{!u||!R||!c.trim()||(await u(R,{label:c.trim(),color:U,icon:A}),O(null))},T=()=>{O(null)},a=async t=>{d&&(await d(t),k(l=>{const h=new Set(l);return h.delete(t),h}))},m=async()=>{if(!N||!w||!f)return;B(!0),M([]);const t=await N(w,f);if(B(!1),t.ok&&t.categories){const l=new Set(C.map(H=>H.id)),h=t.categories.filter(H=>!l.has(H.id));M(h)}},j=async t=>{if(!p)return;const l=await p({label:t.label,color:t.color,icon:t.icon});l.ok&&l.category&&(k(h=>new Set([...h,l.category.id])),M(h=>h.filter(H=>H.id!==t.id)))};return e.jsx("div",{className:"ideation-config-overlay",onClick:r,children:e.jsxs("div",{className:"ideation-config-dialog",onClick:t=>t.stopPropagation(),children:[e.jsxs("div",{className:"ideation-config-header",children:[e.jsx("h3",{children:"Configure Ideation"}),e.jsx("p",{children:"Select the categories to analyze"})]}),e.jsxs("div",{className:"ideation-config-toggles",children:[e.jsx("button",{className:"ideation-config-toggle-btn",onClick:q,children:"Select All"}),e.jsx("button",{className:"ideation-config-toggle-btn",onClick:J,children:"Deselect All"})]}),e.jsx("div",{className:"ideation-config-categories",children:C.map(t=>e.jsx("div",{className:"ideation-config-category-row",children:R===t.id?e.jsxs("div",{className:"ideation-config-edit-row",children:[e.jsx("input",{type:"text",value:c,onChange:l=>L(l.target.value),className:"ideation-config-edit-input",autoFocus:!0,onKeyDown:l=>{l.key==="Enter"&&i(),l.key==="Escape"&&T()}}),e.jsx("div",{className:"ideation-config-picker-row",children:I.slice(0,10).map(l=>e.jsx("button",{className:`ideation-config-icon-btn ${A===l?"selected":""}`,onClick:()=>F(l),children:l},l))}),e.jsx("div",{className:"ideation-config-picker-row",children:Y.map(l=>e.jsx("button",{className:`ideation-config-color-btn ${U===l?"selected":""}`,style:{backgroundColor:l},onClick:()=>b(l)},l))}),e.jsxs("div",{className:"ideation-config-edit-actions",children:[e.jsx("button",{className:"ideation-config-toggle-btn",onClick:i,children:"Save"}),e.jsx("button",{className:"ideation-config-toggle-btn",onClick:T,children:"Cancel"})]})]}):e.jsxs("label",{className:"ideation-config-category",children:[e.jsx("input",{type:"checkbox",checked:g.has(t.id),onChange:()=>X(t.id)}),e.jsx("span",{className:"ideation-config-category-icon",children:t.icon}),e.jsx("span",{className:"ideation-config-category-label",children:t.label}),e.jsx("span",{className:"ideation-config-category-color",style:{backgroundColor:t.color}}),t.isCustom&&e.jsxs("span",{className:"ideation-config-category-actions",children:[e.jsx("button",{className:"ideation-config-cat-btn edit",onClick:l=>{l.preventDefault(),V(t)},title:"Edit category",children:e.jsx("svg",{viewBox:"0 0 16 16",width:"12",height:"12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e.jsx("path",{d:"M11.5 1.5l3 3-9 9H2.5v-3l9-9z"})})}),e.jsx("button",{className:"ideation-config-cat-btn delete",onClick:l=>{l.preventDefault(),a(t.id)},title:"Delete category",children:e.jsx("svg",{viewBox:"0 0 16 16",width:"12",height:"12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e.jsx("path",{d:"M3 4h10M5.5 4V3a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v1M6.5 7v5M9.5 7v5M4.5 4l.5 9a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1l.5-9"})})})]})]})},t.id))}),z?e.jsxs("div",{className:"ideation-config-create-form",children:[e.jsx("div",{className:"ideation-config-create-field",children:e.jsx("input",{type:"text",value:o,onChange:t=>_(t.target.value),placeholder:"Category name",className:"ideation-config-edit-input",autoFocus:!0,onKeyDown:t=>{t.key==="Enter"&&o.trim()&&G(),t.key==="Escape"&&$(!1)}})}),e.jsxs("div",{className:"ideation-config-create-field",children:[e.jsx("span",{className:"ideation-config-create-label",children:"Icon"}),e.jsx("div",{className:"ideation-config-picker-row",children:I.map(t=>e.jsx("button",{className:`ideation-config-icon-btn ${v===t?"selected":""}`,onClick:()=>D(t),children:t},t))})]}),e.jsxs("div",{className:"ideation-config-create-field",children:[e.jsx("span",{className:"ideation-config-create-label",children:"Color"}),e.jsx("div",{className:"ideation-config-picker-row",children:Y.map(t=>e.jsx("button",{className:`ideation-config-color-btn ${S===t?"selected":""}`,style:{backgroundColor:t},onClick:()=>P(t)},t))})]}),e.jsxs("div",{className:"ideation-config-create-actions",children:[e.jsx("button",{className:"ideation-config-toggle-btn",onClick:G,disabled:!o.trim()||y,children:y?"Creating...":"Add Category"}),e.jsx("button",{className:"ideation-config-toggle-btn",onClick:()=>$(!1),children:"Cancel"})]})]}):e.jsxs("div",{className:"ideation-config-add-row",children:[p&&e.jsx("button",{className:"ideation-config-toggle-btn",onClick:()=>$(!0),children:"+ Add Custom Category"}),N&&w&&f&&e.jsx("button",{className:"ideation-config-toggle-btn suggest",onClick:m,disabled:K,children:K?"Suggesting...":"Suggest Categories"})]}),W.length>0&&e.jsxs("div",{className:"ideation-config-suggestions",children:[e.jsx("span",{className:"ideation-config-suggestions-title",children:"AI Suggestions"}),W.map(t=>e.jsxs("div",{className:"ideation-config-suggestion",children:[e.jsx("span",{className:"ideation-config-category-icon",children:t.icon}),e.jsx("span",{className:"ideation-config-category-label",children:t.label}),e.jsx("span",{className:"ideation-config-category-color",style:{backgroundColor:t.color}}),e.jsx("button",{className:"ideation-config-toggle-btn",onClick:()=>j(t),children:"+ Add"})]},t.id))]}),e.jsxs("div",{className:"ideation-config-actions",children:[e.jsx("button",{className:"ideation-config-cancel",onClick:r,children:"Cancel"}),e.jsxs("button",{className:"ideation-config-generate",onClick:()=>s(Array.from(g)),disabled:g.size===0,children:["Generate Ideas (",g.size," categories)"]})]})]})})}const ie=6,me=10*1024*1024;function he({projectId:s,editingIdea:r,onSave:x,onCancel:p}){const[u,d]=n.useState(r?.title||""),[N,w]=n.useState(r?.description||""),[f,C]=n.useState(r?.category||"new_features"),[g,k]=n.useState(r?.effort||"medium"),[z,$]=n.useState(r?.impact||"medium"),[o,_]=n.useState(r?.images||[]),[S,P]=n.useState(r?.links||[]),[v,D]=n.useState(""),[y,E]=n.useState(""),[R,O]=n.useState(!1),[c,L]=n.useState(null),[U,b]=n.useState(!1),A=n.useRef(0),F=n.useRef(null),K=ee(a=>a.categories),B=!!r,W=n.useCallback(async a=>{if(!a.type.startsWith("image/")){L("Only image files are supported");return}if(a.size>me){L("Image must be under 10MB");return}if(o.length>=ie){L(`Maximum ${ie} images`);return}L(null),O(!0);try{const m=await new Promise((ae,ce)=>{const Q=new FileReader;Q.onload=()=>ae(Q.result),Q.onerror=()=>ce(new Error("Failed to read image file")),Q.readAsDataURL(a)}),j=se(te()),l=await(await fetch(`${j}/kanban/images`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:m,projectId:s})})).json();if(!l.ok)throw new Error(l.error||"Failed to upload image");const h=l.attachment,H={id:`img-${Date.now()}-${Math.random().toString(16).slice(2,10)}`,filename:h.filename||a.name,path:h.path||h.url||"",size:a.size,mimeType:a.type,createdAt:Date.now()};_(ae=>[...ae,H])}catch(m){L(m instanceof Error?m.message:"Failed to upload image")}finally{O(!1)}},[o.length,s]),M=n.useCallback(a=>{Array.from(a).forEach(m=>W(m))},[W]),X=n.useCallback(a=>{a.preventDefault(),a.stopPropagation(),b(!1),A.current=0,a.dataTransfer.files.length>0&&M(a.dataTransfer.files)},[M]),q=n.useCallback(a=>{const m=a.clipboardData?.items;if(!m)return;const j=[];for(let t=0;t<m.length;t++)if(m[t].type.startsWith("image/")){const l=m[t].getAsFile();l&&j.push(l)}j.length>0&&(a.preventDefault(),M(j))},[M]),J=n.useCallback(a=>{_(m=>m.filter(j=>j.id!==a))},[]),G=n.useCallback(()=>{const a=v.trim();if(!a)return;const m={id:`ref-${Date.now()}-${Math.random().toString(16).slice(2,10)}`,url:a,title:y.trim()||a};P(j=>[...j,m]),D(""),E("")},[v,y]),V=n.useCallback(a=>{P(m=>m.filter(j=>j.id!==a))},[]),i=()=>{u.trim()&&x({title:u.trim(),description:N.trim(),category:f,effort:g,impact:z,images:o,links:S})},T=a=>{try{return new URL(a).hostname}catch{return a}};return e.jsx("div",{className:"idea-creator-overlay",onClick:p,children:e.jsxs("div",{className:"idea-creator-dialog",onClick:a=>a.stopPropagation(),onPaste:q,children:[e.jsxs("div",{className:"idea-creator-header",children:[e.jsx("h3",{children:B?"Edit Idea":"New Idea"}),e.jsx("p",{children:B?"Update your idea details":"Add your own improvement idea with references"})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Title *"}),e.jsx("input",{type:"text",value:u,onChange:a=>d(a.target.value),placeholder:"What's the idea?",autoFocus:!0,className:"idea-creator-input"})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Description"}),e.jsx("textarea",{value:N,onChange:a=>w(a.target.value),placeholder:"Describe the improvement...",rows:4,className:"idea-creator-textarea"})]}),e.jsxs("div",{className:"idea-creator-selects-row",children:[e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Category"}),e.jsx("select",{value:f,onChange:a=>C(a.target.value),className:"idea-creator-select",children:K.map(a=>e.jsxs("option",{value:a.id,children:[a.icon," ",a.label]},a.id))})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Effort"}),e.jsxs("select",{value:g,onChange:a=>k(a.target.value),className:"idea-creator-select",children:[e.jsx("option",{value:"trivial",children:"Trivial"}),e.jsx("option",{value:"small",children:"Small"}),e.jsx("option",{value:"medium",children:"Medium"}),e.jsx("option",{value:"large",children:"Large"}),e.jsx("option",{value:"complex",children:"Complex"})]})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Impact"}),e.jsxs("select",{value:z,onChange:a=>$(a.target.value),className:"idea-creator-select",children:[e.jsx("option",{value:"low",children:"Low"}),e.jsx("option",{value:"medium",children:"Medium"}),e.jsx("option",{value:"high",children:"High"}),e.jsx("option",{value:"critical",children:"Critical"})]})]})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Images"}),e.jsxs("div",{className:`idea-creator-dropzone ${U?"drag-over":""}`,onDragEnter:a=>{a.preventDefault(),a.stopPropagation(),A.current++,a.dataTransfer.types.includes("Files")&&b(!0)},onDragLeave:a=>{a.preventDefault(),a.stopPropagation(),A.current--,A.current===0&&b(!1)},onDragOver:a=>{a.preventDefault(),a.stopPropagation()},onDrop:X,onClick:()=>F.current?.click(),children:[e.jsx("input",{ref:F,type:"file",accept:"image/*",multiple:!0,style:{display:"none"},onChange:a=>{a.target.files&&M(a.target.files),a.target.value=""}}),R?e.jsx("span",{className:"idea-creator-dropzone-text",children:"Uploading..."}):e.jsx("span",{className:"idea-creator-dropzone-text",children:"Drop images here, paste, or click to browse"})]}),c&&e.jsx("div",{className:"idea-creator-upload-error",children:c}),o.length>0&&e.jsx("div",{className:"idea-creator-image-grid",children:o.map(a=>e.jsxs("div",{className:"idea-creator-image-thumb",children:[e.jsx("img",{src:`${se(te())}/kanban/images/${a.filename||a.path.split("/").pop()}`,alt:a.filename}),e.jsx("button",{className:"idea-creator-image-remove",onClick:()=>J(a.id),title:"Remove image",children:"×"})]},a.id))})]}),e.jsxs("div",{className:"idea-creator-field",children:[e.jsx("label",{children:"Reference Links"}),e.jsxs("div",{className:"idea-creator-link-input-row",children:[e.jsx("input",{type:"text",value:v,onChange:a=>D(a.target.value),placeholder:"https://...",className:"idea-creator-input",onKeyDown:a=>{a.key==="Enter"&&(a.preventDefault(),G())}}),e.jsx("input",{type:"text",value:y,onChange:a=>E(a.target.value),placeholder:"Title (optional)",className:"idea-creator-input",style:{flex:"0 0 140px"},onKeyDown:a=>{a.key==="Enter"&&(a.preventDefault(),G())}}),e.jsx("button",{className:"ideation-btn secondary",onClick:G,disabled:!v.trim(),children:"Add"})]}),S.length>0&&e.jsx("div",{className:"idea-creator-link-list",children:S.map(a=>e.jsxs("div",{className:"idea-creator-link-item",children:[e.jsx("span",{className:"idea-creator-link-icon",children:e.jsx("svg",{viewBox:"0 0 16 16",width:"12",height:"12",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e.jsx("path",{d:"M6.5 9.5l3-3M9 7l1.5-1.5a2.12 2.12 0 0 0-3-3L6 4M7 9l-1.5 1.5a2.12 2.12 0 0 1-3-3L4 6"})})}),e.jsx("span",{className:"idea-creator-link-title",children:a.title||T(a.url)}),e.jsx("button",{className:"idea-creator-link-remove",onClick:()=>V(a.id),title:"Remove link",children:"×"})]},a.id))})]}),e.jsxs("div",{className:"idea-creator-actions",children:[e.jsx("button",{className:"ideation-config-cancel",onClick:p,children:"Cancel"}),e.jsx("button",{className:"ideation-config-generate",onClick:i,disabled:!u.trim()||R,children:B?"Save Changes":"Create Idea"})]})]})})}function ge(s){switch(s){case"critical":return"urgent";case"high":return"high";case"medium":return"medium";case"low":return"low";default:return"medium"}}function ue(s){const r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(s);return r?`${parseInt(r[1],16)}, ${parseInt(r[2],16)}, ${parseInt(r[3],16)}`:"255, 255, 255"}const ne={trivial:"#4ade80",small:"#60a5fa",medium:"#fbbf24",large:"#f97316",complex:"#f87171"},le={low:"#888",medium:"#fbbf24",high:"#f97316",critical:"#f87171"};function oe(s){const r=se(te()),x=s.filename||s.path.split("/").pop()||"";return`${r}/kanban/images/${x}`}function re(s){try{return new URL(s).hostname}catch{return s}}function fe({idea:s,onDismiss:r,onDelete:x,onConvertToTask:p,onEdit:u}){const[d,N]=n.useState(!1),[w,f]=n.useState(null),g=ee(o=>o.categories).find(o=>o.id===s.category),k=s.images&&s.images.length>0,z=s.links&&s.links.length>0,$=d?s.images:s.images?.slice(0,3)||[];return e.jsxs("div",{className:`idea-card ${s.convertedToTaskId?"converted":""} ${d?"expanded":""}`,children:[e.jsxs("div",{className:"idea-card-header",children:[e.jsx("span",{className:"idea-card-category-icon",title:g?.label,children:g?.icon||"?"}),e.jsxs("h4",{className:"idea-card-title",onClick:()=>N(!d),children:[s.title,s.isManual&&e.jsx("span",{className:"idea-card-manual-badge",title:"Manual idea",children:"M"}),e.jsx("span",{className:"idea-card-expand-hint",children:d?"▾":"▸"})]}),e.jsx("div",{className:"idea-card-actions",children:s.convertedToTaskId?e.jsxs("span",{className:"idea-card-converted-badge",title:"Converted to task",children:[e.jsx("svg",{viewBox:"0 0 16 16",width:"14",height:"14",fill:"currentColor",children:e.jsx("path",{d:"M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zm3.78-9.72a.75.75 0 0 0-1.06-1.06L6.75 9.19 5.28 7.72a.75.75 0 0 0-1.06 1.06l2 2a.75.75 0 0 0 1.06 0l4.5-4.5z"})}),e.jsx("span",{style:{fontSize:11,marginLeft:4},children:"Task created"})]}):e.jsxs(e.Fragment,{children:[s.isManual&&u&&e.jsx("button",{className:"idea-card-action-btn edit",onClick:u,title:"Edit idea",children:"✏️"}),x&&e.jsx("button",{className:"idea-card-action-btn delete",onClick:x,title:"Delete idea permanently",children:"🗑️"}),e.jsx("button",{className:"idea-card-action-btn dismiss",onClick:r,title:"Dismiss idea (hide)",children:"✕"})]})})]}),e.jsx("p",{className:`idea-card-description ${d?"expanded":""}`,children:s.description}),k&&e.jsxs("div",{className:`idea-card-images ${d?"expanded":""}`,children:[$.map(o=>e.jsx("div",{className:`idea-card-thumbnail ${d?"large":""}`,onClick:()=>f(oe(o)),title:o.filename,children:e.jsx("img",{src:oe(o),alt:o.filename})},o.id)),!d&&s.images.length>3&&e.jsxs("span",{className:"idea-card-images-overflow",onClick:()=>N(!0),children:["+",s.images.length-3]})]}),z&&e.jsx("div",{className:"idea-card-links",children:s.links.map(o=>e.jsxs("a",{className:`idea-card-link-pill ${d?"expanded":""}`,href:o.url,target:"_blank",rel:"noopener noreferrer",title:o.url,children:[e.jsx("svg",{viewBox:"0 0 16 16",width:"10",height:"10",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e.jsx("path",{d:"M6.5 9.5l3-3M9 7l1.5-1.5a2.12 2.12 0 0 0-3-3L6 4M7 9l-1.5 1.5a2.12 2.12 0 0 1-3-3L4 6"})}),d?o.title?`${o.title} — ${re(o.url)}`:o.url:o.title||re(o.url)]},o.id))}),d&&e.jsxs("div",{className:"idea-card-meta",children:[e.jsx("span",{className:"idea-card-meta-category",style:{color:g?.color},children:g?.label}),e.jsx("span",{className:"idea-card-meta-date",children:new Date(s.createdAt).toLocaleDateString()})]}),e.jsxs("div",{className:"idea-card-footer",children:[e.jsxs("div",{className:"idea-card-badges",children:[e.jsx("span",{className:"idea-badge effort",style:{borderColor:ne[s.effort]||"#888",color:ne[s.effort]||"#888"},children:s.effort}),e.jsxs("span",{className:"idea-badge impact",style:{borderColor:le[s.impact]||"#888",color:le[s.impact]||"#888"},children:[s.impact," impact"]})]}),!s.convertedToTaskId&&e.jsx("button",{className:"idea-card-create-task-btn",onClick:p,title:"Create Kanban task from this idea",children:"+ Create Task"})]}),w&&e.jsx("div",{className:"idea-card-image-preview",onClick:()=>f(null),children:e.jsx("img",{src:w,alt:"Preview"})})]})}function pe({projectId:s,projectPath:r,generateIdeas:x,dismissIdea:p,deleteIdea:u,deleteIdeationSession:d,createKanbanTask:N,convertIdeaToTask:w,createManualIdea:f,updateManualIdea:C,getIdeationSession:g,createCategory:k,updateCategory:z,deleteCategory:$,suggestCategories:o}){const[_,S]=n.useState(!1),[P,v]=n.useState(!1),[D,y]=n.useState(),E=Z(i=>i.selectedCategory),R=Z(i=>i.setSelectedCategory),O=ee(i=>i.categories),c=Z(i=>s?i.sessions.get(s):void 0),L=Z(i=>i.getIdeasByCategory);n.useEffect(()=>{s&&g&&!c&&g(s)},[s,g,c]);const U=s?L(s,E):[],b=c?.status==="generating"||c?.status==="streaming",A=c?.status==="error",F=c?.ideas.filter(i=>!i.dismissed).length||0,K=n.useCallback(async i=>{!s||!r||(S(!1),await x(s,r,i))},[s,r,x]),B=n.useCallback(async()=>{if(!s||!r)return;const i=c?.enabledCategories;await x(s,r,i,!0)},[s,r,c,x]),W=n.useCallback(async i=>{s&&await p(i,s)},[s,p]),M=n.useCallback(async i=>{!s||!u||await u(i,s)},[s,u]),X=n.useCallback(async i=>{if(!s)return;const T=await N(s,{title:i.title,description:i.description,priority:ge(i.impact),columnId:"ideas",tags:[i.category]});T&&(Z.getState().updateIdea(s,i.id,{convertedToTaskId:T.id}),w(i.id,s,T.id))},[s,N,w]),q=n.useCallback(async()=>{s&&await d(s)},[s,d]),J=n.useCallback(async i=>{!s||!f||(await f(s,i),v(!1),y(void 0))},[s,f]),G=n.useCallback(async i=>{!s||!D||!C||(await C(D.id,s,i),v(!1),y(void 0))},[s,D,C]),V=n.useCallback(i=>{y(i),v(!0)},[]);return s?e.jsxs("div",{className:"ideation-panel",children:[e.jsxs("div",{className:"ideation-header",children:[e.jsx("div",{className:"ideation-header-left",children:b&&e.jsxs("div",{className:"ideation-generating",children:[e.jsxs("span",{className:"ideation-generating-dots",children:[e.jsx("span",{}),e.jsx("span",{}),e.jsx("span",{})]}),e.jsx("span",{className:"ideation-generating-text",children:F>0?`${F} ideas found...`:"Analyzing codebase..."})]})}),e.jsxs("div",{className:"ideation-header-actions",children:[f&&e.jsx("button",{className:"ideation-btn secondary",onClick:()=>{y(void 0),v(!0)},title:"Add your own idea",children:"+ New Idea"}),c&&!b&&e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"ideation-btn secondary",onClick:B,title:"Add more ideas to current session",children:"+ Add More"}),e.jsx("button",{className:"ideation-btn secondary",onClick:q,title:"Clear all ideas",children:"Clear"})]}),e.jsx("button",{className:"ideation-btn secondary",onClick:()=>S(!0),title:"Configure categories",disabled:b,children:e.jsxs("svg",{viewBox:"0 0 16 16",width:"14",height:"14",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[e.jsx("circle",{cx:"8",cy:"8",r:"3"}),e.jsx("path",{d:"M8 1v2M8 13v2M1 8h2M13 8h2M3.05 3.05l1.41 1.41M11.54 11.54l1.41 1.41M3.05 12.95l1.41-1.41M11.54 4.46l1.41-1.41"})]})}),!b&&e.jsx("button",{className:"ideation-btn primary",onClick:()=>S(!0),disabled:!r,title:r?"Generate improvement ideas":"Project path required",children:A?"Retry":c?"Regenerate":"Generate Ideas"})]})]}),A&&c?.error&&e.jsxs("div",{className:"ideation-error",children:[e.jsx("span",{className:"ideation-error-icon",children:"⚠️"}),e.jsx("span",{children:c.error})]}),c&&c.ideas.length>0&&e.jsxs("div",{className:"ideation-category-tabs",children:[e.jsxs("button",{className:`ideation-category-tab ${E===null?"active":""}`,onClick:()=>R(null),children:["All (",F,")"]}),O.map(i=>{const T=c.ideas.filter(a=>!a.dismissed&&a.category===i.id).length;return T===0?null:e.jsxs("button",{className:`ideation-category-tab ${E===i.id?"active":""}`,onClick:()=>R(i.id),style:{"--tab-color":i.color,"--tab-color-rgb":ue(i.color)},children:[i.icon," ",i.label," (",T,")"]},i.id)})]}),e.jsx("div",{className:"ideation-ideas-list",children:U.length>0?U.map(i=>e.jsx(fe,{idea:i,onDismiss:()=>W(i.id),onDelete:u?()=>M(i.id):void 0,onConvertToTask:()=>X(i),onEdit:i.isManual&&C?()=>V(i):void 0},i.id)):!b&&!c?e.jsxs("div",{className:"ideation-empty-state",children:[e.jsx("span",{className:"ideation-empty-icon",children:"💡"}),e.jsx("h3",{children:"Discover Improvements"}),e.jsx("p",{children:'Click "Generate Ideas" to AI-analyze your codebase, or "+ New Idea" to add your own inspiration with images and reference links.'})]}):!b&&!A&&c&&U.length===0?e.jsxs("div",{className:"ideation-empty-state",children:[e.jsx("span",{className:"ideation-empty-icon",children:E?"🔍":"✅"}),e.jsx("p",{children:E?"No ideas in this category":"No ideas found. Try generating with different categories or add your own."})]}):null}),_&&e.jsx(de,{onGenerate:K,onCancel:()=>S(!1),initialCategories:c?.enabledCategories,createCategory:k,updateCategory:z,deleteCategory:$,suggestCategories:o,projectId:s,projectPath:r}),P&&s&&e.jsx(he,{projectId:s,editingIdea:D,onSave:D?G:J,onCancel:()=>{v(!1),y(void 0)}})]}):e.jsx("div",{className:"ideation-panel",children:e.jsxs("div",{className:"ideation-empty-state",children:[e.jsx("span",{className:"ideation-empty-icon",children:"💡"}),e.jsx("p",{children:"Select a project to generate improvement ideas"})]})})}export{pe as IdeationPanel};
|