@basou/core 0.40.0 → 0.41.0
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 +4 -0
- package/dist/index.js +66 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -2111,6 +2111,8 @@ type ViewStrings = {
|
|
|
2111
2111
|
recentDecisionsLabel: string;
|
|
2112
2112
|
recentNextStepLabel: string;
|
|
2113
2113
|
recentChangedLabel: string;
|
|
2114
|
+
/** Trails the recent-files line when scratch paths were left out of it. */
|
|
2115
|
+
scratchOmitted: (count: number) => string;
|
|
2114
2116
|
trackCloseInstruction: string;
|
|
2115
2117
|
nextStepRecordedLabel: (age: string) => string;
|
|
2116
2118
|
noteStaleNote: (activityAge: string) => string;
|
|
@@ -4328,6 +4330,8 @@ type OrientationSummary = {
|
|
|
4328
4330
|
displayed: string[];
|
|
4329
4331
|
overflow: number;
|
|
4330
4332
|
outOfRoot: string[];
|
|
4333
|
+
/** Scratch paths left out of `displayed` (see `isTransientToolPath`). */
|
|
4334
|
+
omitted: number;
|
|
4331
4335
|
};
|
|
4332
4336
|
/** Tasks whose status is `planned` or `in_progress`. */
|
|
4333
4337
|
inFlightTasks: InFlightTask[];
|
package/dist/index.js
CHANGED
|
@@ -2098,6 +2098,7 @@ var EN = {
|
|
|
2098
2098
|
recentDecisionsLabel: "Decisions",
|
|
2099
2099
|
recentNextStepLabel: "Next step",
|
|
2100
2100
|
recentChangedLabel: "Changed",
|
|
2101
|
+
scratchOmitted: (count) => `(+${count} scratch omitted)`,
|
|
2101
2102
|
trackCloseInstruction: "When finished, close it with `basou decision void <decision_id>`. It stays listed here every time until closed.",
|
|
2102
2103
|
nextStepRecordedLabel: (age) => `Next step (recorded, ${age})`,
|
|
2103
2104
|
noteStaleNote: (age) => `Note: work continued after this was recorded (latest activity ${age}), so this starting point may be stale.`,
|
|
@@ -2193,6 +2194,7 @@ var JA = {
|
|
|
2193
2194
|
recentDecisionsLabel: "\u5224\u65AD",
|
|
2194
2195
|
recentNextStepLabel: "\u6B21\u306E\u8D77\u70B9",
|
|
2195
2196
|
recentChangedLabel: "\u5909\u66F4",
|
|
2197
|
+
scratchOmitted: (count) => `(\u4F5C\u696D\u7528\u4E00\u6642\u30D5\u30A1\u30A4\u30EB ${count} \u4EF6\u306F\u9664\u5916)`,
|
|
2196
2198
|
trackCloseInstruction: "\u5B8C\u4E86\u3057\u305F\u3089 `basou decision void <decision_id>` \u3067\u9589\u3058\u3066\u304F\u3060\u3055\u3044\u3002\u9589\u3058\u308B\u307E\u3067\u6BCE\u56DE\u3053\u3053\u306B\u8868\u793A\u3055\u308C\u307E\u3059\u3002",
|
|
2197
2199
|
nextStepRecordedLabel: (age) => `\u6B21\u306E\u8D77\u70B9 (\u8A18\u9332\u6E08\u307F, ${age})`,
|
|
2198
2200
|
noteStaleNote: (age) => `\u6CE8: \u3053\u306E\u8D77\u70B9\u306E\u8A18\u9332\u5F8C (\u6700\u7D42\u6D3B\u52D5 ${age}) \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`,
|
|
@@ -2533,8 +2535,8 @@ async function isStaleLock(lockPath) {
|
|
|
2533
2535
|
}
|
|
2534
2536
|
}
|
|
2535
2537
|
function lockfilePath(paths, scope, resourceId) {
|
|
2536
|
-
const
|
|
2537
|
-
const ulid2 =
|
|
2538
|
+
const sep2 = resourceId.indexOf("_");
|
|
2539
|
+
const ulid2 = sep2 >= 0 ? resourceId.slice(sep2 + 1) : resourceId;
|
|
2538
2540
|
return join3(paths.locks, `${scope}_${ulid2}.lock`);
|
|
2539
2541
|
}
|
|
2540
2542
|
|
|
@@ -3597,6 +3599,29 @@ function pickLatestSubstantiveEntry(entries) {
|
|
|
3597
3599
|
})[0];
|
|
3598
3600
|
}
|
|
3599
3601
|
|
|
3602
|
+
// src/lib/transient-paths.ts
|
|
3603
|
+
import { tmpdir } from "os";
|
|
3604
|
+
import { normalize, sep } from "path";
|
|
3605
|
+
var TEMP_ROOTS = ["/tmp", "/var/tmp"];
|
|
3606
|
+
var MIN_ENCODED_DASHES = 3;
|
|
3607
|
+
function isEncodedWorkingDirectory(segment) {
|
|
3608
|
+
return segment.startsWith("-") && segment.split("-").length - 1 >= MIN_ENCODED_DASHES;
|
|
3609
|
+
}
|
|
3610
|
+
function withPrivateAlias(root) {
|
|
3611
|
+
const normalized = normalize(root);
|
|
3612
|
+
if (normalized.startsWith(`${sep}private${sep}`)) {
|
|
3613
|
+
return [normalized, normalized.slice(`${sep}private`.length)];
|
|
3614
|
+
}
|
|
3615
|
+
return [normalized, `${sep}private${normalized}`];
|
|
3616
|
+
}
|
|
3617
|
+
function isTransientToolPath(filePath, temp = tmpdir()) {
|
|
3618
|
+
const candidate = normalize(filePath);
|
|
3619
|
+
if (!candidate.startsWith(sep)) return false;
|
|
3620
|
+
const root = [...TEMP_ROOTS, temp].flatMap(withPrivateAlias).find((r) => candidate === r || candidate.startsWith(r + sep));
|
|
3621
|
+
if (root === void 0) return false;
|
|
3622
|
+
return candidate.slice(root.length).split(sep).some(isEncodedWorkingDirectory);
|
|
3623
|
+
}
|
|
3624
|
+
|
|
3600
3625
|
// src/storage/tasks.ts
|
|
3601
3626
|
import { createHash as createHash2 } from "crypto";
|
|
3602
3627
|
import { mkdir as mkdir3, readdir as readdir4, readFile as readFile7, rename as rename2, stat as stat3, unlink as unlink3 } from "fs/promises";
|
|
@@ -5416,7 +5441,9 @@ async function renderHandoff(input) {
|
|
|
5416
5441
|
(e) => e.session.session.status !== "archived" && e.session.session.source.kind !== "import"
|
|
5417
5442
|
);
|
|
5418
5443
|
const latestSession = pickLatestSubstantiveEntry(liveEntries);
|
|
5419
|
-
const latestFiles = latestSession?.session.session.related_files ?? []
|
|
5444
|
+
const latestFiles = (latestSession?.session.session.related_files ?? []).filter(
|
|
5445
|
+
(file) => !isTransientToolPath(file)
|
|
5446
|
+
);
|
|
5420
5447
|
const sortedFiles = [...new Set(latestFiles)].sort();
|
|
5421
5448
|
const displayedFiles = sortedFiles.slice(0, limit);
|
|
5422
5449
|
const overflow = Math.max(0, sortedFiles.length - limit);
|
|
@@ -5634,9 +5661,9 @@ function shortHandoffId(sessionId) {
|
|
|
5634
5661
|
return sessionId.slice(0, 10);
|
|
5635
5662
|
}
|
|
5636
5663
|
function shortIdWithPrefix(id) {
|
|
5637
|
-
const
|
|
5638
|
-
if (
|
|
5639
|
-
return id.slice(0,
|
|
5664
|
+
const sep2 = id.indexOf("_");
|
|
5665
|
+
if (sep2 === -1) return id.slice(0, 10);
|
|
5666
|
+
return id.slice(0, sep2 + 1) + id.slice(sep2 + 1, sep2 + 1 + 10);
|
|
5640
5667
|
}
|
|
5641
5668
|
|
|
5642
5669
|
// src/lib/duration.ts
|
|
@@ -5743,10 +5770,10 @@ async function resolveIdInternal(paths, input, kind, options = {}) {
|
|
|
5743
5770
|
// src/lib/source-root-scope.ts
|
|
5744
5771
|
import { promises as fs } from "fs";
|
|
5745
5772
|
import { homedir as osHomedir } from "os";
|
|
5746
|
-
import { basename as basename2, dirname as dirname3, isAbsolute, join as join14, normalize, relative, resolve as resolve2 } from "path";
|
|
5773
|
+
import { basename as basename2, dirname as dirname3, isAbsolute, join as join14, normalize as normalize2, relative, resolve as resolve2 } from "path";
|
|
5747
5774
|
var AGENT_INFRA_DIRS = ["~/.claude", "~/.codex", "~/.basou"];
|
|
5748
5775
|
async function realpathBestEffort(absPath) {
|
|
5749
|
-
let current =
|
|
5776
|
+
let current = normalize2(absPath);
|
|
5750
5777
|
const tail = [];
|
|
5751
5778
|
for (let guard = 0; guard < 4096; guard += 1) {
|
|
5752
5779
|
try {
|
|
@@ -5755,15 +5782,15 @@ async function realpathBestEffort(absPath) {
|
|
|
5755
5782
|
} catch (error) {
|
|
5756
5783
|
const code = error?.code;
|
|
5757
5784
|
if (code !== "ENOENT" && code !== "ENOTDIR") {
|
|
5758
|
-
return
|
|
5785
|
+
return normalize2(absPath);
|
|
5759
5786
|
}
|
|
5760
5787
|
const parent = dirname3(current);
|
|
5761
|
-
if (parent === current) return
|
|
5788
|
+
if (parent === current) return normalize2(absPath);
|
|
5762
5789
|
tail.push(basename2(current));
|
|
5763
5790
|
current = parent;
|
|
5764
5791
|
}
|
|
5765
5792
|
}
|
|
5766
|
-
return
|
|
5793
|
+
return normalize2(absPath);
|
|
5767
5794
|
}
|
|
5768
5795
|
function expandTilde(p, homedir5) {
|
|
5769
5796
|
if (p === "~") return homedir5;
|
|
@@ -5772,8 +5799,8 @@ function expandTilde(p, homedir5) {
|
|
|
5772
5799
|
}
|
|
5773
5800
|
function toAbsolute(p, workingDirAbs, homedir5) {
|
|
5774
5801
|
const expanded = expandTilde(p, homedir5);
|
|
5775
|
-
if (isAbsolute(expanded)) return
|
|
5776
|
-
return
|
|
5802
|
+
if (isAbsolute(expanded)) return normalize2(expanded);
|
|
5803
|
+
return normalize2(resolve2(workingDirAbs, expanded));
|
|
5777
5804
|
}
|
|
5778
5805
|
function isUnder(child, parent) {
|
|
5779
5806
|
if (child === parent) return true;
|
|
@@ -5790,12 +5817,12 @@ async function classifyFilesBySourceRoot(input) {
|
|
|
5790
5817
|
const rootsAbs = [];
|
|
5791
5818
|
for (const r of declared) {
|
|
5792
5819
|
const expanded = expandTilde(r, homedir5);
|
|
5793
|
-
const abs = isAbsolute(expanded) ?
|
|
5820
|
+
const abs = isAbsolute(expanded) ? normalize2(expanded) : normalize2(resolve2(input.masterRoot, expanded));
|
|
5794
5821
|
rootsAbs.push(await realpathBestEffort(abs));
|
|
5795
5822
|
}
|
|
5796
5823
|
for (const e of input.extraInRoot ?? []) {
|
|
5797
5824
|
const expanded = expandTilde(e, homedir5);
|
|
5798
|
-
const abs = isAbsolute(expanded) ?
|
|
5825
|
+
const abs = isAbsolute(expanded) ? normalize2(expanded) : normalize2(resolve2(homedir5, expanded));
|
|
5799
5826
|
rootsAbs.push(await realpathBestEffort(abs));
|
|
5800
5827
|
}
|
|
5801
5828
|
if (rootsAbs.length === 0) {
|
|
@@ -5928,7 +5955,13 @@ async function summarizeOrientation(input) {
|
|
|
5928
5955
|
const decisionTitles = (bucket?.decisions ?? []).filter((d) => !voidedDecisionIds.has(d.decisionId)).map((d) => d.title);
|
|
5929
5956
|
const notes = bucket?.notes ?? [];
|
|
5930
5957
|
const hasIntent = decisionTitles.length > 0 || notes.length > 0;
|
|
5931
|
-
const files = hasIntent ? [] : [
|
|
5958
|
+
const files = hasIntent ? [] : [
|
|
5959
|
+
...new Set(
|
|
5960
|
+
(entry.session.session.related_files ?? []).filter(
|
|
5961
|
+
(file) => !isTransientToolPath(file)
|
|
5962
|
+
)
|
|
5963
|
+
)
|
|
5964
|
+
].sort().slice(0, FILES_PER_DIGEST);
|
|
5932
5965
|
return {
|
|
5933
5966
|
sessionId: entry.sessionId,
|
|
5934
5967
|
label: entry.session.session.label ?? null,
|
|
@@ -5999,8 +6032,10 @@ async function summarizeOrientation(input) {
|
|
|
5999
6032
|
} catch {
|
|
6000
6033
|
sourceRoots = null;
|
|
6001
6034
|
}
|
|
6002
|
-
const
|
|
6035
|
+
const recordedFiles = latestEntry?.session.session.related_files ?? [];
|
|
6036
|
+
const latestFiles = recordedFiles.filter((file) => !isTransientToolPath(file));
|
|
6003
6037
|
const uniqueFiles = new Set(latestFiles);
|
|
6038
|
+
const omittedFiles = new Set(recordedFiles).size - uniqueFiles.size;
|
|
6004
6039
|
const sortedFiles = [...uniqueFiles].sort();
|
|
6005
6040
|
const displayed = sortedFiles.slice(0, limit);
|
|
6006
6041
|
const overflow = Math.max(0, uniqueFiles.size - limit);
|
|
@@ -6031,7 +6066,7 @@ async function summarizeOrientation(input) {
|
|
|
6031
6066
|
openTracks,
|
|
6032
6067
|
latestNote,
|
|
6033
6068
|
recentDirection,
|
|
6034
|
-
relatedFiles: { displayed, overflow, outOfRoot },
|
|
6069
|
+
relatedFiles: { displayed, overflow, outOfRoot, omitted: omittedFiles },
|
|
6035
6070
|
inFlightTasks,
|
|
6036
6071
|
plannedTasks,
|
|
6037
6072
|
pendingApprovals,
|
|
@@ -6119,10 +6154,16 @@ function formatOrientationBody(summary, opts) {
|
|
|
6119
6154
|
`- ${t.common.latestDecisionLabel}: (no decisions recorded yet; capture with \`basou decision capture\`)`
|
|
6120
6155
|
);
|
|
6121
6156
|
}
|
|
6122
|
-
if (summary.relatedFiles.displayed.length > 0) {
|
|
6123
|
-
const
|
|
6124
|
-
|
|
6125
|
-
|
|
6157
|
+
if (summary.relatedFiles.displayed.length > 0 || summary.relatedFiles.omitted > 0) {
|
|
6158
|
+
const parts = [];
|
|
6159
|
+
if (summary.relatedFiles.displayed.length > 0) {
|
|
6160
|
+
const more = summary.relatedFiles.overflow > 0 ? ` (... +${summary.relatedFiles.overflow} more)` : "";
|
|
6161
|
+
parts.push(`${summary.relatedFiles.displayed.join(", ")}${more}`);
|
|
6162
|
+
}
|
|
6163
|
+
if (summary.relatedFiles.omitted > 0) {
|
|
6164
|
+
parts.push(t.orientation.scratchOmitted(summary.relatedFiles.omitted));
|
|
6165
|
+
}
|
|
6166
|
+
lines.push(`- ${t.common.recentFilesLabel}: ${parts.join(" ")}`);
|
|
6126
6167
|
if (summary.relatedFiles.outOfRoot.length > 0) {
|
|
6127
6168
|
const OUT_OF_ROOT_DISPLAY = 10;
|
|
6128
6169
|
const out = summary.relatedFiles.outOfRoot;
|
|
@@ -6371,9 +6412,9 @@ function suspectText(reason) {
|
|
|
6371
6412
|
return "suspect";
|
|
6372
6413
|
}
|
|
6373
6414
|
function shortId(id) {
|
|
6374
|
-
const
|
|
6375
|
-
if (
|
|
6376
|
-
return id.slice(0,
|
|
6415
|
+
const sep2 = id.indexOf("_");
|
|
6416
|
+
if (sep2 === -1) return id.slice(0, 10);
|
|
6417
|
+
return id.slice(0, sep2 + 1) + id.slice(sep2 + 1, sep2 + 1 + 10);
|
|
6377
6418
|
}
|
|
6378
6419
|
|
|
6379
6420
|
// src/project/anchor-starter.ts
|