@basou/cli 0.16.0 → 0.17.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.js +60 -11
- package/dist/index.js.map +1 -1
- package/dist/program.js +60 -11
- package/dist/program.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1804,13 +1804,15 @@ async function assertWorkspaceInitialized4(basouRoot) {
|
|
|
1804
1804
|
import { createReadStream } from "fs";
|
|
1805
1805
|
import { readdir, readFile as readFile2, rm, stat as stat2 } from "fs/promises";
|
|
1806
1806
|
import { homedir as homedir4 } from "os";
|
|
1807
|
-
import { basename as basename2, join as join4, resolve as resolve4 } from "path";
|
|
1807
|
+
import { basename as basename2, dirname, join as join4, resolve as resolve4 } from "path";
|
|
1808
1808
|
import { createInterface } from "readline";
|
|
1809
1809
|
import {
|
|
1810
|
+
AGENT_INFRA_DIRS,
|
|
1810
1811
|
assertBasouRootSafe as assertBasouRootSafe6,
|
|
1811
1812
|
basouPaths as basouPaths7,
|
|
1812
1813
|
CLAUDE_IMPORT_SOURCE,
|
|
1813
1814
|
CODEX_IMPORT_SOURCE,
|
|
1815
|
+
classifyFilesBySourceRoot,
|
|
1814
1816
|
claudeTranscriptToImportPayload,
|
|
1815
1817
|
codexRolloutToImportPayload,
|
|
1816
1818
|
enumerateSessionDirs,
|
|
@@ -1908,7 +1910,15 @@ async function doRunImportClaudeCode(options, ctx) {
|
|
|
1908
1910
|
}
|
|
1909
1911
|
};
|
|
1910
1912
|
});
|
|
1911
|
-
await importDerivedSessions(
|
|
1913
|
+
await importDerivedSessions(
|
|
1914
|
+
paths,
|
|
1915
|
+
manifest,
|
|
1916
|
+
options,
|
|
1917
|
+
CLAUDE_IMPORT_SOURCE,
|
|
1918
|
+
candidates,
|
|
1919
|
+
projectPaths,
|
|
1920
|
+
hasDeclaredBoundary(options, manifest)
|
|
1921
|
+
);
|
|
1912
1922
|
}
|
|
1913
1923
|
async function doRunImportCodex(options, ctx) {
|
|
1914
1924
|
assertSelector(options);
|
|
@@ -1933,7 +1943,18 @@ async function doRunImportCodex(options, ctx) {
|
|
|
1933
1943
|
});
|
|
1934
1944
|
}
|
|
1935
1945
|
}));
|
|
1936
|
-
await importDerivedSessions(
|
|
1946
|
+
await importDerivedSessions(
|
|
1947
|
+
paths,
|
|
1948
|
+
manifest,
|
|
1949
|
+
options,
|
|
1950
|
+
CODEX_IMPORT_SOURCE,
|
|
1951
|
+
candidates,
|
|
1952
|
+
projectPaths,
|
|
1953
|
+
hasDeclaredBoundary(options, manifest)
|
|
1954
|
+
);
|
|
1955
|
+
}
|
|
1956
|
+
function hasDeclaredBoundary(options, manifest) {
|
|
1957
|
+
return (options.project?.length ?? 0) > 0 || (manifest.import?.source_roots?.length ?? 0) > 0;
|
|
1937
1958
|
}
|
|
1938
1959
|
function assertSelector(options) {
|
|
1939
1960
|
if (options.session !== void 0 && options.all === true) {
|
|
@@ -1951,9 +1972,25 @@ async function resolveImportTarget(ctx) {
|
|
|
1951
1972
|
const manifest = await readManifest4(paths);
|
|
1952
1973
|
return { repositoryRoot, paths, manifest };
|
|
1953
1974
|
}
|
|
1954
|
-
async function importDerivedSessions(paths, manifest, options, sourceKind, candidates) {
|
|
1975
|
+
async function importDerivedSessions(paths, manifest, options, sourceKind, candidates, projectPaths, boundaryDeclared) {
|
|
1955
1976
|
const existingByExternalId = await loadExistingByExternalId(paths, sourceKind);
|
|
1956
1977
|
const seenThisRun = /* @__PURE__ */ new Set();
|
|
1978
|
+
const crossProjectCheck = boundaryDeclared;
|
|
1979
|
+
const crossProject = [];
|
|
1980
|
+
const noteCrossProject = async (externalId, payload) => {
|
|
1981
|
+
if (!crossProjectCheck) return;
|
|
1982
|
+
try {
|
|
1983
|
+
const scope = await classifyFilesBySourceRoot({
|
|
1984
|
+
files: payload.session.related_files ?? [],
|
|
1985
|
+
workingDirectory: payload.session.working_directory,
|
|
1986
|
+
sourceRoots: projectPaths,
|
|
1987
|
+
masterRoot: dirname(paths.root),
|
|
1988
|
+
extraInRoot: AGENT_INFRA_DIRS
|
|
1989
|
+
});
|
|
1990
|
+
if (scope.outOfRoot.length > 0) crossProject.push({ externalId, outOfRoot: scope.outOfRoot });
|
|
1991
|
+
} catch {
|
|
1992
|
+
}
|
|
1993
|
+
};
|
|
1957
1994
|
const results = [];
|
|
1958
1995
|
const counts = {
|
|
1959
1996
|
skippedNoAction: 0,
|
|
@@ -2010,6 +2047,7 @@ async function importDerivedSessions(paths, manifest, options, sourceKind, candi
|
|
|
2010
2047
|
}
|
|
2011
2048
|
counts.reimported++;
|
|
2012
2049
|
seenThisRun.add(externalId);
|
|
2050
|
+
await noteCrossProject(externalId, payload2);
|
|
2013
2051
|
continue;
|
|
2014
2052
|
}
|
|
2015
2053
|
const payload = validate(await toPayload());
|
|
@@ -2031,10 +2069,21 @@ async function importDerivedSessions(paths, manifest, options, sourceKind, candi
|
|
|
2031
2069
|
results.push(result);
|
|
2032
2070
|
seenThisRun.add(externalId);
|
|
2033
2071
|
sanitizedPaths += result.pathSanitizeReport.relatedFiles + (result.pathSanitizeReport.workingDirectoryRewritten ? 1 : 0);
|
|
2072
|
+
await noteCrossProject(externalId, payload);
|
|
2034
2073
|
}
|
|
2035
2074
|
if (sanitizedPaths > 0) {
|
|
2036
2075
|
console.error(`Imported sessions: ${sanitizedPaths} path(s) sanitized`);
|
|
2037
2076
|
}
|
|
2077
|
+
if (crossProject.length > 0) {
|
|
2078
|
+
const PATH_SAMPLE = 5;
|
|
2079
|
+
for (const { externalId, outOfRoot } of crossProject) {
|
|
2080
|
+
const sample = outOfRoot.slice(0, PATH_SAMPLE).join(", ");
|
|
2081
|
+
const more = outOfRoot.length > PATH_SAMPLE ? ` (... +${outOfRoot.length - PATH_SAMPLE} more)` : "";
|
|
2082
|
+
console.error(
|
|
2083
|
+
`basou: session ${externalId} edited ${outOfRoot.length} file(s) outside this project's source_roots: ${sample}${more} \u2014 they may belong to another project.`
|
|
2084
|
+
);
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2038
2087
|
printImportResult(options, results, counts);
|
|
2039
2088
|
}
|
|
2040
2089
|
async function classifyReimport(priors, sourcePath, externalId, counts) {
|
|
@@ -2941,7 +2990,7 @@ import {
|
|
|
2941
2990
|
unlinkSync,
|
|
2942
2991
|
writeFileSync
|
|
2943
2992
|
} from "fs";
|
|
2944
|
-
import { basename as basename4, dirname, isAbsolute as isAbsolute3, join as join6, relative as relative2, resolve as resolve7 } from "path";
|
|
2993
|
+
import { basename as basename4, dirname as dirname2, isAbsolute as isAbsolute3, join as join6, relative as relative2, resolve as resolve7 } from "path";
|
|
2945
2994
|
import {
|
|
2946
2995
|
basouPaths as basouPaths10,
|
|
2947
2996
|
GENERATED_END,
|
|
@@ -3580,7 +3629,7 @@ function applySymlinkPlan(repositoryRoot, plan) {
|
|
|
3580
3629
|
for (const { name, target } of plan.toCreate) {
|
|
3581
3630
|
const filePath = join6(real, name);
|
|
3582
3631
|
try {
|
|
3583
|
-
mkdirSync(
|
|
3632
|
+
mkdirSync(dirname2(filePath), { recursive: true });
|
|
3584
3633
|
symlinkSync(target, filePath);
|
|
3585
3634
|
created.push(name);
|
|
3586
3635
|
} catch (error) {
|
|
@@ -3720,7 +3769,7 @@ function resolveViewDir(repositoryRoot, viewPath) {
|
|
|
3720
3769
|
return realpathSync(abs);
|
|
3721
3770
|
} catch {
|
|
3722
3771
|
try {
|
|
3723
|
-
return join6(realpathSync(
|
|
3772
|
+
return join6(realpathSync(dirname2(abs)), basename4(abs));
|
|
3724
3773
|
} catch {
|
|
3725
3774
|
return abs;
|
|
3726
3775
|
}
|
|
@@ -3754,7 +3803,7 @@ function applyViewPlan(viewDir, toCreate) {
|
|
|
3754
3803
|
for (const { name, target } of toCreate) {
|
|
3755
3804
|
const filePath = join6(viewDir, name);
|
|
3756
3805
|
try {
|
|
3757
|
-
mkdirSync(
|
|
3806
|
+
mkdirSync(dirname2(filePath), { recursive: true });
|
|
3758
3807
|
symlinkSync(target, filePath);
|
|
3759
3808
|
created.push(name);
|
|
3760
3809
|
} catch (error) {
|
|
@@ -4101,7 +4150,7 @@ async function applyPresetPlan(anchorReal, plan) {
|
|
|
4101
4150
|
isLink = false;
|
|
4102
4151
|
}
|
|
4103
4152
|
if (isLink) throw new Error(`Canonical is a symlink in ${label}`);
|
|
4104
|
-
if (plan.action === "create") mkdirSync(
|
|
4153
|
+
if (plan.action === "create") mkdirSync(dirname2(file), { recursive: true });
|
|
4105
4154
|
const existing = await readMarkdownFile4(file);
|
|
4106
4155
|
await writeMarkdownFile5(file, renderWithMarkers4(existing, plan.desiredBlock, label));
|
|
4107
4156
|
}
|
|
@@ -4617,7 +4666,7 @@ import {
|
|
|
4617
4666
|
// src/lib/durable-write.ts
|
|
4618
4667
|
import { randomUUID } from "crypto";
|
|
4619
4668
|
import { lstat, open, rename, stat as stat3, unlink as unlink2 } from "fs/promises";
|
|
4620
|
-
import { basename as basename5, dirname as
|
|
4669
|
+
import { basename as basename5, dirname as dirname3, join as join7 } from "path";
|
|
4621
4670
|
async function assertNotSymlink(targetPath) {
|
|
4622
4671
|
try {
|
|
4623
4672
|
const st = await lstat(targetPath);
|
|
@@ -4632,7 +4681,7 @@ async function assertNotSymlink(targetPath) {
|
|
|
4632
4681
|
}
|
|
4633
4682
|
}
|
|
4634
4683
|
async function writeFileDurable(targetPath, content) {
|
|
4635
|
-
const dir =
|
|
4684
|
+
const dir = dirname3(targetPath);
|
|
4636
4685
|
const tmpPath = join7(dir, `.${basename5(targetPath)}.tmp.${randomUUID()}`);
|
|
4637
4686
|
let mode = 420;
|
|
4638
4687
|
try {
|