@basou/core 0.13.1 → 0.14.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/dist/index.d.ts +1 -0
- package/dist/index.js +62 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -2081,6 +2081,21 @@ function parseDiffNameStatus(raw) {
|
|
|
2081
2081
|
// src/handoff/handoff-renderer.ts
|
|
2082
2082
|
import { join as join13 } from "path";
|
|
2083
2083
|
|
|
2084
|
+
// src/lib/recency.ts
|
|
2085
|
+
var DECISION_TRAILING_ACTIVITY_GAP_MS = 60 * 60 * 1e3;
|
|
2086
|
+
function isTrailingStale(latestActivityAt, recordedAt) {
|
|
2087
|
+
if (latestActivityAt === null) return false;
|
|
2088
|
+
return Date.parse(latestActivityAt) - Date.parse(recordedAt) > DECISION_TRAILING_ACTIVITY_GAP_MS;
|
|
2089
|
+
}
|
|
2090
|
+
function pickLatestSubstantiveEntry(entries) {
|
|
2091
|
+
return [...entries].sort((a, b) => {
|
|
2092
|
+
const aSubstantive = (a.session.session.related_files?.length ?? 0) > 0 ? 1 : 0;
|
|
2093
|
+
const bSubstantive = (b.session.session.related_files?.length ?? 0) > 0 ? 1 : 0;
|
|
2094
|
+
if (aSubstantive !== bSubstantive) return bSubstantive - aSubstantive;
|
|
2095
|
+
return Date.parse(b.session.session.started_at) - Date.parse(a.session.session.started_at);
|
|
2096
|
+
})[0];
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2084
2099
|
// src/storage/tasks.ts
|
|
2085
2100
|
import { createHash as createHash2 } from "crypto";
|
|
2086
2101
|
import { mkdir as mkdir3, readdir as readdir4, readFile as readFile7, rename as rename2, stat as stat3, unlink as unlink3 } from "fs/promises";
|
|
@@ -3799,12 +3814,21 @@ async function renderHandoff(input) {
|
|
|
3799
3814
|
const decisions = [];
|
|
3800
3815
|
const tasksCreated = [];
|
|
3801
3816
|
const tasksStatusChanged = [];
|
|
3817
|
+
let latestActivityAt = null;
|
|
3818
|
+
const noteActivity = (iso) => {
|
|
3819
|
+
if (latestActivityAt === null || Date.parse(iso) > Date.parse(latestActivityAt)) {
|
|
3820
|
+
latestActivityAt = iso;
|
|
3821
|
+
}
|
|
3822
|
+
};
|
|
3802
3823
|
for (const entry of entries) {
|
|
3803
3824
|
const sessionDir = join13(input.paths.sessions, entry.sessionId);
|
|
3825
|
+
const counted = entry.session.session.status !== "archived";
|
|
3826
|
+
if (counted) noteActivity(entry.session.session.ended_at ?? entry.session.session.started_at);
|
|
3804
3827
|
try {
|
|
3805
3828
|
for await (const ev of replayEvents(sessionDir, {
|
|
3806
3829
|
onWarning: (w) => input.onWarning?.(w, entry.sessionId)
|
|
3807
3830
|
})) {
|
|
3831
|
+
if (counted) noteActivity(ev.occurred_at);
|
|
3808
3832
|
if (ev.type === "decision_recorded") {
|
|
3809
3833
|
decisions.push({
|
|
3810
3834
|
decisionId: ev.decision_id,
|
|
@@ -3864,9 +3888,7 @@ async function renderHandoff(input) {
|
|
|
3864
3888
|
const liveEntries = entries.filter(
|
|
3865
3889
|
(e) => e.session.session.status !== "archived" && e.session.session.source.kind !== "import"
|
|
3866
3890
|
);
|
|
3867
|
-
const latestSession =
|
|
3868
|
-
(a, b) => Date.parse(b.session.session.started_at) - Date.parse(a.session.session.started_at)
|
|
3869
|
-
)[0];
|
|
3891
|
+
const latestSession = pickLatestSubstantiveEntry(liveEntries);
|
|
3870
3892
|
const latestFiles = latestSession?.session.session.related_files ?? [];
|
|
3871
3893
|
const sortedFiles = [...new Set(latestFiles)].sort();
|
|
3872
3894
|
const displayedFiles = sortedFiles.slice(0, limit);
|
|
@@ -3880,6 +3902,7 @@ async function renderHandoff(input) {
|
|
|
3880
3902
|
sessionRange,
|
|
3881
3903
|
sessionCount: entries.length,
|
|
3882
3904
|
latestSession,
|
|
3905
|
+
latestActivityAt,
|
|
3883
3906
|
decisions,
|
|
3884
3907
|
pendingApprovalsCount,
|
|
3885
3908
|
suspectCount,
|
|
@@ -3952,6 +3975,16 @@ function formatHandoffBody(args) {
|
|
|
3952
3975
|
} else {
|
|
3953
3976
|
const last = args.decisions[args.decisions.length - 1];
|
|
3954
3977
|
lines.push(`- ${last.title} [${shortIdWithPrefix(last.decisionId)}]`);
|
|
3978
|
+
if (args.latestActivityAt !== null && isTrailingStale(args.latestActivityAt, last.occurredAt)) {
|
|
3979
|
+
lines.push(
|
|
3980
|
+
" - \u6CE8: \u6700\u7D42\u6D3B\u52D5\u306F\u3053\u306E\u5224\u65AD\u3088\u308A\u5F8C\u3067\u3059\u3002\u4F1A\u8A71\u3067\u65E2\u306B\u89E3\u6C7A\u6E08\u307F\u306E\u53EF\u80FD\u6027\u304C\u3042\u308B\u305F\u3081\u3001\u518D\u958B\u524D\u306B\u7D99\u7D9A\u70B9\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044(\u4F1A\u8A71\u3067\u306E\u610F\u601D\u6C7A\u5B9A\u306F\u81EA\u52D5\u8A18\u9332\u3055\u308C\u307E\u305B\u3093\u3002`basou decision capture` \u3067\u8A18\u9332\u3067\u304D\u307E\u3059)\u3002"
|
|
3981
|
+
);
|
|
3982
|
+
}
|
|
3983
|
+
if (args.latestSession !== void 0 && last.sessionId !== args.latestSession.sessionId) {
|
|
3984
|
+
lines.push(
|
|
3985
|
+
` - \u6CE8: \u3053\u306E\u5224\u65AD\u306F\u6700\u7D42 session \u3068\u306F\u5225\u306E session [${shortIdWithPrefix(last.sessionId)}] \u306E\u3082\u306E\u3067\u3059\u3002`
|
|
3986
|
+
);
|
|
3987
|
+
}
|
|
3955
3988
|
lines.push("");
|
|
3956
3989
|
lines.push(`(${args.decisions.length} decisions total \u2014 see decisions.md)`);
|
|
3957
3990
|
}
|
|
@@ -4305,7 +4338,6 @@ function hasErrorCode3(error) {
|
|
|
4305
4338
|
}
|
|
4306
4339
|
|
|
4307
4340
|
// src/orientation/orientation-renderer.ts
|
|
4308
|
-
var DECISION_TRAILING_ACTIVITY_GAP_MS = 60 * 60 * 1e3;
|
|
4309
4341
|
async function summarizeOrientation(input) {
|
|
4310
4342
|
const limit = input.relatedFilesLimit ?? 10;
|
|
4311
4343
|
const now = new Date(input.nowIso);
|
|
@@ -4333,7 +4365,8 @@ async function summarizeOrientation(input) {
|
|
|
4333
4365
|
decisions.push({
|
|
4334
4366
|
decisionId: ev.decision_id,
|
|
4335
4367
|
title: ev.title,
|
|
4336
|
-
occurredAt: ev.occurred_at
|
|
4368
|
+
occurredAt: ev.occurred_at,
|
|
4369
|
+
sessionId: entry.sessionId
|
|
4337
4370
|
});
|
|
4338
4371
|
}
|
|
4339
4372
|
if (counted && ev.type === "note_added" && ev.kind === "next_step") {
|
|
@@ -4386,9 +4419,7 @@ async function summarizeOrientation(input) {
|
|
|
4386
4419
|
const liveEntries = entries.filter(
|
|
4387
4420
|
(e) => e.session.session.status !== "archived" && e.session.session.source.kind !== "import"
|
|
4388
4421
|
);
|
|
4389
|
-
const latestEntry =
|
|
4390
|
-
(a, b) => Date.parse(b.session.session.started_at) - Date.parse(a.session.session.started_at)
|
|
4391
|
-
)[0];
|
|
4422
|
+
const latestEntry = pickLatestSubstantiveEntry(liveEntries);
|
|
4392
4423
|
const latestSession = latestEntry !== void 0 ? {
|
|
4393
4424
|
sessionId: latestEntry.sessionId,
|
|
4394
4425
|
label: latestEntry.session.session.label ?? null,
|
|
@@ -4474,21 +4505,25 @@ function formatOrientationBody(summary, opts) {
|
|
|
4474
4505
|
lines.push("- \u6700\u7D42 session: (no live sessions)");
|
|
4475
4506
|
}
|
|
4476
4507
|
if (summary.latestDecision !== null) {
|
|
4477
|
-
const
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
);
|
|
4508
|
+
const dec = summary.latestDecision;
|
|
4509
|
+
const decAge = relativeAgeJa(dec.occurredAt, now);
|
|
4510
|
+
lines.push(`- \u76F4\u8FD1\u306E\u5224\u65AD: ${dec.title} [${shortId(dec.decisionId)}] (${decAge})`);
|
|
4481
4511
|
const activityAt = summary.freshness.latestActivityAt;
|
|
4482
|
-
if (activityAt !== null &&
|
|
4512
|
+
if (activityAt !== null && isTrailingStale(activityAt, dec.occurredAt)) {
|
|
4513
|
+
lines.push(
|
|
4514
|
+
` - \u6CE8: \u3053\u308C\u306F\u6700\u5F8C\u306B\u300C\u8A18\u9332\u3055\u308C\u305F\u300D\u5224\u65AD\u3067\u3059\u3002\u6700\u7D42\u6D3B\u52D5 (${relativeAgeJa(activityAt, now)}) \u306F\u3053\u308C\u3088\u308A\u5F8C\u306E\u305F\u3081\u3001\u73FE\u5728\u306E\u65B9\u91DD\u304C\u53CD\u6620\u3055\u308C\u3066\u3044\u306A\u3044\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059(\u4F1A\u8A71\u3067\u306E\u610F\u601D\u6C7A\u5B9A\u306F\u81EA\u52D5\u8A18\u9332\u3055\u308C\u307E\u305B\u3093\u3002\`basou decision capture\` \u3067\u3053\u306E session \u306E\u5224\u65AD\u3092\u8A18\u9332\u3067\u304D\u307E\u3059)\u3002`
|
|
4515
|
+
);
|
|
4516
|
+
}
|
|
4517
|
+
if (summary.latestSession !== null && dec.sessionId !== summary.latestSession.sessionId) {
|
|
4483
4518
|
lines.push(
|
|
4484
|
-
` - \u6CE8: \u3053\
|
|
4519
|
+
` - \u6CE8: \u3053\u306E\u5224\u65AD\u306F\u6700\u7D42 session \u3068\u306F\u5225\u306E session [${shortId(dec.sessionId)}] \u306E\u3082\u306E\u3067\u3059\u3002`
|
|
4485
4520
|
);
|
|
4486
4521
|
}
|
|
4487
4522
|
if (summary.decisionCount > 1) {
|
|
4488
4523
|
lines.push(` - ${summary.decisionCount} decisions total \u2014 see decisions.md`);
|
|
4489
4524
|
}
|
|
4490
4525
|
} else {
|
|
4491
|
-
lines.push("- \u76F4\u8FD1\u306E\u5224\u65AD: (no decisions recorded yet)");
|
|
4526
|
+
lines.push("- \u76F4\u8FD1\u306E\u5224\u65AD: (no decisions recorded yet; capture with `basou decision capture`)");
|
|
4492
4527
|
}
|
|
4493
4528
|
if (summary.relatedFiles.displayed.length > 0) {
|
|
4494
4529
|
const shown = summary.relatedFiles.displayed.join(", ");
|
|
@@ -4539,7 +4574,7 @@ function formatOrientationBody(summary, opts) {
|
|
|
4539
4574
|
`- \u6B21\u306E\u8D77\u70B9 (\u8A18\u9332\u6E08\u307F, ${noteAge}): ${noteSummary(summary.latestNote.body)} [session ${shortId(summary.latestNote.sessionId)}]`
|
|
4540
4575
|
);
|
|
4541
4576
|
const activityAt = summary.freshness.latestActivityAt;
|
|
4542
|
-
if (activityAt !== null &&
|
|
4577
|
+
if (activityAt !== null && isTrailingStale(activityAt, summary.latestNote.occurredAt)) {
|
|
4543
4578
|
lines.push(
|
|
4544
4579
|
` - \u6CE8: \u3053\u306E\u8D77\u70B9\u306E\u8A18\u9332\u5F8C (\u6700\u7D42\u6D3B\u52D5 ${relativeAgeJa(activityAt, now)}) \u3082\u4F5C\u696D\u304C\u7D9A\u3044\u3066\u3044\u307E\u3059\u3002\u518D\u958B\u70B9\u304C\u53E4\u3044\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002`
|
|
4545
4580
|
);
|
|
@@ -4549,9 +4584,17 @@ function formatOrientationBody(summary, opts) {
|
|
|
4549
4584
|
lines.push(`- ${t.title} [${shortId(t.id)}]`);
|
|
4550
4585
|
}
|
|
4551
4586
|
if (summary.latestNote === null && summary.plannedTasks.length === 0) {
|
|
4552
|
-
|
|
4553
|
-
if (
|
|
4554
|
-
lines.push(
|
|
4587
|
+
const dec = summary.latestDecision;
|
|
4588
|
+
if (dec === null) {
|
|
4589
|
+
lines.push("- (no planned tasks or recorded next step yet)");
|
|
4590
|
+
} else if (isTrailingStale(summary.freshness.latestActivityAt, dec.occurredAt)) {
|
|
4591
|
+
lines.push(
|
|
4592
|
+
"- (no planned tasks or recorded next step \u2014 \u6700\u7D42\u6D3B\u52D5\u306F\u76F4\u8FD1\u306E\u5224\u65AD\u3088\u308A\u5F8C\u3067\u3059\u3002\u7D99\u7D9A\u70B9\u3092\u30E6\u30FC\u30B6\u306B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044)"
|
|
4593
|
+
);
|
|
4594
|
+
lines.push(` - \u53C2\u8003 (\u53E4\u3044\u53EF\u80FD\u6027\u30FB\u65B9\u91DD\u3067\u306F\u306A\u3044): ${dec.title}`);
|
|
4595
|
+
} else {
|
|
4596
|
+
lines.push("- (no planned tasks \u2014 direction is inferred from recent decisions)");
|
|
4597
|
+
lines.push(` - \u76F4\u8FD1\u306E\u5224\u65AD: ${dec.title}`);
|
|
4555
4598
|
}
|
|
4556
4599
|
}
|
|
4557
4600
|
lines.push("");
|