vibeteam 0.4.0 → 0.5.1

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.
@@ -93,6 +93,7 @@ const EXEC_PATH = [
93
93
  /** PATH for tmux spawn - includes common locations plus original PATH */
94
94
  const TMUX_SPAWN_PATH = [
95
95
  `${HOME}/.local/bin`,
96
+ `${HOME}/.npm-global/bin`, // npm global installs (vibeteam-mcp lives here)
96
97
  '/opt/homebrew/bin',
97
98
  '/usr/local/bin',
98
99
  '/usr/bin',
@@ -4030,18 +4031,19 @@ async function createSession(options = {}) {
4030
4031
  }
4031
4032
  }
4032
4033
 
4034
+ // Always export PATH into the tmux session so MCP servers (vibeteam-mcp)
4035
+ // and other tools are discoverable. The env passed to execFile only affects
4036
+ // the tmux client process, not the new session itself.
4037
+ envVarsToExport.unshift({ key: 'PATH', value: TMUX_SPAWN_PATH });
4038
+
4033
4039
  // Build claude command with environment exports prepended
4034
4040
  let claudeCmd;
4035
4041
  const baseClaudeCmd = claudeArgs.length > 0 ? `claude ${claudeArgs.join(' ')}` : 'claude';
4036
- if (envVarsToExport.length > 0) {
4037
- const exports = envVarsToExport
4038
- .map(e => `export ${e.key}=${escapeShellValue(e.value)}`)
4039
- .join(' && ');
4040
- claudeCmd = `${exports} && ${baseClaudeCmd}`;
4041
- log(`Environment exports prepended to command (${envVarsToExport.length} vars)`);
4042
- } else {
4043
- claudeCmd = baseClaudeCmd;
4044
- }
4042
+ const exports = envVarsToExport
4043
+ .map(e => `export ${e.key}=${escapeShellValue(e.value)}`)
4044
+ .join(' && ');
4045
+ claudeCmd = `${exports} && ${baseClaudeCmd}`;
4046
+ log(`Environment exports prepended to command (${envVarsToExport.length} vars)`);
4045
4047
 
4046
4048
  // SECURITY FIX: Use execFile with array args to prevent command injection
4047
4049
  // Pass PATH via environment variable instead of shell string interpolation
@@ -6339,23 +6341,53 @@ async function handleHttpRequest(req, res) {
6339
6341
  // Claude Usage API
6340
6342
  // ============================================================================
6341
6343
  // Get Claude Code usage limits from Anthropic API
6344
+ // Cache usage data to avoid hitting Anthropic's aggressive OAuth rate limits (429)
6345
+ if (!global._usageCache) {
6346
+ global._usageCache = { data: null, timestamp: 0, ttl: 120000 }; // 2-minute TTL
6347
+ }
6342
6348
  if (req.method === 'GET' && req.url === '/usage') {
6349
+ const cache = global._usageCache;
6350
+ const now = Date.now();
6351
+
6352
+ // Return cached data if still fresh
6353
+ if (cache.data && (now - cache.timestamp) < cache.ttl) {
6354
+ res.writeHead(200, { 'Content-Type': 'application/json' });
6355
+ res.end(JSON.stringify({ ok: true, usage: cache.data, cached: true }));
6356
+ return;
6357
+ }
6358
+
6343
6359
  try {
6344
- // Get OAuth token from macOS Keychain using execFileSync (no shell injection risk)
6345
- const { execFileSync } = await import('child_process');
6360
+ // Get OAuth token - try credentials file first (Keychain's security -w truncates large JSON),
6361
+ // then fall back to Keychain
6362
+ const { readFileSync } = await import('fs');
6363
+ const { join } = await import('path');
6364
+ const { homedir } = await import('os');
6346
6365
  let tokenData;
6366
+
6367
+ // Method 1: Read from ~/.claude/.credentials.json (most reliable)
6347
6368
  try {
6348
- const keychainResult = execFileSync(
6349
- 'security',
6350
- ['find-generic-password', '-s', 'Claude Code-credentials', '-w'],
6351
- { encoding: 'utf8', timeout: 5000 }
6352
- ).trim();
6353
- tokenData = JSON.parse(keychainResult);
6354
- } catch (keychainErr) {
6369
+ const credPath = join(homedir(), '.claude', '.credentials.json');
6370
+ tokenData = JSON.parse(readFileSync(credPath, 'utf8'));
6371
+ } catch (_fileErr) {
6372
+ // Method 2: Fall back to macOS Keychain
6373
+ try {
6374
+ const { execFileSync } = await import('child_process');
6375
+ const keychainResult = execFileSync(
6376
+ 'security',
6377
+ ['find-generic-password', '-s', 'Claude Code-credentials', '-w'],
6378
+ { encoding: 'utf8', timeout: 5000 }
6379
+ ).trim();
6380
+ tokenData = JSON.parse(keychainResult);
6381
+ } catch (_keychainErr) {
6382
+ // ignore, handled below
6383
+ }
6384
+ }
6385
+
6386
+ if (!tokenData) {
6355
6387
  res.writeHead(401, { 'Content-Type': 'application/json' });
6356
6388
  res.end(JSON.stringify({
6357
6389
  ok: false,
6358
- error: 'Could not retrieve Claude credentials from Keychain. Make sure you are logged into Claude Code.'
6390
+ error: 'Could not retrieve Claude credentials. Make sure you are logged into Claude Code.'
6359
6391
  }));
6360
6392
  return;
6361
6393
  }
@@ -6379,16 +6411,41 @@ async function handleHttpRequest(req, res) {
6379
6411
 
6380
6412
  if (!usageResponse.ok) {
6381
6413
  const errorText = await usageResponse.text();
6414
+
6415
+ // On rate limit (429), return stale cached data if available
6416
+ if (usageResponse.status === 429 && cache.data) {
6417
+ log('Usage API rate limited (429), returning stale cached data');
6418
+ // Extend cache TTL to back off from the API
6419
+ cache.timestamp = now - cache.ttl + 60000; // retry in 60s
6420
+ res.writeHead(200, { 'Content-Type': 'application/json' });
6421
+ res.end(JSON.stringify({ ok: true, usage: cache.data, cached: true }));
6422
+ return;
6423
+ }
6424
+
6382
6425
  res.writeHead(usageResponse.status, { 'Content-Type': 'application/json' });
6383
6426
  res.end(JSON.stringify({ ok: false, error: `Anthropic API error: ${errorText}` }));
6384
6427
  return;
6385
6428
  }
6386
6429
 
6387
6430
  const usageData = await usageResponse.json();
6431
+
6432
+ // Update cache with fresh data
6433
+ cache.data = usageData;
6434
+ cache.timestamp = now;
6435
+
6388
6436
  res.writeHead(200, { 'Content-Type': 'application/json' });
6389
6437
  res.end(JSON.stringify({ ok: true, usage: usageData }));
6390
6438
  } catch (err) {
6391
6439
  log(`Error fetching usage: ${err.message}`);
6440
+
6441
+ // On any error, return stale cached data if available
6442
+ if (cache.data) {
6443
+ log('Returning stale cached usage data after error');
6444
+ res.writeHead(200, { 'Content-Type': 'application/json' });
6445
+ res.end(JSON.stringify({ ok: true, usage: cache.data, cached: true }));
6446
+ return;
6447
+ }
6448
+
6392
6449
  res.writeHead(500, { 'Content-Type': 'application/json' });
6393
6450
  res.end(JSON.stringify({ ok: false, error: err.message }));
6394
6451
  }
@@ -6721,18 +6778,24 @@ async function handleHttpRequest(req, res) {
6721
6778
  execFile('tmux', ['kill-session', '-t', session.tmuxSession], EXEC_OPTIONS, () => {
6722
6779
  // SECURITY FIX: Use execFile with array args to prevent command injection
6723
6780
  const tmuxEnv = { ...process.env, PATH: TMUX_SPAWN_PATH };
6781
+ // Build env exports for the tmux session (PATH + global settings)
6782
+ const restartEnvExports = [`export PATH=${escapeShellValue(TMUX_SPAWN_PATH)}`];
6724
6783
  // Load global settings for restart
6725
6784
  const globalSettings = readGlobalSettings();
6726
6785
  if (globalSettings.claudeEnv && Object.keys(globalSettings.claudeEnv).length > 0) {
6727
6786
  Object.entries(globalSettings.claudeEnv).forEach(([key, value]) => {
6728
6787
  tmuxEnv[key] = value;
6788
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
6789
+ restartEnvExports.push(`export ${key}=${escapeShellValue(value)}`);
6790
+ }
6729
6791
  });
6730
6792
  }
6793
+ const restartClaudeCmd = `${restartEnvExports.join(' && ')} && claude --permission-mode=bypassPermissions --dangerously-skip-permissions`;
6731
6794
  const tmuxArgs = [
6732
6795
  'new-session', '-d',
6733
6796
  '-s', session.tmuxSession,
6734
6797
  '-c', cwd,
6735
- 'claude --permission-mode=bypassPermissions --dangerously-skip-permissions'
6798
+ restartClaudeCmd
6736
6799
  ];
6737
6800
  execFile('tmux', tmuxArgs, { env: tmuxEnv }, (error) => {
6738
6801
  if (error) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vibeteam",
3
- "version": "0.4.0",
4
- "description": "3D visualization of Claude Code as an interactive workshop",
3
+ "version": "0.5.1",
4
+ "description": "AI agent orchestration platform for Claude Code",
5
5
  "author": "asara",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -0,0 +1 @@
1
+ import{u as b,a as s,j as t,e as U}from"./index-Gl2uhE1e.js";const P="vibeteam-activity-filters",Y=[{value:"tool_use",label:"Tool Use"},{value:"prompt",label:"Prompts"},{value:"permission",label:"Permissions"},{value:"session_end",label:"Session End"},{value:"error",label:"Errors"}],B=[{value:"5m",label:"5m"},{value:"15m",label:"15m"},{value:"1h",label:"1h"},{value:"all",label:"All"}],J=["tool_use","prompt","status_change","permission","error","session_end"],K=["5m","15m","1h","all"];function W(){try{const n=localStorage.getItem(P);if(!n)return{selectedTypes:[],timeRange:"all"};const a=JSON.parse(n),v=Array.isArray(a.selectedTypes)?a.selectedTypes.filter(y=>J.includes(y)):[],g=K.includes(a.timeRange)?a.timeRange:"all";return{selectedTypes:v,timeRange:g}}catch{return{selectedTypes:[],timeRange:"all"}}}function q(n,a){try{localStorage.setItem(P,JSON.stringify({selectedTypes:n,timeRange:a}))}catch{}}function z(n){switch(n){case"5m":return 300*1e3;case"15m":return 900*1e3;case"1h":return 3600*1e3;case"all":return 1/0}}function Q(n){const a=Date.now()-n;return a<5e3?"just now":a<6e4?`${Math.floor(a/1e3)}s ago`:a<36e5?`${Math.floor(a/6e4)}m ago`:a<864e5?`${Math.floor(a/36e5)}h ago`:`${Math.floor(a/864e5)}d ago`}function X(n){switch(n.type){case"tool_use":return n.tool?U(n.tool):"🔧";case"prompt":return"💬";case"permission":return"⚠️";case"session_end":return"✅";case"error":return"❌";case"status_change":return"🔄";default:return"📌"}}function Z(n,a){return n.length<=a?n:n.slice(0,a)+"..."}function te(){const n=b(e=>e.activityEvents),a=b(e=>e.resetActivityUnread),v=b(e=>e.agents),g=b(e=>e.selectAgent),y=s.useMemo(()=>W(),[]),[u,k]=s.useState([]),[r,C]=s.useState(y.selectedTypes),[f,$]=s.useState(y.timeRange),[p,T]=s.useState(!1),[N,E]=s.useState(!1),[c,x]=s.useState(!1),[,O]=s.useState(0),o=s.useRef(null),m=s.useRef(!0),h=s.useRef(0),[w,j]=s.useState(0),A=s.useRef(null),I=s.useRef(null),R=s.useRef(0);s.useEffect(()=>{q(r,f)},[r,f]),s.useEffect(()=>{if(!p&&!N)return;const e=l=>{const i=l.target;A.current?.contains(i)||I.current?.contains(i)||(T(!1),E(!1))};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[p,N]),s.useEffect(()=>{const e=setInterval(()=>O(l=>l+1),1e4);return()=>clearInterval(e)},[]),s.useEffect(()=>{m.current&&!c&&(a(),h.current=0,j(0))},[n.length,a,c]),s.useEffect(()=>{!c&&m.current&&o.current?o.current.scrollTop=o.current.scrollHeight:c||(h.current++,j(h.current))},[n.length,c]);const L=s.useCallback(()=>{if(!o.current)return;const{scrollTop:e,scrollHeight:l,clientHeight:i}=o.current,d=l-e-i<40;m.current=d,d&&(h.current=0,j(0),a(),c&&x(!1))},[a,c]),_=s.useCallback(()=>{o.current&&(o.current.scrollTop=o.current.scrollHeight,m.current=!0,h.current=0,j(0),a(),x(!1))},[a]),D=s.useCallback(e=>{e.agentId&&e.agentId!=="unknown"&&g(e.agentId)},[g]),H=s.useCallback(e=>{k(l=>l.includes(e)?l.filter(i=>i!==e):[...l,e])},[]),V=s.useCallback(e=>{C(l=>l.includes(e)?l.filter(i=>i!==e):[...l,e])},[]),G=s.useCallback(()=>{x(e=>e?!1:(R.current=n.length,!0))},[n.length]),S=c?n.length-R.current:0,F=s.useMemo(()=>{const e=Date.now(),l=z(f);return(c?n.slice(0,R.current):n).filter(d=>!(u.length>0&&!u.includes(d.agentId)||r.length>0&&!r.includes(d.type)||l!==1/0&&e-d.timestamp>l))},[n,u,r,f,c]),M=s.useMemo(()=>{const e=new Map;for(const[l,i]of v)e.set(l,{id:l,name:i.name,color:i.color});return Array.from(e.values())},[v]);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:A,children:[t.jsxs("button",{className:`activity-filter-btn ${u.length>0?"active":""}`,onClick:()=>{T(!p),E(!1)},children:["Agent",u.length>0?` (${u.length})`:""]}),p&&t.jsxs("div",{className:"activity-filter-dropdown",children:[M.length===0?t.jsx("div",{className:"activity-filter-empty",children:"No agents"}):M.map(e=>t.jsxs("label",{className:"activity-filter-option",children:[t.jsx("input",{type:"checkbox",checked:u.includes(e.id),onChange:()=>H(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:()=>k([]),children:"Clear"})]})]}),t.jsxs("div",{className:"activity-filter-dropdown-wrapper",ref:I,children:[t.jsxs("button",{className:`activity-filter-btn ${r.length>0?"active":""}`,onClick:()=>{E(!N),T(!1)},children:["Type",r.length>0?` (${r.length})`:""]}),N&&t.jsxs("div",{className:"activity-filter-dropdown",children:[Y.map(e=>t.jsxs("label",{className:"activity-filter-option",children:[t.jsx("input",{type:"checkbox",checked:r.includes(e.value),onChange:()=>V(e.value)}),t.jsx("span",{children:e.label})]},e.value)),r.length>0&&t.jsx("button",{className:"activity-filter-clear",onClick:()=>C([]),children:"Clear"})]})]}),t.jsx("button",{className:`activity-pause-btn ${c?"paused":""}`,onClick:G,title:c?"Resume feed":"Pause feed",children:c?"▶":"⏸"})]}),t.jsx("div",{className:"activity-time-range",children:B.map(e=>t.jsx("button",{className:`activity-time-btn ${f===e.value?"active":""}`,onClick:()=>$(e.value),children:e.label},e.value))})]}),c&&t.jsxs("div",{className:"activity-paused-banner",children:["Paused ",S>0?`- ${S} new event${S!==1?"s":""}`:"",t.jsx("button",{className:"activity-paused-resume",onClick:()=>{x(!1),_()},children:"Resume"})]}),t.jsx("div",{className:"activity-event-list",ref:o,onScroll:L,children:F.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"})]}):F.map(e=>t.jsxs("div",{className:"activity-event-card",onClick:()=>D(e),title:e.description,children:[t.jsx("span",{className:"activity-event-time",children:Q(e.timestamp)}),t.jsx("span",{className:"activity-agent-dot",style:{background:e.agentColor}}),t.jsx("span",{className:"activity-event-agent",children:e.agentName}),t.jsx("span",{className:"activity-event-icon",children:X(e)}),t.jsx("span",{className:"activity-event-desc",children:Z(e.description,80)})]},e.id))}),!c&&w>0&&!m.current&&t.jsxs("button",{className:"activity-new-events",onClick:_,children:[w," new event",w!==1?"s":""]})]})}export{te as ActivityFeedPanel};
@@ -0,0 +1 @@
1
+ .activity-feed-panel{display:flex;flex-direction:column;height:100%;background:#0a0a0f;color:#e0e0e0;font-size:12px}.activity-filter-bar{display:flex;align-items:center;justify-content:space-between;padding:6px 8px;border-bottom:1px solid rgba(255,255,255,.08);gap:8px;flex-shrink:0}.activity-filter-group{display:flex;gap:4px}.activity-filter-dropdown-wrapper{position:relative}.activity-filter-btn{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);color:#a0a0a0;padding:3px 8px;border-radius:4px;font-size:11px;cursor:pointer;transition:all .15s}.activity-filter-btn:hover{background:#ffffff1a;color:#e0e0e0}.activity-filter-btn.active{background:#00ffff1a;border-color:#00ffff4d;color:#0ff}.activity-filter-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#1a1a2e;border:1px solid rgba(255,255,255,.12);border-radius:6px;padding:4px;min-width:160px;z-index:1000;box-shadow:0 4px 12px #0006}.activity-filter-option{display:flex;align-items:center;gap:6px;padding:4px 6px;border-radius:3px;cursor:pointer;font-size:11px;color:silver}.activity-filter-option:hover{background:#ffffff0f}.activity-filter-option input[type=checkbox]{width:12px;height:12px;accent-color:#00ffff}.activity-filter-empty{padding:8px;text-align:center;color:#666;font-size:11px}.activity-filter-clear{display:block;width:100%;padding:4px;margin-top:4px;border:none;border-top:1px solid rgba(255,255,255,.08);background:none;color:#888;font-size:10px;cursor:pointer;text-align:center}.activity-filter-clear:hover{color:#0ff}.activity-time-range{display:flex;gap:2px;background:#ffffff08;border-radius:4px;padding:1px}.activity-time-btn{background:none;border:none;color:#666;padding:2px 6px;border-radius:3px;font-size:10px;cursor:pointer;transition:all .15s}.activity-time-btn:hover{color:#a0a0a0}.activity-time-btn.active{background:#ffffff1a;color:#e0e0e0}.activity-event-list{flex:1;overflow-y:auto;overflow-x:hidden;padding:2px 0}.activity-event-list::-webkit-scrollbar{width:4px}.activity-event-list::-webkit-scrollbar-track{background:transparent}.activity-event-list::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:2px}.activity-event-card{display:flex;align-items:center;gap:6px;padding:5px 8px;cursor:pointer;transition:background .1s;border-bottom:1px solid rgba(255,255,255,.03);min-height:28px}.activity-event-card:hover{background:#ffffff0a}.activity-event-time{font-family:SF Mono,Fira Code,monospace;font-size:10px;color:#555;min-width:48px;flex-shrink:0}.activity-agent-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.activity-event-agent{color:#888;font-size:11px;min-width:60px;max-width:80px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0}.activity-event-icon{font-size:12px;flex-shrink:0;width:16px;text-align:center}.activity-event-desc{color:#b0b0b0;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}.activity-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:24px;text-align:center}.activity-empty-icon{font-size:32px;margin-bottom:8px;opacity:.5}.activity-empty-text{color:#666;font-size:14px;margin-bottom:4px}.activity-empty-hint{color:#444;font-size:12px}.activity-pause-btn{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);color:#a0a0a0;padding:3px 6px;border-radius:4px;font-size:11px;cursor:pointer;transition:all .15s;line-height:1}.activity-pause-btn:hover{background:#ffffff1a;color:#e0e0e0}.activity-pause-btn.paused{background:#ffc83226;border-color:#ffc8324d;color:#ffc832}.activity-paused-banner{display:flex;align-items:center;justify-content:center;gap:8px;padding:4px 8px;background:#ffc83214;border-bottom:1px solid rgba(255,200,50,.15);color:#d4a520;font-size:11px;flex-shrink:0}.activity-paused-resume{background:none;border:none;color:#ffc832;font-size:11px;cursor:pointer;text-decoration:underline;padding:0}.activity-paused-resume:hover{color:#ffe066}.activity-new-events{position:absolute;bottom:12px;left:50%;transform:translate(-50%);background:#00ffff26;border:1px solid rgba(0,255,255,.3);color:#0ff;padding:4px 12px;border-radius:12px;font-size:11px;cursor:pointer;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);transition:all .2s;z-index:10}.activity-new-events:hover{background:#00ffff40}
@@ -0,0 +1 @@
1
+ .ideation-panel{display:flex;flex-direction:column;height:100%;overflow:hidden}.ideation-header{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-bottom:1px solid rgba(255,255,255,.06);gap:8px;flex-shrink:0}.ideation-header-left{flex:1;min-width:0}.ideation-header-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.ideation-btn{display:flex;align-items:center;gap:4px;padding:5px 10px;border:none;border-radius:6px;font-size:12px;font-weight:500;cursor:pointer;transition:all .15s ease;white-space:nowrap}.ideation-btn.primary{background:#4ade8026;color:#4ade80;border:1px solid rgba(74,222,128,.3)}.ideation-btn.primary:hover:not(:disabled){background:#4ade8040}.ideation-btn.secondary{background:#ffffff0f;color:#aaa;border:1px solid rgba(255,255,255,.1)}.ideation-btn.secondary:hover:not(:disabled){background:#ffffff1a;color:#fff}.ideation-btn:disabled{opacity:.4;cursor:not-allowed}.ideation-generating{display:flex;align-items:center;gap:8px;font-size:12px;color:#4ade80}.ideation-generating-dots{display:flex;gap:3px}.ideation-generating-dots span{width:4px;height:4px;border-radius:50%;background:#4ade80;animation:ideation-dot-pulse 1.4s ease-in-out infinite}.ideation-generating-dots span:nth-child(2){animation-delay:.2s}.ideation-generating-dots span:nth-child(3){animation-delay:.4s}@keyframes ideation-dot-pulse{0%,80%,to{opacity:.3;transform:scale(.8)}40%{opacity:1;transform:scale(1)}}.ideation-generating-text{font-size:11px}.ideation-error{padding:8px 12px;background:#f871711a;border-bottom:1px solid rgba(248,113,113,.2);color:#f87171;font-size:12px}.ideation-category-tabs{display:flex;gap:4px;padding:8px 12px;overflow-x:auto;border-bottom:1px solid rgba(255,255,255,.06);flex-shrink:0}.ideation-category-tabs::-webkit-scrollbar{height:3px}.ideation-category-tabs::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:3px}.ideation-category-tab{padding:4px 10px;border:1px solid rgba(255,255,255,.1);border-radius:12px;background:transparent;color:#888;font-size:11px;cursor:pointer;white-space:nowrap;transition:all .15s ease}.ideation-category-tab:hover{background:#ffffff0f;color:#ccc}.ideation-category-tab.active{background:rgba(var(--tab-color-rgb, 255, 255, 255),.15);border-color:var(--tab-color, rgba(255, 255, 255, .3));color:var(--tab-color, #fff)}.ideation-ideas-list{flex:1;overflow-y:auto;padding:8px;display:flex;flex-direction:column;gap:6px}.ideation-ideas-list::-webkit-scrollbar{width:5px}.ideation-ideas-list::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:3px}.idea-card{background:#ffffff08;border:1px solid rgba(255,255,255,.06);border-radius:8px;padding:10px 12px;transition:all .15s ease}.idea-card:hover{background:#ffffff0d;border-color:#ffffff1a}.idea-card.converted{opacity:.6}.idea-card-header{display:flex;align-items:flex-start;gap:8px}.idea-card-category-icon{font-size:14px;line-height:1;flex-shrink:0;margin-top:1px}.idea-card-title{flex:1;margin:0;font-size:13px;font-weight:600;color:#e0e0e0;cursor:pointer;line-height:1.3}.idea-card-title:hover{color:#fff}.idea-card-actions{display:flex;gap:4px;flex-shrink:0}.idea-card-action-btn{width:24px;height:24px;display:flex;align-items:center;justify-content:center;border:none;border-radius:4px;background:transparent;cursor:pointer;color:#888;transition:all .15s ease}.idea-card-action-btn.dismiss:hover{background:#f8717126;color:#f87171}.idea-card-converted-badge{color:#4ade80;display:flex;align-items:center}.idea-card-description{margin:6px 0 8px 22px;font-size:12px;color:#888;line-height:1.4;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.idea-card-description.expanded{-webkit-line-clamp:unset}.idea-card-footer{display:flex;align-items:center;justify-content:space-between;margin-left:22px;gap:8px}.idea-card-badges{display:flex;gap:6px}.idea-card-create-task-btn{padding:3px 10px;border:1px solid rgba(74,222,128,.3);border-radius:6px;background:#4ade801a;color:#4ade80;font-size:11px;font-weight:500;cursor:pointer;transition:all .15s ease;white-space:nowrap}.idea-card-create-task-btn:hover{background:#4ade8033;border-color:#4ade8080}.idea-badge{padding:2px 7px;border:1px solid;border-radius:10px;font-size:10px;font-weight:500;text-transform:capitalize}.ideation-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;text-align:center;color:#666;flex:1}.ideation-empty-icon{font-size:32px;margin-bottom:12px}.ideation-empty-state h3{margin:0 0 8px;font-size:14px;color:#aaa}.ideation-empty-state p{margin:0;font-size:12px;line-height:1.5;max-width:280px}.ideation-config-overlay{position:fixed;inset:0;background:#0009;display:flex;align-items:center;justify-content:center;z-index:10000}.ideation-config-dialog{background:#1e1e2a;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:20px;width:360px;max-width:90vw;box-shadow:0 20px 60px #00000080}.ideation-config-header h3{margin:0 0 4px;font-size:16px;color:#fff}.ideation-config-header p{margin:0 0 16px;font-size:12px;color:#888}.ideation-config-toggles{display:flex;gap:8px;margin-bottom:12px}.ideation-config-toggle-btn{padding:4px 10px;border:1px solid rgba(255,255,255,.1);border-radius:6px;background:transparent;color:#888;font-size:11px;cursor:pointer;transition:all .15s ease}.ideation-config-toggle-btn:hover{background:#ffffff0f;color:#ccc}.ideation-config-categories{display:flex;flex-direction:column;gap:6px;margin-bottom:16px}.ideation-config-category{display:flex;align-items:center;gap:8px;padding:8px 10px;background:#ffffff08;border:1px solid rgba(255,255,255,.06);border-radius:8px;cursor:pointer;transition:all .15s ease}.ideation-config-category:hover{background:#ffffff0f}.ideation-config-category input[type=checkbox]{accent-color:#4ade80}.ideation-config-category-icon{font-size:14px}.ideation-config-category-label{flex:1;font-size:13px;color:#ddd}.ideation-config-category-color{width:8px;height:8px;border-radius:50%}.ideation-config-actions{display:flex;justify-content:flex-end;gap:8px}.ideation-config-cancel{padding:7px 14px;border:1px solid rgba(255,255,255,.1);border-radius:6px;background:transparent;color:#888;font-size:13px;cursor:pointer;transition:all .15s ease}.ideation-config-cancel:hover{background:#ffffff0f;color:#ccc}.ideation-config-generate{padding:7px 14px;border:1px solid rgba(74,222,128,.3);border-radius:6px;background:#4ade8026;color:#4ade80;font-size:13px;font-weight:500;cursor:pointer;transition:all .15s ease}.ideation-config-generate:hover:not(:disabled){background:#4ade8040}.ideation-config-generate:disabled{opacity:.4;cursor:not-allowed}.idea-card-manual-badge{display:inline-block;margin-left:6px;padding:0 4px;border-radius:3px;background:#60a5fa26;color:#60a5fa;font-size:9px;font-weight:700;vertical-align:middle;line-height:16px}.idea-card-action-btn.edit:hover{background:#60a5fa26;color:#60a5fa}.idea-card-action-btn.delete:hover{background:#f8717126;color:#f87171}.idea-card-expand-hint{display:inline-block;margin-left:6px;font-size:10px;color:#666;transition:color .15s ease}.idea-card-title:hover .idea-card-expand-hint{color:#aaa}.idea-card.expanded{border-color:#ffffff1f;background:#ffffff0a}.idea-card-images.expanded{flex-wrap:wrap}.idea-card-thumbnail.large{width:80px;height:80px}.idea-card-link-pill.expanded{max-width:300px}.idea-card-meta{display:flex;align-items:center;gap:12px;margin:6px 0 4px 22px;font-size:11px}.idea-card-meta-category{font-weight:600}.idea-card-meta-date{color:#666}.idea-card-images{display:flex;align-items:center;gap:6px;margin:6px 0 4px 22px}.idea-card-thumbnail{width:48px;height:48px;border-radius:6px;overflow:hidden;border:1px solid rgba(255,255,255,.1);cursor:pointer;flex-shrink:0;transition:border-color .15s ease}.idea-card-thumbnail:hover{border-color:#ffffff4d}.idea-card-thumbnail img{width:100%;height:100%;object-fit:cover}.idea-card-images-overflow{font-size:11px;color:#888;padding:4px 8px;background:#ffffff0d;border-radius:4px}.idea-card-image-preview{position:fixed;inset:0;background:#000000d9;display:flex;align-items:center;justify-content:center;z-index:10001;cursor:pointer}.idea-card-image-preview img{max-width:90vw;max-height:90vh;border-radius:8px;box-shadow:0 20px 60px #00000080}.idea-card-links{display:flex;flex-wrap:wrap;gap:4px;margin:4px 0 4px 22px}.idea-card-link-pill{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:10px;background:#60a5fa1a;border:1px solid rgba(96,165,250,.2);color:#60a5fa;font-size:10px;text-decoration:none;transition:all .15s ease;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.idea-card-link-pill:hover{background:#60a5fa33;border-color:#60a5fa66;color:#93bbfd}.idea-creator-overlay{position:fixed;inset:0;background:#0009;display:flex;align-items:center;justify-content:center;z-index:10000}.idea-creator-dialog{background:#1e1e2a;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:20px;width:420px;max-width:90vw;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px #00000080}.idea-creator-dialog::-webkit-scrollbar{width:5px}.idea-creator-dialog::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:3px}.idea-creator-header h3{margin:0 0 4px;font-size:16px;color:#fff}.idea-creator-header p{margin:0 0 16px;font-size:12px;color:#888}.idea-creator-field{margin-bottom:12px}.idea-creator-field label{display:block;font-size:11px;font-weight:600;color:#aaa;margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px}.idea-creator-input{width:100%;padding:7px 10px;border:1px solid rgba(255,255,255,.1);border-radius:6px;background:#ffffff0d;color:#e0e0e0;font-size:13px;outline:none;transition:border-color .15s ease;box-sizing:border-box}.idea-creator-input:focus{border-color:#60a5fa80}.idea-creator-textarea{width:100%;padding:7px 10px;border:1px solid rgba(255,255,255,.1);border-radius:6px;background:#ffffff0d;color:#e0e0e0;font-size:13px;outline:none;resize:vertical;font-family:inherit;transition:border-color .15s ease;box-sizing:border-box}.idea-creator-textarea:focus{border-color:#60a5fa80}.idea-creator-selects-row{display:flex;gap:8px}.idea-creator-selects-row .idea-creator-field{flex:1}.idea-creator-select{width:100%;padding:7px 8px;border:1px solid rgba(255,255,255,.1);border-radius:6px;background:#ffffff0d;color:#e0e0e0;font-size:12px;outline:none;cursor:pointer;box-sizing:border-box}.idea-creator-select:focus{border-color:#60a5fa80}.idea-creator-select option{background:#1e1e2a;color:#e0e0e0}.idea-creator-dropzone{border:2px dashed rgba(255,255,255,.1);border-radius:8px;padding:16px;text-align:center;cursor:pointer;transition:all .15s ease}.idea-creator-dropzone:hover{border-color:#fff3;background:#ffffff05}.idea-creator-dropzone.drag-over{border-color:#60a5fa80;background:#60a5fa0d}.idea-creator-dropzone-text{font-size:12px;color:#888}.idea-creator-upload-error{margin-top:4px;font-size:11px;color:#f87171}.idea-creator-image-grid{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.idea-creator-image-thumb{position:relative;width:64px;height:64px;border-radius:6px;overflow:hidden;border:1px solid rgba(255,255,255,.1)}.idea-creator-image-thumb img{width:100%;height:100%;object-fit:cover}.idea-creator-image-remove{position:absolute;top:2px;right:2px;width:18px;height:18px;border-radius:50%;border:none;background:#000000b3;color:#fff;font-size:12px;cursor:pointer;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease}.idea-creator-image-thumb:hover .idea-creator-image-remove{opacity:1}.idea-creator-link-input-row{display:flex;gap:6px;align-items:center}.idea-creator-link-input-row .idea-creator-input{flex:1}.idea-creator-link-list{display:flex;flex-direction:column;gap:4px;margin-top:6px}.idea-creator-link-item{display:flex;align-items:center;gap:6px;padding:4px 8px;background:#ffffff08;border:1px solid rgba(255,255,255,.06);border-radius:6px;font-size:12px}.idea-creator-link-icon{color:#60a5fa;flex-shrink:0;display:flex}.idea-creator-link-title{flex:1;color:#aaa;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.idea-creator-link-remove{width:18px;height:18px;border-radius:50%;border:none;background:transparent;color:#888;font-size:14px;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .15s ease}.idea-creator-link-remove:hover{background:#f8717126;color:#f87171}.idea-creator-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:16px}
@@ -0,0 +1 @@
1
+ import{a as i,j as e,c as J,l as Q,f as O}from"./index-Gl2uhE1e.js";const $=[{id:"code_improvements",label:"Code Improvements",color:"#4ade80",icon:"🔧"},{id:"ui_ux",label:"UI/UX",color:"#60a5fa",icon:"🎨"},{id:"security",label:"Security",color:"#f87171",icon:"🔒"},{id:"performance",label:"Performance",color:"#fbbf24",icon:"⚡"},{id:"documentation",label:"Documentation",color:"#a78bfa",icon:"📝"},{id:"code_quality",label:"Code Quality",color:"#22d3d8",icon:"✨"},{id:"new_features",label:"New Features",color:"#a855f7",icon:"🚀"}];function re({onGenerate:s,onCancel:n,initialCategories:h}){const[g,m]=i.useState(()=>new Set(h||$.map(l=>l.id))),c=l=>{m(u=>{const x=new Set(u);return x.has(l)?x.delete(l):x.add(l),x})},v=()=>m(new Set($.map(l=>l.id))),j=()=>m(new Set);return e.jsx("div",{className:"ideation-config-overlay",onClick:n,children:e.jsxs("div",{className:"ideation-config-dialog",onClick:l=>l.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:v,children:"Select All"}),e.jsx("button",{className:"ideation-config-toggle-btn",onClick:j,children:"Deselect All"})]}),e.jsx("div",{className:"ideation-config-categories",children:$.map(l=>e.jsxs("label",{className:"ideation-config-category",children:[e.jsx("input",{type:"checkbox",checked:g.has(l.id),onChange:()=>c(l.id)}),e.jsx("span",{className:"ideation-config-category-icon",children:l.icon}),e.jsx("span",{className:"ideation-config-category-label",children:l.label}),e.jsx("span",{className:"ideation-config-category-color",style:{backgroundColor:l.color}})]},l.id))}),e.jsxs("div",{className:"ideation-config-actions",children:[e.jsx("button",{className:"ideation-config-cancel",onClick:n,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 V=6,oe=10*1024*1024;function ce({projectId:s,editingIdea:n,onSave:h,onCancel:g}){const[m,c]=i.useState(n?.title||""),[v,j]=i.useState(n?.description||""),[l,u]=i.useState(n?.category||"new_features"),[x,N]=i.useState(n?.effort||"medium"),[M,r]=i.useState(n?.impact||"medium"),[f,k]=i.useState(n?.images||[]),[b,L]=i.useState(n?.links||[]),[o,_]=i.useState(""),[w,C]=i.useState(""),[R,T]=i.useState(!1),[B,S]=i.useState(null),[X,U]=i.useState(!1),A=i.useRef(0),G=i.useRef(null),z=!!n,P=i.useCallback(async a=>{if(!a.type.startsWith("image/")){S("Only image files are supported");return}if(a.size>oe){S("Image must be under 10MB");return}if(f.length>=V){S(`Maximum ${V} images`);return}S(null),T(!0);try{const d=await new Promise((K,le)=>{const H=new FileReader;H.onload=()=>K(H.result),H.onerror=()=>le(new Error("Failed to read image file")),H.readAsDataURL(a)}),p=J(Q()),E=await(await fetch(`${p}/kanban/images`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:d,projectId:s})})).json();if(!E.ok)throw new Error(E.error||"Failed to upload image");const I=E.attachment,ne={id:`img-${Date.now()}-${Math.random().toString(16).slice(2,10)}`,filename:I.filename||a.name,path:I.path||I.url||"",size:a.size,mimeType:a.type,createdAt:Date.now()};k(K=>[...K,ne])}catch(d){S(d instanceof Error?d.message:"Failed to upload image")}finally{T(!1)}},[f.length,s]),D=i.useCallback(a=>{Array.from(a).forEach(d=>P(d))},[P]),t=i.useCallback(a=>{a.preventDefault(),a.stopPropagation(),U(!1),A.current=0,a.dataTransfer.files.length>0&&D(a.dataTransfer.files)},[D]),y=i.useCallback(a=>{const d=a.clipboardData?.items;if(!d)return;const p=[];for(let F=0;F<d.length;F++)if(d[F].type.startsWith("image/")){const E=d[F].getAsFile();E&&p.push(E)}p.length>0&&(a.preventDefault(),D(p))},[D]),W=i.useCallback(a=>{k(d=>d.filter(p=>p.id!==a))},[]),q=i.useCallback(()=>{const a=o.trim();if(!a)return;const d={id:`ref-${Date.now()}-${Math.random().toString(16).slice(2,10)}`,url:a,title:w.trim()||a};L(p=>[...p,d]),_(""),C("")},[o,w]),se=i.useCallback(a=>{L(d=>d.filter(p=>p.id!==a))},[]),te=()=>{m.trim()&&h({title:m.trim(),description:v.trim(),category:l,effort:x,impact:M,images:f,links:b})},ie=a=>{try{return new URL(a).hostname}catch{return a}};return e.jsx("div",{className:"idea-creator-overlay",onClick:g,children:e.jsxs("div",{className:"idea-creator-dialog",onClick:a=>a.stopPropagation(),onPaste:y,children:[e.jsxs("div",{className:"idea-creator-header",children:[e.jsx("h3",{children:z?"Edit Idea":"New Idea"}),e.jsx("p",{children:z?"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:m,onChange:a=>c(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:v,onChange:a=>j(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:l,onChange:a=>u(a.target.value),className:"idea-creator-select",children:$.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:x,onChange:a=>N(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:M,onChange:a=>r(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 ${X?"drag-over":""}`,onDragEnter:a=>{a.preventDefault(),a.stopPropagation(),A.current++,a.dataTransfer.types.includes("Files")&&U(!0)},onDragLeave:a=>{a.preventDefault(),a.stopPropagation(),A.current--,A.current===0&&U(!1)},onDragOver:a=>{a.preventDefault(),a.stopPropagation()},onDrop:t,onClick:()=>G.current?.click(),children:[e.jsx("input",{ref:G,type:"file",accept:"image/*",multiple:!0,style:{display:"none"},onChange:a=>{a.target.files&&D(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"})]}),B&&e.jsx("div",{className:"idea-creator-upload-error",children:B}),f.length>0&&e.jsx("div",{className:"idea-creator-image-grid",children:f.map(a=>e.jsxs("div",{className:"idea-creator-image-thumb",children:[e.jsx("img",{src:`${J(Q())}/kanban/images/${a.filename||a.path.split("/").pop()}`,alt:a.filename}),e.jsx("button",{className:"idea-creator-image-remove",onClick:()=>W(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:o,onChange:a=>_(a.target.value),placeholder:"https://...",className:"idea-creator-input",onKeyDown:a=>{a.key==="Enter"&&(a.preventDefault(),q())}}),e.jsx("input",{type:"text",value:w,onChange:a=>C(a.target.value),placeholder:"Title (optional)",className:"idea-creator-input",style:{flex:"0 0 140px"},onKeyDown:a=>{a.key==="Enter"&&(a.preventDefault(),q())}}),e.jsx("button",{className:"ideation-btn secondary",onClick:q,disabled:!o.trim(),children:"Add"})]}),b.length>0&&e.jsx("div",{className:"idea-creator-link-list",children:b.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||ie(a.url)}),e.jsx("button",{className:"idea-creator-link-remove",onClick:()=>se(a.id),title:"Remove link",children:"×"})]},a.id))})]}),e.jsxs("div",{className:"idea-creator-actions",children:[e.jsx("button",{className:"ideation-config-cancel",onClick:g,children:"Cancel"}),e.jsx("button",{className:"ideation-config-generate",onClick:te,disabled:!m.trim()||R,children:z?"Save Changes":"Create Idea"})]})]})})}function de(s){switch(s){case"critical":return"urgent";case"high":return"high";case"medium":return"medium";case"low":return"low";default:return"medium"}}function me(s){const n=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(s);return n?`${parseInt(n[1],16)}, ${parseInt(n[2],16)}, ${parseInt(n[3],16)}`:"255, 255, 255"}const Z={trivial:"#4ade80",small:"#60a5fa",medium:"#fbbf24",large:"#f97316",complex:"#f87171"},Y={low:"#888",medium:"#fbbf24",high:"#f97316",critical:"#f87171"};function ee(s){const n=J(Q()),h=s.filename||s.path.split("/").pop()||"";return`${n}/kanban/images/${h}`}function ae(s){try{return new URL(s).hostname}catch{return s}}function he({idea:s,onDismiss:n,onDelete:h,onConvertToTask:g,onEdit:m}){const[c,v]=i.useState(!1),[j,l]=i.useState(null),u=$.find(r=>r.id===s.category),x=s.images&&s.images.length>0,N=s.links&&s.links.length>0,M=c?s.images:s.images?.slice(0,3)||[];return e.jsxs("div",{className:`idea-card ${s.convertedToTaskId?"converted":""} ${c?"expanded":""}`,children:[e.jsxs("div",{className:"idea-card-header",children:[e.jsx("span",{className:"idea-card-category-icon",title:u?.label,children:u?.icon||"?"}),e.jsxs("h4",{className:"idea-card-title",onClick:()=>v(!c),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:c?"▾":"▸"})]}),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&&m&&e.jsx("button",{className:"idea-card-action-btn edit",onClick:m,title:"Edit idea",children:e.jsx("svg",{viewBox:"0 0 16 16",width:"14",height:"14",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e.jsx("path",{d:"M11.5 1.5l3 3-9 9H2.5v-3l9-9z"})})}),h&&e.jsx("button",{className:"idea-card-action-btn delete",onClick:h,title:"Delete idea permanently",children:e.jsx("svg",{viewBox:"0 0 16 16",width:"14",height:"14",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"})})}),e.jsx("button",{className:"idea-card-action-btn dismiss",onClick:n,title:"Dismiss idea (hide)",children:e.jsx("svg",{viewBox:"0 0 16 16",width:"14",height:"14",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:e.jsx("path",{d:"M4 4l8 8M12 4l-8 8"})})})]})})]}),e.jsx("p",{className:`idea-card-description ${c?"expanded":""}`,children:s.description}),x&&e.jsxs("div",{className:`idea-card-images ${c?"expanded":""}`,children:[M.map(r=>e.jsx("div",{className:`idea-card-thumbnail ${c?"large":""}`,onClick:()=>l(ee(r)),title:r.filename,children:e.jsx("img",{src:ee(r),alt:r.filename})},r.id)),!c&&s.images.length>3&&e.jsxs("span",{className:"idea-card-images-overflow",onClick:()=>v(!0),children:["+",s.images.length-3]})]}),N&&e.jsx("div",{className:"idea-card-links",children:s.links.map(r=>e.jsxs("a",{className:`idea-card-link-pill ${c?"expanded":""}`,href:r.url,target:"_blank",rel:"noopener noreferrer",title:r.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"})}),c?r.title?`${r.title} — ${ae(r.url)}`:r.url:r.title||ae(r.url)]},r.id))}),c&&e.jsxs("div",{className:"idea-card-meta",children:[e.jsx("span",{className:"idea-card-meta-category",style:{color:u?.color},children:u?.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:Z[s.effort]||"#888",color:Z[s.effort]||"#888"},children:s.effort}),e.jsxs("span",{className:"idea-badge impact",style:{borderColor:Y[s.impact]||"#888",color:Y[s.impact]||"#888"},children:[s.impact," impact"]})]}),!s.convertedToTaskId&&e.jsx("button",{className:"idea-card-create-task-btn",onClick:g,title:"Create Kanban task from this idea",children:"+ Create Task"})]}),j&&e.jsx("div",{className:"idea-card-image-preview",onClick:()=>l(null),children:e.jsx("img",{src:j,alt:"Preview"})})]})}function ge({projectId:s,projectPath:n,generateIdeas:h,dismissIdea:g,deleteIdea:m,deleteIdeationSession:c,createKanbanTask:v,convertIdeaToTask:j,createManualIdea:l,updateManualIdea:u}){const[x,N]=i.useState(!1),[M,r]=i.useState(!1),[f,k]=i.useState(),b=O(t=>t.selectedCategory),L=O(t=>t.setSelectedCategory),o=O(t=>s?t.sessions.get(s):void 0),_=O(t=>t.getIdeasByCategory),w=s?_(s,b):[],C=o?.status==="generating"||o?.status==="streaming",R=o?.status==="error",T=o?.ideas.filter(t=>!t.dismissed).length||0,B=i.useCallback(async t=>{!s||!n||(N(!1),await h(s,n,t))},[s,n,h]),S=i.useCallback(async()=>{if(!s||!n)return;const t=o?.enabledCategories;await h(s,n,t,!0)},[s,n,o,h]),X=i.useCallback(async t=>{s&&await g(t,s)},[s,g]),U=i.useCallback(async t=>{!s||!m||await m(t,s)},[s,m]),A=i.useCallback(async t=>{if(!s)return;const y=await v(s,{title:t.title,description:t.description,priority:de(t.impact),columnId:"ideas",tags:[t.category]});y&&(O.getState().updateIdea(s,t.id,{convertedToTaskId:y.id}),j(t.id,s,y.id))},[s,v,j]),G=i.useCallback(async()=>{s&&await c(s)},[s,c]),z=i.useCallback(async t=>{!s||!l||(await l(s,t),r(!1),k(void 0))},[s,l]),P=i.useCallback(async t=>{!s||!f||!u||(await u(f.id,s,t),r(!1),k(void 0))},[s,f,u]),D=i.useCallback(t=>{k(t),r(!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:C&&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:T>0?`${T} ideas found...`:"Analyzing codebase..."})]})}),e.jsxs("div",{className:"ideation-header-actions",children:[l&&e.jsx("button",{className:"ideation-btn secondary",onClick:()=>{k(void 0),r(!0)},title:"Add your own idea",children:"+ New Idea"}),o&&!C&&e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"ideation-btn secondary",onClick:S,title:"Add more ideas to current session",children:"+ Add More"}),e.jsx("button",{className:"ideation-btn secondary",onClick:G,title:"Clear all ideas",children:"Clear"})]}),e.jsx("button",{className:"ideation-btn secondary",onClick:()=>N(!0),title:"Configure categories",disabled:C,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"})]})}),!C&&e.jsx("button",{className:"ideation-btn primary",onClick:()=>N(!0),disabled:!n,title:n?"Generate improvement ideas":"Project path required",children:R?"Retry":o?"Regenerate":"Generate Ideas"})]})]}),R&&o?.error&&e.jsx("div",{className:"ideation-error",children:e.jsxs("span",{children:["Error: ",o.error]})}),o&&o.ideas.length>0&&e.jsxs("div",{className:"ideation-category-tabs",children:[e.jsxs("button",{className:`ideation-category-tab ${b===null?"active":""}`,onClick:()=>L(null),children:["All (",T,")"]}),$.map(t=>{const y=o.ideas.filter(W=>!W.dismissed&&W.category===t.id).length;return y===0?null:e.jsxs("button",{className:`ideation-category-tab ${b===t.id?"active":""}`,onClick:()=>L(t.id),style:{"--tab-color":t.color,"--tab-color-rgb":me(t.color)},children:[t.icon," ",t.label," (",y,")"]},t.id)})]}),e.jsx("div",{className:"ideation-ideas-list",children:w.length>0?w.map(t=>e.jsx(he,{idea:t,onDismiss:()=>X(t.id),onDelete:m?()=>U(t.id):void 0,onConvertToTask:()=>A(t),onEdit:t.isManual&&u?()=>D(t):void 0},t.id)):!C&&!o?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.'})]}):!C&&o&&w.length===0?e.jsxs("div",{className:"ideation-empty-state",children:[e.jsx("span",{className:"ideation-empty-icon",children:b?"🔍":"✅"}),e.jsx("p",{children:b?"No ideas in this category":"No ideas found. Try generating with different categories or add your own."})]}):null}),x&&e.jsx(re,{onGenerate:B,onCancel:()=>N(!1),initialCategories:o?.enabledCategories}),M&&s&&e.jsx(ce,{projectId:s,editingIdea:f,onSave:f?P:z,onCancel:()=>{r(!1),k(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{ge as IdeationPanel};