create-claude-kanban 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claude-kanban",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "description": "Scaffold a multi-agent kanban system for Claude Code projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -767,6 +767,152 @@
767
767
  .report-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 250; }
768
768
  .report-overlay.open { display: block; }
769
769
 
770
+ /* ── Task Detail Popup ── */
771
+ .td-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.55); z-index: 400; backdrop-filter: blur(3px); }
772
+ .td-overlay.open { display: block; }
773
+ .td-popup {
774
+ display: none;
775
+ position: fixed;
776
+ top: 50%; left: 50%;
777
+ transform: translate(-50%, -50%);
778
+ width: 680px;
779
+ max-width: 94vw;
780
+ max-height: 85vh;
781
+ background: var(--s1);
782
+ border: 1px solid var(--b1);
783
+ border-radius: 6px;
784
+ z-index: 410;
785
+ flex-direction: column;
786
+ box-shadow: 0 20px 60px rgba(0,0,0,0.5);
787
+ }
788
+ .td-popup.open { display: flex; }
789
+ .td-header {
790
+ padding: 16px 20px;
791
+ border-bottom: 1px solid var(--b1);
792
+ display: flex;
793
+ align-items: flex-start;
794
+ gap: 12px;
795
+ flex-shrink: 0;
796
+ }
797
+ .td-header-left { flex: 1; min-width: 0; }
798
+ .td-header h2 { font-size: 15px; font-weight: 700; color: var(--t1); line-height: 1.4; margin: 0; }
799
+ .td-header .td-id {
800
+ font-size: 11px;
801
+ font-family: 'JetBrains Mono', monospace;
802
+ color: var(--t4);
803
+ margin-bottom: 4px;
804
+ }
805
+ .td-close {
806
+ background: none;
807
+ border: 1px solid var(--b1);
808
+ border-radius: var(--r);
809
+ color: var(--t3);
810
+ cursor: pointer;
811
+ font-size: 14px;
812
+ width: 28px; height: 28px;
813
+ display: flex; align-items: center; justify-content: center;
814
+ flex-shrink: 0;
815
+ }
816
+ .td-close:hover { color: var(--t1); background: var(--s3); }
817
+ .td-meta {
818
+ padding: 10px 20px;
819
+ border-bottom: 1px solid var(--b1);
820
+ display: flex;
821
+ gap: 12px;
822
+ flex-wrap: wrap;
823
+ flex-shrink: 0;
824
+ }
825
+ .td-tag {
826
+ font-size: 10px;
827
+ font-family: 'JetBrains Mono', monospace;
828
+ padding: 3px 8px;
829
+ border-radius: 2px;
830
+ font-weight: 600;
831
+ letter-spacing: 0.03em;
832
+ }
833
+ .td-tag-status { background: var(--s3); color: var(--t2); }
834
+ .td-tag-status[data-s="in_progress"] { background: rgba(59,130,246,0.15); color: var(--ac); }
835
+ .td-tag-status[data-s="completed"] { background: rgba(34,197,94,0.15); color: var(--gn); }
836
+ .td-tag-status[data-s="in_review"] { background: rgba(139,92,246,0.15); color: var(--vl); }
837
+ .td-tag-priority { background: var(--s3); color: var(--t3); }
838
+ .td-tag-priority[data-p="high"] { background: rgba(239,68,68,0.12); color: var(--rd); }
839
+ .td-tag-agent { background: var(--s3); color: var(--t3); }
840
+ .td-tag-project { border: 1px solid var(--b1); color: var(--t3); }
841
+ .td-body {
842
+ flex: 1;
843
+ overflow-y: auto;
844
+ padding: 20px;
845
+ }
846
+ .td-body .td-md { font-size: 13px; line-height: 1.75; color: var(--t2); }
847
+ .td-body .td-md h1 { font-size: 18px; font-weight: 700; margin: 24px 0 10px; color: var(--t1); border-bottom: 1px solid var(--b1); padding-bottom: 8px; }
848
+ .td-body .td-md h2 { font-size: 15px; font-weight: 600; margin: 20px 0 8px; color: var(--t1); }
849
+ .td-body .td-md h3 { font-size: 13px; font-weight: 600; margin: 16px 0 6px; color: var(--t2); }
850
+ .td-body .td-md h4 { font-size: 12px; font-weight: 600; margin: 14px 0 4px; color: var(--t2); }
851
+ .td-body .td-md p { margin: 8px 0; }
852
+ .td-body .td-md ul, .td-body .td-md ol { margin: 6px 0; padding-left: 20px; }
853
+ .td-body .td-md li { margin: 3px 0; }
854
+ .td-body .td-md code { background: var(--bg); padding: 1px 6px; border-radius: 2px; font-size: 12px; border: 1px solid var(--b1); color: var(--t1); }
855
+ .td-body .td-md pre { background: var(--bg); padding: 14px; border-radius: var(--r); border: 1px solid var(--b1); overflow-x: auto; margin: 10px 0; }
856
+ .td-body .td-md pre code { background: none; border: none; padding: 0; }
857
+ .td-body .td-md table { width: 100%; border-collapse: collapse; margin: 10px 0; font-size: 12px; }
858
+ .td-body .td-md th { background: var(--s2); text-align: left; padding: 8px 12px; border: 1px solid var(--b1); font-weight: 600; color: var(--t1); }
859
+ .td-body .td-md td { padding: 6px 12px; border: 1px solid var(--b1); }
860
+ .td-body .td-md tr:hover td { background: var(--s2); }
861
+ .td-body .td-md blockquote { border-left: 2px solid var(--b2); padding: 4px 14px; margin: 10px 0; color: var(--t3); }
862
+ .td-body .td-md strong { color: var(--t1); }
863
+ .td-body .td-md hr { border: none; border-top: 1px solid var(--b1); margin: 20px 0; }
864
+ .td-body .td-section {
865
+ margin-bottom: 16px;
866
+ }
867
+ .td-body .td-section-label {
868
+ font-size: 10px;
869
+ font-weight: 600;
870
+ color: var(--t4);
871
+ letter-spacing: 0.04em;
872
+ text-transform: uppercase;
873
+ margin-bottom: 6px;
874
+ }
875
+ .td-body .td-empty { text-align: center; padding: 40px; color: var(--t4); font-size: 12px; }
876
+ .td-footer {
877
+ padding: 12px 20px;
878
+ border-top: 1px solid var(--b1);
879
+ display: flex;
880
+ gap: 8px;
881
+ justify-content: flex-end;
882
+ flex-shrink: 0;
883
+ }
884
+ .td-footer .btn { font-size: 12px; padding: 6px 14px; }
885
+ .td-deps {
886
+ display: flex;
887
+ flex-wrap: wrap;
888
+ gap: 4px;
889
+ margin-top: 4px;
890
+ }
891
+ .td-dep-chip {
892
+ font-size: 10px;
893
+ font-family: 'JetBrains Mono', monospace;
894
+ padding: 2px 8px;
895
+ border-radius: 2px;
896
+ background: var(--s3);
897
+ color: var(--ac);
898
+ cursor: pointer;
899
+ }
900
+ .td-dep-chip:hover { background: var(--s2); text-decoration: underline; }
901
+ .td-active-form {
902
+ font-size: 11px;
903
+ color: var(--am);
904
+ font-style: italic;
905
+ margin-top: 4px;
906
+ }
907
+ .td-ref {
908
+ color: var(--ac);
909
+ cursor: pointer;
910
+ font-weight: 600;
911
+ font-family: 'JetBrains Mono', monospace;
912
+ font-size: 0.92em;
913
+ }
914
+ .td-ref:hover { text-decoration: underline; }
915
+
770
916
  /* Report button on card */
