@gabrywu/knowledge-bank 0.1.2-alpha.227 → 0.1.2-alpha.252

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.
@@ -448,6 +448,29 @@ table tr.selected {
448
448
  color: #475569;
449
449
  }
450
450
 
451
+ .scope-badge {
452
+ display: inline-flex;
453
+ align-items: center;
454
+ padding: 2px 10px;
455
+ border-radius: 9999px;
456
+ font-size: 0.75rem;
457
+ font-weight: 600;
458
+ text-transform: capitalize;
459
+ }
460
+
461
+ .scope-personal {
462
+ background-color: #e0f2fe;
463
+ color: #0277bd;
464
+ }
465
+ .scope-project {
466
+ background-color: #f3e5f5;
467
+ color: #7b1fa2;
468
+ }
469
+ .scope-organization {
470
+ background-color: #fff3e0;
471
+ color: #f57c00;
472
+ }
473
+
451
474
  .badge {
452
475
  display: inline-flex;
453
476
  align-items: center;
@@ -856,6 +879,36 @@ table td.timestamp-column {
856
879
  transition-delay: 0s;
857
880
  }
858
881
 
882
+ /* JSON tooltip styles */
883
+ .json-tooltip {
884
+ min-width: 400px;
885
+ max-width: 600px;
886
+ }
887
+
888
+ .json-preview {
889
+ white-space: pre-wrap;
890
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
891
+ font-size: 0.75rem;
892
+ line-height: 1.4;
893
+ margin: 0;
894
+ max-height: 200px;
895
+ overflow-y: auto;
896
+ background-color: #f8f9fa;
897
+ padding: 8px;
898
+ border-radius: 4px;
899
+ border: 1px solid var(--border-color);
900
+ }
901
+
902
+ .message-json-column {
903
+ font-size: 0.875rem;
904
+ max-width: 300px;
905
+ }
906
+
907
+ .data-json-column {
908
+ font-size: 0.875rem;
909
+ max-width: 250px;
910
+ }
911
+
859
912
  table td {
860
913
  padding: 14px 16px;
861
914
  border-bottom: 1px solid var(--border-color);
@@ -23,8 +23,8 @@ function formatTimestamp(timestamp) {
23
23
  * Common table columns for consistent UI
24
24
  */
25
25
  const TABLE_COLUMNS = {
26
- session: ['id', 'session_id', 'cwd', 'git_branch', 'created_at'],
27
- knowledge_item: ['id', 'title', 'summary', 'knowledge_type', 'status', 'created_at'],
26
+ session: ['id', 'session_id', 'first_user_prompt', 'cwd', 'git_branch', 'created_at'],
27
+ knowledge_item: ['id', 'title', 'summary', 'knowledge_type', 'scope', 'created_at'],
28
28
  session_event: ['id', 'session_id', 'name', 'created_at'],
29
29
  };
30
30
 
@@ -4,7 +4,8 @@
4
4
  <div class="table-grid" style="grid-template-columns: repeat(auto-fill, minmax(240px, 1fr))">
5
5
  <% const sessionCount = (tableInfo.find(t => t.name === 'session') || {}).count || 0; const
6
6
  knowledgeCount = (tableInfo.find(t => t.name === 'knowledge_item') || {}).count || 0; const
7
- eventCount = (tableInfo.find(t => t.name === 'session_event') || {}).count || 0; %>
7
+ eventCount = (tableInfo.find(t => t.name === 'session_event') || {}).count || 0; const
8
+ sessionDetailCount = (tableInfo.find(t => t.name === 'session_detail') || {}).count || 0; %>
8
9
  <div class="repository-card">
9
10
  <div
10
11
  class="repo-card-body text-center"
@@ -57,6 +58,24 @@
57
58
  <a href="/tables/session_event" class="btn-page" style="margin-top: 16px">View All</a>
58
59
  </div>
59
60
  </div>
61
+ <div class="repository-card">
62
+ <div
63
+ class="repo-card-body text-center"
64
+ style="
65
+ display: flex;
66
+ flex-direction: column;
67
+ align-items: center;
68
+ justify-content: center;
69
+ padding: 32px;
70
+ "
71
+ >
72
+ <span class="stat-value" style="font-size: 3rem; color: var(--info-color)"
73
+ ><%= sessionDetailCount %></span
74
+ >
75
+ <span class="stat-label">Session Details</span>
76
+ <a href="/tables/session_detail" class="btn-page" style="margin-top: 16px">View All</a>
77
+ </div>
78
+ </div>
60
79
  </div>
61
80
  </section>
62
81
  </div>
@@ -45,7 +45,7 @@
45
45
  </li>
46
46
  <% const tableLinks = [ { name:
47
47
  'knowledge_item', label: 'Knowledge', icon: '📚' }, { name: 'session', label: 'Sessions',
48
- icon: '💬' }, { name: 'session_event', label: 'Session Events', icon: '🔗' } ];
48
+ icon: '💬' }, { name: 'session_event', label: 'Session Events', icon: '🔗' }, { name: 'session_detail', label: 'Session Details', icon: '📋' } ];
49
49
  tableLinks.forEach(link => { %>
50
50
  <li>
51
51
  <a
@@ -1,11 +1,11 @@
1
- <% const isTimestamp = col === 'created_at' || col.endsWith('_at'); const isStatus = col ===
2
- 'status'; const isType = col === 'knowledge_type'; const isID = col === 'id'; const isSessionID =
1
+ <% const isTimestamp = col === 'created_at' || col.endsWith('_at'); const isScope = col ===
2
+ 'scope'; const isType = col === 'knowledge_type'; const isID = col === 'id'; const isSessionID =
3
3
  col === 'session_id'; const isBranch = col === 'git_branch'; const isCwd = col ===
4
- 'cwd'; const isTitle = col === 'title'; const isSummary = col === 'summary'; const
5
- isEventName = col === 'name' && tableName === 'session_event'; %> <% if (isID) { %>
4
+ 'cwd'; const isFirstUserPrompt = col === 'first_user_prompt'; const isTitle = col === 'title'; const isSummary = col === 'summary'; const
5
+ isEventName = col === 'name' && tableName === 'session_event'; const isMessage = col === 'message' && tableName === 'session_detail'; const isData = col === 'data' && tableName === 'session_detail'; %> <% if (isID) { %>
6
6
  <td class="text-mono font-bold text-xs id-column" style="color: #64748b">#<%= val %></td>
7
- <% } else if (isStatus) { %>
8
- <td><span class="status-badge status-<%= val.toLowerCase() %>"><%= val.toLowerCase() %></span></td>
7
+ <% } else if (isScope) { %>
8
+ <td><span class="scope-badge scope-<%= val.toLowerCase() %>"><%= val.toLowerCase() %></span></td>
9
9
  <% } else if (isType) { %>
10
10
  <td><span class="badge"><%= val %></span></td>
11
11
  <% } else if (isTimestamp) { %>
@@ -29,8 +29,76 @@ isEventName = col === 'name' && tableName === 'session_event'; %> <% if (isID) {
29
29
  </span>
30
30
  <% } else { %> <%= val || '-' %> <% } %>
31
31
  </td>
32
+ <% } else if (isFirstUserPrompt) { %>
33
+ <td class="text-xs first-user-prompt-column">
34
+ <% if (val && val.length > 60) { %>
35
+ <span class="has-tooltip">
36
+ <%= val.substring(0, 60) %>...
37
+ <div class="tooltip-box" onclick="event.stopPropagation()"><%= val %></div>
38
+ </span>
39
+ <% } else { %> <%= val || '-' %> <% } %>
40
+ </td>
32
41
  <% } else if (isEventName) { %>
33
42
  <td class="event-name-column"><%= val || '-' %></td>
43
+ <% } else if (isMessage) { %>
44
+ <td class="message-json-column">
45
+ <% if (val) { %>
46
+ <% let messageContent = ''; %>
47
+ <% try { %>
48
+ <% const messageObj = typeof val === 'string' ? JSON.parse(val) : val; %>
49
+ <% if (messageObj && messageObj.role && messageObj.content) { %>
50
+ <% messageContent = `${messageObj.role}: ${messageObj.content}`; %>
51
+ <% } else { %>
52
+ <% messageContent = JSON.stringify(messageObj, null, 2); %>
53
+ <% } %>
54
+ <% } catch(e) { %>
55
+ <% messageContent = val; %>
56
+ <% } %>
57
+ <% if (messageContent.length > 100) { %>
58
+ <span class="has-tooltip">
59
+ <%= messageContent.substring(0, 100) %>...
60
+ <div class="tooltip-box json-tooltip" onclick="event.stopPropagation()">
61
+ <pre class="json-preview"><%= messageContent %></pre>
62
+ </div>
63
+ </span>
64
+ <% } else { %>
65
+ <%= messageContent %>
66
+ <% } %>
67
+ <% } else { %>
68
+ -
69
+ <% } %>
70
+ </td>
71
+ <% } else if (isData) { %>
72
+ <td class="data-json-column">
73
+ <% if (val) { %>
74
+ <% let dataContent = ''; %>
75
+ <% try { %>
76
+ <% const dataObj = typeof val === 'string' ? JSON.parse(val) : val; %>
77
+ <% if (dataObj && dataObj.type) { %>
78
+ <% dataContent = `type: ${dataObj.type}`; %>
79
+ <% if (dataObj.hookEvent) { %>
80
+ <% dataContent += `, event: ${dataObj.hookEvent}`; %>
81
+ <% } %>
82
+ <% } else { %>
83
+ <% dataContent = JSON.stringify(dataObj, null, 2); %>
84
+ <% } %>
85
+ <% } catch(e) { %>
86
+ <% dataContent = val; %>
87
+ <% } %>
88
+ <% if (dataContent.length > 80) { %>
89
+ <span class="has-tooltip">
90
+ <%= dataContent.substring(0, 80) %>...
91
+ <div class="tooltip-box json-tooltip" onclick="event.stopPropagation()">
92
+ <pre class="json-preview"><%= dataContent %></pre>
93
+ </div>
94
+ </span>
95
+ <% } else { %>
96
+ <%= dataContent %>
97
+ <% } %>
98
+ <% } else { %>
99
+ -
100
+ <% } %>
101
+ </td>
34
102
  <% } else { %>
35
103
  <td
36
104
  class="<%= '' %> <%= (isSummary || (typeof val === 'string' && val.length > 30)) ? 'text-xs' : '' %>"
@@ -1,8 +1,8 @@
1
1
  <div class="details-grid">
2
2
  <% Object.entries(data).forEach(([k, v]) => { %> <% if (v === null || k === 'content') return; %>
3
3
  <%
4
- // Check if field contains JSON data (session_event: input/output, session: env/config)
5
- const isJsonField = ['input', 'output', 'env', 'config'].includes(k) && v && v.trim().startsWith('{');
4
+ // Check if field contains JSON data (session_event: input/output, session: env/config, session_detail: data/message)
5
+ const isJsonField = ['input', 'output', 'env', 'config', 'data', 'message'].includes(k) && v && v.trim().startsWith('{');
6
6
  const isTimestamp = k.endsWith('_at') || k === 'created_at';
7
7
  const val = isTimestamp ? formatTimestamp(v) : v;
8
8
  %>
@@ -0,0 +1 @@
1
+ <span class="scope-badge scope-<%= scope.toLowerCase() %>"><%= scope.toLowerCase() %></span>
@@ -38,17 +38,26 @@
38
38
  </select>
39
39
  </div>
40
40
  <div class="filter-group">
41
- <span class="filter-label">Status</span>
42
- <select id="filter-status" class="filter-select">
43
- <option value="">All Status</option>
44
- <option value="draft">Draft</option>
45
- <option value="suggested">Suggested</option>
46
- <option value="verified">Verified</option>
41
+ <span class="filter-label">Scope</span>
42
+ <select id="filter-scope" class="filter-select">
43
+ <option value="">All Scopes</option>
44
+ <option value="personal">Personal</option>
45
+ <option value="project">Project</option>
46
+ <option value="organization">Organization</option>
47
47
  </select>
48
48
  </div>
49
49
  <% } %>
50
50
 
51
51
  <% if (tableName === 'session') { %>
52
+ <div class="filter-group">
53
+ <span class="filter-label">First User Prompt</span>
54
+ <input
55
+ type="text"
56
+ id="filter-first_user_prompt"
57
+ class="filter-input"
58
+ placeholder="Search First Prompt..."
59
+ />
60
+ </div>
52
61
  <div class="filter-group">
53
62
  <span class="filter-label">Working Directory</span>
54
63
  <input
@@ -81,6 +90,21 @@
81
90
  </div>
82
91
  <% } %>
83
92
 
93
+ <% if (tableName === 'session_detail') { %>
94
+ <div class="filter-group">
95
+ <span class="filter-label">Type</span>
96
+ <select id="filter-type" class="filter-select">
97
+ <option value="">All Types</option>
98
+ <option value="user">User</option>
99
+ <option value="assistant">Assistant</option>
100
+ <option value="system">System</option>
101
+ <option value="progress">Progress</option>
102
+ <option value="queue-operation">Queue Operation</option>
103
+ <option value="summary">Summary</option>
104
+ </select>
105
+ </div>
106
+ <% } %>
107
+
84
108
  <button id="clear-all-filters" class="btn-clear" disabled>Clear All</button>
85
109
  <button id="refresh-table" class="btn-clear" style="margin-left: auto; display: flex; align-items: center; gap: 4px">
86
110
  <span>🔄</span> Refresh
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gabrywu/knowledge-bank",
3
- "version": "0.1.2-alpha.227",
3
+ "version": "0.1.2-alpha.252",
4
4
  "description": "Claude Code plugin for lightweight knowledge management with event-driven architecture",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",