@basou/cli 0.53.0 → 0.54.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 +189 -93
- package/dist/index.js.map +1 -1
- package/dist/program.js +189 -93
- package/dist/program.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -4876,6 +4876,9 @@ async function resolveRepositoryRootForInit(cwd) {
|
|
|
4876
4876
|
}
|
|
4877
4877
|
|
|
4878
4878
|
// src/commands/note.ts
|
|
4879
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
4880
|
+
import { homedir as homedir9 } from "os";
|
|
4881
|
+
import { resolve as resolve8 } from "path";
|
|
4879
4882
|
import {
|
|
4880
4883
|
acquireLock as acquireLock4,
|
|
4881
4884
|
appendEventToExistingSession as appendEventToExistingSession2,
|
|
@@ -4886,7 +4889,8 @@ import {
|
|
|
4886
4889
|
findErrorCode as findErrorCode7,
|
|
4887
4890
|
LOCAL_CLI_EVENT_SOURCE as LOCAL_CLI_EVENT_SOURCE3,
|
|
4888
4891
|
readManifest as readManifest6,
|
|
4889
|
-
resolveSessionId as resolveSessionId2
|
|
4892
|
+
resolveSessionId as resolveSessionId2,
|
|
4893
|
+
sanitizePath as sanitizePath2
|
|
4890
4894
|
} from "@basou/core";
|
|
4891
4895
|
import { InvalidArgumentError as InvalidArgumentError3 } from "commander";
|
|
4892
4896
|
var NOTE_SUBCOMMAND_LOOKALIKES = /* @__PURE__ */ new Set([
|
|
@@ -4904,11 +4908,33 @@ var NOTE_SUBCOMMAND_LOOKALIKES = /* @__PURE__ */ new Set([
|
|
|
4904
4908
|
]);
|
|
4905
4909
|
var LABEL_BODY_MAX = 80;
|
|
4906
4910
|
var LABEL_TRUNCATE_HEAD2 = LABEL_BODY_MAX - 3;
|
|
4911
|
+
var NOTE_HELP = `
|
|
4912
|
+
Text that contains backticks, $(...), $VAR or ! is safest on stdin through a
|
|
4913
|
+
heredoc whose delimiter is QUOTED: the shell then passes the text through
|
|
4914
|
+
untouched. Inside double quotes the shell runs backticks and $(...) as commands
|
|
4915
|
+
and records their output in place of the text, without any error.
|
|
4916
|
+
|
|
4917
|
+
Example (heredoc on stdin):
|
|
4918
|
+
basou note <<'EOF'
|
|
4919
|
+
Next: rebase \`topic\` onto main, then rerun the $CI job.
|
|
4920
|
+
EOF
|
|
4921
|
+
|
|
4922
|
+
Keep the text on its own lines: words on the same line as <<'EOF' are ordinary
|
|
4923
|
+
shell words, not part of the quoted text. 'basou note -' does not read stdin;
|
|
4924
|
+
omit the argument instead.
|
|
4925
|
+
|
|
4926
|
+
Trailing newlines in text read from stdin or --file are dropped (a heredoc
|
|
4927
|
+
always ends with one); everything else is recorded exactly as read.
|
|
4928
|
+
`;
|
|
4929
|
+
var HEREDOC_EXAMPLE = [" basou note <<'EOF'", " <your note>", " EOF"].join("\n");
|
|
4930
|
+
var NO_INPUT_HINT2 = `No note text. Pass it on stdin through a quoted heredoc, with the text on its own lines:
|
|
4931
|
+
${HEREDOC_EXAMPLE}
|
|
4932
|
+
or pass it as an argument, or with --file <path>.`;
|
|
4907
4933
|
function registerNoteCommand(program2) {
|
|
4908
|
-
program2.command("note").description("Record a free-text note (orientation surfaces the latest as the next step)").argument("
|
|
4934
|
+
program2.command("note").description("Record a free-text note (orientation surfaces the latest as the next step)").argument("[body]", "Note text (omit it to read the text from stdin or --file)", parseBody).option("--file <path>", "Read the note text from a file instead of the argument or stdin").option(
|
|
4909
4935
|
"--session <session_id>",
|
|
4910
4936
|
"Attach to an existing session; otherwise an ad-hoc session is created"
|
|
4911
|
-
).option("--json", "Output the result as JSON").option("-v, --verbose", "Show error causes").action(async (body, options) => {
|
|
4937
|
+
).option("--json", "Output the result as JSON").option("-v, --verbose", "Show error causes").addHelpText("after", NOTE_HELP).action(async (body, options) => {
|
|
4912
4938
|
await runNote(body, options);
|
|
4913
4939
|
});
|
|
4914
4940
|
}
|
|
@@ -4923,17 +4949,29 @@ async function runNote(body, options, ctx = {}) {
|
|
|
4923
4949
|
process.exitCode = 1;
|
|
4924
4950
|
}
|
|
4925
4951
|
}
|
|
4926
|
-
async function doRunNote(
|
|
4952
|
+
async function doRunNote(bodyArgument, options, ctx) {
|
|
4953
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
4954
|
+
const { body, source } = await readNoteBody(bodyArgument, options, ctx, cwd);
|
|
4955
|
+
if (source === "stdin" && body.trim().length === 0) {
|
|
4956
|
+
throw new Error(NO_INPUT_HINT2);
|
|
4957
|
+
}
|
|
4927
4958
|
if (body.trim().length === 0) {
|
|
4928
4959
|
throw new Error("Note body must not be empty");
|
|
4929
4960
|
}
|
|
4930
4961
|
const reserved = body.trim().toLowerCase();
|
|
4931
4962
|
if (NOTE_SUBCOMMAND_LOOKALIKES.has(reserved)) {
|
|
4932
4963
|
throw new Error(
|
|
4933
|
-
`'basou note' records a free-text note and has no '${body.trim()}' subcommand. To record a note, pass its full text
|
|
4964
|
+
`'basou note' records a free-text note and has no '${body.trim()}' subcommand. To record a note, pass its full text, e.g. on stdin through a quoted heredoc, with the text on its own lines:
|
|
4965
|
+
${HEREDOC_EXAMPLE}`
|
|
4966
|
+
);
|
|
4967
|
+
}
|
|
4968
|
+
if (reserved === "-") {
|
|
4969
|
+
throw new Error(
|
|
4970
|
+
source === "argument" ? `'basou note -' does not read stdin; it would record '-' as the note. To pass the note on stdin, omit the argument:
|
|
4971
|
+
${HEREDOC_EXAMPLE}` : `The note text is just '-', which would be recorded as the next step. Write the note itself, e.g.:
|
|
4972
|
+
${HEREDOC_EXAMPLE}`
|
|
4934
4973
|
);
|
|
4935
4974
|
}
|
|
4936
|
-
const cwd = ctx.cwd ?? process.cwd();
|
|
4937
4975
|
const repositoryRoot = await resolveBasouRootForCommand(cwd, "note");
|
|
4938
4976
|
const paths = basouPaths11(repositoryRoot);
|
|
4939
4977
|
await assertWorkspaceInitialized7(paths.root);
|
|
@@ -4972,7 +5010,7 @@ async function doRunNote(body, options, ctx) {
|
|
|
4972
5010
|
workingDirectory: repositoryRoot,
|
|
4973
5011
|
invocation: {
|
|
4974
5012
|
command: "basou note",
|
|
4975
|
-
args:
|
|
5013
|
+
args: noteInvocationArgs({ body, source, file: options.file, cwd, repositoryRoot })
|
|
4976
5014
|
},
|
|
4977
5015
|
targetEventBuilders: [
|
|
4978
5016
|
(sessionId, eventId) => buildNoteEvent({ eventId, sessionId, occurredAt, body })
|
|
@@ -5005,6 +5043,64 @@ function buildAdHocLabel2(body) {
|
|
|
5005
5043
|
const truncated = oneLine3.length > LABEL_BODY_MAX ? `${oneLine3.slice(0, LABEL_TRUNCATE_HEAD2)}...` : oneLine3;
|
|
5006
5044
|
return `Ad-hoc note: ${truncated}`;
|
|
5007
5045
|
}
|
|
5046
|
+
async function readNoteBody(bodyArgument, options, ctx, cwd) {
|
|
5047
|
+
if (bodyArgument !== void 0 && options.file !== void 0) {
|
|
5048
|
+
throw new Error("Pass the note text either as an argument or with --file, not both.");
|
|
5049
|
+
}
|
|
5050
|
+
if (bodyArgument !== void 0) {
|
|
5051
|
+
return { body: bodyArgument, source: "argument" };
|
|
5052
|
+
}
|
|
5053
|
+
if (options.file !== void 0) {
|
|
5054
|
+
let raw;
|
|
5055
|
+
try {
|
|
5056
|
+
raw = await readFile4(resolve8(cwd, options.file), "utf8");
|
|
5057
|
+
} catch (error) {
|
|
5058
|
+
if (findErrorCode7(error, "ENOENT")) {
|
|
5059
|
+
throw new Error("--file names a file that does not exist", { cause: error });
|
|
5060
|
+
}
|
|
5061
|
+
if (findErrorCode7(error, "EISDIR")) {
|
|
5062
|
+
throw new Error("--file names a directory, not a file", { cause: error });
|
|
5063
|
+
}
|
|
5064
|
+
throw new Error("Could not read the file --file names", { cause: error });
|
|
5065
|
+
}
|
|
5066
|
+
return { body: dropTrailingNewlines(raw), source: "file" };
|
|
5067
|
+
}
|
|
5068
|
+
if (ctx.readInput !== void 0) {
|
|
5069
|
+
return { body: dropTrailingNewlines(await ctx.readInput()), source: "stdin" };
|
|
5070
|
+
}
|
|
5071
|
+
if (process.stdin.isTTY === true) {
|
|
5072
|
+
throw new Error(NO_INPUT_HINT2);
|
|
5073
|
+
}
|
|
5074
|
+
return { body: dropTrailingNewlines(await readStdinToEnd2()), source: "stdin" };
|
|
5075
|
+
}
|
|
5076
|
+
function dropTrailingNewlines(text) {
|
|
5077
|
+
let end = text.length;
|
|
5078
|
+
while (end > 0 && text[end - 1] === "\n") {
|
|
5079
|
+
end -= 1;
|
|
5080
|
+
if (end > 0 && text[end - 1] === "\r") end -= 1;
|
|
5081
|
+
}
|
|
5082
|
+
return text.slice(0, end);
|
|
5083
|
+
}
|
|
5084
|
+
async function readStdinToEnd2() {
|
|
5085
|
+
const chunks = [];
|
|
5086
|
+
for await (const chunk of process.stdin) {
|
|
5087
|
+
chunks.push(Buffer.from(chunk));
|
|
5088
|
+
}
|
|
5089
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
5090
|
+
}
|
|
5091
|
+
function noteInvocationArgs(input) {
|
|
5092
|
+
if (input.source === "argument") return [input.body];
|
|
5093
|
+
if (input.source === "file" && input.file !== void 0) {
|
|
5094
|
+
return [
|
|
5095
|
+
"--file",
|
|
5096
|
+
sanitizePath2(resolve8(input.cwd, input.file), {
|
|
5097
|
+
workingDirectory: input.repositoryRoot,
|
|
5098
|
+
homedir: homedir9()
|
|
5099
|
+
})
|
|
5100
|
+
];
|
|
5101
|
+
}
|
|
5102
|
+
return [];
|
|
5103
|
+
}
|
|
5008
5104
|
function parseBody(raw) {
|
|
5009
5105
|
if (raw.trim().length === 0) {
|
|
5010
5106
|
throw new InvalidArgumentError3("Note body must not be empty");
|
|
@@ -5155,7 +5251,7 @@ import {
|
|
|
5155
5251
|
writeFileSync,
|
|
5156
5252
|
writeSync
|
|
5157
5253
|
} from "fs";
|
|
5158
|
-
import { basename as basename6, dirname as dirname4, isAbsolute as isAbsolute4, join as join12, relative as relative2, resolve as
|
|
5254
|
+
import { basename as basename6, dirname as dirname4, isAbsolute as isAbsolute4, join as join12, relative as relative2, resolve as resolve9 } from "path";
|
|
5159
5255
|
import {
|
|
5160
5256
|
appendBasouGitignore as appendBasouGitignore2,
|
|
5161
5257
|
basouPaths as basouPaths12,
|
|
@@ -5530,7 +5626,7 @@ async function runProjectAdopt(options, ctx = {}) {
|
|
|
5530
5626
|
}
|
|
5531
5627
|
}
|
|
5532
5628
|
function classifySourceRoot(repositoryRoot, declaredPath) {
|
|
5533
|
-
const absolute =
|
|
5629
|
+
const absolute = resolve9(repositoryRoot, declaredPath);
|
|
5534
5630
|
let real;
|
|
5535
5631
|
try {
|
|
5536
5632
|
real = realpathSync(absolute);
|
|
@@ -5637,7 +5733,7 @@ async function gatherRepoWiring(repositoryRoot, entry) {
|
|
|
5637
5733
|
};
|
|
5638
5734
|
let real;
|
|
5639
5735
|
try {
|
|
5640
|
-
real = realpathSync(
|
|
5736
|
+
real = realpathSync(resolve9(repositoryRoot, entry.path));
|
|
5641
5737
|
} catch {
|
|
5642
5738
|
return { ...base, reachable: false, instructionFiles: [] };
|
|
5643
5739
|
}
|
|
@@ -5756,7 +5852,7 @@ function gatherRepoGitignore(repositoryRoot, entry) {
|
|
|
5756
5852
|
};
|
|
5757
5853
|
let real;
|
|
5758
5854
|
try {
|
|
5759
|
-
real = realpathSync(
|
|
5855
|
+
real = realpathSync(resolve9(repositoryRoot, entry.path));
|
|
5760
5856
|
} catch {
|
|
5761
5857
|
return { ...base, reachable: false, currentLines: [] };
|
|
5762
5858
|
}
|
|
@@ -5777,7 +5873,7 @@ function readGitignoreLines(file) {
|
|
|
5777
5873
|
}
|
|
5778
5874
|
}
|
|
5779
5875
|
function applyGitignorePlan(repositoryRoot, plan) {
|
|
5780
|
-
const file = join12(realpathSync(
|
|
5876
|
+
const file = join12(realpathSync(resolve9(repositoryRoot, plan.path)), ".gitignore");
|
|
5781
5877
|
let existing = "";
|
|
5782
5878
|
try {
|
|
5783
5879
|
existing = readFileSync(file, "utf8");
|
|
@@ -5912,7 +6008,7 @@ function gatherRepoSymlinks(repositoryRoot, anchorReal, entry) {
|
|
|
5912
6008
|
const base = { path: entry.path, ...isSelf ? { self: true } : {} };
|
|
5913
6009
|
let real;
|
|
5914
6010
|
try {
|
|
5915
|
-
real = realpathSync(
|
|
6011
|
+
real = realpathSync(resolve9(repositoryRoot, entry.path));
|
|
5916
6012
|
} catch {
|
|
5917
6013
|
return { ...base, isAnchor: false, reachable: false, canonicalPresent: false, files: [] };
|
|
5918
6014
|
}
|
|
@@ -5984,7 +6080,7 @@ function gatherRepoSymlinks(repositoryRoot, anchorReal, entry) {
|
|
|
5984
6080
|
function applySymlinkPlan(repositoryRoot, plan) {
|
|
5985
6081
|
let real;
|
|
5986
6082
|
try {
|
|
5987
|
-
real = realpathSync(
|
|
6083
|
+
real = realpathSync(resolve9(repositoryRoot, plan.path));
|
|
5988
6084
|
} catch (error) {
|
|
5989
6085
|
const message = failureReason(error);
|
|
5990
6086
|
return { created: [], failed: plan.toCreate.map((c) => ({ file: c.name, message })) };
|
|
@@ -6010,9 +6106,9 @@ function viewCanonicalCollision(repositoryRoot, roster, viewName) {
|
|
|
6010
6106
|
for (const entry of roster) {
|
|
6011
6107
|
let name;
|
|
6012
6108
|
try {
|
|
6013
|
-
name = basename6(realpathSync(
|
|
6109
|
+
name = basename6(realpathSync(resolve9(repositoryRoot, entry.path)));
|
|
6014
6110
|
} catch {
|
|
6015
|
-
name = basename6(
|
|
6111
|
+
name = basename6(resolve9(repositoryRoot, entry.path));
|
|
6016
6112
|
}
|
|
6017
6113
|
if (name === viewName) return entry.path;
|
|
6018
6114
|
}
|
|
@@ -6259,7 +6355,7 @@ async function runProjectWorkspace(options, ctx = {}) {
|
|
|
6259
6355
|
}
|
|
6260
6356
|
}
|
|
6261
6357
|
function resolveViewDir(repositoryRoot, viewPath) {
|
|
6262
|
-
const abs =
|
|
6358
|
+
const abs = resolve9(repositoryRoot, viewPath);
|
|
6263
6359
|
try {
|
|
6264
6360
|
return realpathSync(abs);
|
|
6265
6361
|
} catch {
|
|
@@ -6273,7 +6369,7 @@ function resolveViewDir(repositoryRoot, viewPath) {
|
|
|
6273
6369
|
function gatherViewRepo(repositoryRoot, viewDir, entry) {
|
|
6274
6370
|
let repoReal;
|
|
6275
6371
|
try {
|
|
6276
|
-
repoReal = realpathSync(
|
|
6372
|
+
repoReal = realpathSync(resolve9(repositoryRoot, entry.path));
|
|
6277
6373
|
} catch {
|
|
6278
6374
|
return { path: entry.path, reachable: false };
|
|
6279
6375
|
}
|
|
@@ -6325,7 +6421,7 @@ function classifyViewLink(viewDir, name, rosterRealpaths) {
|
|
|
6325
6421
|
} catch {
|
|
6326
6422
|
return null;
|
|
6327
6423
|
}
|
|
6328
|
-
const resolved = isAbsolute4(target) ? target :
|
|
6424
|
+
const resolved = isAbsolute4(target) ? target : resolve9(viewDir, target);
|
|
6329
6425
|
try {
|
|
6330
6426
|
if (rosterRealpaths.has(realpathSync(resolved))) return null;
|
|
6331
6427
|
} catch {
|
|
@@ -6411,11 +6507,11 @@ async function doRunProjectWorkspace(options, ctx) {
|
|
|
6411
6507
|
} else {
|
|
6412
6508
|
const viewDir = resolveViewDir(repositoryRoot, viewPath);
|
|
6413
6509
|
const facts = roster.map((entry) => gatherViewRepo(repositoryRoot, viewDir, entry));
|
|
6414
|
-
const rosterNames = roster.map((entry) => basename6(
|
|
6510
|
+
const rosterNames = roster.map((entry) => basename6(resolve9(repositoryRoot, entry.path)));
|
|
6415
6511
|
const rosterRealpaths = /* @__PURE__ */ new Set();
|
|
6416
6512
|
for (const entry of roster) {
|
|
6417
6513
|
try {
|
|
6418
|
-
rosterRealpaths.add(realpathSync(
|
|
6514
|
+
rosterRealpaths.add(realpathSync(resolve9(repositoryRoot, entry.path)));
|
|
6419
6515
|
} catch {
|
|
6420
6516
|
}
|
|
6421
6517
|
}
|
|
@@ -6595,7 +6691,7 @@ async function gatherRepoPreset(repositoryRoot, anchorReal, entry) {
|
|
|
6595
6691
|
}
|
|
6596
6692
|
let real;
|
|
6597
6693
|
try {
|
|
6598
|
-
real = realpathSync(
|
|
6694
|
+
real = realpathSync(resolve9(repositoryRoot, entry.path));
|
|
6599
6695
|
} catch {
|
|
6600
6696
|
return { ...declared, isAnchor: false, reachable: false, canonicalPresent: false };
|
|
6601
6697
|
}
|
|
@@ -6651,7 +6747,7 @@ function viewPresetReposFor(repositoryRoot, roster) {
|
|
|
6651
6747
|
anchorReal = void 0;
|
|
6652
6748
|
}
|
|
6653
6749
|
return roster.map((entry) => {
|
|
6654
|
-
const abs =
|
|
6750
|
+
const abs = resolve9(repositoryRoot, entry.path);
|
|
6655
6751
|
let real;
|
|
6656
6752
|
try {
|
|
6657
6753
|
real = realpathSync(abs);
|
|
@@ -6975,7 +7071,7 @@ function gatherArchiveTeardown(repositoryRoot, manifest, target) {
|
|
|
6975
7071
|
};
|
|
6976
7072
|
let real;
|
|
6977
7073
|
try {
|
|
6978
|
-
real = realpathSync(
|
|
7074
|
+
real = realpathSync(resolve9(repositoryRoot, target));
|
|
6979
7075
|
} catch {
|
|
6980
7076
|
return empty;
|
|
6981
7077
|
}
|
|
@@ -7024,7 +7120,7 @@ function viewLinkPointsAt(viewDir, name, repoReal) {
|
|
|
7024
7120
|
if (!lstatSync(filePath).isSymbolicLink()) return false;
|
|
7025
7121
|
const target = readlinkSync(filePath);
|
|
7026
7122
|
if (isAbsolute4(target)) return false;
|
|
7027
|
-
return realpathSync(
|
|
7123
|
+
return realpathSync(resolve9(viewDir, target)) === repoReal;
|
|
7028
7124
|
} catch {
|
|
7029
7125
|
return false;
|
|
7030
7126
|
}
|
|
@@ -7035,7 +7131,7 @@ function viewLinkPointsAtPath(viewDir, name, expectedRepoPath) {
|
|
|
7035
7131
|
if (!lstatSync(filePath).isSymbolicLink()) return false;
|
|
7036
7132
|
const target = readlinkSync(filePath);
|
|
7037
7133
|
if (isAbsolute4(target)) return false;
|
|
7038
|
-
return
|
|
7134
|
+
return resolve9(viewDir, target) === expectedRepoPath;
|
|
7039
7135
|
} catch {
|
|
7040
7136
|
return false;
|
|
7041
7137
|
}
|
|
@@ -7044,19 +7140,19 @@ function gatherRepoTeardown(repositoryRoot, manifest, target) {
|
|
|
7044
7140
|
const anchorReal = realpathSync(repositoryRoot);
|
|
7045
7141
|
let repoReal;
|
|
7046
7142
|
try {
|
|
7047
|
-
repoReal = realpathSync(
|
|
7143
|
+
repoReal = realpathSync(resolve9(repositoryRoot, target));
|
|
7048
7144
|
} catch {
|
|
7049
7145
|
repoReal = void 0;
|
|
7050
7146
|
}
|
|
7051
7147
|
const isAnchor = repoReal !== void 0 && repoReal === anchorReal;
|
|
7052
|
-
const targetAbs =
|
|
7148
|
+
const targetAbs = resolve9(repositoryRoot, target);
|
|
7053
7149
|
const canonicalName = basename6(repoReal ?? targetAbs);
|
|
7054
7150
|
const roster = manifest.repos ?? [];
|
|
7055
7151
|
const declaredEntry = roster.find((r) => {
|
|
7056
7152
|
try {
|
|
7057
|
-
return realpathSync(
|
|
7153
|
+
return realpathSync(resolve9(repositoryRoot, r.path)) === (repoReal ?? "\0");
|
|
7058
7154
|
} catch {
|
|
7059
|
-
return
|
|
7155
|
+
return resolve9(repositoryRoot, r.path) === targetAbs;
|
|
7060
7156
|
}
|
|
7061
7157
|
});
|
|
7062
7158
|
const inRoster = declaredEntry !== void 0;
|
|
@@ -7065,7 +7161,7 @@ function gatherRepoTeardown(repositoryRoot, manifest, target) {
|
|
|
7065
7161
|
const canonicalShared = roster.some((r) => {
|
|
7066
7162
|
let rReal = null;
|
|
7067
7163
|
try {
|
|
7068
|
-
rReal = realpathSync(
|
|
7164
|
+
rReal = realpathSync(resolve9(repositoryRoot, r.path));
|
|
7069
7165
|
} catch {
|
|
7070
7166
|
rReal = null;
|
|
7071
7167
|
}
|
|
@@ -7073,8 +7169,8 @@ function gatherRepoTeardown(repositoryRoot, manifest, target) {
|
|
|
7073
7169
|
if (repoReal !== void 0 && rReal === repoReal) return false;
|
|
7074
7170
|
return basename6(rReal).toLowerCase() === cnFold;
|
|
7075
7171
|
}
|
|
7076
|
-
if (
|
|
7077
|
-
return basename6(
|
|
7172
|
+
if (resolve9(repositoryRoot, r.path) === targetAbs) return false;
|
|
7173
|
+
return basename6(resolve9(repositoryRoot, r.path)).toLowerCase() === cnFold;
|
|
7078
7174
|
});
|
|
7079
7175
|
const collisionNote = "shared with another repo of the same basename, so it cannot be removed (check manually)";
|
|
7080
7176
|
const items = [];
|
|
@@ -7255,7 +7351,7 @@ function applyRepoTeardown(repositoryRoot, manifest, plan) {
|
|
|
7255
7351
|
const changed = (label) => failed.push({ label, message: "the state changed since the scan (re-run)" });
|
|
7256
7352
|
let currentRepoReal = null;
|
|
7257
7353
|
try {
|
|
7258
|
-
currentRepoReal = realpathSync(
|
|
7354
|
+
currentRepoReal = realpathSync(resolve9(repositoryRoot, plan.target));
|
|
7259
7355
|
} catch {
|
|
7260
7356
|
currentRepoReal = null;
|
|
7261
7357
|
}
|
|
@@ -7290,7 +7386,7 @@ function applyRepoTeardown(repositoryRoot, manifest, plan) {
|
|
|
7290
7386
|
continue;
|
|
7291
7387
|
}
|
|
7292
7388
|
const viewDir = resolveViewDir(repositoryRoot, viewPath);
|
|
7293
|
-
const owned = repoReal !== null ? viewLinkPointsAt(viewDir, item.label, repoReal) : viewLinkPointsAtPath(viewDir, item.label,
|
|
7389
|
+
const owned = repoReal !== null ? viewLinkPointsAt(viewDir, item.label, repoReal) : viewLinkPointsAtPath(viewDir, item.label, resolve9(repositoryRoot, plan.target));
|
|
7294
7390
|
if (!owned) {
|
|
7295
7391
|
changed(item.label);
|
|
7296
7392
|
continue;
|
|
@@ -7452,7 +7548,7 @@ async function doRunProjectArchive(target, options, ctx) {
|
|
|
7452
7548
|
const roster = manifest.repos ?? [];
|
|
7453
7549
|
let targetIsAnchor = false;
|
|
7454
7550
|
try {
|
|
7455
|
-
targetIsAnchor = realpathSync(
|
|
7551
|
+
targetIsAnchor = realpathSync(resolve9(repositoryRoot, target)) === realpathSync(repositoryRoot);
|
|
7456
7552
|
} catch {
|
|
7457
7553
|
targetIsAnchor = false;
|
|
7458
7554
|
}
|
|
@@ -7609,7 +7705,7 @@ async function doRunProjectRename(oldPath, newPath, options, ctx) {
|
|
|
7609
7705
|
const roster = manifest.repos ?? [];
|
|
7610
7706
|
let oldIsAnchor = false;
|
|
7611
7707
|
try {
|
|
7612
|
-
oldIsAnchor = realpathSync(
|
|
7708
|
+
oldIsAnchor = realpathSync(resolve9(repositoryRoot, oldPath)) === realpathSync(repositoryRoot);
|
|
7613
7709
|
} catch {
|
|
7614
7710
|
oldIsAnchor = false;
|
|
7615
7711
|
}
|
|
@@ -7755,7 +7851,7 @@ async function doRunProjectNew(repos, options, ctx) {
|
|
|
7755
7851
|
const viewStem = productName ?? workspaceName;
|
|
7756
7852
|
const viewOverridesProjectName = productName !== void 0 && typeof options.view === "string";
|
|
7757
7853
|
const declared = repos.map((p) => {
|
|
7758
|
-
const abs =
|
|
7854
|
+
const abs = resolve9(cwd, p);
|
|
7759
7855
|
let real;
|
|
7760
7856
|
try {
|
|
7761
7857
|
real = realpathSync(abs);
|
|
@@ -8020,7 +8116,7 @@ function pathPresent(p) {
|
|
|
8020
8116
|
}
|
|
8021
8117
|
function gatherRetrofit(repositoryRoot, anchorReal, roster, argAbs, argReal, viewCanonicalName) {
|
|
8022
8118
|
const declaredEntry = roster.find((entry) => {
|
|
8023
|
-
const entryAbs =
|
|
8119
|
+
const entryAbs = resolve9(repositoryRoot, entry.path);
|
|
8024
8120
|
if (argReal !== void 0) {
|
|
8025
8121
|
try {
|
|
8026
8122
|
if (realpathSync(entryAbs) === argReal) return true;
|
|
@@ -8160,7 +8256,7 @@ async function doRunProjectRetrofit(repo, options, ctx) {
|
|
|
8160
8256
|
}
|
|
8161
8257
|
return result2;
|
|
8162
8258
|
}
|
|
8163
|
-
const argAbs =
|
|
8259
|
+
const argAbs = resolve9(repositoryRoot, repo);
|
|
8164
8260
|
let argReal;
|
|
8165
8261
|
try {
|
|
8166
8262
|
argReal = realpathSync(argAbs);
|
|
@@ -8381,7 +8477,7 @@ function renderProjectRetrofit(result) {
|
|
|
8381
8477
|
}
|
|
8382
8478
|
|
|
8383
8479
|
// src/commands/protocol.ts
|
|
8384
|
-
import { readFile as
|
|
8480
|
+
import { readFile as readFile5, stat as stat5 } from "fs/promises";
|
|
8385
8481
|
import {
|
|
8386
8482
|
carryForwardProtocolStamp,
|
|
8387
8483
|
PROTOCOL_END as PROTOCOL_END2,
|
|
@@ -8438,7 +8534,7 @@ async function readProtocolSources(entries) {
|
|
|
8438
8534
|
for (const entry of entries) {
|
|
8439
8535
|
let content;
|
|
8440
8536
|
try {
|
|
8441
|
-
content = await
|
|
8537
|
+
content = await readFile5(entry.source, "utf8");
|
|
8442
8538
|
} catch (error) {
|
|
8443
8539
|
if (error instanceof Error && error.code === "ENOENT") {
|
|
8444
8540
|
throw new Error(
|
|
@@ -8571,7 +8667,7 @@ import { InvalidArgumentError as InvalidArgumentError4 } from "commander";
|
|
|
8571
8667
|
|
|
8572
8668
|
// src/commands/refresh-watch.ts
|
|
8573
8669
|
import { readdir as readdir2, stat as stat6 } from "fs/promises";
|
|
8574
|
-
import { homedir as
|
|
8670
|
+
import { homedir as homedir10 } from "os";
|
|
8575
8671
|
import { join as join13 } from "path";
|
|
8576
8672
|
import { findErrorCode as findErrorCode8 } from "@basou/core";
|
|
8577
8673
|
var DEFAULT_WATCH_INTERVAL_SEC = 30;
|
|
@@ -8579,8 +8675,8 @@ var MIN_WATCH_INTERVAL_SEC = 5;
|
|
|
8579
8675
|
var MAX_WATCH_INTERVAL_SEC = 86400;
|
|
8580
8676
|
function watchedRoots(ctx) {
|
|
8581
8677
|
return [
|
|
8582
|
-
ctx.codexSessionsDir ?? join13(
|
|
8583
|
-
ctx.claudeProjectsDir ?? join13(
|
|
8678
|
+
ctx.codexSessionsDir ?? join13(homedir10(), ".codex", "sessions"),
|
|
8679
|
+
ctx.claudeProjectsDir ?? join13(homedir10(), ".claude", "projects")
|
|
8584
8680
|
];
|
|
8585
8681
|
}
|
|
8586
8682
|
async function scanSourceLogs(roots) {
|
|
@@ -8701,19 +8797,19 @@ function parseInterval(value) {
|
|
|
8701
8797
|
return seconds;
|
|
8702
8798
|
}
|
|
8703
8799
|
function abortableSleep(ms, signal) {
|
|
8704
|
-
return new Promise((
|
|
8800
|
+
return new Promise((resolve15) => {
|
|
8705
8801
|
if (signal.aborted) {
|
|
8706
|
-
|
|
8802
|
+
resolve15();
|
|
8707
8803
|
return;
|
|
8708
8804
|
}
|
|
8709
8805
|
let timer;
|
|
8710
8806
|
const onAbort = () => {
|
|
8711
8807
|
clearTimeout(timer);
|
|
8712
|
-
|
|
8808
|
+
resolve15();
|
|
8713
8809
|
};
|
|
8714
8810
|
timer = setTimeout(() => {
|
|
8715
8811
|
signal.removeEventListener("abort", onAbort);
|
|
8716
|
-
|
|
8812
|
+
resolve15();
|
|
8717
8813
|
}, ms);
|
|
8718
8814
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
8719
8815
|
});
|
|
@@ -8939,7 +9035,7 @@ async function assertWorkspaceInitialized8(basouRoot) {
|
|
|
8939
9035
|
}
|
|
8940
9036
|
|
|
8941
9037
|
// src/commands/report.ts
|
|
8942
|
-
import { isAbsolute as isAbsolute5, resolve as
|
|
9038
|
+
import { isAbsolute as isAbsolute5, resolve as resolve10 } from "path";
|
|
8943
9039
|
import {
|
|
8944
9040
|
assertBasouRootSafe as assertBasouRootSafe10,
|
|
8945
9041
|
basouPaths as basouPaths14,
|
|
@@ -8979,7 +9075,7 @@ async function doRunReportGenerate(options, ctx) {
|
|
|
8979
9075
|
onTaskSkip: (taskId, reason) => printTaskSkip(taskId, reason)
|
|
8980
9076
|
});
|
|
8981
9077
|
if (options.out !== void 0) {
|
|
8982
|
-
const outPath = isAbsolute5(options.out) ? options.out :
|
|
9078
|
+
const outPath = isAbsolute5(options.out) ? options.out : resolve10(cwd, options.out);
|
|
8983
9079
|
await writeMarkdownFile6(outPath, result.body);
|
|
8984
9080
|
const { sessions, decisions, tasks } = result.data;
|
|
8985
9081
|
console.error(
|
|
@@ -9017,9 +9113,9 @@ async function assertWorkspaceInitialized9(basouRoot) {
|
|
|
9017
9113
|
}
|
|
9018
9114
|
|
|
9019
9115
|
// src/commands/review.ts
|
|
9020
|
-
import { readFile as
|
|
9021
|
-
import { homedir as
|
|
9022
|
-
import { resolve as
|
|
9116
|
+
import { readFile as readFile6 } from "fs/promises";
|
|
9117
|
+
import { homedir as homedir11 } from "os";
|
|
9118
|
+
import { resolve as resolve11 } from "path";
|
|
9023
9119
|
import {
|
|
9024
9120
|
assertBasouRootSafe as assertBasouRootSafe11,
|
|
9025
9121
|
basouPaths as basouPaths15,
|
|
@@ -9031,7 +9127,7 @@ import {
|
|
|
9031
9127
|
parseReviewRecordInput,
|
|
9032
9128
|
readManifest as readManifest9,
|
|
9033
9129
|
resolveRepoRoot,
|
|
9034
|
-
sanitizePath as
|
|
9130
|
+
sanitizePath as sanitizePath3
|
|
9035
9131
|
} from "@basou/core";
|
|
9036
9132
|
function registerReviewCommand(program2) {
|
|
9037
9133
|
const review = program2.command("review").description("Record reviews that ran (the durable signal a review happened)");
|
|
@@ -9119,9 +9215,9 @@ async function doRunReviewRecord(options, ctx) {
|
|
|
9119
9215
|
const manifest = await readManifest9(paths);
|
|
9120
9216
|
const invocationArgs = options.file !== void 0 ? [
|
|
9121
9217
|
"--file",
|
|
9122
|
-
|
|
9218
|
+
sanitizePath3(resolve11(cwd, options.file), {
|
|
9123
9219
|
workingDirectory: repositoryRoot,
|
|
9124
|
-
homedir:
|
|
9220
|
+
homedir: homedir11()
|
|
9125
9221
|
})
|
|
9126
9222
|
] : [];
|
|
9127
9223
|
const adHoc = await createAdHocSessionWithEvent3({
|
|
@@ -9161,7 +9257,7 @@ ${detail}
|
|
|
9161
9257
|
async function readReviewInput(options, ctx) {
|
|
9162
9258
|
if (options.file !== void 0) {
|
|
9163
9259
|
try {
|
|
9164
|
-
return await
|
|
9260
|
+
return await readFile6(options.file, "utf8");
|
|
9165
9261
|
} catch (error) {
|
|
9166
9262
|
if (findErrorCode11(error, "ENOENT")) {
|
|
9167
9263
|
throw new Error(`Input file not found: ${options.file}`);
|
|
@@ -9173,18 +9269,18 @@ async function readReviewInput(options, ctx) {
|
|
|
9173
9269
|
return await ctx.readInput();
|
|
9174
9270
|
}
|
|
9175
9271
|
if (process.stdin.isTTY === true) {
|
|
9176
|
-
throw new Error(
|
|
9272
|
+
throw new Error(NO_INPUT_HINT3);
|
|
9177
9273
|
}
|
|
9178
|
-
return await
|
|
9274
|
+
return await readStdinToEnd3();
|
|
9179
9275
|
}
|
|
9180
|
-
async function
|
|
9276
|
+
async function readStdinToEnd3() {
|
|
9181
9277
|
const chunks = [];
|
|
9182
9278
|
for await (const chunk of process.stdin) {
|
|
9183
9279
|
chunks.push(Buffer.from(chunk));
|
|
9184
9280
|
}
|
|
9185
9281
|
return Buffer.concat(chunks).toString("utf8");
|
|
9186
9282
|
}
|
|
9187
|
-
var
|
|
9283
|
+
var NO_INPUT_HINT3 = "No input: pipe a JSON object describing the review to stdin or pass --file <path>.";
|
|
9188
9284
|
function reviewToPayload(review) {
|
|
9189
9285
|
const payload = {
|
|
9190
9286
|
reviewer: review.reviewer,
|
|
@@ -9454,8 +9550,8 @@ function unattachedLines(u) {
|
|
|
9454
9550
|
}
|
|
9455
9551
|
|
|
9456
9552
|
// src/commands/run.ts
|
|
9457
|
-
import { mkdir as mkdir2, readFile as
|
|
9458
|
-
import { homedir as
|
|
9553
|
+
import { mkdir as mkdir2, readFile as readFile7 } from "fs/promises";
|
|
9554
|
+
import { homedir as homedir12 } from "os";
|
|
9459
9555
|
import { join as join14 } from "path";
|
|
9460
9556
|
import {
|
|
9461
9557
|
acquireLock as acquireLock5,
|
|
@@ -9681,7 +9777,7 @@ async function runTrackedTool(args, options, ctx, adapter) {
|
|
|
9681
9777
|
const rawRelated = computeRelatedFiles(preSnapshot, postSnapshot, diff);
|
|
9682
9778
|
const relatedFiles = sanitizeRelatedFiles(rawRelated, {
|
|
9683
9779
|
workingDirectory: repoRoot,
|
|
9684
|
-
homedir:
|
|
9780
|
+
homedir: homedir12()
|
|
9685
9781
|
}).sanitized;
|
|
9686
9782
|
const finalStatus = decideFinalStatus2(result, signalReceived);
|
|
9687
9783
|
await appendEvent(sessionDir, {
|
|
@@ -9825,7 +9921,7 @@ function buildInitialSession2(input) {
|
|
|
9825
9921
|
source: { ...input.source },
|
|
9826
9922
|
started_at: input.startedAt,
|
|
9827
9923
|
status: "initialized",
|
|
9828
|
-
working_directory: sanitizeWorkingDirectory2(input.cwd, { homedir:
|
|
9924
|
+
working_directory: sanitizeWorkingDirectory2(input.cwd, { homedir: homedir12() }),
|
|
9829
9925
|
invocation: {
|
|
9830
9926
|
command: input.command,
|
|
9831
9927
|
args: [...input.args],
|
|
@@ -9901,7 +9997,7 @@ async function noteCodexHookStatusPreSpawn(_cwd, ctx) {
|
|
|
9901
9997
|
const hooksPath = ctx.codexHooksPath ?? DEFAULT_CODEX_HOOKS_PATH;
|
|
9902
9998
|
let location;
|
|
9903
9999
|
try {
|
|
9904
|
-
location = findBasouSessionStartHook2(JSON.parse(await
|
|
10000
|
+
location = findBasouSessionStartHook2(JSON.parse(await readFile7(hooksPath, "utf8")));
|
|
9905
10001
|
} catch (error) {
|
|
9906
10002
|
if (!(error instanceof Error && error.code === "ENOENT")) return null;
|
|
9907
10003
|
location = null;
|
|
@@ -9915,7 +10011,7 @@ async function noteCodexHookStatusPreSpawn(_cwd, ctx) {
|
|
|
9915
10011
|
}
|
|
9916
10012
|
|
|
9917
10013
|
// src/commands/session.ts
|
|
9918
|
-
import { readFile as
|
|
10014
|
+
import { readFile as readFile8 } from "fs/promises";
|
|
9919
10015
|
import { basename as basename7, isAbsolute as isAbsolute6, join as join15, relative as relative3, sep as sep2 } from "path";
|
|
9920
10016
|
import {
|
|
9921
10017
|
acquireLock as acquireLock6,
|
|
@@ -10386,7 +10482,7 @@ async function doRunSessionImport(options, ctx) {
|
|
|
10386
10482
|
}
|
|
10387
10483
|
async function readInputFile(path) {
|
|
10388
10484
|
try {
|
|
10389
|
-
return await
|
|
10485
|
+
return await readFile8(path, "utf8");
|
|
10390
10486
|
} catch (error) {
|
|
10391
10487
|
if (findErrorCode12(error, "ENOENT")) {
|
|
10392
10488
|
throw new Error("Import source not found", { cause: error });
|
|
@@ -10503,7 +10599,7 @@ async function doRunSessionNote(sessionIdInput, options, ctx) {
|
|
|
10503
10599
|
}
|
|
10504
10600
|
async function readNoteFile(path) {
|
|
10505
10601
|
try {
|
|
10506
|
-
return await
|
|
10602
|
+
return await readFile8(path, "utf8");
|
|
10507
10603
|
} catch (error) {
|
|
10508
10604
|
if (findErrorCode12(error, "ENOENT")) {
|
|
10509
10605
|
throw new Error("Note source not found", { cause: error });
|
|
@@ -10828,7 +10924,7 @@ function formatVersionGateMessage(error) {
|
|
|
10828
10924
|
}
|
|
10829
10925
|
|
|
10830
10926
|
// src/commands/task.ts
|
|
10831
|
-
import { readFile as
|
|
10927
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
10832
10928
|
import { join as join16 } from "path";
|
|
10833
10929
|
import {
|
|
10834
10930
|
archiveTask,
|
|
@@ -11843,7 +11939,7 @@ function parsePositiveInt2(raw) {
|
|
|
11843
11939
|
}
|
|
11844
11940
|
async function readDescriptionFile(path) {
|
|
11845
11941
|
try {
|
|
11846
|
-
return await
|
|
11942
|
+
return await readFile9(path, "utf8");
|
|
11847
11943
|
} catch (error) {
|
|
11848
11944
|
if (findErrorCode15(error, "ENOENT")) {
|
|
11849
11945
|
throw new Error("Description source not found", { cause: error });
|
|
@@ -12048,7 +12144,7 @@ async function assertWorkspaceInitialized14(basouRoot) {
|
|
|
12048
12144
|
// src/commands/view.ts
|
|
12049
12145
|
import { spawn } from "child_process";
|
|
12050
12146
|
import { createHash as createHash2 } from "crypto";
|
|
12051
|
-
import { basename as basename10, resolve as
|
|
12147
|
+
import { basename as basename10, resolve as resolve14 } from "path";
|
|
12052
12148
|
import {
|
|
12053
12149
|
assertBasouRootSafe as assertBasouRootSafe18,
|
|
12054
12150
|
basouPaths as basouPaths24,
|
|
@@ -12061,7 +12157,7 @@ import { InvalidArgumentError as InvalidArgumentError8 } from "commander";
|
|
|
12061
12157
|
// src/lib/portfolio-coverage.ts
|
|
12062
12158
|
import { createReadStream as createReadStream2 } from "fs";
|
|
12063
12159
|
import { readdir as readdir3, stat as stat7 } from "fs/promises";
|
|
12064
|
-
import { homedir as
|
|
12160
|
+
import { homedir as homedir13 } from "os";
|
|
12065
12161
|
import { basename as basename8, dirname as dirname5, join as join17 } from "path";
|
|
12066
12162
|
import { createInterface as createInterface2 } from "readline";
|
|
12067
12163
|
import { basouPaths as basouPaths23, readManifest as readManifest14, resolveRepositoryRoot as resolveRepositoryRoot13 } from "@basou/core";
|
|
@@ -12071,8 +12167,8 @@ function uncapturedTotal(result) {
|
|
|
12071
12167
|
async function checkPortfolioCoverage(workspaces, ctx = {}) {
|
|
12072
12168
|
const { roots, inertWorkspaces } = await collectDeclaredRoots(workspaces);
|
|
12073
12169
|
const listedDirs = new Set([...roots].map((root) => encodeProjectDir(root)));
|
|
12074
|
-
const claudeProjectsDir = ctx.claudeProjectsDir ?? join17(
|
|
12075
|
-
const codexSessionsDir = ctx.codexSessionsDir ?? join17(
|
|
12170
|
+
const claudeProjectsDir = ctx.claudeProjectsDir ?? join17(homedir13(), ".claude", "projects");
|
|
12171
|
+
const codexSessionsDir = ctx.codexSessionsDir ?? join17(homedir13(), ".codex", "sessions");
|
|
12076
12172
|
const tally = new Tally(roots);
|
|
12077
12173
|
const absentTrees = [];
|
|
12078
12174
|
const claudeFiles = await listClaudeTranscripts(claudeProjectsDir);
|
|
@@ -12376,7 +12472,7 @@ function inertLines(result) {
|
|
|
12376
12472
|
// src/lib/portfolio-safety.ts
|
|
12377
12473
|
import { execFile as execFile2 } from "child_process";
|
|
12378
12474
|
import { lstat as lstat2, realpath as realpath4 } from "fs/promises";
|
|
12379
|
-
import { isAbsolute as isAbsolute7, join as join18, relative as relative4, resolve as
|
|
12475
|
+
import { isAbsolute as isAbsolute7, join as join18, relative as relative4, resolve as resolve12, sep as sep3 } from "path";
|
|
12380
12476
|
import { promisify as promisify2 } from "util";
|
|
12381
12477
|
import { readManifest as readManifest15 } from "@basou/core";
|
|
12382
12478
|
var execFileAsync2 = promisify2(execFile2);
|
|
@@ -12387,7 +12483,7 @@ async function canonical(p) {
|
|
|
12387
12483
|
try {
|
|
12388
12484
|
return await realpath4(p);
|
|
12389
12485
|
} catch {
|
|
12390
|
-
return
|
|
12486
|
+
return resolve12(p);
|
|
12391
12487
|
}
|
|
12392
12488
|
}
|
|
12393
12489
|
function isInside(child, parent) {
|
|
@@ -12455,13 +12551,13 @@ async function checkPortfolioSafety(workspaces) {
|
|
|
12455
12551
|
}
|
|
12456
12552
|
const monitored = /* @__PURE__ */ new Map();
|
|
12457
12553
|
for (const root of sourceRoots) {
|
|
12458
|
-
const display =
|
|
12554
|
+
const display = resolve12(ws.repoRoot, root);
|
|
12459
12555
|
const real = await canonical(display);
|
|
12460
12556
|
if (real !== wsReal) monitored.set(real, display);
|
|
12461
12557
|
}
|
|
12462
12558
|
const claimed = new Set(monitored.keys());
|
|
12463
12559
|
if (isMaster && viewPath !== void 0) {
|
|
12464
|
-
const viewReal = await canonical(
|
|
12560
|
+
const viewReal = await canonical(resolve12(ws.repoRoot, viewPath));
|
|
12465
12561
|
if (viewReal !== wsReal) claimed.add(viewReal);
|
|
12466
12562
|
}
|
|
12467
12563
|
records.push({ ws, real: wsReal, isMaster, claimed });
|
|
@@ -12554,7 +12650,7 @@ function formatSafetyReport(result) {
|
|
|
12554
12650
|
|
|
12555
12651
|
// src/lib/view-server.ts
|
|
12556
12652
|
import { createServer } from "http";
|
|
12557
|
-
import { basename as basename9, join as join19, resolve as
|
|
12653
|
+
import { basename as basename9, join as join19, resolve as resolve13 } from "path";
|
|
12558
12654
|
import {
|
|
12559
12655
|
computeWorkStats as computeWorkStats2,
|
|
12560
12656
|
enumerateApprovals as enumerateApprovals2,
|
|
@@ -13308,7 +13404,7 @@ function startViewServer(opts) {
|
|
|
13308
13404
|
};
|
|
13309
13405
|
let boundPort = port;
|
|
13310
13406
|
const getPort = () => boundPort;
|
|
13311
|
-
return new Promise((
|
|
13407
|
+
return new Promise((resolve15, reject) => {
|
|
13312
13408
|
const server = createServer((req, res) => {
|
|
13313
13409
|
handleRequest(req, res, deps, getPort, runExclusive).catch((error) => {
|
|
13314
13410
|
sendError(res, error instanceof HttpError ? error.status : 500, pathlessMessage(error));
|
|
@@ -13319,7 +13415,7 @@ function startViewServer(opts) {
|
|
|
13319
13415
|
const address = server.address();
|
|
13320
13416
|
boundPort = isAddressInfo(address) ? address.port : port;
|
|
13321
13417
|
server.off("error", reject);
|
|
13322
|
-
|
|
13418
|
+
resolve15({
|
|
13323
13419
|
url: `http://${host}:${boundPort}`,
|
|
13324
13420
|
port: boundPort,
|
|
13325
13421
|
close: () => closeServer(server)
|
|
@@ -13331,8 +13427,8 @@ function isAddressInfo(value) {
|
|
|
13331
13427
|
return value !== null && typeof value === "object";
|
|
13332
13428
|
}
|
|
13333
13429
|
function closeServer(server) {
|
|
13334
|
-
return new Promise((
|
|
13335
|
-
server.close(() =>
|
|
13430
|
+
return new Promise((resolve15) => {
|
|
13431
|
+
server.close(() => resolve15());
|
|
13336
13432
|
server.closeAllConnections();
|
|
13337
13433
|
});
|
|
13338
13434
|
}
|
|
@@ -13604,7 +13700,7 @@ async function rosterRepos(repoRoot, manifest, resolveRemoteUrl) {
|
|
|
13604
13700
|
const roster = manifest.repos ?? [];
|
|
13605
13701
|
return Promise.all(
|
|
13606
13702
|
roster.map(async (repo) => {
|
|
13607
|
-
const abs =
|
|
13703
|
+
const abs = resolve13(repoRoot, repo.path);
|
|
13608
13704
|
const remote = await resolveRemoteUrl(abs);
|
|
13609
13705
|
const url = remote !== void 0 ? toBrowserUrl(remote) : null;
|
|
13610
13706
|
return {
|
|
@@ -13880,12 +13976,12 @@ async function buildSingleDeps(ctx, cwd) {
|
|
|
13880
13976
|
};
|
|
13881
13977
|
}
|
|
13882
13978
|
async function buildPortfolioDeps(workspaceFlags, ctx, cwd) {
|
|
13883
|
-
const specs = workspaceFlags.length > 0 ? workspaceFlags.map((p) => ({ path:
|
|
13979
|
+
const specs = workspaceFlags.length > 0 ? workspaceFlags.map((p) => ({ path: resolve14(cwd, p) })) : await loadPortfolioConfig(ctx.portfolioConfigPath);
|
|
13884
13980
|
const entries = [];
|
|
13885
13981
|
const seenPath = /* @__PURE__ */ new Set();
|
|
13886
13982
|
const seenKey = /* @__PURE__ */ new Set();
|
|
13887
13983
|
for (const spec of specs) {
|
|
13888
|
-
const repoRoot =
|
|
13984
|
+
const repoRoot = resolve14(spec.path);
|
|
13889
13985
|
if (seenPath.has(repoRoot)) continue;
|
|
13890
13986
|
seenPath.add(repoRoot);
|
|
13891
13987
|
const entry = await buildWorkspaceEntry(repoRoot, ctx, spec.label);
|
|
@@ -13962,7 +14058,7 @@ function openInBrowser(url, override) {
|
|
|
13962
14058
|
}
|
|
13963
14059
|
}
|
|
13964
14060
|
function waitForShutdown(signal) {
|
|
13965
|
-
return new Promise((
|
|
14061
|
+
return new Promise((resolve15) => {
|
|
13966
14062
|
const cleanup = () => {
|
|
13967
14063
|
process.off("SIGINT", onSignal);
|
|
13968
14064
|
process.off("SIGTERM", onSignal);
|
|
@@ -13970,18 +14066,18 @@ function waitForShutdown(signal) {
|
|
|
13970
14066
|
};
|
|
13971
14067
|
const onSignal = () => {
|
|
13972
14068
|
cleanup();
|
|
13973
|
-
|
|
14069
|
+
resolve15();
|
|
13974
14070
|
};
|
|
13975
14071
|
const onAbort = () => {
|
|
13976
14072
|
cleanup();
|
|
13977
|
-
|
|
14073
|
+
resolve15();
|
|
13978
14074
|
};
|
|
13979
14075
|
process.on("SIGINT", onSignal);
|
|
13980
14076
|
process.on("SIGTERM", onSignal);
|
|
13981
14077
|
if (signal !== void 0) {
|
|
13982
14078
|
if (signal.aborted) {
|
|
13983
14079
|
cleanup();
|
|
13984
|
-
|
|
14080
|
+
resolve15();
|
|
13985
14081
|
return;
|
|
13986
14082
|
}
|
|
13987
14083
|
signal.addEventListener("abort", onAbort);
|
|
@@ -14015,7 +14111,7 @@ async function assertWorkspaceInitialized15(basouRoot) {
|
|
|
14015
14111
|
function readBuildStamp() {
|
|
14016
14112
|
if (false) return void 0;
|
|
14017
14113
|
try {
|
|
14018
|
-
return JSON.parse('{"version":"0.
|
|
14114
|
+
return JSON.parse('{"version":"0.54.0","commit":"ac2e5dd","committedAt":"2026-09-25T23:04:16+09:00"}');
|
|
14019
14115
|
} catch {
|
|
14020
14116
|
return void 0;
|
|
14021
14117
|
}
|