771
917
  .card .report-btn {
772
918
  font-size: 9px;
@@ -1454,6 +1600,26 @@
1454
1600
  </div>
1455
1601
  </div>
1456
1602
 
1603
+ <div class="td-overlay" id="tdOverlay" onclick="closeTaskDetail()"></div>
1604
+ <div class="td-popup" id="tdPopup">
1605
+ <div class="td-header">
1606
+ <div class="td-header-left">
1607
+ <div class="td-id" id="tdId"></div>
1608
+ <h2 id="tdTitle"></h2>
1609
+ </div>
1610
+ <button class="td-close" onclick="closeTaskDetail()">&times;</button>
1611
+ </div>
1612
+ <div class="td-meta" id="tdMeta"></div>
1613
+ <div class="td-body" id="tdBody">
1614
+ <div class="td-empty">Loading...</div>
1615
+ </div>
1616
+ <div class="td-footer">
1617
+ <button class="btn btn-ghost" onclick="closeTaskDetail()">Close</button>
1618
+ <button class="btn btn-ghost" id="tdEditBtn" onclick="closeTaskDetail();editTask(tdCurrentId)">Edit</button>
1619
+ <button class="btn btn-primary" id="tdBoardBtn" onclick="closeTaskDetail();scrollToCard(tdCurrentId)">Board</button>
1620
+ </div>
1621
+ </div>
1622
+
1457
1623
  <div class="activity-overlay" id="actOverlay" onclick="closeActivity()"></div>
1458
1624
  <div class="activity-panel" id="actPanel">
1459
1625
  <div class="ap-header">
@@ -2037,7 +2203,7 @@ document.addEventListener("keydown",function(e){
2037
2203
  if(e.ctrlKey&&e.shiftKey&&(e.key==="K"||e.key==="k")){e.preventDefault();stopExecution();return;}
2038
2204
  if(e.target.closest("input,select,textarea"))return;
2039
2205
  if(e.key==="n"||e.key==="N")openModal();
2040
- if(e.key==="Escape"){closeModal();closeReport();closeActivity();closeChat();}
2206
+ if(e.key==="Escape"){if(tdCurrentId){closeTaskDetail();return;}closeModal();closeReport();closeActivity();closeChat();}
2041
2207
  if(e.key==="a"||e.key==="A")toggleActivity();
2042
2208
  if(e.key==="c"||e.key==="C")toggleChat();
2043
2209
  });
@@ -2080,6 +2246,102 @@ function closeReport(){
2080
2246
  document.getElementById("reportOverlay").classList.remove("open");
2081
2247
  }
2082
2248
 
2249
+ // ── Task Detail Popup ──
2250
+ var tdCurrentId=null;
2251
+ function openTaskDetail(id){
2252
+ tdCurrentId=String(id);
2253
+ var t=allTasks.find(function(x){return String(x.id)===tdCurrentId;});
2254
+ if(!t){
2255
+ // Task not in current view — fetch all and search
2256
+ fetch("/api/tasks").then(function(r){return r.json();}).then(function(tasks){
2257
+ var found=tasks.find(function(x){return String(x.id)===tdCurrentId;});
2258
+ if(found)renderTaskDetail(found);
2259
+ else showTaskDetailError(tdCurrentId);
2260
+ }).catch(function(){showTaskDetailError(tdCurrentId);});
2261
+ }else{
2262
+ renderTaskDetail(t);
2263
+ }
2264
+ document.getElementById("tdOverlay").classList.add("open");
2265
+ document.getElementById("tdPopup").classList.add("open");
2266
+ }
2267
+ function showTaskDetailError(id){
2268
+ document.getElementById("tdId").textContent="#"+id;
2269
+ document.getElementById("tdTitle").textContent="Task not found";
2270
+ document.getElementById("tdMeta").innerHTML="";
2271
+ document.getElementById("tdBody").innerHTML='<div class="td-empty">Task #'+esc(id)+' not found</div>';
2272
+ }
2273
+ function renderTaskDetail(t){
2274
+ document.getElementById("tdId").textContent="#"+t.id+(t.project?" \u00B7 "+t.project:"");
2275
+ document.getElementById("tdTitle").textContent=t.subject||"Untitled";
2276
+ // Meta tags
2277
+ var statusLabel={pending:"TO DO",in_progress:"IN PROGRESS",in_review:"IN REVIEW",completed:"DONE"};
2278
+ var priorityLabel={high:"P0 URGENT",medium:"P1 NORMAL",low:"P2 LOW"};
2279
+ var meta='<span class="td-tag td-tag-status" data-s="'+(t.status||"pending")+'">'+(statusLabel[t.status]||"PENDING")+'</span>';
2280
+ if(t.priority)meta+='<span class="td-tag td-tag-priority" data-p="'+t.priority+'">'+(priorityLabel[t.priority]||t.priority.toUpperCase())+'</span>';
2281
+ if(t.agent)meta+='<span class="td-tag td-tag-agent">'+esc(t.agent)+'</span>';
2282
+ if(t.project)meta+='<span class="td-tag td-tag-project">'+esc(t.project)+'</span>';
2283
+ document.getElementById("tdMeta").innerHTML=meta;
2284
+ // Body
2285
+ var html='';
2286
+ // Description
2287
+ if(t.description){
2288
+ html+='<div class="td-section"><div class="td-section-label">Description</div>';
2289
+ html+='<div class="td-md">'+renderMarkdown(t.description)+'</div>';
2290
+ html+='</div>';
2291
+ }
2292
+ // Active form
2293
+ if(t.activeForm&&t.status==="in_progress"){
2294
+ html+='<div class="td-active-form">'+esc(t.activeForm)+'</div>';
2295
+ }
2296
+ // Dependencies
2297
+ if(t.blockedBy&&t.blockedBy.length>0){
2298
+ html+='<div class="td-section"><div class="td-section-label">Blocked By</div><div class="td-deps">';
2299
+ for(var i=0;i<t.blockedBy.length;i++){
2300
+ html+='<span class="td-dep-chip" onclick="openTaskDetail(\''+esc(String(t.blockedBy[i]))+'\')">'+esc("#"+t.blockedBy[i])+'</span>';
2301
+ }
2302
+ html+='</div></div>';
2303
+ }
2304
+ // Subtasks
2305
+ if(t.subtasks&&t.subtasks.length>0){
2306
+ html+='<div class="td-section"><div class="td-section-label">Subtasks</div><div class="td-deps">';
2307
+ for(var i=0;i<t.subtasks.length;i++){
2308
+ html+='<span class="td-dep-chip" onclick="openTaskDetail(\''+esc(String(t.subtasks[i]))+'\')">'+esc("#"+t.subtasks[i])+'</span>';
2309
+ }
2310
+ html+='</div></div>';
2311
+ }
2312
+ // Report summary
2313
+ if(t.reportSummary){
2314
+ html+='<div class="td-section"><div class="td-section-label">Report Summary</div>';
2315
+ html+='<div class="td-md">'+renderMarkdown(t.reportSummary)+'</div>';
2316
+ html+='</div>';
2317
+ }
2318
+ // Report path
2319
+ if(t.reportPath){
2320
+ html+='<div class="td-section"><div class="td-section-label">Report File</div>';
2321
+ html+='<div style="font-size:11px;font-family:JetBrains Mono,monospace;color:var(--t3)">'+esc(t.reportPath)+'</div>';
2322
+ html+='</div>';
2323
+ }
2324
+ // Timestamps
2325
+ var times=[];
2326
+ if(t.createdAt)times.push("Created: "+new Date(t.createdAt).toLocaleString("ko-KR"));
2327
+ if(t.startedAt)times.push("Started: "+new Date(t.startedAt).toLocaleString("ko-KR"));
2328
+ if(t.completedAt)times.push("Completed: "+new Date(t.completedAt).toLocaleString("ko-KR"));
2329
+ if(times.length>0){
2330
+ html+='<div class="td-section"><div class="td-section-label">Timeline</div>';
2331
+ html+='<div style="font-size:11px;font-family:JetBrains Mono,monospace;color:var(--t4);line-height:1.8">'+times.join("<br>")+'</div>';
2332
+ html+='</div>';
2333
+ }
2334
+ if(!html)html='<div class="td-empty">No details available</div>';
2335
+ document.getElementById("tdBody").innerHTML=html;
2336
+ // Footer buttons
2337
+ document.getElementById("tdEditBtn").style.display=t._editable!==false?"inline-flex":"none";
2338
+ }
2339
+ function closeTaskDetail(){
2340
+ document.getElementById("tdOverlay").classList.remove("open");
2341
+ document.getElementById("tdPopup").classList.remove("open");
2342
+ tdCurrentId=null;
2343
+ }
2344
+
2083
2345
  function renderMarkdown(md){
2084
2346
  var html=esc(md);
2085
2347
  html=html.replace(/```(\w*)\n([\s\S]*?)```/g,function(m,lang,code){return '<pre><code>'+code+'</code></pre>';});
@@ -2112,6 +2374,8 @@ function renderMarkdown(md){
2112
2374
  html=html.replace(/<\/(h[1-4]|ul|ol|pre|table|blockquote)><\/p>/g,'</$1>');
2113
2375
  html=html.replace(/<hr><\/p>/g,'<hr>');
2114
2376
  html=html.replace(/<p><\/p>/g,'');
2377
+ // Task #N references → clickable links (avoid matching inside tags/code)
2378
+ html=html.replace(/(?<![&\w])#(\d{1,5})(?![\w<])/g,'<span class="td-ref" onclick="openTaskDetail(\'$1\')">#$1</span>');
2115
2379
  return html;
2116
2380
  }
2117
2381
 
@@ -2344,20 +2608,23 @@ function stripActionBlocks(text){
2344
2608
  return (text||"").replace(/:::action\n[\s\S]*?\n:::/g,"").trim();
2345
2609
  }
2346
2610
  function renderActionResult(ar){
2611
+ var link=function(id){return '<span class="action-link" onclick="openTaskDetail(\''+esc(String(id))+'\')">\uC0C1\uC138</span>';};
2347
2612
  if(ar.action==="task_create"&&ar.ok){
2348
- return '<div class="chat-action-result"><span class="action-icon" style="color:var(--gn)">+</span><span class="action-text">\uD0DC\uC2A4\uD06C #'+esc(ar.task.id)+' \uC0DD\uC131: '+esc(ar.task.subject)+'</span><span class="action-link" onclick="scrollToCard(\''+esc(ar.task.id)+'\')">\uBCF4\uAE30</span></div>';
2613
+ return '<div class="chat-action-result"><span class="action-icon" style="color:var(--gn)">+</span><span class="action-text">\uD0DC\uC2A4\uD06C #'+esc(ar.task.id)+' \uC0DD\uC131: '+esc(ar.task.subject)+'</span>'+link(ar.task.id)+'</div>';
2349
2614
  }
2350
2615
  if(ar.action==="task_update"&&ar.ok&&ar.task){
2351
- return '<div class="chat-action-result"><span class="action-icon" style="color:var(--am)">~</span><span class="action-text">\uD0DC\uC2A4\uD06C #'+esc(ar.task.id)+' \uC218\uC815\uB428</span></div>';
2616
+ return '<div class="chat-action-result"><span class="action-icon" style="color:var(--am)">~</span><span class="action-text">\uD0DC\uC2A4\uD06C #'+esc(ar.task.id)+' \uC218\uC815\uB428</span>'+link(ar.task.id)+'</div>';
2352
2617
  }
2353
2618
  if(ar.action==="task_delete"&&ar.ok){
2354
2619
  return '<div class="chat-action-result"><span class="action-icon" style="color:var(--rd)">-</span><span class="action-text">\uD0DC\uC2A4\uD06C #'+esc(ar.id)+' \uC0AD\uC81C\uB428</span></div>';
2355
2620
  }
2356
2621
  if(ar.action==="task_execute"&&ar.ok){
2357
- return '<div class="chat-action-result"><span class="action-icon" style="color:var(--am)">\u25B6</span><span class="action-text">\uD0DC\uC2A4\uD06C #'+esc(ar.id)+' \uC2E4\uD589 \uC2DC\uC791</span></div>';
2622
+ return '<div class="chat-action-result"><span class="action-icon" style="color:var(--am)">\u25B6</span><span class="action-text">\uD0DC\uC2A4\uD06C #'+esc(ar.id)+' \uC2E4\uD589 \uC2DC\uC791</span>'+link(ar.id)+'</div>';
2358
2623
  }
2359
2624
  if(ar.action==="task_execute_batch"&&ar.ok){
2360
- return '<div class="chat-action-result"><span class="action-icon" style="color:var(--am)">\u25B6\u25B6</span><span class="action-text">\uD0DC\uC2A4\uD06C '+(ar.ids||[]).map(function(id){return"#"+id;}).join(", ")+' \uC77C\uAD04 \uC2E4\uD589</span></div>';
2625
+ var ids=ar.ids||[];
2626
+ var chips=ids.map(function(id){return '<span class="action-link" onclick="openTaskDetail(\''+esc(String(id))+'\')" style="margin-left:0">#'+esc(String(id))+'</span>';}).join(" ");
2627
+ return '<div class="chat-action-result"><span class="action-icon" style="color:var(--am)">\u25B6\u25B6</span><span class="action-text">\uC77C\uAD04 \uC2E4\uD589</span>'+chips+'</div>';
2361
2628
  }
2362
2629
  return "";
2363
2630
  }