@ouro.bot/cli 0.1.0-alpha.104 → 0.1.0-alpha.105
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/changelog.json +7 -0
- package/dist/mind/obligation-steering.js +15 -6
- package/package.json +1 -1
package/changelog.json
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.105",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Family-wide status answers now dedupe normalized session keys, drop inner/self noise, and ignore stale non-obligation lanes so 'what are you doing?' stays focused on real active work across all live sessions.",
|
|
8
|
+
"BlueBubbles and CLI lanes that refer to the same live thread now collapse into one clean status line, preventing duplicate session bullets when family asks for the full cross-session picture."
|
|
9
|
+
]
|
|
10
|
+
},
|
|
4
11
|
{
|
|
5
12
|
"version": "0.1.0-alpha.104",
|
|
6
13
|
"changes": [
|
|
@@ -7,7 +7,9 @@ exports.renderConcreteStatusGuidance = renderConcreteStatusGuidance;
|
|
|
7
7
|
exports.renderLiveThreadStatusShape = renderLiveThreadStatusShape;
|
|
8
8
|
exports.buildExactStatusReply = buildExactStatusReply;
|
|
9
9
|
exports.renderExactStatusReplyContract = renderExactStatusReplyContract;
|
|
10
|
+
const config_1 = require("../heart/config");
|
|
10
11
|
const runtime_1 = require("../nerves/runtime");
|
|
12
|
+
const RECENT_OTHER_LIVE_SESSION_WINDOW_MS = 60 * 60 * 1000;
|
|
11
13
|
function findActivePersistentObligation(frame) {
|
|
12
14
|
if (!frame)
|
|
13
15
|
return null;
|
|
@@ -26,10 +28,10 @@ function matchesSessionOrigin(frame, origin) {
|
|
|
26
28
|
return Boolean(frame.currentSession
|
|
27
29
|
&& origin.friendId === frame.currentSession.friendId
|
|
28
30
|
&& origin.channel === frame.currentSession.channel
|
|
29
|
-
&& origin.key === frame.currentSession.key);
|
|
31
|
+
&& (0, config_1.sanitizeKey)(origin.key) === (0, config_1.sanitizeKey)(frame.currentSession.key));
|
|
30
32
|
}
|
|
31
33
|
function sessionOriginKey(origin) {
|
|
32
|
-
return `${origin.friendId}/${origin.channel}/${origin.key}`;
|
|
34
|
+
return `${origin.friendId}/${origin.channel}/${(0, config_1.sanitizeKey)(origin.key)}`;
|
|
33
35
|
}
|
|
34
36
|
function codingSessionTimestampMs(session) {
|
|
35
37
|
return Date.parse(session.lastActivityAt ?? session.startedAt);
|
|
@@ -71,13 +73,13 @@ function formatOtherSessionNextAction(obligation, codingSession) {
|
|
|
71
73
|
return "check this session and bring back the latest concrete state";
|
|
72
74
|
}
|
|
73
75
|
function findFriendNameForOrigin(frame, origin) {
|
|
74
|
-
return (frame.friendActivity?.allOtherLiveSessions ?? []).find((entry) => entry
|
|
75
|
-
&& entry.channel === origin.channel
|
|
76
|
-
&& entry.key === origin.key)?.friendName ?? origin.friendId;
|
|
76
|
+
return (frame.friendActivity?.allOtherLiveSessions ?? []).find((entry) => sessionOriginKey(entry) === sessionOriginKey(origin))?.friendName ?? origin.friendId;
|
|
77
77
|
}
|
|
78
78
|
function buildOtherActiveSessionLines(frame) {
|
|
79
79
|
const originMap = new Map();
|
|
80
80
|
for (const session of frame.friendActivity?.allOtherLiveSessions ?? []) {
|
|
81
|
+
if (session.friendId === "self" || session.channel === "inner")
|
|
82
|
+
continue;
|
|
81
83
|
originMap.set(sessionOriginKey(session), {
|
|
82
84
|
friendId: session.friendId,
|
|
83
85
|
channel: session.channel,
|
|
@@ -102,6 +104,12 @@ function buildOtherActiveSessionLines(frame) {
|
|
|
102
104
|
.filter((candidate) => candidate.originSession && sessionOriginKey(candidate.originSession) === sessionOriginKey(origin))
|
|
103
105
|
.sort((left, right) => codingSessionTimestampMs(right) - codingSessionTimestampMs(left))[0] ?? null;
|
|
104
106
|
const liveSession = (frame.friendActivity?.allOtherLiveSessions ?? []).find((candidate) => sessionOriginKey(candidate) === sessionOriginKey(origin)) ?? null;
|
|
107
|
+
const hasFreshSessionActivity = liveSession
|
|
108
|
+
? (Date.now() - liveSession.lastActivityMs) <= RECENT_OTHER_LIVE_SESSION_WINDOW_MS
|
|
109
|
+
: false;
|
|
110
|
+
if (!obligation && !codingSession && !hasFreshSessionActivity) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
105
113
|
const timestampMs = Math.max(liveSession?.lastActivityMs ?? 0, codingSession ? codingSessionTimestampMs(codingSession) : 0, obligation ? obligationTimestampMs(obligation) : 0);
|
|
106
114
|
const activeLane = codingSession
|
|
107
115
|
? formatCodingLaneLabel(codingSession)
|
|
@@ -114,7 +122,8 @@ function buildOtherActiveSessionLines(frame) {
|
|
|
114
122
|
timestampMs,
|
|
115
123
|
line: `- ${friendName}/${origin.channel}/${origin.key}: [${status}] ${activeLane}; artifact ${artifact}; next ${nextAction}`,
|
|
116
124
|
};
|
|
117
|
-
}).
|
|
125
|
+
}).filter((entry) => entry !== null)
|
|
126
|
+
.sort((left, right) => right.timestampMs - left.timestampMs);
|
|
118
127
|
return summaries.length > 0 ? summaries.map((entry) => entry.line) : ["- none"];
|
|
119
128
|
}
|
|
120
129
|
function findStatusObligation(frame) {
|