muuuuse 3.1.1 → 4.0.1
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/src/agents.js +51 -16
- package/src/cli.js +3 -7
- package/src/runtime.js +12 -5
package/package.json
CHANGED
package/src/agents.js
CHANGED
|
@@ -555,8 +555,7 @@ function selectClaudeSessionFile(currentPath, processStartedAtMs, options = {})
|
|
|
555
555
|
return selectSessionCandidatePath(candidates, currentPath, processStartedAtMs);
|
|
556
556
|
}
|
|
557
557
|
|
|
558
|
-
function extractClaudeAssistantText(content
|
|
559
|
-
const flowMode = options.flowMode === true;
|
|
558
|
+
function extractClaudeAssistantText(content) {
|
|
560
559
|
if (!Array.isArray(content)) {
|
|
561
560
|
return "";
|
|
562
561
|
}
|
|
@@ -569,7 +568,23 @@ function extractClaudeAssistantText(content, options = {}) {
|
|
|
569
568
|
if (item.type === "text" && typeof item.text === "string") {
|
|
570
569
|
return [item.text.trim()];
|
|
571
570
|
}
|
|
572
|
-
|
|
571
|
+
return [];
|
|
572
|
+
})
|
|
573
|
+
.filter((text) => text.length > 0)
|
|
574
|
+
.join("\n");
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
function extractClaudeThinkingText(content) {
|
|
578
|
+
if (!Array.isArray(content)) {
|
|
579
|
+
return "";
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
return content
|
|
583
|
+
.flatMap((item) => {
|
|
584
|
+
if (!item || typeof item !== "object") {
|
|
585
|
+
return [];
|
|
586
|
+
}
|
|
587
|
+
if (item.type === "thinking" && typeof item.thinking === "string") {
|
|
573
588
|
return [item.thinking.trim()];
|
|
574
589
|
}
|
|
575
590
|
return [];
|
|
@@ -586,28 +601,46 @@ function parseClaudeAssistantLine(line, options = {}) {
|
|
|
586
601
|
return null;
|
|
587
602
|
}
|
|
588
603
|
|
|
589
|
-
|
|
604
|
+
const isFinal = entry.message?.stop_reason === "end_turn";
|
|
605
|
+
if (!flowMode && !isFinal) {
|
|
590
606
|
return null;
|
|
591
607
|
}
|
|
592
608
|
|
|
593
|
-
const
|
|
594
|
-
|
|
595
|
-
|
|
609
|
+
const id = entry.uuid || entry.message.id || hashText(line);
|
|
610
|
+
const timestamp = entry.timestamp || new Date().toISOString();
|
|
611
|
+
const results = [];
|
|
612
|
+
|
|
613
|
+
if (flowMode) {
|
|
614
|
+
const thinking = sanitizeRelayText(extractClaudeThinkingText(entry.message.content));
|
|
615
|
+
if (thinking) {
|
|
616
|
+
results.push({
|
|
617
|
+
id: `${id}-thinking`,
|
|
618
|
+
text: thinking,
|
|
619
|
+
phase: "commentary",
|
|
620
|
+
timestamp,
|
|
621
|
+
});
|
|
622
|
+
}
|
|
596
623
|
}
|
|
597
624
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
625
|
+
const text = sanitizeRelayText(extractClaudeAssistantText(entry.message.content));
|
|
626
|
+
if (text) {
|
|
627
|
+
results.push({
|
|
628
|
+
id,
|
|
629
|
+
text,
|
|
630
|
+
phase: isFinal ? "final_answer" : "commentary",
|
|
631
|
+
timestamp,
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
return results.length > 0 ? results : null;
|
|
604
636
|
} catch {
|
|
605
637
|
return null;
|
|
606
638
|
}
|
|
607
639
|
}
|
|
608
640
|
|
|
609
641
|
function parseClaudeFinalLine(line) {
|
|
610
|
-
|
|
642
|
+
const results = parseClaudeAssistantLine(line, { flowMode: false });
|
|
643
|
+
return Array.isArray(results) ? results[0] || null : results;
|
|
611
644
|
}
|
|
612
645
|
|
|
613
646
|
function readClaudeAnswers(filePath, offset, sinceMs = null, options = {}) {
|
|
@@ -616,8 +649,10 @@ function readClaudeAnswers(filePath, offset, sinceMs = null, options = {}) {
|
|
|
616
649
|
.split("\n")
|
|
617
650
|
.map((line) => line.trim())
|
|
618
651
|
.filter((line) => line.length > 0)
|
|
619
|
-
.
|
|
620
|
-
|
|
652
|
+
.flatMap((line) => {
|
|
653
|
+
const result = parseClaudeAssistantLine(line, options);
|
|
654
|
+
return Array.isArray(result) ? result : result ? [result] : [];
|
|
655
|
+
})
|
|
621
656
|
.filter((entry) => isAnswerNewEnough(entry, sinceMs));
|
|
622
657
|
|
|
623
658
|
return { nextOffset, answers };
|
package/src/cli.js
CHANGED
|
@@ -56,11 +56,10 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
56
56
|
|
|
57
57
|
const seatId = normalizeSeatId(command);
|
|
58
58
|
if (seatId) {
|
|
59
|
-
const { flowMode,
|
|
59
|
+
const { flowMode, continueTargets } = parseSeatOptions(command, argv.slice(1));
|
|
60
60
|
const seat = new ArmedSeat({
|
|
61
61
|
cwd: process.cwd(),
|
|
62
62
|
continueTargets,
|
|
63
|
-
continueSeatId,
|
|
64
63
|
flowMode,
|
|
65
64
|
seatId,
|
|
66
65
|
});
|
|
@@ -125,10 +124,9 @@ function renderLinkTargets(seat) {
|
|
|
125
124
|
function parseSeatOptions(command, args) {
|
|
126
125
|
const seatId = normalizeSeatId(command);
|
|
127
126
|
let flowMode = "off";
|
|
128
|
-
let continueSeatId = null;
|
|
129
127
|
let continueTargets = [];
|
|
130
128
|
if (args.length === 0) {
|
|
131
|
-
return { flowMode,
|
|
129
|
+
return { flowMode, continueTargets };
|
|
132
130
|
}
|
|
133
131
|
|
|
134
132
|
if (String(args[0] || "").trim().toLowerCase() === "link") {
|
|
@@ -136,7 +134,6 @@ function parseSeatOptions(command, args) {
|
|
|
136
134
|
if (parsedLinks.consumed === args.length - 1 && parsedLinks.consumed > 0) {
|
|
137
135
|
return {
|
|
138
136
|
flowMode: parsedLinks.flowMode,
|
|
139
|
-
continueSeatId: parsedLinks.continueTargets[0]?.targetSeatId || null,
|
|
140
137
|
continueTargets: parsedLinks.continueTargets,
|
|
141
138
|
};
|
|
142
139
|
}
|
|
@@ -153,13 +150,12 @@ function parseSeatOptions(command, args) {
|
|
|
153
150
|
const continueToken = String(args[index] || "").trim().toLowerCase();
|
|
154
151
|
const targetSeatId = normalizeSeatId(args[index + 1]);
|
|
155
152
|
if (continueToken === "continue" && targetSeatId) {
|
|
156
|
-
continueSeatId = targetSeatId;
|
|
157
153
|
continueTargets = [{ targetSeatId, flowMode }];
|
|
158
154
|
index += 2;
|
|
159
155
|
}
|
|
160
156
|
|
|
161
157
|
if (index === args.length) {
|
|
162
|
-
return { flowMode,
|
|
158
|
+
return { flowMode, continueTargets };
|
|
163
159
|
}
|
|
164
160
|
}
|
|
165
161
|
|
package/src/runtime.js
CHANGED
|
@@ -650,7 +650,6 @@ class ArmedSeat {
|
|
|
650
650
|
),
|
|
651
651
|
this.flowMode
|
|
652
652
|
);
|
|
653
|
-
this.continueSeatId = this.continueTargets[0]?.targetSeatId || normalizeContinueSeatId(options.continueSeatId);
|
|
654
653
|
this.cwd = normalizeWorkingPath(options.cwd);
|
|
655
654
|
if (this.continueTargets.some((target) => target.targetSeatId === this.seatId)) {
|
|
656
655
|
throw new Error(`\`muuuuse ${this.seatId}\` cannot continue to itself.`);
|
|
@@ -728,7 +727,6 @@ class ArmedSeat {
|
|
|
728
727
|
partnerSeatId: this.partnerSeatId,
|
|
729
728
|
sessionName: this.sessionName,
|
|
730
729
|
flowMode: this.flowMode,
|
|
731
|
-
continueSeatId: this.continueSeatId,
|
|
732
730
|
continueTargets: this.continueTargets,
|
|
733
731
|
cwd: this.cwd,
|
|
734
732
|
pid: process.pid,
|
|
@@ -745,7 +743,6 @@ class ArmedSeat {
|
|
|
745
743
|
partnerSeatId: this.partnerSeatId,
|
|
746
744
|
sessionName: this.sessionName,
|
|
747
745
|
flowMode: this.flowMode,
|
|
748
|
-
continueSeatId: this.continueSeatId,
|
|
749
746
|
continueTargets: this.continueTargets,
|
|
750
747
|
cwd: this.cwd,
|
|
751
748
|
pid: process.pid,
|
|
@@ -1525,10 +1522,10 @@ class ArmedSeat {
|
|
|
1525
1522
|
buildAnswerSignaturePayload(this.sessionName, this.trustState.challenge, signedEntry),
|
|
1526
1523
|
this.identity.privateKey
|
|
1527
1524
|
);
|
|
1525
|
+
|
|
1528
1526
|
appendJsonl(this.paths.eventsPath, signedEntry);
|
|
1529
1527
|
this.forwardContinuation(signedEntry);
|
|
1530
1528
|
this.rememberEmittedAnswer(answerKey);
|
|
1531
|
-
|
|
1532
1529
|
this.log(`[${this.seatId}] ${previewText(payload)}`);
|
|
1533
1530
|
}
|
|
1534
1531
|
|
|
@@ -1538,6 +1535,10 @@ class ArmedSeat {
|
|
|
1538
1535
|
}
|
|
1539
1536
|
|
|
1540
1537
|
for (const targetEntry of this.continueTargets) {
|
|
1538
|
+
if (!shouldAcceptInboundEntry(targetEntry.flowMode, signedEntry)) {
|
|
1539
|
+
continue;
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1541
1542
|
const target = this.findContinuationTarget(targetEntry.targetSeatId);
|
|
1542
1543
|
if (!target) {
|
|
1543
1544
|
this.log(`[${this.seatId}] continue ${targetEntry.targetSeatId} unavailable`);
|
|
@@ -1706,7 +1707,6 @@ function buildSeatReport(sessionName, seatId) {
|
|
|
1706
1707
|
partnerSeatId: status?.partnerSeatId || meta?.partnerSeatId || getPartnerSeatId(seatId),
|
|
1707
1708
|
state: wrapperLive ? status?.state || "running" : "orphaned_child",
|
|
1708
1709
|
flowMode: status?.flowMode || meta?.flowMode || "off",
|
|
1709
|
-
continueSeatId: status?.continueSeatId || meta?.continueSeatId || null,
|
|
1710
1710
|
continueTargets: normalizeContinueTargets(
|
|
1711
1711
|
status?.continueTargets || meta?.continueTargets || (
|
|
1712
1712
|
(status?.continueSeatId || meta?.continueSeatId)
|
|
@@ -1790,6 +1790,13 @@ function stopAllSessions() {
|
|
|
1790
1790
|
signalPid(seat.wrapperPid, "SIGTERM");
|
|
1791
1791
|
}
|
|
1792
1792
|
}
|
|
1793
|
+
|
|
1794
|
+
// Clean up session directory so stale data doesn't bleed into next session.
|
|
1795
|
+
try {
|
|
1796
|
+
fs.rmSync(sessionPaths.dir, { recursive: true, force: true });
|
|
1797
|
+
} catch {
|
|
1798
|
+
// Best-effort cleanup.
|
|
1799
|
+
}
|
|
1793
1800
|
}
|
|
1794
1801
|
|
|
1795
1802
|
return {
|