@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/index.js
CHANGED
|
@@ -138,7 +138,7 @@ import {
|
|
|
138
138
|
assertBasouRootSafe,
|
|
139
139
|
assertLockStoreSafe,
|
|
140
140
|
assertSessionDirSafe,
|
|
141
|
-
basouPaths,
|
|
141
|
+
basouPaths as basouPaths2,
|
|
142
142
|
EVENT_SCHEMA_VERSION,
|
|
143
143
|
enumerateApprovals,
|
|
144
144
|
findErrorCode,
|
|
@@ -152,9 +152,154 @@ import {
|
|
|
152
152
|
prefixedUlid,
|
|
153
153
|
readSessionYaml,
|
|
154
154
|
readYamlFile,
|
|
155
|
-
replayEvents
|
|
155
|
+
replayEvents
|
|
156
|
+
} from "@basou/core";
|
|
157
|
+
|
|
158
|
+
// src/lib/repo-root.ts
|
|
159
|
+
import { realpath, stat } from "fs/promises";
|
|
160
|
+
import { basename, resolve } from "path";
|
|
161
|
+
import {
|
|
162
|
+
basouPaths,
|
|
163
|
+
defaultPortfolioConfigPath,
|
|
164
|
+
loadPortfolioConfig,
|
|
165
|
+
readManifest,
|
|
166
|
+
resolveBasouRepositoryRoot,
|
|
156
167
|
resolveRepositoryRoot
|
|
157
168
|
} from "@basou/core";
|
|
169
|
+
async function resolveBasouRootForCommand(cwd, commandName, opts = {}) {
|
|
170
|
+
let root;
|
|
171
|
+
try {
|
|
172
|
+
root = await resolveBasouRepositoryRoot(cwd, {
|
|
173
|
+
onRedirect: ({ via, root: root2 }) => {
|
|
174
|
+
if (opts.quiet !== true) console.error(`Resolved workspace view to ${root2} (via ${via}).`);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
} catch (error) {
|
|
178
|
+
if (error instanceof Error && error.message === "Not a git repository") {
|
|
179
|
+
throw new Error(
|
|
180
|
+
`Not a git repository. Run 'git init' first, then re-run 'basou ${commandName}'.`,
|
|
181
|
+
{ cause: error }
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
if (!await hasBasouStore(root)) {
|
|
187
|
+
const master = await resolveMemberToMaster(
|
|
188
|
+
root,
|
|
189
|
+
opts.portfolioConfigPath ?? defaultPortfolioConfigPath()
|
|
190
|
+
);
|
|
191
|
+
if (master !== void 0) {
|
|
192
|
+
if (opts.quiet !== true) {
|
|
193
|
+
console.error(
|
|
194
|
+
`Resolved portfolio member to ${master.root} (via portfolio: ${master.label}).`
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
return master.root;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return root;
|
|
201
|
+
}
|
|
202
|
+
async function resolveRepositoryRootInPlace(cwd, commandName) {
|
|
203
|
+
try {
|
|
204
|
+
return await resolveRepositoryRoot(cwd);
|
|
205
|
+
} catch (error) {
|
|
206
|
+
if (!(error instanceof Error) || error.message !== "Not a git repository") throw error;
|
|
207
|
+
const links = await describeWorkspaceView(cwd);
|
|
208
|
+
if (links !== void 0) {
|
|
209
|
+
throw new Error(
|
|
210
|
+
`Not a git repository: this is a workspace view (it links ${links}). Run 'basou ${commandName}' inside a repository instead.`,
|
|
211
|
+
{ cause: error }
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
throw new Error(
|
|
215
|
+
`Not a git repository. Run 'git init' first, then re-run 'basou ${commandName}'.`,
|
|
216
|
+
{ cause: error }
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async function describeWorkspaceView(dir) {
|
|
221
|
+
let via;
|
|
222
|
+
try {
|
|
223
|
+
await resolveBasouRepositoryRoot(dir, {
|
|
224
|
+
onRedirect: (info) => {
|
|
225
|
+
via = info.via;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
} catch (error) {
|
|
229
|
+
if (error instanceof Error && error.message.startsWith("Ambiguous workspace view:")) {
|
|
230
|
+
return "more than one repository with a .basou store";
|
|
231
|
+
}
|
|
232
|
+
return void 0;
|
|
233
|
+
}
|
|
234
|
+
return via;
|
|
235
|
+
}
|
|
236
|
+
async function hasBasouStore(root) {
|
|
237
|
+
try {
|
|
238
|
+
return (await stat(basouPaths(root).root)).isDirectory();
|
|
239
|
+
} catch {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async function resolveMemberToMaster(repoRoot, configPath) {
|
|
244
|
+
let workspaces;
|
|
245
|
+
try {
|
|
246
|
+
workspaces = await loadPortfolioConfig(configPath);
|
|
247
|
+
} catch (error) {
|
|
248
|
+
if (!(error instanceof Error) || !error.message.startsWith("No portfolio config at")) {
|
|
249
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
250
|
+
console.error(`Ignoring ~/.basou/portfolio.yaml: ${detail}`);
|
|
251
|
+
}
|
|
252
|
+
return void 0;
|
|
253
|
+
}
|
|
254
|
+
const memberReal = await realpathOrNull(repoRoot);
|
|
255
|
+
if (memberReal === null) return void 0;
|
|
256
|
+
const claimants = /* @__PURE__ */ new Map();
|
|
257
|
+
const seenMaster = /* @__PURE__ */ new Set();
|
|
258
|
+
for (const ws of workspaces) {
|
|
259
|
+
const masterReal = await realpathOrNull(ws.path);
|
|
260
|
+
if (masterReal === null) continue;
|
|
261
|
+
if (masterReal === memberReal) continue;
|
|
262
|
+
if (seenMaster.has(masterReal)) continue;
|
|
263
|
+
seenMaster.add(masterReal);
|
|
264
|
+
let manifest;
|
|
265
|
+
try {
|
|
266
|
+
manifest = await readManifest(basouPaths(masterReal));
|
|
267
|
+
} catch (error) {
|
|
268
|
+
if (error instanceof Error && error.message !== "YAML file not found") {
|
|
269
|
+
console.error(
|
|
270
|
+
`Skipping portfolio workspace '${ws.label ?? basename(masterReal)}': could not read its manifest (${error.message}).`
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
const sourceRoots = manifest.import?.source_roots ?? ["."];
|
|
276
|
+
for (const sr of sourceRoots) {
|
|
277
|
+
const real = await realpathOrNull(resolve(masterReal, sr));
|
|
278
|
+
if (real !== null && real === memberReal) {
|
|
279
|
+
claimants.set(masterReal, { root: masterReal, label: ws.label ?? basename(masterReal) });
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const matched = [...claimants.values()];
|
|
285
|
+
if (matched.length === 1) return matched[0];
|
|
286
|
+
if (matched.length > 1) {
|
|
287
|
+
const names = matched.map((c) => c.label).join(", ");
|
|
288
|
+
throw new Error(
|
|
289
|
+
`This repository is declared as a source root by ${matched.length} portfolio workspaces (${names}). Disambiguate in ~/.basou/portfolio.yaml so only one aggregates it.`
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
return void 0;
|
|
293
|
+
}
|
|
294
|
+
async function realpathOrNull(p) {
|
|
295
|
+
try {
|
|
296
|
+
return await realpath(p);
|
|
297
|
+
} catch {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// src/commands/approval.ts
|
|
158
303
|
var APPR_PREFIX = "appr_";
|
|
159
304
|
var SHORT_ID_BASE_LEN = 6;
|
|
160
305
|
var SHORT_ID_MAX_LEN = 26;
|
|
@@ -190,8 +335,8 @@ async function runApprovalList(options, ctx = {}) {
|
|
|
190
335
|
}
|
|
191
336
|
async function doRunApprovalList(options, ctx) {
|
|
192
337
|
const cwd = ctx.cwd ?? process.cwd();
|
|
193
|
-
const repositoryRoot = await
|
|
194
|
-
const paths =
|
|
338
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "approval list");
|
|
339
|
+
const paths = basouPaths2(repositoryRoot);
|
|
195
340
|
await assertWorkspaceInitialized(paths.root);
|
|
196
341
|
const ids = await enumerateApprovals(paths);
|
|
197
342
|
for (const entry of ids.unfollowed) {
|
|
@@ -263,8 +408,8 @@ async function runApprovalShow(idInput, options, ctx = {}) {
|
|
|
263
408
|
}
|
|
264
409
|
async function doRunApprovalShow(idInput, options, ctx) {
|
|
265
410
|
const cwd = ctx.cwd ?? process.cwd();
|
|
266
|
-
const repositoryRoot = await
|
|
267
|
-
const paths =
|
|
411
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "approval show");
|
|
412
|
+
const paths = basouPaths2(repositoryRoot);
|
|
268
413
|
await assertWorkspaceInitialized(paths.root);
|
|
269
414
|
const { id, unfollowed } = await resolveApprovalId(paths, idInput);
|
|
270
415
|
for (const entry2 of unfollowed) console.error(`Warning: ${describeUnfollowed(entry2)}`);
|
|
@@ -329,8 +474,8 @@ async function doRunApprovalResolve(idInput, options, ctx, decision) {
|
|
|
329
474
|
}
|
|
330
475
|
}
|
|
331
476
|
const cwd = ctx.cwd ?? process.cwd();
|
|
332
|
-
const repositoryRoot = await
|
|
333
|
-
const paths =
|
|
477
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, `approval ${decision}`);
|
|
478
|
+
const paths = basouPaths2(repositoryRoot);
|
|
334
479
|
await assertWorkspaceInitialized(paths.root);
|
|
335
480
|
const { id, location } = await resolveApprovalId(paths, idInput);
|
|
336
481
|
if (location === "resolved") {
|
|
@@ -651,19 +796,6 @@ function truncate(value, maxLength) {
|
|
|
651
796
|
if (value.length <= maxLength) return value;
|
|
652
797
|
return `${value.slice(0, maxLength - 3)}...`;
|
|
653
798
|
}
|
|
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
799
|
async function assertWorkspaceInitialized(basouRoot) {
|
|
668
800
|
try {
|
|
669
801
|
await assertBasouRootSafe(basouRoot);
|
|
@@ -733,16 +865,16 @@ import {
|
|
|
733
865
|
|
|
734
866
|
// src/commands/import.ts
|
|
735
867
|
import { createReadStream } from "fs";
|
|
736
|
-
import { readdir, readFile, rm, stat } from "fs/promises";
|
|
868
|
+
import { readdir, readFile, rm, stat as stat2 } from "fs/promises";
|
|
737
869
|
import { homedir } from "os";
|
|
738
|
-
import { basename, dirname as dirname2, join as join2, resolve } from "path";
|
|
870
|
+
import { basename as basename2, dirname as dirname2, join as join2, resolve as resolve2 } from "path";
|
|
739
871
|
import { createInterface } from "readline";
|
|
740
872
|
import {
|
|
741
873
|
AGENT_INFRA_DIRS,
|
|
742
874
|
assertBasouRootSafe as assertBasouRootSafe2,
|
|
743
875
|
assertLockStoreSafe as assertLockStoreSafe2,
|
|
744
876
|
assertSessionStoreSafe,
|
|
745
|
-
basouPaths as
|
|
877
|
+
basouPaths as basouPaths3,
|
|
746
878
|
CLAUDE_IMPORT_SOURCE,
|
|
747
879
|
CODEX_IMPORT_SOURCE,
|
|
748
880
|
classifyFilesBySourceRoot,
|
|
@@ -753,11 +885,10 @@ import {
|
|
|
753
885
|
findErrorCode as findErrorCode2,
|
|
754
886
|
importSessionFromJson,
|
|
755
887
|
observedFilesOf,
|
|
756
|
-
readManifest,
|
|
888
|
+
readManifest as readManifest2,
|
|
757
889
|
readSessionObservation,
|
|
758
890
|
readSessionYaml as readSessionYaml2,
|
|
759
891
|
reimportPreservingId,
|
|
760
|
-
resolveRepositoryRoot as resolveRepositoryRoot2,
|
|
761
892
|
SESSION_IMPORT_SCHEMA_VERSION,
|
|
762
893
|
SessionImportPayloadSchema
|
|
763
894
|
} from "@basou/core";
|
|
@@ -827,10 +958,10 @@ function resolveSourceRoots(args) {
|
|
|
827
958
|
const { projectFlags, manifest, repoRoot, cwd } = args;
|
|
828
959
|
let resolved;
|
|
829
960
|
if (projectFlags.length > 0) {
|
|
830
|
-
resolved = projectFlags.map((p) =>
|
|
961
|
+
resolved = projectFlags.map((p) => resolve2(cwd, p));
|
|
831
962
|
} else {
|
|
832
963
|
const roots = manifest.import?.source_roots;
|
|
833
|
-
resolved = roots !== void 0 && roots.length > 0 ? roots.map((r) =>
|
|
964
|
+
resolved = roots !== void 0 && roots.length > 0 ? roots.map((r) => resolve2(repoRoot, r)) : [repoRoot];
|
|
834
965
|
}
|
|
835
966
|
return [...new Set(resolved)];
|
|
836
967
|
}
|
|
@@ -848,7 +979,7 @@ async function doRunImportClaudeCode(options, ctx) {
|
|
|
848
979
|
const files = await selectTranscriptFiles(projectsRoot, projectPaths, options);
|
|
849
980
|
const projectSet = new Set(projectPaths);
|
|
850
981
|
const candidates = files.map((file) => {
|
|
851
|
-
const externalId =
|
|
982
|
+
const externalId = basename2(file, ".jsonl");
|
|
852
983
|
return {
|
|
853
984
|
externalId,
|
|
854
985
|
sourcePath: file,
|
|
@@ -923,10 +1054,10 @@ function assertSelector(options) {
|
|
|
923
1054
|
}
|
|
924
1055
|
async function resolveImportTarget(ctx) {
|
|
925
1056
|
const cwd = ctx.cwd ?? process.cwd();
|
|
926
|
-
const repositoryRoot = await
|
|
927
|
-
const paths =
|
|
1057
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "import");
|
|
1058
|
+
const paths = basouPaths3(repositoryRoot);
|
|
928
1059
|
await assertWorkspaceInitialized2(paths.root);
|
|
929
|
-
const manifest = await
|
|
1060
|
+
const manifest = await readManifest2(paths);
|
|
930
1061
|
return { repositoryRoot, paths, manifest };
|
|
931
1062
|
}
|
|
932
1063
|
async function importDerivedSessions(paths, manifest, options, sourceKind, candidates, projectPaths, boundaryDeclared) {
|
|
@@ -1173,7 +1304,7 @@ async function selectTranscriptFiles(projectsRoot, projectPaths, options) {
|
|
|
1173
1304
|
}
|
|
1174
1305
|
async function pathExists(file) {
|
|
1175
1306
|
try {
|
|
1176
|
-
await
|
|
1307
|
+
await stat2(file);
|
|
1177
1308
|
return true;
|
|
1178
1309
|
} catch (error) {
|
|
1179
1310
|
if (findErrorCode2(error, "ENOENT")) return false;
|
|
@@ -1182,7 +1313,7 @@ async function pathExists(file) {
|
|
|
1182
1313
|
}
|
|
1183
1314
|
async function statSize(file) {
|
|
1184
1315
|
try {
|
|
1185
|
-
return (await
|
|
1316
|
+
return (await stat2(file)).size;
|
|
1186
1317
|
} catch (error) {
|
|
1187
1318
|
if (findErrorCode2(error, "ENOENT")) return void 0;
|
|
1188
1319
|
throw error;
|
|
@@ -1374,18 +1505,6 @@ function shortId2(id) {
|
|
|
1374
1505
|
}
|
|
1375
1506
|
return id.slice(0, SHORT_ID_LEN2);
|
|
1376
1507
|
}
|
|
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
1508
|
async function assertWorkspaceInitialized2(basouRoot) {
|
|
1390
1509
|
try {
|
|
1391
1510
|
await assertBasouRootSafe2(basouRoot);
|
|
@@ -1578,111 +1697,6 @@ async function probeStaleness(args) {
|
|
|
1578
1697
|
}
|
|
1579
1698
|
}
|
|
1580
1699
|
|
|
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
1700
|
// src/commands/board.ts
|
|
1687
1701
|
var DEFAULT_BOARD_PATH = "board/board.yaml";
|
|
1688
1702
|
function registerBoardCommand(program2) {
|
|
@@ -2479,7 +2493,6 @@ import {
|
|
|
2479
2493
|
prefixedUlid as prefixedUlid2,
|
|
2480
2494
|
readManifest as readManifest4,
|
|
2481
2495
|
replayEvents as replayEvents2,
|
|
2482
|
-
resolveRepositoryRoot as resolveRepositoryRoot3,
|
|
2483
2496
|
resolveSessionId,
|
|
2484
2497
|
sanitizePath
|
|
2485
2498
|
} from "@basou/core";
|
|
@@ -2762,7 +2775,7 @@ async function warnLinkedFilesOutsideRoots(input) {
|
|
|
2762
2775
|
}
|
|
2763
2776
|
async function doRunDecisionRecord(options, ctx) {
|
|
2764
2777
|
const cwd = ctx.cwd ?? process.cwd();
|
|
2765
|
-
const repositoryRoot = await
|
|
2778
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "decision record");
|
|
2766
2779
|
const paths = basouPaths6(repositoryRoot);
|
|
2767
2780
|
await assertWorkspaceInitialized4(paths.root);
|
|
2768
2781
|
const now = ctx.nowProvider !== void 0 ? ctx.nowProvider() : /* @__PURE__ */ new Date();
|
|
@@ -3409,19 +3422,6 @@ function printDecisionResult(options, result) {
|
|
|
3409
3422
|
);
|
|
3410
3423
|
}
|
|
3411
3424
|
}
|
|
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
3425
|
async function assertWorkspaceInitialized4(basouRoot) {
|
|
3426
3426
|
try {
|
|
3427
3427
|
await assertBasouRootSafe4(basouRoot);
|
|
@@ -3441,7 +3441,6 @@ import {
|
|
|
3441
3441
|
readMarkdownFile as readMarkdownFile3,
|
|
3442
3442
|
renderDecisions as renderDecisions2,
|
|
3443
3443
|
renderWithMarkers as renderWithMarkers2,
|
|
3444
|
-
resolveRepositoryRoot as resolveRepositoryRoot4,
|
|
3445
3444
|
writeMarkdownFile as writeMarkdownFile2
|
|
3446
3445
|
} from "@basou/core";
|
|
3447
3446
|
function registerDecisionsCommand(program2) {
|
|
@@ -3461,7 +3460,7 @@ async function runDecisionsGenerate(options, ctx = {}) {
|
|
|
3461
3460
|
async function doRunDecisionsGenerate(options, ctx) {
|
|
3462
3461
|
void options;
|
|
3463
3462
|
const cwd = ctx.cwd ?? process.cwd();
|
|
3464
|
-
const repositoryRoot = await
|
|
3463
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "decisions generate");
|
|
3465
3464
|
const paths = basouPaths7(repositoryRoot);
|
|
3466
3465
|
await assertWorkspaceInitialized5(paths.root);
|
|
3467
3466
|
const nowIso = (ctx.nowProvider?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
@@ -3476,19 +3475,6 @@ async function doRunDecisionsGenerate(options, ctx) {
|
|
|
3476
3475
|
await writeMarkdownFile2(paths.files.decisions, finalBody);
|
|
3477
3476
|
console.log(`Generated .basou/decisions.md (decisions: ${result.decisionCount})`);
|
|
3478
3477
|
}
|
|
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
3478
|
async function assertWorkspaceInitialized5(basouRoot) {
|
|
3493
3479
|
try {
|
|
3494
3480
|
await assertBasouRootSafe5(basouRoot);
|
|
@@ -3519,7 +3505,6 @@ import {
|
|
|
3519
3505
|
prefixedUlid as prefixedUlid3,
|
|
3520
3506
|
readManifest as readManifest5,
|
|
3521
3507
|
readYamlFile as readYamlFile2,
|
|
3522
|
-
resolveRepositoryRoot as resolveRepositoryRoot5,
|
|
3523
3508
|
SESSION_SCHEMA_VERSION,
|
|
3524
3509
|
SessionSchema,
|
|
3525
3510
|
sanitizeWorkingDirectory,
|
|
@@ -3542,7 +3527,7 @@ async function runExec(command, args, options, ctx = {}) {
|
|
|
3542
3527
|
const now = ctx.now ?? (() => /* @__PURE__ */ new Date());
|
|
3543
3528
|
const cwd = options.cwd ?? process.cwd();
|
|
3544
3529
|
const timeout_ms = options.timeout !== void 0 ? parseDuration(options.timeout) : void 0;
|
|
3545
|
-
const repoRoot = await
|
|
3530
|
+
const repoRoot = await resolveRepositoryRootInPlace(cwd, "exec");
|
|
3546
3531
|
const paths = basouPaths8(repoRoot);
|
|
3547
3532
|
await assertBasouRootSafe6(paths.root);
|
|
3548
3533
|
const manifest = await readManifest5(paths);
|
|
@@ -3840,18 +3825,6 @@ async function finalizeSessionAsFailed(paths, sessionDir, sessionId, appendEvent
|
|
|
3840
3825
|
s.session.invocation.exit_code = null;
|
|
3841
3826
|
});
|
|
3842
3827
|
}
|
|
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
3828
|
|
|
3856
3829
|
// src/commands/handoff.ts
|
|
3857
3830
|
import {
|
|
@@ -5439,7 +5412,6 @@ import {
|
|
|
5439
5412
|
appendBasouGitignore,
|
|
5440
5413
|
createManifest,
|
|
5441
5414
|
ensureBasouDirectory,
|
|
5442
|
-
resolveRepositoryRoot as resolveRepositoryRoot6,
|
|
5443
5415
|
writeManifest
|
|
5444
5416
|
} from "@basou/core";
|
|
5445
5417
|
function collectValue(value, previous) {
|
|
@@ -5471,7 +5443,7 @@ async function runInit(options, ctx = {}) {
|
|
|
5471
5443
|
}
|
|
5472
5444
|
async function doRunInit(options, ctx) {
|
|
5473
5445
|
const cwd = ctx.cwd ?? process.cwd();
|
|
5474
|
-
const repositoryRoot = await
|
|
5446
|
+
const repositoryRoot = await resolveRepositoryRootInPlace(cwd, "init");
|
|
5475
5447
|
const workspaceName = options.name ?? basename6(repositoryRoot);
|
|
5476
5448
|
if (options.repoUrl !== void 0) {
|
|
5477
5449
|
console.error(
|
|
@@ -5507,18 +5479,6 @@ function renderGitignoreWarning(error, verbose) {
|
|
|
5507
5479
|
if (label !== void 0) console.error(`Caused by: ${label}`);
|
|
5508
5480
|
}
|
|
5509
5481
|
}
|
|
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
5482
|
|
|
5523
5483
|
// src/commands/note.ts
|
|
5524
5484
|
import { readFile as readFile5 } from "fs/promises";
|
|
@@ -5918,7 +5878,6 @@ import {
|
|
|
5918
5878
|
renderAnchorStarter,
|
|
5919
5879
|
renderViewPresetBlock,
|
|
5920
5880
|
renderWithMarkers as renderWithMarkers4,
|
|
5921
|
-
resolveRepositoryRoot as resolveRepositoryRoot7,
|
|
5922
5881
|
safeSimpleGit,
|
|
5923
5882
|
seedMarkers,
|
|
5924
5883
|
summarizePresetPlan,
|
|
@@ -8464,19 +8423,6 @@ async function runProjectNew(repos, options, ctx = {}) {
|
|
|
8464
8423
|
process.exitCode = 1;
|
|
8465
8424
|
}
|
|
8466
8425
|
}
|
|
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
8426
|
function validateProjectName(name) {
|
|
8481
8427
|
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name)) {
|
|
8482
8428
|
throw new Error(
|
|
@@ -8487,7 +8433,7 @@ function validateProjectName(name) {
|
|
|
8487
8433
|
}
|
|
8488
8434
|
async function doRunProjectNew(repos, options, ctx) {
|
|
8489
8435
|
const cwd = ctx.cwd ?? process.cwd();
|
|
8490
|
-
const repositoryRoot = await
|
|
8436
|
+
const repositoryRoot = await resolveRepositoryRootInPlace(cwd, "project new");
|
|
8491
8437
|
const workspaceName = basename7(repositoryRoot);
|
|
8492
8438
|
const productName = options.projectName !== void 0 ? validateProjectName(options.projectName) : void 0;
|
|
8493
8439
|
const viewStem = productName ?? workspaceName;
|
|
@@ -9694,7 +9640,6 @@ import {
|
|
|
9694
9640
|
basouPaths as basouPaths15,
|
|
9695
9641
|
findErrorCode as findErrorCode11,
|
|
9696
9642
|
renderReport,
|
|
9697
|
-
resolveRepositoryRoot as resolveRepositoryRoot8,
|
|
9698
9643
|
writeMarkdownFile as writeMarkdownFile6
|
|
9699
9644
|
} from "@basou/core";
|
|
9700
9645
|
function registerReportCommand(program2) {
|
|
@@ -9715,7 +9660,7 @@ async function runReportGenerate(options, ctx = {}) {
|
|
|
9715
9660
|
}
|
|
9716
9661
|
async function doRunReportGenerate(options, ctx) {
|
|
9717
9662
|
const cwd = ctx.cwd ?? process.cwd();
|
|
9718
|
-
const repositoryRoot = await
|
|
9663
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "report generate");
|
|
9719
9664
|
const paths = basouPaths15(repositoryRoot);
|
|
9720
9665
|
await assertWorkspaceInitialized10(paths.root);
|
|
9721
9666
|
const nowIso = (ctx.nowProvider?.() ?? /* @__PURE__ */ new Date()).toISOString();
|
|
@@ -9741,19 +9686,6 @@ async function doRunReportGenerate(options, ctx) {
|
|
|
9741
9686
|
console.log(result.body);
|
|
9742
9687
|
}
|
|
9743
9688
|
}
|
|
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
9689
|
async function assertWorkspaceInitialized10(basouRoot) {
|
|
9758
9690
|
try {
|
|
9759
9691
|
await assertBasouRootSafe11(basouRoot);
|
|
@@ -10226,7 +10158,6 @@ import {
|
|
|
10226
10158
|
readYamlFile as readYamlFile5,
|
|
10227
10159
|
resolveClaudeCodeCommand,
|
|
10228
10160
|
resolveCodexCommand,
|
|
10229
|
-
resolveRepositoryRoot as resolveRepositoryRoot9,
|
|
10230
10161
|
SESSION_SCHEMA_VERSION as SESSION_SCHEMA_VERSION2,
|
|
10231
10162
|
SessionSchema as SessionSchema2,
|
|
10232
10163
|
sanitizeRelatedFiles,
|
|
@@ -10281,7 +10212,7 @@ async function runTrackedTool(args, options, ctx, adapter) {
|
|
|
10281
10212
|
const { command } = await adapter.resolveCommand();
|
|
10282
10213
|
const childArgs = adapter.transformArgs ? adapter.transformArgs(args) : args;
|
|
10283
10214
|
const cwd = options.cwd ?? process.cwd();
|
|
10284
|
-
const repoRoot = await
|
|
10215
|
+
const repoRoot = await resolveRepositoryRootInPlace(cwd, "run");
|
|
10285
10216
|
const paths = basouPaths18(repoRoot);
|
|
10286
10217
|
await assertBasouRootSafe13(paths.root);
|
|
10287
10218
|
const manifest = await readManifest11(paths);
|
|
@@ -10650,18 +10581,6 @@ async function finalizeSessionAsFailed2(paths, sessionDir, sessionId, appendEven
|
|
|
10650
10581
|
s.session.invocation.exit_code = null;
|
|
10651
10582
|
});
|
|
10652
10583
|
}
|
|
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
10584
|
async function noteCodexHookStatusPreSpawn(_cwd, ctx) {
|
|
10666
10585
|
const hooksPath = ctx.codexHooksPath ?? DEFAULT_CODEX_HOOKS_PATH;
|
|
10667
10586
|
let location;
|
|
@@ -11388,8 +11307,7 @@ import {
|
|
|
11388
11307
|
assertBasouRootSafe as assertBasouRootSafe15,
|
|
11389
11308
|
basouPaths as basouPaths20,
|
|
11390
11309
|
computeWorkStats,
|
|
11391
|
-
findErrorCode as findErrorCode14
|
|
11392
|
-
resolveRepositoryRoot as resolveRepositoryRoot10
|
|
11310
|
+
findErrorCode as findErrorCode14
|
|
11393
11311
|
} from "@basou/core";
|
|
11394
11312
|
function registerStatsCommand(program2) {
|
|
11395
11313
|
program2.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 +11324,7 @@ async function runStats(options, ctx = {}) {
|
|
|
11406
11324
|
}
|
|
11407
11325
|
async function doRunStats(options, ctx) {
|
|
11408
11326
|
const cwd = ctx.cwd ?? process.cwd();
|
|
11409
|
-
const repositoryRoot = await
|
|
11327
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "stats");
|
|
11410
11328
|
const paths = basouPaths20(repositoryRoot);
|
|
11411
11329
|
await assertWorkspaceInitialized13(paths.root);
|
|
11412
11330
|
const now = ctx.nowProvider?.() ?? /* @__PURE__ */ new Date();
|
|
@@ -11494,18 +11412,6 @@ function formatFloorMs(ms) {
|
|
|
11494
11412
|
function formatInt(n) {
|
|
11495
11413
|
return n.toLocaleString("en-US");
|
|
11496
11414
|
}
|
|
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
11415
|
async function assertWorkspaceInitialized13(basouRoot) {
|
|
11510
11416
|
try {
|
|
11511
11417
|
await assertBasouRootSafe15(basouRoot);
|
|
@@ -11524,7 +11430,6 @@ import {
|
|
|
11524
11430
|
buildStatusSnapshot,
|
|
11525
11431
|
findErrorCode as findErrorCode15,
|
|
11526
11432
|
readManifest as readManifest13,
|
|
11527
|
-
resolveRepositoryRoot as resolveRepositoryRoot11,
|
|
11528
11433
|
writeStatus
|
|
11529
11434
|
} from "@basou/core";
|
|
11530
11435
|
function registerStatusCommand(program2) {
|
|
@@ -11542,7 +11447,7 @@ async function runStatus(options, ctx = {}) {
|
|
|
11542
11447
|
}
|
|
11543
11448
|
async function doRunStatus(options, ctx) {
|
|
11544
11449
|
const cwd = ctx.cwd ?? process.cwd();
|
|
11545
|
-
const repositoryRoot = await
|
|
11450
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "status");
|
|
11546
11451
|
const paths = basouPaths21(repositoryRoot);
|
|
11547
11452
|
try {
|
|
11548
11453
|
await assertBasouRootSafe16(paths.root);
|
|
@@ -11580,18 +11485,6 @@ function renderTextStatus(s) {
|
|
|
11580
11485
|
const present = Object.values(dp).filter((v) => v === true).length;
|
|
11581
11486
|
console.log(`Subdirectories present: ${present}/${total}`);
|
|
11582
11487
|
}
|
|
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
11488
|
function formatVersionGateMessage(error) {
|
|
11596
11489
|
const issues = error.issues;
|
|
11597
11490
|
if (!Array.isArray(issues)) return void 0;
|
|
@@ -12733,7 +12626,6 @@ import {
|
|
|
12733
12626
|
basouPaths as basouPaths23,
|
|
12734
12627
|
enumerateSessionEntries as enumerateSessionEntries3,
|
|
12735
12628
|
findErrorCode as findErrorCode17,
|
|
12736
|
-
resolveRepositoryRoot as resolveRepositoryRoot12,
|
|
12737
12629
|
resolveSessionId as resolveSessionId5,
|
|
12738
12630
|
verifyEventsChain
|
|
12739
12631
|
} from "@basou/core";
|
|
@@ -12762,7 +12654,7 @@ async function doRunVerify(options, ctx) {
|
|
|
12762
12654
|
throw new Error("Specify either --session <id> or --all, not both");
|
|
12763
12655
|
}
|
|
12764
12656
|
const cwd = ctx.cwd ?? process.cwd();
|
|
12765
|
-
const repositoryRoot = await
|
|
12657
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "verify");
|
|
12766
12658
|
const paths = basouPaths23(repositoryRoot);
|
|
12767
12659
|
await assertWorkspaceInitialized15(paths.root);
|
|
12768
12660
|
const sessionIds = options.session !== void 0 ? [await resolveSessionId5(paths, options.session, { allowNotDirectory: true })] : await enumerateAllSessionNames2(paths);
|
|
@@ -12816,18 +12708,6 @@ async function enumerateAllSessionNames2(paths) {
|
|
|
12816
12708
|
const { dirs, notDirectories } = await enumerateSessionEntries3(paths);
|
|
12817
12709
|
return [...dirs, ...notDirectories].sort();
|
|
12818
12710
|
}
|
|
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
12711
|
async function assertWorkspaceInitialized15(basouRoot) {
|
|
12832
12712
|
try {
|
|
12833
12713
|
await assertBasouRootSafe18(basouRoot);
|
|
@@ -12848,8 +12728,7 @@ import {
|
|
|
12848
12728
|
basouPaths as basouPaths25,
|
|
12849
12729
|
findErrorCode as findErrorCode19,
|
|
12850
12730
|
loadPortfolioConfig as loadPortfolioConfig6,
|
|
12851
|
-
readManifest as readManifest18
|
|
12852
|
-
resolveRepositoryRoot as resolveRepositoryRoot14
|
|
12731
|
+
readManifest as readManifest18
|
|
12853
12732
|
} from "@basou/core";
|
|
12854
12733
|
import { InvalidArgumentError as InvalidArgumentError8 } from "commander";
|
|
12855
12734
|
|
|
@@ -12859,12 +12738,15 @@ import { readdir as readdir3, stat as stat7 } from "fs/promises";
|
|
|
12859
12738
|
import { homedir as homedir12 } from "os";
|
|
12860
12739
|
import { basename as basename9, dirname as dirname7, join as join16 } from "path";
|
|
12861
12740
|
import { createInterface as createInterface2 } from "readline";
|
|
12862
|
-
import { basouPaths as basouPaths24, readManifest as readManifest15
|
|
12741
|
+
import { basouPaths as basouPaths24, readManifest as readManifest15 } from "@basou/core";
|
|
12863
12742
|
function uncapturedTotal(result) {
|
|
12864
12743
|
return result.groups.reduce((sum, g) => sum + g.logs, 0) + result.unplaceable;
|
|
12865
12744
|
}
|
|
12866
12745
|
async function checkPortfolioCoverage(workspaces, ctx = {}) {
|
|
12867
|
-
const { roots, inertWorkspaces } = await collectDeclaredRoots(
|
|
12746
|
+
const { roots, inertWorkspaces } = await collectDeclaredRoots(
|
|
12747
|
+
workspaces,
|
|
12748
|
+
ctx.portfolioConfigPath
|
|
12749
|
+
);
|
|
12868
12750
|
const listedDirs = new Set([...roots].map((root) => encodeProjectDir(root)));
|
|
12869
12751
|
const claudeProjectsDir = ctx.claudeProjectsDir ?? join16(homedir12(), ".claude", "projects");
|
|
12870
12752
|
const codexSessionsDir = ctx.codexSessionsDir ?? join16(homedir12(), ".codex", "sessions");
|
|
@@ -12889,13 +12771,16 @@ async function checkPortfolioCoverage(workspaces, ctx = {}) {
|
|
|
12889
12771
|
}
|
|
12890
12772
|
return tally.finish(absentTrees, inertWorkspaces);
|
|
12891
12773
|
}
|
|
12892
|
-
async function collectDeclaredRoots(workspaces) {
|
|
12774
|
+
async function collectDeclaredRoots(workspaces, portfolioConfigPath) {
|
|
12893
12775
|
const roots = /* @__PURE__ */ new Set();
|
|
12894
12776
|
const inertWorkspaces = [];
|
|
12895
12777
|
for (const ws of workspaces) {
|
|
12896
12778
|
let importRoot;
|
|
12897
12779
|
try {
|
|
12898
|
-
importRoot = await
|
|
12780
|
+
importRoot = await resolveBasouRootForCommand(ws.repoRoot, "import", {
|
|
12781
|
+
quiet: true,
|
|
12782
|
+
...portfolioConfigPath !== void 0 ? { portfolioConfigPath } : {}
|
|
12783
|
+
});
|
|
12899
12784
|
} catch {
|
|
12900
12785
|
inertWorkspaces.push({ path: ws.repoRoot, reason: "not_a_git_repo" });
|
|
12901
12786
|
continue;
|
|
@@ -15009,9 +14894,13 @@ async function handleWorkspaceGet(res, sub, ws, nowProvider, resolveRemoteUrl, b
|
|
|
15009
14894
|
}
|
|
15010
14895
|
return false;
|
|
15011
14896
|
}
|
|
14897
|
+
var IMPORT_SUBS = /* @__PURE__ */ new Set(["import/claude-code", "import/codex"]);
|
|
15012
14898
|
async function handleWorkspacePost(res, sub, ws, body, deps, runExclusive) {
|
|
15013
14899
|
const nowIso = deps.nowProvider().toISOString();
|
|
15014
14900
|
const actionOptions = readActionOptions(body);
|
|
14901
|
+
if (!ws.initialized && (sub === "refresh" || IMPORT_SUBS.has(sub))) {
|
|
14902
|
+
throw new Error("Workspace not initialized. Run 'basou init' first.");
|
|
14903
|
+
}
|
|
15015
14904
|
if (sub === "refresh") {
|
|
15016
14905
|
const result = await runExclusive(
|
|
15017
14906
|
() => refreshAll({ options: actionOptions, ctx: ws.importCtx, paths: ws.paths, nowIso })
|
|
@@ -15388,7 +15277,8 @@ async function doRunView(options, ctx) {
|
|
|
15388
15277
|
if (isWholeRegistry) {
|
|
15389
15278
|
const coverage = await checkPortfolioCoverage(deps.workspaces, {
|
|
15390
15279
|
...ctx.claudeProjectsDir !== void 0 ? { claudeProjectsDir: ctx.claudeProjectsDir } : {},
|
|
15391
|
-
...ctx.codexSessionsDir !== void 0 ? { codexSessionsDir: ctx.codexSessionsDir } : {}
|
|
15280
|
+
...ctx.codexSessionsDir !== void 0 ? { codexSessionsDir: ctx.codexSessionsDir } : {},
|
|
15281
|
+
...ctx.portfolioConfigPath !== void 0 ? { portfolioConfigPath: ctx.portfolioConfigPath } : {}
|
|
15392
15282
|
});
|
|
15393
15283
|
console.log("");
|
|
15394
15284
|
for (const line of formatCoverageReport(coverage)) console.log(line);
|
|
@@ -15431,7 +15321,7 @@ async function doRunView(options, ctx) {
|
|
|
15431
15321
|
}
|
|
15432
15322
|
}
|
|
15433
15323
|
async function buildSingleDeps(ctx, cwd) {
|
|
15434
|
-
const repositoryRoot = await
|
|
15324
|
+
const repositoryRoot = await resolveBasouRootForCommand(cwd, "view");
|
|
15435
15325
|
const paths = basouPaths25(repositoryRoot);
|
|
15436
15326
|
await assertWorkspaceInitialized16(paths.root);
|
|
15437
15327
|
const entry = await buildWorkspaceEntry(repositoryRoot, ctx);
|
|
@@ -15562,18 +15452,6 @@ function waitForShutdown(signal) {
|
|
|
15562
15452
|
}
|
|
15563
15453
|
});
|
|
15564
15454
|
}
|
|
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
15455
|
async function assertWorkspaceInitialized16(basouRoot) {
|
|
15578
15456
|
try {
|
|
15579
15457
|
await assertBasouRootSafe19(basouRoot);
|
|
@@ -15617,7 +15495,7 @@ function installExperimentalNotice(program2, names = EXPERIMENTAL_COMMANDS, writ
|
|
|
15617
15495
|
function readBuildStamp() {
|
|
15618
15496
|
if (false) return void 0;
|
|
15619
15497
|
try {
|
|
15620
|
-
return JSON.parse('{"version":"0.
|
|
15498
|
+
return JSON.parse('{"version":"0.66.0","commit":"2cd6700","committedAt":"2026-10-08T13:10:32+09:00"}');
|
|
15621
15499
|
} catch {
|
|
15622
15500
|
return void 0;
|
|
15623
15501
|
}
|