replit-tools 1.2.35 → 1.2.37
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 +1 -1
- package/scripts/claude-session-manager.sh +119 -40
package/package.json
CHANGED
|
@@ -42,39 +42,52 @@ get_recent_sessions() {
|
|
|
42
42
|
|
|
43
43
|
const sessionData = new Map();
|
|
44
44
|
|
|
45
|
+
const isRealPrompt = (txt) => {
|
|
46
|
+
if (!txt) return false;
|
|
47
|
+
const t = txt.trim();
|
|
48
|
+
if (!t) return false;
|
|
49
|
+
if (/^[✅❌📦🔗⚠️🚀🎉🔧📝]/.test(t)) return false;
|
|
50
|
+
if (/Claude (history|binary|versions) symlink/.test(t)) return false;
|
|
51
|
+
if (t.startsWith('# AGENTS.md')) return false;
|
|
52
|
+
return true;
|
|
53
|
+
};
|
|
54
|
+
|
|
45
55
|
// --- Claude sessions ---
|
|
46
56
|
if (fs.existsSync(historyFile)) {
|
|
47
57
|
const lines = fs.readFileSync(historyFile, 'utf8').trim().split('\n');
|
|
58
|
+
const entries = [];
|
|
48
59
|
for (const line of lines) {
|
|
49
60
|
try {
|
|
50
61
|
const j = JSON.parse(line);
|
|
51
|
-
if (
|
|
52
|
-
const key = 'claude:' + j.sessionId;
|
|
53
|
-
if (!sessionData.has(key)) {
|
|
54
|
-
sessionData.set(key, {
|
|
55
|
-
tool: 'claude',
|
|
56
|
-
id: j.sessionId,
|
|
57
|
-
firstSeen: j.timestamp,
|
|
58
|
-
lastSeen: j.timestamp,
|
|
59
|
-
firstPrompt: j.display || '',
|
|
60
|
-
lastPrompt: j.display || '',
|
|
61
|
-
messageCount: 0
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
const data = sessionData.get(key);
|
|
65
|
-
if (j.timestamp < data.firstSeen) {
|
|
66
|
-
data.firstSeen = j.timestamp;
|
|
67
|
-
data.firstPrompt = j.display || data.firstPrompt;
|
|
68
|
-
}
|
|
69
|
-
if (j.timestamp > data.lastSeen) {
|
|
70
|
-
data.lastSeen = j.timestamp;
|
|
71
|
-
data.lastPrompt = j.display || data.lastPrompt;
|
|
72
|
-
}
|
|
62
|
+
if (j.sessionId && j.timestamp) entries.push(j);
|
|
73
63
|
} catch(e) {}
|
|
74
64
|
}
|
|
65
|
+
entries.sort((a, b) => a.timestamp - b.timestamp);
|
|
66
|
+
for (const j of entries) {
|
|
67
|
+
const key = 'claude:' + j.sessionId;
|
|
68
|
+
if (!sessionData.has(key)) {
|
|
69
|
+
sessionData.set(key, {
|
|
70
|
+
tool: 'claude',
|
|
71
|
+
id: j.sessionId,
|
|
72
|
+
firstSeen: j.timestamp,
|
|
73
|
+
lastSeen: j.timestamp,
|
|
74
|
+
firstPrompt: '',
|
|
75
|
+
lastPrompt: '',
|
|
76
|
+
messageCount: 0
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const data = sessionData.get(key);
|
|
80
|
+
if (j.timestamp < data.firstSeen) data.firstSeen = j.timestamp;
|
|
81
|
+
if (j.timestamp > data.lastSeen) data.lastSeen = j.timestamp;
|
|
82
|
+
if (isRealPrompt(j.display)) {
|
|
83
|
+
if (!data.firstPrompt) data.firstPrompt = j.display;
|
|
84
|
+
data.lastPrompt = j.display;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
75
87
|
|
|
76
|
-
for (const [key, data] of sessionData) {
|
|
88
|
+
for (const [key, data] of Array.from(sessionData)) {
|
|
77
89
|
if (data.tool !== 'claude') continue;
|
|
90
|
+
if (!data.firstPrompt) { sessionData.delete(key); continue; }
|
|
78
91
|
const jsonlPath = path.join(projectsDir, data.id + '.jsonl');
|
|
79
92
|
const agentPath = path.join(projectsDir, 'agent-' + data.id.substring(0,7) + '.jsonl');
|
|
80
93
|
let filePath = fs.existsSync(jsonlPath) ? jsonlPath : (fs.existsSync(agentPath) ? agentPath : null);
|
|
@@ -117,6 +130,22 @@ get_recent_sessions() {
|
|
|
117
130
|
const id = meta.payload.id;
|
|
118
131
|
const firstTs = Date.parse(meta.payload.timestamp || meta.timestamp);
|
|
119
132
|
|
|
133
|
+
const cleanUser = (raw) => {
|
|
134
|
+
if (!raw) return '';
|
|
135
|
+
let t = raw
|
|
136
|
+
.replace(/<environment_context>[\s\S]*?<\/environment_context>/g, '')
|
|
137
|
+
.replace(/<user_instructions>[\s\S]*?<\/user_instructions>/g, '')
|
|
138
|
+
.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, '')
|
|
139
|
+
.replace(/<command-name>[\s\S]*?<\/command-name>/g, '')
|
|
140
|
+
.replace(/<command-message>[\s\S]*?<\/command-message>/g, '')
|
|
141
|
+
.replace(/<command-args>[\s\S]*?<\/command-args>/g, '')
|
|
142
|
+
.replace(/<local-command-stdout>[\s\S]*?<\/local-command-stdout>/g, '')
|
|
143
|
+
.replace(/<local-command-caveat>[\s\S]*?<\/local-command-caveat>/g, '')
|
|
144
|
+
.trim();
|
|
145
|
+
if (t.startsWith('# AGENTS.md')) return '';
|
|
146
|
+
return t;
|
|
147
|
+
};
|
|
148
|
+
|
|
120
149
|
let lastTs = firstTs;
|
|
121
150
|
let firstPrompt = '';
|
|
122
151
|
let lastPrompt = '';
|
|
@@ -126,8 +155,9 @@ get_recent_sessions() {
|
|
|
126
155
|
const j = JSON.parse(ln);
|
|
127
156
|
if (j.timestamp) lastTs = Math.max(lastTs, Date.parse(j.timestamp));
|
|
128
157
|
if (j.type === 'response_item' && j.payload && j.payload.role === 'user' && Array.isArray(j.payload.content)) {
|
|
129
|
-
const
|
|
130
|
-
|
|
158
|
+
const raw = (j.payload.content.find(c => c.type === 'input_text') || {}).text || '';
|
|
159
|
+
const text = cleanUser(raw);
|
|
160
|
+
if (text) {
|
|
131
161
|
if (!firstPrompt) firstPrompt = text;
|
|
132
162
|
lastPrompt = text;
|
|
133
163
|
msgCount++;
|
|
@@ -136,6 +166,9 @@ get_recent_sessions() {
|
|
|
136
166
|
} catch(e) {}
|
|
137
167
|
}
|
|
138
168
|
|
|
169
|
+
// Skip sessions with no real user input (sub-agents, programmatic runs)
|
|
170
|
+
if (msgCount === 0 || !firstPrompt) continue;
|
|
171
|
+
|
|
139
172
|
const stat = fs.statSync(f);
|
|
140
173
|
sessionData.set('codex:' + id, {
|
|
141
174
|
tool: 'codex',
|
|
@@ -293,23 +326,46 @@ get_recent_24h_sessions() {
|
|
|
293
326
|
const cwd = '/home/runner/workspace';
|
|
294
327
|
const sessions = new Map();
|
|
295
328
|
|
|
329
|
+
// Heuristic: skip captured shell output / non-real prompts
|
|
330
|
+
const isRealPrompt = (txt) => {
|
|
331
|
+
if (!txt) return false;
|
|
332
|
+
const t = txt.trim();
|
|
333
|
+
if (!t) return false;
|
|
334
|
+
// Skip messages that are obviously captured shell output
|
|
335
|
+
if (/^[✅❌📦🔗⚠️🚀🎉🔧📝]/.test(t)) return false;
|
|
336
|
+
if (/Claude (history|binary|versions) symlink/.test(t)) return false;
|
|
337
|
+
if (t.startsWith('# AGENTS.md')) return false;
|
|
338
|
+
return true;
|
|
339
|
+
};
|
|
340
|
+
|
|
296
341
|
// Claude
|
|
297
342
|
const historyFile = '${history}';
|
|
298
343
|
if (fs.existsSync(historyFile)) {
|
|
299
344
|
const lines = fs.readFileSync(historyFile, 'utf8').trim().split('\n');
|
|
345
|
+
// Sort by timestamp ascending so we can pick first real prompt per session
|
|
346
|
+
const entries = [];
|
|
300
347
|
for (const line of lines) {
|
|
301
348
|
try {
|
|
302
349
|
const j = JSON.parse(line);
|
|
303
|
-
if (
|
|
304
|
-
const key = 'claude:' + j.sessionId;
|
|
305
|
-
if (!sessions.has(key)) {
|
|
306
|
-
sessions.set(key, { tool: 'claude', id: j.sessionId, firstSeen: j.timestamp, lastSeen: j.timestamp, firstPrompt: j.display || '' });
|
|
307
|
-
}
|
|
308
|
-
const s = sessions.get(key);
|
|
309
|
-
if (j.timestamp < s.firstSeen) { s.firstSeen = j.timestamp; s.firstPrompt = j.display || s.firstPrompt; }
|
|
310
|
-
if (j.timestamp > s.lastSeen) { s.lastSeen = j.timestamp; }
|
|
350
|
+
if (j.sessionId && j.timestamp) entries.push(j);
|
|
311
351
|
} catch(e) {}
|
|
312
352
|
}
|
|
353
|
+
entries.sort((a, b) => a.timestamp - b.timestamp);
|
|
354
|
+
for (const j of entries) {
|
|
355
|
+
const key = 'claude:' + j.sessionId;
|
|
356
|
+
if (!sessions.has(key)) {
|
|
357
|
+
sessions.set(key, { tool: 'claude', id: j.sessionId, firstSeen: j.timestamp, lastSeen: j.timestamp, firstPrompt: '' });
|
|
358
|
+
}
|
|
359
|
+
const s = sessions.get(key);
|
|
360
|
+
if (j.timestamp < s.firstSeen) s.firstSeen = j.timestamp;
|
|
361
|
+
if (j.timestamp > s.lastSeen) s.lastSeen = j.timestamp;
|
|
362
|
+
// Set firstPrompt only on first real user prompt encountered
|
|
363
|
+
if (!s.firstPrompt && isRealPrompt(j.display)) s.firstPrompt = j.display;
|
|
364
|
+
}
|
|
365
|
+
// Drop sessions with no real user prompt
|
|
366
|
+
for (const [key, s] of Array.from(sessions)) {
|
|
367
|
+
if (s.tool === 'claude' && !s.firstPrompt) sessions.delete(key);
|
|
368
|
+
}
|
|
313
369
|
}
|
|
314
370
|
|
|
315
371
|
// Codex
|
|
@@ -338,20 +394,43 @@ get_recent_24h_sessions() {
|
|
|
338
394
|
if (meta.payload.cwd !== cwd) continue;
|
|
339
395
|
const id = meta.payload.id;
|
|
340
396
|
const firstTs = Date.parse(meta.payload.timestamp || meta.timestamp);
|
|
397
|
+
|
|
398
|
+
const cleanUser = (raw) => {
|
|
399
|
+
if (!raw) return '';
|
|
400
|
+
let t = raw
|
|
401
|
+
.replace(/<environment_context>[\s\S]*?<\/environment_context>/g, '')
|
|
402
|
+
.replace(/<user_instructions>[\s\S]*?<\/user_instructions>/g, '')
|
|
403
|
+
.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, '')
|
|
404
|
+
.replace(/<command-name>[\s\S]*?<\/command-name>/g, '')
|
|
405
|
+
.replace(/<command-message>[\s\S]*?<\/command-message>/g, '')
|
|
406
|
+
.replace(/<command-args>[\s\S]*?<\/command-args>/g, '')
|
|
407
|
+
.replace(/<local-command-stdout>[\s\S]*?<\/local-command-stdout>/g, '')
|
|
408
|
+
.replace(/<local-command-caveat>[\s\S]*?<\/local-command-caveat>/g, '')
|
|
409
|
+
.trim();
|
|
410
|
+
if (t.startsWith('# AGENTS.md')) return '';
|
|
411
|
+
return t;
|
|
412
|
+
};
|
|
413
|
+
|
|
341
414
|
let lastTs = firstTs;
|
|
342
415
|
let firstPrompt = '';
|
|
416
|
+
let realMsgCount = 0;
|
|
343
417
|
for (const ln of lns) {
|
|
344
418
|
try {
|
|
345
419
|
const j = JSON.parse(ln);
|
|
346
420
|
if (j.timestamp) lastTs = Math.max(lastTs, Date.parse(j.timestamp));
|
|
347
|
-
if (
|
|
348
|
-
const text = (j.payload.content.find(c => c.type === 'input_text') || {}).text || '';
|
|
349
|
-
if (text
|
|
350
|
-
firstPrompt = text;
|
|
421
|
+
if (j.type === 'response_item' && j.payload && j.payload.role === 'user' && Array.isArray(j.payload.content)) {
|
|
422
|
+
const text = cleanUser((j.payload.content.find(c => c.type === 'input_text') || {}).text || '');
|
|
423
|
+
if (text) {
|
|
424
|
+
if (!firstPrompt) firstPrompt = text;
|
|
425
|
+
realMsgCount++;
|
|
351
426
|
}
|
|
352
427
|
}
|
|
353
428
|
} catch(e) {}
|
|
354
429
|
}
|
|
430
|
+
|
|
431
|
+
// Skip sub-agent / programmatic sessions with no real user prompt
|
|
432
|
+
if (realMsgCount === 0 || !firstPrompt) continue;
|
|
433
|
+
|
|
355
434
|
sessions.set('codex:' + id, { tool: 'codex', id, firstSeen: firstTs, lastSeen: lastTs, firstPrompt });
|
|
356
435
|
} catch(e) {}
|
|
357
436
|
}
|
|
@@ -649,7 +728,7 @@ claude_prompt() {
|
|
|
649
728
|
echo ""
|
|
650
729
|
echo " Starting Codex login..."
|
|
651
730
|
echo ""
|
|
652
|
-
codex login
|
|
731
|
+
codex login --device-auth
|
|
653
732
|
echo ""
|
|
654
733
|
echo " Login complete. Returning to menu..."
|
|
655
734
|
sleep 1
|
|
@@ -675,8 +754,8 @@ alias claude-pick='claude -r --dangerously-skip-permissions'
|
|
|
675
754
|
alias claude-new='claude --dangerously-skip-permissions'
|
|
676
755
|
alias j='claude /login --dangerously-skip-permissions'
|
|
677
756
|
alias claude-login='claude /login --dangerously-skip-permissions'
|
|
678
|
-
alias k='codex login'
|
|
679
|
-
alias codex-login='codex login'
|
|
757
|
+
alias k='codex login --device-auth'
|
|
758
|
+
alias codex-login='codex login --device-auth'
|
|
680
759
|
alias codex-new='codex --dangerously-bypass-approvals-and-sandbox'
|
|
681
760
|
alias codex-resume='codex --dangerously-bypass-approvals-and-sandbox resume'
|
|
682
761
|
|