@ouro.bot/cli 0.1.0-alpha.687 → 0.1.0-alpha.689
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
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
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.689",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Avoid self-mutating npm@latest in the trusted-publishing workflow; verify the npm toolchain floor and use a pinned fallback so publish can complete reliably after merge."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"version": "0.1.0-alpha.688",
|
|
12
|
+
"changes": [
|
|
13
|
+
"Render freshest friend-facing contact timing in protected turn orientation and active-work status so private/self turns cannot mistake stale background timestamps for current contact."
|
|
14
|
+
]
|
|
15
|
+
},
|
|
4
16
|
{
|
|
5
17
|
"version": "0.1.0-alpha.687",
|
|
6
18
|
"changes": [
|
|
@@ -11,6 +11,7 @@ exports.formatActiveWorkChanges = formatActiveWorkChanges;
|
|
|
11
11
|
const runtime_1 = require("../nerves/runtime");
|
|
12
12
|
const state_machine_1 = require("./bridges/state-machine");
|
|
13
13
|
const obligations_1 = require("../arc/obligations");
|
|
14
|
+
const session_activity_1 = require("./session-activity");
|
|
14
15
|
const target_resolution_1 = require("./target-resolution");
|
|
15
16
|
const config_1 = require("./config");
|
|
16
17
|
const RECENT_ACTIVE_OBLIGATION_WINDOW_MS = 60 * 60 * 1000;
|
|
@@ -683,6 +684,12 @@ function formatActiveWorkFrame(frame, options) {
|
|
|
683
684
|
const lines = ["## what i'm holding"];
|
|
684
685
|
lines.push("this is my top-level live world-state right now. private-runtime work, coding lanes, other sessions, and return obligations all belong inside this picture.");
|
|
685
686
|
lines.push("if older checkpoints elsewhere in the transcript disagree with this picture, this picture wins.");
|
|
687
|
+
const friendContactTiming = (0, session_activity_1.describeSessionActivityTiming)((0, session_activity_1.selectFreshestFriendFacingActivity)(frame.friendActivity?.allOtherLiveSessions ?? []), { prefix: "freshest friend-facing contact" });
|
|
688
|
+
if (friendContactTiming) {
|
|
689
|
+
lines.push("");
|
|
690
|
+
lines.push("## contact timing");
|
|
691
|
+
lines.push(`- ${friendContactTiming}`);
|
|
692
|
+
}
|
|
686
693
|
const primaryObligation = findPrimaryOpenObligation(frame);
|
|
687
694
|
const currentSessionObligation = findCurrentSessionOpenObligation(frame);
|
|
688
695
|
const activeLane = formatActiveLane(frame, primaryObligation);
|
|
@@ -34,6 +34,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.listSessionActivity = listSessionActivity;
|
|
37
|
+
exports.selectFreshestFriendFacingActivity = selectFreshestFriendFacingActivity;
|
|
38
|
+
exports.describeSessionActivityTiming = describeSessionActivityTiming;
|
|
37
39
|
exports.findFreshestFriendSession = findFreshestFriendSession;
|
|
38
40
|
const fs = __importStar(require("fs"));
|
|
39
41
|
const path = __importStar(require("path"));
|
|
@@ -44,6 +46,16 @@ const DEFAULT_ACTIVE_THRESHOLD_MS = 24 * 60 * 60 * 1000;
|
|
|
44
46
|
function activityPriority(source) {
|
|
45
47
|
return source === "friend-facing" ? 0 : 1;
|
|
46
48
|
}
|
|
49
|
+
function formatElapsed(ms) {
|
|
50
|
+
const minutes = Math.max(0, Math.floor(ms / 60000));
|
|
51
|
+
if (minutes < 60)
|
|
52
|
+
return `${minutes}m ago`;
|
|
53
|
+
const hours = Math.floor(minutes / 60);
|
|
54
|
+
if (hours < 24)
|
|
55
|
+
return `${hours}h ago`;
|
|
56
|
+
const days = Math.floor(hours / 24);
|
|
57
|
+
return `${days}d ago`;
|
|
58
|
+
}
|
|
47
59
|
function resolveFriendName(friendId, friendsDir, agentName) {
|
|
48
60
|
if (friendId === "self")
|
|
49
61
|
return agentName;
|
|
@@ -183,6 +195,36 @@ function listSessionActivity(query) {
|
|
|
183
195
|
return b.lastActivityMs - a.lastActivityMs;
|
|
184
196
|
});
|
|
185
197
|
}
|
|
198
|
+
function selectFreshestFriendFacingActivity(records) {
|
|
199
|
+
const candidates = records
|
|
200
|
+
.filter((record) => record.friendId !== "self" && record.channel !== "inner" && record.activitySource === "friend-facing")
|
|
201
|
+
.sort((a, b) => b.lastActivityMs - a.lastActivityMs);
|
|
202
|
+
return candidates[0] ?? null;
|
|
203
|
+
}
|
|
204
|
+
function describeSessionActivityTiming(record, options = {}) {
|
|
205
|
+
if (!record)
|
|
206
|
+
return "";
|
|
207
|
+
const nowMs = options.nowMs ?? Date.now();
|
|
208
|
+
const parts = [];
|
|
209
|
+
const inboundMs = record.lastInboundAt ? Date.parse(record.lastInboundAt) : NaN;
|
|
210
|
+
const outboundMs = record.lastOutboundAt ? Date.parse(record.lastOutboundAt) : NaN;
|
|
211
|
+
if (Number.isFinite(inboundMs)) {
|
|
212
|
+
parts.push(`last inbound ${formatElapsed(nowMs - inboundMs)}`);
|
|
213
|
+
}
|
|
214
|
+
if (Number.isFinite(outboundMs)) {
|
|
215
|
+
parts.push(`i last replied ${formatElapsed(nowMs - outboundMs)}`);
|
|
216
|
+
}
|
|
217
|
+
if (record.unansweredInboundCount > 0) {
|
|
218
|
+
const count = record.unansweredInboundCount;
|
|
219
|
+
parts.push(`${count} unanswered inbound message${count === 1 ? "" : "s"}`);
|
|
220
|
+
}
|
|
221
|
+
if (parts.length === 0) {
|
|
222
|
+
parts.push(`last activity ${formatElapsed(nowMs - record.lastActivityMs)}`);
|
|
223
|
+
}
|
|
224
|
+
const label = `${record.friendName}/${record.channel}/${record.key}`;
|
|
225
|
+
const prefix = options.prefix ?? "friend-facing contact";
|
|
226
|
+
return `${prefix}: ${label}; ${parts.join("; ")}`;
|
|
227
|
+
}
|
|
186
228
|
function findFreshestFriendSession(query) {
|
|
187
229
|
const { activeOnly = false, activeThresholdMs = DEFAULT_ACTIVE_THRESHOLD_MS, nowMs, ...rest } = query;
|
|
188
230
|
const currentSession = rest.currentSession ?? null;
|
|
@@ -197,6 +197,7 @@ function buildStartOfTurnPacket(view, opts) {
|
|
|
197
197
|
recoverySentinel: opts?.recoverySentinel,
|
|
198
198
|
resumeHint: buildResumeHint(view, opts?.canonicalObligations ? effectiveObligations : undefined),
|
|
199
199
|
currentSessionTiming: opts?.currentSessionTiming,
|
|
200
|
+
friendContactTiming: opts?.friendContactTiming,
|
|
200
201
|
tempo,
|
|
201
202
|
tokenBudget,
|
|
202
203
|
assembledAt: new Date().toISOString(),
|
|
@@ -238,6 +239,7 @@ function renderStartOfTurnPacket(packet) {
|
|
|
238
239
|
{ label: "arc", content: packet.arcResume ?? "", priority: 7 },
|
|
239
240
|
{ label: "recoverySentinel", content: packet.recoverySentinel ? (0, context_loss_sentinel_1.formatContextLossSentinelText)(packet.recoverySentinel) : "", priority: 7 },
|
|
240
241
|
{ label: "resume", content: packet.resumeHint, priority: 6 },
|
|
242
|
+
{ label: "friendContact", content: packet.friendContactTiming ?? "", priority: 6 },
|
|
241
243
|
{ label: "sessionTiming", content: packet.currentSessionTiming ?? "", priority: 5 },
|
|
242
244
|
{ label: "obligations", content: packet.obligations, priority: 5 },
|
|
243
245
|
{ label: "cares", content: packet.cares, priority: 4 },
|
|
@@ -263,7 +265,7 @@ function renderStartOfTurnPacket(packet) {
|
|
|
263
265
|
if (tokens <= budget.max)
|
|
264
266
|
break;
|
|
265
267
|
// Skip continuity sections — they are protected.
|
|
266
|
-
if (section.label === "resume" || section.label === "arc" || section.label === "recoverySentinel" || section.label === "sessionTiming")
|
|
268
|
+
if (section.label === "resume" || section.label === "arc" || section.label === "recoverySentinel" || section.label === "friendContact" || section.label === "sessionTiming")
|
|
267
269
|
continue;
|
|
268
270
|
// Remove this section entirely
|
|
269
271
|
const idx = sections.findIndex((s) => s.label === section.label);
|
|
@@ -300,6 +302,9 @@ function formatSections(sections) {
|
|
|
300
302
|
case "sessionTiming":
|
|
301
303
|
parts.push(`**Thread timing:** ${section.content}`);
|
|
302
304
|
break;
|
|
305
|
+
case "friendContact":
|
|
306
|
+
parts.push(`**Recent contact:** ${section.content}`);
|
|
307
|
+
break;
|
|
303
308
|
case "obligations":
|
|
304
309
|
parts.push(`**Owed:**\n${section.content}`);
|
|
305
310
|
break;
|
package/dist/senses/pipeline.js
CHANGED
|
@@ -62,6 +62,7 @@ const bundle_state_1 = require("../heart/bundle-state");
|
|
|
62
62
|
const sync_1 = require("../heart/sync");
|
|
63
63
|
const config_1 = require("../heart/config");
|
|
64
64
|
const session_events_1 = require("../heart/session-events");
|
|
65
|
+
const session_activity_1 = require("../heart/session-activity");
|
|
65
66
|
const presence_1 = require("../arc/presence");
|
|
66
67
|
const episodes_1 = require("../arc/episodes");
|
|
67
68
|
const turn_context_1 = require("../heart/turn-context");
|
|
@@ -660,6 +661,7 @@ async function handleInboundTurn(input) {
|
|
|
660
661
|
targetCandidates: ctx.targetCandidates,
|
|
661
662
|
innerReturnObligations: ctx.returnObligations,
|
|
662
663
|
});
|
|
664
|
+
const friendContactTiming = (0, session_activity_1.describeSessionActivityTiming)((0, session_activity_1.selectFreshestFriendFacingActivity)(sessionActivity), { prefix: "freshest friend-facing contact" });
|
|
663
665
|
const delegationDecision = (0, delegation_1.decideDelegation)({
|
|
664
666
|
channel: input.channel,
|
|
665
667
|
ingressTexts: input.continuityIngressTexts ?? [],
|
|
@@ -731,6 +733,7 @@ async function handleInboundTurn(input) {
|
|
|
731
733
|
all: activeWorkFrame.pendingObligations,
|
|
732
734
|
},
|
|
733
735
|
currentSessionTiming,
|
|
736
|
+
friendContactTiming,
|
|
734
737
|
flightRecorderResume: ctx.flightRecorderResume,
|
|
735
738
|
recoverySentinel: ctx.recoverySentinel,
|
|
736
739
|
});
|