@jjlabsio/claude-crew 0.1.14 → 0.1.15
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/hud/index.mjs +52 -10
- package/package.json +1 -1
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"name": "claude-crew",
|
|
12
12
|
"source": "./",
|
|
13
13
|
"description": "오케스트레이터 + PM, 플래너, 개발, QA, 마케팅 에이전트 팀으로 단일 제품의 개발과 마케팅을 통합 관리",
|
|
14
|
-
"version": "0.1.
|
|
14
|
+
"version": "0.1.15",
|
|
15
15
|
"author": {
|
|
16
16
|
"name": "Jaejin Song",
|
|
17
17
|
"email": "wowlxx28@gmail.com"
|
|
@@ -28,5 +28,5 @@
|
|
|
28
28
|
"category": "workflow"
|
|
29
29
|
}
|
|
30
30
|
],
|
|
31
|
-
"version": "0.1.
|
|
31
|
+
"version": "0.1.15"
|
|
32
32
|
}
|
package/hud/index.mjs
CHANGED
|
@@ -187,6 +187,35 @@ function colorizeContext(pct) {
|
|
|
187
187
|
return `ctx:${color(`${pct}%`)}`;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
// Rate limits (5h / weekly)
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
function getRateLimits(stdin) {
|
|
194
|
+
const rl = stdin?.rate_limits;
|
|
195
|
+
if (!rl) return null;
|
|
196
|
+
const parse = (v) => {
|
|
197
|
+
if (v == null) return null;
|
|
198
|
+
const n = typeof v === 'number' ? v : parseFloat(v);
|
|
199
|
+
return isNaN(n) ? null : Math.round(Math.min(Math.max(n, 0), 100));
|
|
200
|
+
};
|
|
201
|
+
const fiveHour = parse(rl.five_hour?.used_percentage);
|
|
202
|
+
const sevenDay = parse(rl.seven_day?.used_percentage);
|
|
203
|
+
if (fiveHour == null && sevenDay == null) return null;
|
|
204
|
+
return { fiveHour, sevenDay };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function colorizeRateLimits(limits) {
|
|
208
|
+
if (!limits) return null;
|
|
209
|
+
const colorize = (pct) => {
|
|
210
|
+
const color = pct >= 85 ? red : pct >= 70 ? yellow : green;
|
|
211
|
+
return color(`${pct}%`);
|
|
212
|
+
};
|
|
213
|
+
const parts = [];
|
|
214
|
+
if (limits.fiveHour != null) parts.push(`5h:${colorize(limits.fiveHour)}`);
|
|
215
|
+
if (limits.sevenDay != null) parts.push(`weekly:${colorize(limits.sevenDay)}`);
|
|
216
|
+
return parts.join(' ');
|
|
217
|
+
}
|
|
218
|
+
|
|
190
219
|
// ---------------------------------------------------------------------------
|
|
191
220
|
// Transcript parsing (agents + skills)
|
|
192
221
|
// ---------------------------------------------------------------------------
|
|
@@ -261,7 +290,10 @@ function parseTranscript(transcriptPath) {
|
|
|
261
290
|
if (entry.type === 'tool_result') {
|
|
262
291
|
const toolUseId = entry.tool_use_id;
|
|
263
292
|
if (toolUseId && agentMap.has(toolUseId)) {
|
|
264
|
-
agentMap.get(toolUseId)
|
|
293
|
+
const agent = agentMap.get(toolUseId);
|
|
294
|
+
agent.status = 'completed';
|
|
295
|
+
const ts = entry.timestamp || lastTimestamp;
|
|
296
|
+
if (ts) agent.endTime = new Date(ts);
|
|
265
297
|
}
|
|
266
298
|
}
|
|
267
299
|
if (entry.type === 'user') {
|
|
@@ -271,8 +303,10 @@ function parseTranscript(transcriptPath) {
|
|
|
271
303
|
if (block.type === 'tool_result') {
|
|
272
304
|
const toolUseId = block.tool_use_id;
|
|
273
305
|
if (toolUseId && agentMap.has(toolUseId)) {
|
|
274
|
-
agentMap.get(toolUseId)
|
|
275
|
-
|
|
306
|
+
const agent = agentMap.get(toolUseId);
|
|
307
|
+
agent.status = 'completed';
|
|
308
|
+
const ts = entry.timestamp || lastTimestamp;
|
|
309
|
+
if (ts) agent.endTime = new Date(ts);
|
|
276
310
|
}
|
|
277
311
|
}
|
|
278
312
|
}
|
|
@@ -307,14 +341,18 @@ function shortModelName(model) {
|
|
|
307
341
|
// ---------------------------------------------------------------------------
|
|
308
342
|
// Agent duration formatting
|
|
309
343
|
// ---------------------------------------------------------------------------
|
|
310
|
-
function formatAgentDuration(startTime) {
|
|
311
|
-
if (!startTime) return '
|
|
312
|
-
const ms = Date.
|
|
344
|
+
function formatAgentDuration(startTime, endTime) {
|
|
345
|
+
if (!startTime) return '';
|
|
346
|
+
const ms = (endTime ?? new Date()).getTime() - startTime.getTime();
|
|
347
|
+
if (ms < 1000) return '<1s';
|
|
313
348
|
const seconds = Math.floor(ms / 1000);
|
|
314
|
-
const minutes = Math.floor(seconds / 60);
|
|
315
|
-
if (seconds < 10) return '';
|
|
316
349
|
if (seconds < 60) return `${seconds}s`;
|
|
317
|
-
|
|
350
|
+
const minutes = Math.floor(seconds / 60);
|
|
351
|
+
const secs = seconds % 60;
|
|
352
|
+
if (minutes < 60) return `${minutes}m${secs}s`;
|
|
353
|
+
const hours = Math.floor(minutes / 60);
|
|
354
|
+
const mins = minutes % 60;
|
|
355
|
+
return `${hours}h${mins}m`;
|
|
318
356
|
}
|
|
319
357
|
|
|
320
358
|
// ---------------------------------------------------------------------------
|
|
@@ -337,7 +375,7 @@ function renderAgentsMultiLine(agents, maxLines = 5) {
|
|
|
337
375
|
const rawType = a.type.includes(':') ? a.type.split(':').pop() : a.type;
|
|
338
376
|
const name = rawType.padEnd(7);
|
|
339
377
|
const model = shortModelName(a.model).padEnd(8);
|
|
340
|
-
const duration = formatAgentDuration(a.startTime).padStart(
|
|
378
|
+
const duration = formatAgentDuration(a.startTime, a.endTime).padStart(6);
|
|
341
379
|
const desc = a.description.length > 40 ? a.description.slice(0, 37) + '...' : a.description;
|
|
342
380
|
|
|
343
381
|
detailLines.push(
|
|
@@ -441,6 +479,10 @@ async function main() {
|
|
|
441
479
|
|
|
442
480
|
midElements.push(colorizeSession(transcript.sessionStart));
|
|
443
481
|
|
|
482
|
+
const rateLimits = getRateLimits(stdin);
|
|
483
|
+
const rateLimitsStr = colorizeRateLimits(rateLimits);
|
|
484
|
+
if (rateLimitsStr) midElements.push(rateLimitsStr);
|
|
485
|
+
|
|
444
486
|
// --- Output ---
|
|
445
487
|
const outputLines = [];
|
|
446
488
|
outputLines.push(topElements.join(SEPARATOR));
|