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.
- package/dist/server/server/index.js +83 -20
- package/package.json +2 -2
- package/public/assets/ActivityFeedPanel-PnOZd3L5.js +1 -0
- package/public/assets/ActivityFeedPanel-r2bME9T5.css +1 -0
- package/public/assets/IdeationPanel-BOrX5vnk.css +1 -0
- package/public/assets/IdeationPanel-CNGLEeAV.js +1 -0
- package/public/assets/KanbanPanel-BIX9hmXc.js +33 -0
- package/public/assets/KanbanPanel-DcsENGbB.css +1 -0
- package/public/assets/ProjectStatePanel-CQCfvkud.css +1 -0
- package/public/assets/ProjectStatePanel-tVSPb68u.js +1 -0
- package/public/assets/index-Gl2uhE1e.js +21 -0
- package/public/assets/index-iyhXuGiU.css +1 -0
- package/public/index.html +2 -2
- package/public/assets/index-BkULvyno.css +0 -1
- package/public/assets/index-C29btrsG.js +0 -4367
|
@@ -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
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
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
|
|
6345
|
-
|
|
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
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
"description": "
|
|
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};
|