carmoji 0.3.8 → 0.3.9
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/carmoji.js +50 -4
- package/package.json +1 -1
package/carmoji.js
CHANGED
|
@@ -611,9 +611,50 @@ function sessionTokens(payload) {
|
|
|
611
611
|
return state.total;
|
|
612
612
|
}
|
|
613
613
|
|
|
614
|
+
/**
|
|
615
|
+
* The agent's final say for the turn. Hooks never carry assistant text,
|
|
616
|
+
* but Stop hands over transcript_path, and the JSONL's tail holds the
|
|
617
|
+
* reply — Claude records {type:"assistant", message:{content:[{type:
|
|
618
|
+
* "text",text}]}}, Codex rollouts {payload:{type:"agent_message",message}}.
|
|
619
|
+
*/
|
|
620
|
+
function lastAssistantText(payload) {
|
|
621
|
+
try {
|
|
622
|
+
const transcript = payload.transcript_path;
|
|
623
|
+
if (!transcript) return undefined;
|
|
624
|
+
const size = statSync(transcript).size;
|
|
625
|
+
const window = Math.min(size, 256 * 1024);
|
|
626
|
+
if (window === 0) return undefined;
|
|
627
|
+
const fd = openSync(transcript, 'r');
|
|
628
|
+
const buffer = Buffer.alloc(window);
|
|
629
|
+
const bytesRead = readSync(fd, buffer, 0, window, size - window);
|
|
630
|
+
closeSync(fd);
|
|
631
|
+
const lines = buffer.subarray(0, bytesRead).toString('utf8').split('\n');
|
|
632
|
+
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
633
|
+
const line = lines[i];
|
|
634
|
+
if (!line.includes('"assistant"') && !line.includes('agent_message')) continue;
|
|
635
|
+
try {
|
|
636
|
+
const record = JSON.parse(line);
|
|
637
|
+
if (record.type === 'assistant') {
|
|
638
|
+
const texts = (record.message?.content ?? [])
|
|
639
|
+
.filter((block) => block.type === 'text' && block.text)
|
|
640
|
+
.map((block) => block.text);
|
|
641
|
+
if (texts.length) return texts.join(' ');
|
|
642
|
+
}
|
|
643
|
+
if (record.payload?.type === 'agent_message' && record.payload.message) {
|
|
644
|
+
return String(record.payload.message);
|
|
645
|
+
}
|
|
646
|
+
} catch { /* the window's first line may be cut mid-record */ }
|
|
647
|
+
}
|
|
648
|
+
} catch { /* no transcript, no say */ }
|
|
649
|
+
return undefined;
|
|
650
|
+
}
|
|
651
|
+
|
|
614
652
|
const TEST_EVENTS = {
|
|
615
653
|
start: { event: 'session_start' },
|
|
616
|
-
prompt: { event: 'prompt' },
|
|
654
|
+
prompt: { event: 'prompt', detail: 'Fix the corner release bug' },
|
|
655
|
+
say: { event: 'turn_done',
|
|
656
|
+
detail: 'Done — corners now release on yaw alone with an 8s cap, '
|
|
657
|
+
+ 'and cornerEnded bypasses every gate so the lean never sticks.' },
|
|
617
658
|
edit: { event: 'tool_start', tool: 'Edit' },
|
|
618
659
|
read: { event: 'tool_start', tool: 'Read' },
|
|
619
660
|
run: { event: 'tool_start', tool: 'Bash' },
|
|
@@ -1385,15 +1426,20 @@ async function main() {
|
|
|
1385
1426
|
// project directory, so fall back to that.
|
|
1386
1427
|
const cwd = payload.cwd || process.cwd();
|
|
1387
1428
|
if (cwd) message.project = basename(cwd);
|
|
1388
|
-
// A snippet of human-readable context for the phone to show.
|
|
1429
|
+
// A snippet of human-readable context for the phone to show. The
|
|
1430
|
+
// turn's reply gets more room than a toast line — it feeds the
|
|
1431
|
+
// reviewable chat history, not just a caption.
|
|
1389
1432
|
const detail = event.event === 'prompt'
|
|
1390
1433
|
? firstString(payload.prompt, payload.user_prompt, payload.userPrompt,
|
|
1391
1434
|
payload.message, payload.input, payload.text)
|
|
1392
1435
|
: event.event === 'permission'
|
|
1393
1436
|
? firstString(payload.message, payload.detail,
|
|
1394
1437
|
payload.tool_input ? summarizeToolInput(payload) : undefined)
|
|
1395
|
-
:
|
|
1396
|
-
|
|
1438
|
+
: event.event === 'turn_done'
|
|
1439
|
+
? lastAssistantText(payload)
|
|
1440
|
+
: undefined;
|
|
1441
|
+
const detailCap = event.event === 'turn_done' ? 400 : 140;
|
|
1442
|
+
if (detail) message.detail = String(detail).replace(/\s+/g, ' ').slice(0, detailCap);
|
|
1397
1443
|
// Plan-window usage comes from Claude Code's local transcripts;
|
|
1398
1444
|
// recompute only at turn boundaries.
|
|
1399
1445
|
if (source === 'claude') {
|