@basou/cli 0.65.0 → 0.66.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 +195 -317
- package/dist/index.js.map +1 -1
- package/dist/program.js +194 -318
- package/dist/program.js.map +1 -1
- package/package.json +2 -2
package/dist/program.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
assertBasouRootSafe,
|
|
15
15
|
assertLockStoreSafe,
|
|
16
16
|
assertSessionDirSafe,
|
|
17
|
-
basouPaths,
|
|
17
|
+
basouPaths as basouPaths2,
|
|
18
18
|
EVENT_SCHEMA_VERSION,
|
|
19
19
|
enumerateApprovals,
|
|
20
20
|
findErrorCode,
|
|
@@ -28,8 +28,7 @@ import {
|
|
|
28
28
|
prefixedUlid,
|
|
29
29
|
readSessionYaml,
|
|
30
30
|
readYamlFile,
|
|
31
|
-
replayEvents
|
|
32
|
-
resolveRepositoryRoot
|
|
31
|
+
replayEvents
|
|
33
32
|
} from "@basou/core";
|
|
34
33
|
|
|
35
34
|
// src/lib/error-render.ts
|
|
@@ -154,6 +153,150 @@ function printTaskSkip(taskId, reason) {
|
|
|
154
153
|
console.error(`Skipped ${shortTaskId(taskId)}: ${reason}`);
|
|
155
154
|
}
|
|
156
155
|
|
|
156
|
+
// src/lib/repo-root.ts
|
|
157
|
+
import { realpath, stat } from "fs/promises";
|
|
158
|
+
import { basename, resolve } from "path";
|
|
159
|
+
import {
|
|
160
|
+
basouPaths,
|
|
161
|
+
defaultPortfolioConfigPath,
|
|
162
|
+
loadPortfolioConfig,
|
|
163
|
+
readManifest,
|
|
164
|
+
resolveBasouRepositoryRoot,
|
|
165
|
+
resolveRepositoryRoot
|
|
166
|
+
} from "@basou/core";
|
|
167
|
+
async function resolveBasouRootForCommand(cwd, commandName, opts = {}) {
|
|
168
|
+
let root;
|
|
169
|
+
try {
|
|
170
|
+
root = await resolveBasouRepositoryRoot(cwd, {
|
|
171
|
+
onRedirect: ({ via, root: root2 }) => {
|
|
172
|
+
if (opts.quiet !== true) console.error(`Resolved workspace view to ${root2} (via ${via}).`);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
} catch (error) {
|
|
176
|
+
if (error instanceof Error && error.message === "Not a git repository") {
|
|
177
|
+
throw new Error(
|
|
178
|
+
`Not a git repository. Run 'git init' first, then re-run 'basou ${commandName}'.`,
|
|
179
|
+
{ cause: error }
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
if (!await hasBasouStore(root)) {
|
|
185
|
+
const master = await resolveMemberToMaster(
|
|
186
|
+
root,
|
|
187
|
+
opts.portfolioConfigPath ?? defaultPortfolioConfigPath()
|
|
188
|
+
);
|
|
189
|
+
if (master !== void 0) {
|
|
190
|
+
if (opts.quiet !== true) {
|
|
191
|
+
console.error(
|
|
192
|
+
`Resolved portfolio member to ${master.root} (via portfolio: ${master.label}).`
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
return master.root;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return root;
|
|
199
|
+
}
|
|
200
|
+
async function resolveRepositoryRootInPlace(cwd, commandName) {
|
|
201
|
+
try {
|
|
202
|
+
return await resolveRepositoryRoot(cwd);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
if (!(error instanceof Error) || error.message !== "Not a git repository") throw error;
|
|
205
|
+
const links = await describeWorkspaceView(cwd);
|
|
206
|
+
if (links !== void 0) {
|
|
207
|
+
throw new Error(
|
|
208
|
+
`Not a git repository: this is a workspace view (it links ${links}). Run 'basou ${commandName}' inside a repository instead.`,
|
|
209
|
+
{ cause: error }
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
throw new Error(
|
|
213
|
+
`Not a git repository. Run 'git init' first, then re-run 'basou ${commandName}'.`,
|
|
214
|
+
{ cause: error }
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async function describeWorkspaceView(dir) {
|
|
219
|
+
let via;
|
|
220
|
+
try {
|
|
221
|
+
await resolveBasouRepositoryRoot(dir, {
|
|
222
|
+
onRedirect: (info) => {
|
|
223
|
+
via = info.via;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
} catch (error) {
|
|
227
|
+
if (error instanceof Error && error.message.startsWith("Ambiguous workspace view:")) {
|
|
228
|
+
return "more than one repository with a .basou store";
|
|
229
|
+
}
|
|
230
|
+
return void 0;
|
|
231
|
+
}
|
|
232
|
+
return via;
|
|
233
|
+
}
|
|
234
|
+
async function hasBasouStore(root) {
|
|
235
|
+
try {
|
|
236
|
+
return (await stat(basouPaths(root).root)).isDirectory();
|
|
237
|
+
} catch {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async function resolveMemberToMaster(repoRoot, configPath) {
|
|
242
|
+
let workspaces;
|
|
243
|
+
try {
|
|
244
|
+
workspaces = await loadPortfolioConfig(configPath);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
if (!(error instanceof Error) || !error.message.startsWith("No portfolio config at")) {
|
|
247
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
248
|
+
console.error(`Ignoring ~/.basou/portfolio.yaml: ${detail}`);
|
|
249
|
+
}
|
|
250
|
+
return void 0;
|
|
251
|
+
}
|
|
252
|
+
const memberReal = await realpathOrNull(repoRoot);
|
|
253
|
+
if (memberReal === null) return void 0;
|
|
254
|
+
const claimants = /* @__PURE__ */ new Map();
|
|
255
|
+
const seenMaster = /* @__PURE__ */ new Set();
|
|
256
|
+
for (const ws of workspaces) {
|
|
257
|
+
const masterReal = await realpathOrNull(ws.path);
|
|
258
|
+
if (masterReal === null) continue;
|
|
259
|
+
if (masterReal === memberReal) continue;
|
|
260
|
+
if (seenMaster.has(masterReal)) continue;
|
|
261
|
+
seenMaster.add(masterReal);
|
|
262
|
+
let manifest;
|
|
263
|
+
try {
|
|
264
|
+
manifest = await readManifest(basouPaths(masterReal));
|
|
265
|
+
} catch (error) {
|
|
266
|
+
if (error instanceof Error && error.message !== "YAML file not found") {
|
|
267
|
+
console.error(
|
|
268
|
+
`Skipping portfolio workspace '${ws.label ?? basename(masterReal)}': could not read its manifest (${error.message}).`
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
const sourceRoots = manifest.import?.source_roots ?? ["."];
|
|
274
|
+
for (const sr of sourceRoots) {
|
|
275
|
+
const real = await realpathOrNull(resolve(masterReal, sr));
|
|
276
|
+
if (real !== null && real === memberReal) {
|
|
277
|
+
claimants.set(masterReal, { root: masterReal, label: ws.label ?? basename(masterReal) });
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
const matched = [...claimants.values()];
|
|
283
|
+
if (matched.length === 1) return matched[0];
|
|
284
|
+
if (matched.length > 1) {
|
|
285
|
+
const names = matched.map((c) => c.label).join(", ");
|
|
286
|
+
throw new Error(
|
|
287
|
+
`This repository is declared as a source root by ${matched.length} portfolio workspaces (${names}). Disambiguate in ~/.basou/portfolio.yaml so only one aggregates it.`
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
return void 0;
|
|
291
|
+
}
|
|
292
|
+
async function realpathOrNull(p) {
|
|
293
|
+
try {
|
|
294
|
+
return await realpath(p);
|
|
295
|
+
} catch {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
157
300
|
// src/commands/approval.ts
|
|
158
301
|
var APPR_PREFIX = "appr_";
|
|
159
302
|
var SHORT_ID_BASE_LEN = 6;
|
|
@@ -190,8 +333,8 @@ async function runApprovalList(options, ctx = {}) {
|
|
|
190
333
|
}
|
|
191
334
|
async function doRunApprovalList(options, ctx) {
|
|
192
335
|
const cwd = ctx.cwd ?? process.cwd();
|
|
193
|
-
const repositoryRoot = await
|
|
194
|
-
const paths =
|
|
336
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "approval list");
|
|
337
|
+
const paths = basouPaths2(repositoryRoot);
|
|
195
338
|
await assertWorkspaceInitialized(paths.root);
|
|
196
339
|
const ids = await enumerateApprovals(paths);
|
|
197
340
|
for (const entry of ids.unfollowed) {
|
|
@@ -263,8 +406,8 @@ async function runApprovalShow(idInput, options, ctx = {}) {
|
|
|
263
406
|
}
|
|
264
407
|
async function doRunApprovalShow(idInput, options, ctx) {
|
|
265
408
|
const cwd = ctx.cwd ?? process.cwd();
|
|
266
|
-
const repositoryRoot = await
|
|
267
|
-
const paths =
|
|
409
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "approval show");
|
|
410
|
+
const paths = basouPaths2(repositoryRoot);
|
|
268
411
|
await assertWorkspaceInitialized(paths.root);
|
|
269
412
|
const { id, unfollowed } = await resolveApprovalId(paths, idInput);
|
|
270
413
|
for (const entry2 of unfollowed) console.error(`Warning: ${describeUnfollowed(entry2)}`);
|
|
@@ -329,8 +472,8 @@ async function doRunApprovalResolve(idInput, options, ctx, decision) {
|
|
|
329
472
|
}
|
|
330
473
|
}
|
|
331
474
|
const cwd = ctx.cwd ?? process.cwd();
|
|
332
|
-
const repositoryRoot = await
|
|
333
|
-
const paths =
|
|
475
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, `approval ${decision}`);
|
|
476
|
+
const paths = basouPaths2(repositoryRoot);
|
|
334
477
|
await assertWorkspaceInitialized(paths.root);
|
|
335
478
|
const { id, location } = await resolveApprovalId(paths, idInput);
|
|
336
479
|
if (location === "resolved") {
|
|
@@ -651,19 +794,6 @@ function truncate(value, maxLength) {
|
|
|
651
794
|
if (value.length <= maxLength) return value;
|
|
652
795
|
return `${value.slice(0, maxLength - 3)}...`;
|
|
653
796
|
}
|
|
654
|
-
async function resolveRepositoryRootForApproval(cwd, subcmd) {
|
|
655
|
-
try {
|
|
656
|
-
return await resolveRepositoryRoot(cwd);
|
|
657
|
-
} catch (error) {
|
|
658
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
659
|
-
throw new Error(
|
|
660
|
-
`Not a git repository. Run 'git init' first, then re-run 'basou approval ${subcmd}'.`,
|
|
661
|
-
{ cause: error }
|
|
662
|
-
);
|
|
663
|
-
}
|
|
664
|
-
throw error;
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
797
|
async function assertWorkspaceInitialized(basouRoot) {
|
|
668
798
|
try {
|
|
669
799
|
await assertBasouRootSafe(basouRoot);
|
|
@@ -733,16 +863,16 @@ import {
|
|
|
733
863
|
|
|
734
864
|
// src/commands/import.ts
|
|
735
865
|
import { createReadStream } from "fs";
|
|
736
|
-
import { readdir, readFile, rm, stat } from "fs/promises";
|
|
866
|
+
import { readdir, readFile, rm, stat as stat2 } from "fs/promises";
|
|
737
867
|
import { homedir } from "os";
|
|
738
|
-
import { basename, dirname as dirname2, join as join2, resolve } from "path";
|
|
868
|
+
import { basename as basename2, dirname as dirname2, join as join2, resolve as resolve2 } from "path";
|
|
739
869
|
import { createInterface } from "readline";
|
|
740
870
|
import {
|
|
741
871
|
AGENT_INFRA_DIRS,
|
|
742
872
|
assertBasouRootSafe as assertBasouRootSafe2,
|
|
743
873
|
assertLockStoreSafe as assertLockStoreSafe2,
|
|
744
874
|
assertSessionStoreSafe,
|
|
745
|
-
basouPaths as
|
|
875
|
+
basouPaths as basouPaths3,
|
|
746
876
|
CLAUDE_IMPORT_SOURCE,
|
|
747
877
|
CODEX_IMPORT_SOURCE,
|
|
748
878
|
classifyFilesBySourceRoot,
|
|
@@ -753,11 +883,10 @@ import {
|
|
|
753
883
|
findErrorCode as findErrorCode2,
|
|
754
884
|
importSessionFromJson,
|
|
755
885
|
observedFilesOf,
|
|
756
|
-
readManifest,
|
|
886
|
+
readManifest as readManifest2,
|
|
757
887
|
readSessionObservation,
|
|
758
888
|
readSessionYaml as readSessionYaml2,
|
|
759
889
|
reimportPreservingId,
|
|
760
|
-
resolveRepositoryRoot as resolveRepositoryRoot2,
|
|
761
890
|
SESSION_IMPORT_SCHEMA_VERSION,
|
|
762
891
|
SessionImportPayloadSchema
|
|
763
892
|
} from "@basou/core";
|
|
@@ -827,10 +956,10 @@ function resolveSourceRoots(args) {
|
|
|
827
956
|
const { projectFlags, manifest, repoRoot, cwd } = args;
|
|
828
957
|
let resolved;
|
|
829
958
|
if (projectFlags.length > 0) {
|
|
830
|
-
resolved = projectFlags.map((p) =>
|
|
959
|
+
resolved = projectFlags.map((p) => resolve2(cwd, p));
|
|
831
960
|
} else {
|
|
832
961
|
const roots = manifest.import?.source_roots;
|
|
833
|
-
resolved = roots !== void 0 && roots.length > 0 ? roots.map((r) =>
|
|
962
|
+
resolved = roots !== void 0 && roots.length > 0 ? roots.map((r) => resolve2(repoRoot, r)) : [repoRoot];
|
|
834
963
|
}
|
|
835
964
|
return [...new Set(resolved)];
|
|
836
965
|
}
|
|
@@ -848,7 +977,7 @@ async function doRunImportClaudeCode(options, ctx) {
|
|
|
848
977
|
const files = await selectTranscriptFiles(projectsRoot, projectPaths, options);
|
|
849
978
|
const projectSet = new Set(projectPaths);
|
|
850
979
|
const candidates = files.map((file) => {
|
|
851
|
-
const externalId =
|
|
980
|
+
const externalId = basename2(file, ".jsonl");
|
|
852
981
|
return {
|
|
853
982
|
externalId,
|
|
854
983
|
sourcePath: file,
|
|
@@ -923,10 +1052,10 @@ function assertSelector(options) {
|
|
|
923
1052
|
}
|
|
924
1053
|
async function resolveImportTarget(ctx) {
|
|
925
1054
|
const cwd = ctx.cwd ?? process.cwd();
|
|
926
|
-
const repositoryRoot = await
|
|
927
|
-
const paths =
|
|
1055
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "import");
|
|
1056
|
+
const paths = basouPaths3(repositoryRoot);
|
|
928
1057
|
await assertWorkspaceInitialized2(paths.root);
|
|
929
|
-
const manifest = await
|
|
1058
|
+
const manifest = await readManifest2(paths);
|
|
930
1059
|
return { repositoryRoot, paths, manifest };
|
|
931
1060
|
}
|
|
932
1061
|
async function importDerivedSessions(paths, manifest, options, sourceKind, candidates, projectPaths, boundaryDeclared) {
|
|
@@ -1173,7 +1302,7 @@ async function selectTranscriptFiles(projectsRoot, projectPaths, options) {
|
|
|
1173
1302
|
}
|
|
1174
1303
|
async function pathExists(file) {
|
|
1175
1304
|
try {
|
|
1176
|
-
await
|
|
1305
|
+
await stat2(file);
|
|
1177
1306
|
return true;
|
|
1178
1307
|
} catch (error) {
|
|
1179
1308
|
if (findErrorCode2(error, "ENOENT")) return false;
|
|
@@ -1182,7 +1311,7 @@ async function pathExists(file) {
|
|
|
1182
1311
|
}
|
|
1183
1312
|
async function statSize(file) {
|
|
1184
1313
|
try {
|
|
1185
|
-
return (await
|
|
1314
|
+
return (await stat2(file)).size;
|
|
1186
1315
|
} catch (error) {
|
|
1187
1316
|
if (findErrorCode2(error, "ENOENT")) return void 0;
|
|
1188
1317
|
throw error;
|
|
@@ -1374,18 +1503,6 @@ function shortId2(id) {
|
|
|
1374
1503
|
}
|
|
1375
1504
|
return id.slice(0, SHORT_ID_LEN2);
|
|
1376
1505
|
}
|
|
1377
|
-
async function resolveRepositoryRootForImport(cwd) {
|
|
1378
|
-
try {
|
|
1379
|
-
return await resolveRepositoryRoot2(cwd);
|
|
1380
|
-
} catch (error) {
|
|
1381
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
1382
|
-
throw new Error("Not a git repository. Run 'git init' first, then re-run 'basou import'.", {
|
|
1383
|
-
cause: error
|
|
1384
|
-
});
|
|
1385
|
-
}
|
|
1386
|
-
throw error;
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
1506
|
async function assertWorkspaceInitialized2(basouRoot) {
|
|
1390
1507
|
try {
|
|
1391
1508
|
await assertBasouRootSafe2(basouRoot);
|
|
@@ -1578,111 +1695,6 @@ async function probeStaleness(args) {
|
|
|
1578
1695
|
}
|
|
1579
1696
|
}
|
|
1580
1697
|
|
|
1581
|
-
// src/lib/repo-root.ts
|
|
1582
|
-
import { realpath, stat as stat2 } from "fs/promises";
|
|
1583
|
-
import { basename as basename2, resolve as resolve2 } from "path";
|
|
1584
|
-
import {
|
|
1585
|
-
basouPaths as basouPaths3,
|
|
1586
|
-
defaultPortfolioConfigPath,
|
|
1587
|
-
loadPortfolioConfig,
|
|
1588
|
-
readManifest as readManifest2,
|
|
1589
|
-
resolveBasouRepositoryRoot
|
|
1590
|
-
} from "@basou/core";
|
|
1591
|
-
async function resolveBasouRootForCommand(cwd, commandName, opts = {}) {
|
|
1592
|
-
let root;
|
|
1593
|
-
try {
|
|
1594
|
-
root = await resolveBasouRepositoryRoot(cwd, {
|
|
1595
|
-
onRedirect: ({ via, root: root2 }) => console.error(`Resolved workspace view to ${root2} (via ${via}).`)
|
|
1596
|
-
});
|
|
1597
|
-
} catch (error) {
|
|
1598
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
1599
|
-
throw new Error(
|
|
1600
|
-
`Not a git repository. Run 'git init' first, then re-run 'basou ${commandName}'.`,
|
|
1601
|
-
{ cause: error }
|
|
1602
|
-
);
|
|
1603
|
-
}
|
|
1604
|
-
throw error;
|
|
1605
|
-
}
|
|
1606
|
-
if (!await hasBasouStore(root)) {
|
|
1607
|
-
const master = await resolveMemberToMaster(
|
|
1608
|
-
root,
|
|
1609
|
-
opts.portfolioConfigPath ?? defaultPortfolioConfigPath()
|
|
1610
|
-
);
|
|
1611
|
-
if (master !== void 0) {
|
|
1612
|
-
console.error(
|
|
1613
|
-
`Resolved portfolio member to ${master.root} (via portfolio: ${master.label}).`
|
|
1614
|
-
);
|
|
1615
|
-
return master.root;
|
|
1616
|
-
}
|
|
1617
|
-
}
|
|
1618
|
-
return root;
|
|
1619
|
-
}
|
|
1620
|
-
async function hasBasouStore(root) {
|
|
1621
|
-
try {
|
|
1622
|
-
return (await stat2(basouPaths3(root).root)).isDirectory();
|
|
1623
|
-
} catch {
|
|
1624
|
-
return false;
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1627
|
-
async function resolveMemberToMaster(repoRoot, configPath) {
|
|
1628
|
-
let workspaces;
|
|
1629
|
-
try {
|
|
1630
|
-
workspaces = await loadPortfolioConfig(configPath);
|
|
1631
|
-
} catch (error) {
|
|
1632
|
-
if (!(error instanceof Error) || !error.message.startsWith("No portfolio config at")) {
|
|
1633
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
1634
|
-
console.error(`Ignoring ~/.basou/portfolio.yaml: ${detail}`);
|
|
1635
|
-
}
|
|
1636
|
-
return void 0;
|
|
1637
|
-
}
|
|
1638
|
-
const memberReal = await realpathOrNull(repoRoot);
|
|
1639
|
-
if (memberReal === null) return void 0;
|
|
1640
|
-
const claimants = /* @__PURE__ */ new Map();
|
|
1641
|
-
const seenMaster = /* @__PURE__ */ new Set();
|
|
1642
|
-
for (const ws of workspaces) {
|
|
1643
|
-
const masterReal = await realpathOrNull(ws.path);
|
|
1644
|
-
if (masterReal === null) continue;
|
|
1645
|
-
if (masterReal === memberReal) continue;
|
|
1646
|
-
if (seenMaster.has(masterReal)) continue;
|
|
1647
|
-
seenMaster.add(masterReal);
|
|
1648
|
-
let manifest;
|
|
1649
|
-
try {
|
|
1650
|
-
manifest = await readManifest2(basouPaths3(masterReal));
|
|
1651
|
-
} catch (error) {
|
|
1652
|
-
if (error instanceof Error && error.message !== "YAML file not found") {
|
|
1653
|
-
console.error(
|
|
1654
|
-
`Skipping portfolio workspace '${ws.label ?? basename2(masterReal)}': could not read its manifest (${error.message}).`
|
|
1655
|
-
);
|
|
1656
|
-
}
|
|
1657
|
-
continue;
|
|
1658
|
-
}
|
|
1659
|
-
const sourceRoots = manifest.import?.source_roots ?? ["."];
|
|
1660
|
-
for (const sr of sourceRoots) {
|
|
1661
|
-
const real = await realpathOrNull(resolve2(masterReal, sr));
|
|
1662
|
-
if (real !== null && real === memberReal) {
|
|
1663
|
-
claimants.set(masterReal, { root: masterReal, label: ws.label ?? basename2(masterReal) });
|
|
1664
|
-
break;
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
const matched = [...claimants.values()];
|
|
1669
|
-
if (matched.length === 1) return matched[0];
|
|
1670
|
-
if (matched.length > 1) {
|
|
1671
|
-
const names = matched.map((c) => c.label).join(", ");
|
|
1672
|
-
throw new Error(
|
|
1673
|
-
`This repository is declared as a source root by ${matched.length} portfolio workspaces (${names}). Disambiguate in ~/.basou/portfolio.yaml so only one aggregates it.`
|
|
1674
|
-
);
|
|
1675
|
-
}
|
|
1676
|
-
return void 0;
|
|
1677
|
-
}
|
|
1678
|
-
async function realpathOrNull(p) {
|
|
1679
|
-
try {
|
|
1680
|
-
return await realpath(p);
|
|
1681
|
-
} catch {
|
|
1682
|
-
return null;
|
|
1683
|
-
}
|
|
1684
|
-
}
|
|
1685
|
-
|
|
1686
1698
|
// src/commands/board.ts
|
|
1687
1699
|
var DEFAULT_BOARD_PATH = "board/board.yaml";
|
|
1688
1700
|
function registerBoardCommand(program) {
|
|
@@ -2479,7 +2491,6 @@ import {
|
|
|
2479
2491
|
prefixedUlid as prefixedUlid2,
|
|
2480
2492
|
readManifest as readManifest4,
|
|
2481
2493
|
replayEvents as replayEvents2,
|
|
2482
|
-
resolveRepositoryRoot as resolveRepositoryRoot3,
|
|
2483
2494
|
resolveSessionId,
|
|
2484
2495
|
sanitizePath
|
|
2485
2496
|
} from "@basou/core";
|
|
@@ -2762,7 +2773,7 @@ async function warnLinkedFilesOutsideRoots(input) {
|
|
|
2762
2773
|
}
|
|
2763
2774
|
async function doRunDecisionRecord(options, ctx) {
|
|
2764
2775
|
const cwd = ctx.cwd ?? process.cwd();
|
|
2765
|
-
const repositoryRoot = await
|
|
2776
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "decision record");
|
|
2766
2777
|
const paths = basouPaths6(repositoryRoot);
|
|
2767
2778
|
await assertWorkspaceInitialized4(paths.root);
|
|
2768
2779
|
const now = ctx.nowProvider !== void 0 ? ctx.nowProvider() : /* @__PURE__ */ new Date();
|
|
@@ -3409,19 +3420,6 @@ function printDecisionResult(options, result) {
|
|
|
3409
3420
|
);
|
|
3410
3421
|
}
|
|
3411
3422
|
}
|
|
3412
|
-
async function resolveRepositoryRootForDecision(cwd) {
|
|
3413
|
-
try {
|
|
3414
|
-
return await resolveRepositoryRoot3(cwd);
|
|
3415
|
-
} catch (error) {
|
|
3416
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
3417
|
-
throw new Error(
|
|
3418
|
-
"Not a git repository. Run 'git init' first, then re-run 'basou decision record'.",
|
|
3419
|
-
{ cause: error }
|
|
3420
|
-
);
|
|
3421
|
-
}
|
|
3422
|
-
throw error;
|
|
3423
|
-
}
|
|
3424
|
-
}
|
|
3425
3423
|
async function assertWorkspaceInitialized4(basouRoot) {
|
|
3426
3424
|
try {
|
|
3427
3425
|
await assertBasouRootSafe4(basouRoot);
|
|
@@ -3441,7 +3439,6 @@ import {
|
|
|
3441
3439
|
readMarkdownFile as readMarkdownFile3,
|
|
3442
3440
|
renderDecisions as renderDecisions2,
|
|
3443
3441
|
renderWithMarkers as renderWithMarkers2,
|
|
3444
|
-
resolveRepositoryRoot as resolveRepositoryRoot4,
|
|
3445
3442
|
writeMarkdownFile as writeMarkdownFile2
|
|
3446
3443
|
} from "@basou/core";
|
|
3447
3444
|
function registerDecisionsCommand(program) {
|
|
@@ -3461,7 +3458,7 @@ async function runDecisionsGenerate(options, ctx = {}) {
|
|
|
3461
3458
|
async function doRunDecisionsGenerate(options, ctx) {
|
|
3462
3459
|
void options;
|
|
3463
3460
|
const cwd = ctx.cwd ?? process.cwd();
|
|
3464
|
-
const repositoryRoot = await
|
|
3461
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "decisions generate");
|
|
3465
3462
|
const paths = basouPaths7(repositoryRoot);
|
|
3466
3463
|
await assertWorkspaceInitialized5(paths.root);
|
|
3467
3464
|
const nowIso = (ctx.nowProvider?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
@@ -3476,19 +3473,6 @@ async function doRunDecisionsGenerate(options, ctx) {
|
|
|
3476
3473
|
await writeMarkdownFile2(paths.files.decisions, finalBody);
|
|
3477
3474
|
console.log(`Generated .basou/decisions.md (decisions: ${result.decisionCount})`);
|
|
3478
3475
|
}
|
|
3479
|
-
async function resolveRepositoryRootForDecisions(cwd) {
|
|
3480
|
-
try {
|
|
3481
|
-
return await resolveRepositoryRoot4(cwd);
|
|
3482
|
-
} catch (error) {
|
|
3483
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
3484
|
-
throw new Error(
|
|
3485
|
-
"Not a git repository. Run 'git init' first, then re-run 'basou decisions generate'.",
|
|
3486
|
-
{ cause: error }
|
|
3487
|
-
);
|
|
3488
|
-
}
|
|
3489
|
-
throw error;
|
|
3490
|
-
}
|
|
3491
|
-
}
|
|
3492
3476
|
async function assertWorkspaceInitialized5(basouRoot) {
|
|
3493
3477
|
try {
|
|
3494
3478
|
await assertBasouRootSafe5(basouRoot);
|
|
@@ -3519,7 +3503,6 @@ import {
|
|
|
3519
3503
|
prefixedUlid as prefixedUlid3,
|
|
3520
3504
|
readManifest as readManifest5,
|
|
3521
3505
|
readYamlFile as readYamlFile2,
|
|
3522
|
-
resolveRepositoryRoot as resolveRepositoryRoot5,
|
|
3523
3506
|
SESSION_SCHEMA_VERSION,
|
|
3524
3507
|
SessionSchema,
|
|
3525
3508
|
sanitizeWorkingDirectory,
|
|
@@ -3542,7 +3525,7 @@ async function runExec(command, args, options, ctx = {}) {
|
|
|
3542
3525
|
const now = ctx.now ?? (() => /* @__PURE__ */ new Date());
|
|
3543
3526
|
const cwd = options.cwd ?? process.cwd();
|
|
3544
3527
|
const timeout_ms = options.timeout !== void 0 ? parseDuration(options.timeout) : void 0;
|
|
3545
|
-
const repoRoot = await
|
|
3528
|
+
const repoRoot = await resolveRepositoryRootInPlace(cwd, "exec");
|
|
3546
3529
|
const paths = basouPaths8(repoRoot);
|
|
3547
3530
|
await assertBasouRootSafe6(paths.root);
|
|
3548
3531
|
const manifest = await readManifest5(paths);
|
|
@@ -3840,18 +3823,6 @@ async function finalizeSessionAsFailed(paths, sessionDir, sessionId, appendEvent
|
|
|
3840
3823
|
s.session.invocation.exit_code = null;
|
|
3841
3824
|
});
|
|
3842
3825
|
}
|
|
3843
|
-
async function resolveRepositoryRootForExec(cwd) {
|
|
3844
|
-
try {
|
|
3845
|
-
return await resolveRepositoryRoot5(cwd);
|
|
3846
|
-
} catch (error) {
|
|
3847
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
3848
|
-
throw new Error("Not a git repository. Run 'git init' first, then re-run 'basou exec'.", {
|
|
3849
|
-
cause: error
|
|
3850
|
-
});
|
|
3851
|
-
}
|
|
3852
|
-
throw error;
|
|
3853
|
-
}
|
|
3854
|
-
}
|
|
3855
3826
|
|
|
3856
3827
|
// src/commands/handoff.ts
|
|
3857
3828
|
import {
|
|
@@ -5439,7 +5410,6 @@ import {
|
|
|
5439
5410
|
appendBasouGitignore,
|
|
5440
5411
|
createManifest,
|
|
5441
5412
|
ensureBasouDirectory,
|
|
5442
|
-
resolveRepositoryRoot as resolveRepositoryRoot6,
|
|
5443
5413
|
writeManifest
|
|
5444
5414
|
} from "@basou/core";
|
|
5445
5415
|
function collectValue(value, previous) {
|
|
@@ -5471,7 +5441,7 @@ async function runInit(options, ctx = {}) {
|
|
|
5471
5441
|
}
|
|
5472
5442
|
async function doRunInit(options, ctx) {
|
|
5473
5443
|
const cwd = ctx.cwd ?? process.cwd();
|
|
5474
|
-
const repositoryRoot = await
|
|
5444
|
+
const repositoryRoot = await resolveRepositoryRootInPlace(cwd, "init");
|
|
5475
5445
|
const workspaceName = options.name ?? basename6(repositoryRoot);
|
|
5476
5446
|
if (options.repoUrl !== void 0) {
|
|
5477
5447
|
console.error(
|
|
@@ -5507,18 +5477,6 @@ function renderGitignoreWarning(error, verbose) {
|
|
|
5507
5477
|
if (label !== void 0) console.error(`Caused by: ${label}`);
|
|
5508
5478
|
}
|
|
5509
5479
|
}
|
|
5510
|
-
async function resolveRepositoryRootForInit(cwd) {
|
|
5511
|
-
try {
|
|
5512
|
-
return await resolveRepositoryRoot6(cwd);
|
|
5513
|
-
} catch (error) {
|
|
5514
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
5515
|
-
throw new Error("Not a git repository. Run 'git init' first, then re-run 'basou init'.", {
|
|
5516
|
-
cause: error
|
|
5517
|
-
});
|
|
5518
|
-
}
|
|
5519
|
-
throw error;
|
|
5520
|
-
}
|
|
5521
|
-
}
|
|
5522
5480
|
|
|
5523
5481
|
// src/commands/note.ts
|
|
5524
5482
|
import { readFile as readFile5 } from "fs/promises";
|
|
@@ -5918,7 +5876,6 @@ import {
|
|
|
5918
5876
|
renderAnchorStarter,
|
|
5919
5877
|
renderViewPresetBlock,
|
|
5920
5878
|
renderWithMarkers as renderWithMarkers4,
|
|
5921
|
-
resolveRepositoryRoot as resolveRepositoryRoot7,
|
|
5922
5879
|
safeSimpleGit,
|
|
5923
5880
|
seedMarkers,
|
|
5924
5881
|
summarizePresetPlan,
|
|
@@ -8464,19 +8421,6 @@ async function runProjectNew(repos, options, ctx = {}) {
|
|
|
8464
8421
|
process.exitCode = 1;
|
|
8465
8422
|
}
|
|
8466
8423
|
}
|
|
8467
|
-
async function resolveRepositoryRootForNew(cwd) {
|
|
8468
|
-
try {
|
|
8469
|
-
return await resolveRepositoryRoot7(cwd);
|
|
8470
|
-
} catch (error) {
|
|
8471
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
8472
|
-
throw new Error(
|
|
8473
|
-
"Not a git repository. Run 'git init' first, then re-run 'basou project new'.",
|
|
8474
|
-
{ cause: error }
|
|
8475
|
-
);
|
|
8476
|
-
}
|
|
8477
|
-
throw error;
|
|
8478
|
-
}
|
|
8479
|
-
}
|
|
8480
8424
|
function validateProjectName(name) {
|
|
8481
8425
|
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name)) {
|
|
8482
8426
|
throw new Error(
|
|
@@ -8487,7 +8431,7 @@ function validateProjectName(name) {
|
|
|
8487
8431
|
}
|
|
8488
8432
|
async function doRunProjectNew(repos, options, ctx) {
|
|
8489
8433
|
const cwd = ctx.cwd ?? process.cwd();
|
|
8490
|
-
const repositoryRoot = await
|
|
8434
|
+
const repositoryRoot = await resolveRepositoryRootInPlace(cwd, "project new");
|
|
8491
8435
|
const workspaceName = basename7(repositoryRoot);
|
|
8492
8436
|
const productName = options.projectName !== void 0 ? validateProjectName(options.projectName) : void 0;
|
|
8493
8437
|
const viewStem = productName ?? workspaceName;
|
|
@@ -9694,7 +9638,6 @@ import {
|
|
|
9694
9638
|
basouPaths as basouPaths15,
|
|
9695
9639
|
findErrorCode as findErrorCode11,
|
|
9696
9640
|
renderReport,
|
|
9697
|
-
resolveRepositoryRoot as resolveRepositoryRoot8,
|
|
9698
9641
|
writeMarkdownFile as writeMarkdownFile6
|
|
9699
9642
|
} from "@basou/core";
|
|
9700
9643
|
function registerReportCommand(program) {
|
|
@@ -9715,7 +9658,7 @@ async function runReportGenerate(options, ctx = {}) {
|
|
|
9715
9658
|
}
|
|
9716
9659
|
async function doRunReportGenerate(options, ctx) {
|
|
9717
9660
|
const cwd = ctx.cwd ?? process.cwd();
|
|
9718
|
-
const repositoryRoot = await
|
|
9661
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "report generate");
|
|
9719
9662
|
const paths = basouPaths15(repositoryRoot);
|
|
9720
9663
|
await assertWorkspaceInitialized10(paths.root);
|
|
9721
9664
|
const nowIso = (ctx.nowProvider?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
@@ -9741,19 +9684,6 @@ async function doRunReportGenerate(options, ctx) {
|
|
|
9741
9684
|
console.log(result.body);
|
|
9742
9685
|
}
|
|
9743
9686
|
}
|
|
9744
|
-
async function resolveRepositoryRootForReport(cwd) {
|
|
9745
|
-
try {
|
|
9746
|
-
return await resolveRepositoryRoot8(cwd);
|
|
9747
|
-
} catch (error) {
|
|
9748
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
9749
|
-
throw new Error(
|
|
9750
|
-
"Not a git repository. Run 'git init' first, then re-run 'basou report generate'.",
|
|
9751
|
-
{ cause: error }
|
|
9752
|
-
);
|
|
9753
|
-
}
|
|
9754
|
-
throw error;
|
|
9755
|
-
}
|
|
9756
|
-
}
|
|
9757
9687
|
async function assertWorkspaceInitialized10(basouRoot) {
|
|
9758
9688
|
try {
|
|
9759
9689
|
await assertBasouRootSafe11(basouRoot);
|
|
@@ -10226,7 +10156,6 @@ import {
|
|
|
10226
10156
|
readYamlFile as readYamlFile5,
|
|
10227
10157
|
resolveClaudeCodeCommand,
|
|
10228
10158
|
resolveCodexCommand,
|
|
10229
|
-
resolveRepositoryRoot as resolveRepositoryRoot9,
|
|
10230
10159
|
SESSION_SCHEMA_VERSION as SESSION_SCHEMA_VERSION2,
|
|
10231
10160
|
SessionSchema as SessionSchema2,
|
|
10232
10161
|
sanitizeRelatedFiles,
|
|
@@ -10281,7 +10210,7 @@ async function runTrackedTool(args, options, ctx, adapter) {
|
|
|
10281
10210
|
const { command } = await adapter.resolveCommand();
|
|
10282
10211
|
const childArgs = adapter.transformArgs ? adapter.transformArgs(args) : args;
|
|
10283
10212
|
const cwd = options.cwd ?? process.cwd();
|
|
10284
|
-
const repoRoot = await
|
|
10213
|
+
const repoRoot = await resolveRepositoryRootInPlace(cwd, "run");
|
|
10285
10214
|
const paths = basouPaths18(repoRoot);
|
|
10286
10215
|
await assertBasouRootSafe13(paths.root);
|
|
10287
10216
|
const manifest = await readManifest11(paths);
|
|
@@ -10650,18 +10579,6 @@ async function finalizeSessionAsFailed2(paths, sessionDir, sessionId, appendEven
|
|
|
10650
10579
|
s.session.invocation.exit_code = null;
|
|
10651
10580
|
});
|
|
10652
10581
|
}
|
|
10653
|
-
async function resolveRepositoryRootForRun(cwd) {
|
|
10654
|
-
try {
|
|
10655
|
-
return await resolveRepositoryRoot9(cwd);
|
|
10656
|
-
} catch (error) {
|
|
10657
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
10658
|
-
throw new Error("Not a git repository. Run 'git init' first, then re-run 'basou run'.", {
|
|
10659
|
-
cause: error
|
|
10660
|
-
});
|
|
10661
|
-
}
|
|
10662
|
-
throw error;
|
|
10663
|
-
}
|
|
10664
|
-
}
|
|
10665
10582
|
async function noteCodexHookStatusPreSpawn(_cwd, ctx) {
|
|
10666
10583
|
const hooksPath = ctx.codexHooksPath ?? DEFAULT_CODEX_HOOKS_PATH;
|
|
10667
10584
|
let location;
|
|
@@ -11388,8 +11305,7 @@ import {
|
|
|
11388
11305
|
assertBasouRootSafe as assertBasouRootSafe15,
|
|
11389
11306
|
basouPaths as basouPaths20,
|
|
11390
11307
|
computeWorkStats,
|
|
11391
|
-
findErrorCode as findErrorCode14
|
|
11392
|
-
resolveRepositoryRoot as resolveRepositoryRoot10
|
|
11308
|
+
findErrorCode as findErrorCode14
|
|
11393
11309
|
} from "@basou/core";
|
|
11394
11310
|
function registerStatsCommand(program) {
|
|
11395
11311
|
program.command("stats").description("Report how much the AI worked (output volume + time proxies) across sessions").option("--by-source", "Break the totals down by session source kind").option("--by-day", "Break billable time and volume down by calendar day").option("--json", "Output the full stats as JSON").option("-v, --verbose", "Show error causes").action(async (options) => {
|
|
@@ -11406,7 +11322,7 @@ async function runStats(options, ctx = {}) {
|
|
|
11406
11322
|
}
|
|
11407
11323
|
async function doRunStats(options, ctx) {
|
|
11408
11324
|
const cwd = ctx.cwd ?? process.cwd();
|
|
11409
|
-
const repositoryRoot = await
|
|
11325
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "stats");
|
|
11410
11326
|
const paths = basouPaths20(repositoryRoot);
|
|
11411
11327
|
await assertWorkspaceInitialized13(paths.root);
|
|
11412
11328
|
const now = ctx.nowProvider?.() ?? /* @__PURE__ */ new Date();
|
|
@@ -11494,18 +11410,6 @@ function formatFloorMs(ms) {
|
|
|
11494
11410
|
function formatInt(n) {
|
|
11495
11411
|
return n.toLocaleString("en-US");
|
|
11496
11412
|
}
|
|
11497
|
-
async function resolveRepositoryRootForStats(cwd) {
|
|
11498
|
-
try {
|
|
11499
|
-
return await resolveRepositoryRoot10(cwd);
|
|
11500
|
-
} catch (error) {
|
|
11501
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
11502
|
-
throw new Error("Not a git repository. Run 'git init' first, then re-run 'basou stats'.", {
|
|
11503
|
-
cause: error
|
|
11504
|
-
});
|
|
11505
|
-
}
|
|
11506
|
-
throw error;
|
|
11507
|
-
}
|
|
11508
|
-
}
|
|
11509
11413
|
async function assertWorkspaceInitialized13(basouRoot) {
|
|
11510
11414
|
try {
|
|
11511
11415
|
await assertBasouRootSafe15(basouRoot);
|
|
@@ -11524,7 +11428,6 @@ import {
|
|
|
11524
11428
|
buildStatusSnapshot,
|
|
11525
11429
|
findErrorCode as findErrorCode15,
|
|
11526
11430
|
readManifest as readManifest13,
|
|
11527
|
-
resolveRepositoryRoot as resolveRepositoryRoot11,
|
|
11528
11431
|
writeStatus
|
|
11529
11432
|
} from "@basou/core";
|
|
11530
11433
|
function registerStatusCommand(program) {
|
|
@@ -11542,7 +11445,7 @@ async function runStatus(options, ctx = {}) {
|
|
|
11542
11445
|
}
|
|
11543
11446
|
async function doRunStatus(options, ctx) {
|
|
11544
11447
|
const cwd = ctx.cwd ?? process.cwd();
|
|
11545
|
-
const repositoryRoot = await
|
|
11448
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "status");
|
|
11546
11449
|
const paths = basouPaths21(repositoryRoot);
|
|
11547
11450
|
try {
|
|
11548
11451
|
await assertBasouRootSafe16(paths.root);
|
|
@@ -11580,18 +11483,6 @@ function renderTextStatus(s) {
|
|
|
11580
11483
|
const present = Object.values(dp).filter((v) => v === true).length;
|
|
11581
11484
|
console.log(`Subdirectories present: ${present}/${total}`);
|
|
11582
11485
|
}
|
|
11583
|
-
async function resolveRepositoryRootForStatus(cwd) {
|
|
11584
|
-
try {
|
|
11585
|
-
return await resolveRepositoryRoot11(cwd);
|
|
11586
|
-
} catch (error) {
|
|
11587
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
11588
|
-
throw new Error("Not a git repository. Run 'git init' first, then re-run 'basou status'.", {
|
|
11589
|
-
cause: error
|
|
11590
|
-
});
|
|
11591
|
-
}
|
|
11592
|
-
throw error;
|
|
11593
|
-
}
|
|
11594
|
-
}
|
|
11595
11486
|
function formatVersionGateMessage(error) {
|
|
11596
11487
|
const issues = error.issues;
|
|
11597
11488
|
if (!Array.isArray(issues)) return void 0;
|
|
@@ -12733,7 +12624,6 @@ import {
|
|
|
12733
12624
|
basouPaths as basouPaths23,
|
|
12734
12625
|
enumerateSessionEntries as enumerateSessionEntries3,
|
|
12735
12626
|
findErrorCode as findErrorCode17,
|
|
12736
|
-
resolveRepositoryRoot as resolveRepositoryRoot12,
|
|
12737
12627
|
resolveSessionId as resolveSessionId5,
|
|
12738
12628
|
verifyEventsChain
|
|
12739
12629
|
} from "@basou/core";
|
|
@@ -12762,7 +12652,7 @@ async function doRunVerify(options, ctx) {
|
|
|
12762
12652
|
throw new Error("Specify either --session <id> or --all, not both");
|
|
12763
12653
|
}
|
|
12764
12654
|
const cwd = ctx.cwd ?? process.cwd();
|
|
12765
|
-
const repositoryRoot = await
|
|
12655
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "verify");
|
|
12766
12656
|
const paths = basouPaths23(repositoryRoot);
|
|
12767
12657
|
await assertWorkspaceInitialized15(paths.root);
|
|
12768
12658
|
const sessionIds = options.session !== void 0 ? [await resolveSessionId5(paths, options.session, { allowNotDirectory: true })] : await enumerateAllSessionNames2(paths);
|
|
@@ -12816,18 +12706,6 @@ async function enumerateAllSessionNames2(paths) {
|
|
|
12816
12706
|
const { dirs, notDirectories } = await enumerateSessionEntries3(paths);
|
|
12817
12707
|
return [...dirs, ...notDirectories].sort();
|
|
12818
12708
|
}
|
|
12819
|
-
async function resolveRepositoryRootForVerify(cwd) {
|
|
12820
|
-
try {
|
|
12821
|
-
return await resolveRepositoryRoot12(cwd);
|
|
12822
|
-
} catch (error) {
|
|
12823
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
12824
|
-
throw new Error("Not a git repository. Run 'git init' first, then re-run 'basou verify'.", {
|
|
12825
|
-
cause: error
|
|
12826
|
-
});
|
|
12827
|
-
}
|
|
12828
|
-
throw error;
|
|
12829
|
-
}
|
|
12830
|
-
}
|
|
12831
12709
|
async function assertWorkspaceInitialized15(basouRoot) {
|
|
12832
12710
|
try {
|
|
12833
12711
|
await assertBasouRootSafe18(basouRoot);
|
|
@@ -12848,8 +12726,7 @@ import {
|
|
|
12848
12726
|
basouPaths as basouPaths25,
|
|
12849
12727
|
findErrorCode as findErrorCode19,
|
|
12850
12728
|
loadPortfolioConfig as loadPortfolioConfig6,
|
|
12851
|
-
readManifest as readManifest18
|
|
12852
|
-
resolveRepositoryRoot as resolveRepositoryRoot14
|
|
12729
|
+
readManifest as readManifest18
|
|
12853
12730
|
} from "@basou/core";
|
|
12854
12731
|
import { InvalidArgumentError as InvalidArgumentError8 } from "commander";
|
|
12855
12732
|
|
|
@@ -12859,12 +12736,15 @@ import { readdir as readdir3, stat as stat7 } from "fs/promises";
|
|
|
12859
12736
|
import { homedir as homedir12 } from "os";
|
|
12860
12737
|
import { basename as basename9, dirname as dirname7, join as join16 } from "path";
|
|
12861
12738
|
import { createInterface as createInterface2 } from "readline";
|
|
12862
|
-
import { basouPaths as basouPaths24, readManifest as readManifest15
|
|
12739
|
+
import { basouPaths as basouPaths24, readManifest as readManifest15 } from "@basou/core";
|
|
12863
12740
|
function uncapturedTotal(result) {
|
|
12864
12741
|
return result.groups.reduce((sum, g) => sum + g.logs, 0) + result.unplaceable;
|
|
12865
12742
|
}
|
|
12866
12743
|
async function checkPortfolioCoverage(workspaces, ctx = {}) {
|
|
12867
|
-
const { roots, inertWorkspaces } = await collectDeclaredRoots(
|
|
12744
|
+
const { roots, inertWorkspaces } = await collectDeclaredRoots(
|
|
12745
|
+
workspaces,
|
|
12746
|
+
ctx.portfolioConfigPath
|
|
12747
|
+
);
|
|
12868
12748
|
const listedDirs = new Set([...roots].map((root) => encodeProjectDir(root)));
|
|
12869
12749
|
const claudeProjectsDir = ctx.claudeProjectsDir ?? join16(homedir12(), ".claude", "projects");
|
|
12870
12750
|
const codexSessionsDir = ctx.codexSessionsDir ?? join16(homedir12(), ".codex", "sessions");
|
|
@@ -12889,13 +12769,16 @@ async function checkPortfolioCoverage(workspaces, ctx = {}) {
|
|
|
12889
12769
|
}
|
|
12890
12770
|
return tally.finish(absentTrees, inertWorkspaces);
|
|
12891
12771
|
}
|
|
12892
|
-
async function collectDeclaredRoots(workspaces) {
|
|
12772
|
+
async function collectDeclaredRoots(workspaces, portfolioConfigPath) {
|
|
12893
12773
|
const roots = /* @__PURE__ */ new Set();
|
|
12894
12774
|
const inertWorkspaces = [];
|
|
12895
12775
|
for (const ws of workspaces) {
|
|
12896
12776
|
let importRoot;
|
|
12897
12777
|
try {
|
|
12898
|
-
importRoot = await
|
|
12778
|
+
importRoot = await resolveBasouRootForCommand(ws.repoRoot, "import", {
|
|
12779
|
+
quiet: true,
|
|
12780
|
+
...portfolioConfigPath !== void 0 ? { portfolioConfigPath } : {}
|
|
12781
|
+
});
|
|
12899
12782
|
} catch {
|
|
12900
12783
|
inertWorkspaces.push({ path: ws.repoRoot, reason: "not_a_git_repo" });
|
|
12901
12784
|
continue;
|
|
@@ -15009,9 +14892,13 @@ async function handleWorkspaceGet(res, sub, ws, nowProvider, resolveRemoteUrl, b
|
|
|
15009
14892
|
}
|
|
15010
14893
|
return false;
|
|
15011
14894
|
}
|
|
14895
|
+
var IMPORT_SUBS = /* @__PURE__ */ new Set(["import/claude-code", "import/codex"]);
|
|
15012
14896
|
async function handleWorkspacePost(res, sub, ws, body, deps, runExclusive) {
|
|
15013
14897
|
const nowIso = deps.nowProvider().toISOString();
|
|
15014
14898
|
const actionOptions = readActionOptions(body);
|
|
14899
|
+
if (!ws.initialized && (sub === "refresh" || IMPORT_SUBS.has(sub))) {
|
|
14900
|
+
throw new Error("Workspace not initialized. Run 'basou init' first.");
|
|
14901
|
+
}
|
|
15015
14902
|
if (sub === "refresh") {
|
|
15016
14903
|
const result = await runExclusive(
|
|
15017
14904
|
() => refreshAll({ options: actionOptions, ctx: ws.importCtx, paths: ws.paths, nowIso })
|
|
@@ -15388,7 +15275,8 @@ async function doRunView(options, ctx) {
|
|
|
15388
15275
|
if (isWholeRegistry) {
|
|
15389
15276
|
const coverage = await checkPortfolioCoverage(deps.workspaces, {
|
|
15390
15277
|
...ctx.claudeProjectsDir !== void 0 ? { claudeProjectsDir: ctx.claudeProjectsDir } : {},
|
|
15391
|
-
...ctx.codexSessionsDir !== void 0 ? { codexSessionsDir: ctx.codexSessionsDir } : {}
|
|
15278
|
+
...ctx.codexSessionsDir !== void 0 ? { codexSessionsDir: ctx.codexSessionsDir } : {},
|
|
15279
|
+
...ctx.portfolioConfigPath !== void 0 ? { portfolioConfigPath: ctx.portfolioConfigPath } : {}
|
|
15392
15280
|
});
|
|
15393
15281
|
console.log("");
|
|
15394
15282
|
for (const line of formatCoverageReport(coverage)) console.log(line);
|
|
@@ -15431,7 +15319,7 @@ async function doRunView(options, ctx) {
|
|
|
15431
15319
|
}
|
|
15432
15320
|
}
|
|
15433
15321
|
async function buildSingleDeps(ctx, cwd) {
|
|
15434
|
-
const repositoryRoot = await
|
|
15322
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "view");
|
|
15435
15323
|
const paths = basouPaths25(repositoryRoot);
|
|
15436
15324
|
await assertWorkspaceInitialized16(paths.root);
|
|
15437
15325
|
const entry = await buildWorkspaceEntry(repositoryRoot, ctx);
|
|
@@ -15562,18 +15450,6 @@ function waitForShutdown(signal) {
|
|
|
15562
15450
|
}
|
|
15563
15451
|
});
|
|
15564
15452
|
}
|
|
15565
|
-
async function resolveRepositoryRootForView(cwd) {
|
|
15566
|
-
try {
|
|
15567
|
-
return await resolveRepositoryRoot14(cwd);
|
|
15568
|
-
} catch (error) {
|
|
15569
|
-
if (error instanceof Error && error.message === "Not a git repository") {
|
|
15570
|
-
throw new Error("Not a git repository. Run 'git init' first, then re-run 'basou view'.", {
|
|
15571
|
-
cause: error
|
|
15572
|
-
});
|
|
15573
|
-
}
|
|
15574
|
-
throw error;
|
|
15575
|
-
}
|
|
15576
|
-
}
|
|
15577
15453
|
async function assertWorkspaceInitialized16(basouRoot) {
|
|
15578
15454
|
try {
|
|
15579
15455
|
await assertBasouRootSafe19(basouRoot);
|
|
@@ -15617,7 +15493,7 @@ function installExperimentalNotice(program, names = EXPERIMENTAL_COMMANDS, write
|
|
|
15617
15493
|
function readBuildStamp() {
|
|
15618
15494
|
if (false) return void 0;
|
|
15619
15495
|
try {
|
|
15620
|
-
return JSON.parse('{"version":"0.
|
|
15496
|
+
return JSON.parse('{"version":"0.66.0","commit":"2cd6700","committedAt":"2026-10-08T13:10:32+09:00"}');
|
|
15621
15497
|
} catch {
|
|
15622
15498
|
return void 0;
|
|
15623
15499
|
}
|