@basou/cli 0.68.3 → 0.69.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/program.js CHANGED
@@ -1948,7 +1948,8 @@ It prints a declaration of the newest board_version, in the language the
1948
1948
  manifest declares for the workspace's own repo: a title from the workspace's
1949
1949
  name, the six stages with a meaning each, one lane to cut again, nothing to
1950
1950
  observe, no component registered, an axis of version 1, and the effort from
1951
- the day of the first session, in this host's time zone. It writes nothing:
1951
+ the day of the first session, in this host's time zone, with no milestone
1952
+ (a comment says what one holds). It writes nothing:
1952
1953
  save it, from the workspace's own repo, only where no board is, through a file
1953
1954
  of its own:
1954
1955
 
@@ -2955,7 +2956,6 @@ async function doRunChannelClear(face, options) {
2955
2956
  }
2956
2957
 
2957
2958
  // src/commands/decision.ts
2958
- import { readFile as readFile3 } from "fs/promises";
2959
2959
  import { homedir as homedir3 } from "os";
2960
2960
  import { join as join7, resolve as resolve4 } from "path";
2961
2961
  import {
@@ -2968,7 +2968,7 @@ import {
2968
2968
  createAdHocSessionWithEvent,
2969
2969
  displayPath as displayPath4,
2970
2970
  EVENT_SCHEMA_VERSION as EVENT_SCHEMA_VERSION2,
2971
- findErrorCode as findErrorCode4,
2971
+ findErrorCode as findErrorCode5,
2972
2972
  isValidPrefixedId,
2973
2973
  LOCAL_CLI_EVENT_SOURCE as LOCAL_CLI_EVENT_SOURCE2,
2974
2974
  loadSessionEntries,
@@ -2980,6 +2980,35 @@ import {
2980
2980
  } from "@basou/core";
2981
2981
  import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
2982
2982
 
2983
+ // src/lib/input-file.ts
2984
+ import { readFile as readFile3 } from "fs/promises";
2985
+ import { findErrorCode as findErrorCode4 } from "@basou/core";
2986
+ function refuseDashInputFile(flag, value, alternative) {
2987
+ if (value !== "-") return;
2988
+ if (alternative === "stdin") {
2989
+ throw new Error(
2990
+ `${flag} - is refused: - is reserved for standard input. Omit ${flag} to read stdin, or pass ${flag} ./- to read a file named -.`
2991
+ );
2992
+ }
2993
+ const toFile = "textFlag" in alternative ? `Write the text to a file and pass ${flag} <path>, or pass it with ${alternative.textFlag}` : `Write ${alternative.fileOnly} to a file and pass its path with ${flag}`;
2994
+ throw new Error(
2995
+ `${flag} - is refused: - is reserved for standard input, which this command does not read. ${toFile}; a file named - is read with ${flag} ./-.`
2996
+ );
2997
+ }
2998
+ async function readInputFileText(flag, path) {
2999
+ try {
3000
+ return await readFile3(path, "utf8");
3001
+ } catch (error) {
3002
+ if (findErrorCode4(error, "ENOENT")) {
3003
+ throw new Error(`${flag} names a file that does not exist`, { cause: error });
3004
+ }
3005
+ if (findErrorCode4(error, "EISDIR")) {
3006
+ throw new Error(`${flag} names a directory, not a file`, { cause: error });
3007
+ }
3008
+ throw new Error(`Could not read the file ${flag} names`, { cause: error });
3009
+ }
3010
+ }
3011
+
2983
3012
  // src/commands/decision-gaps.ts
2984
3013
  import {
2985
3014
  basouPaths as basouPaths5,
@@ -3347,6 +3376,7 @@ async function runDecisionCapture(options, ctx = {}) {
3347
3376
  }
3348
3377
  }
3349
3378
  async function doRunDecisionCapture(options, ctx) {
3379
+ refuseDashInputFile("--file", options.file, "stdin");
3350
3380
  const cwd = ctx.cwd ?? process.cwd();
3351
3381
  const repositoryRoot = await resolveBasouRootForCommand(cwd, "decision capture");
3352
3382
  const paths = basouPaths6(repositoryRoot);
@@ -3562,14 +3592,7 @@ function parseReason(raw) {
3562
3592
  }
3563
3593
  async function readCaptureInput(options, ctx) {
3564
3594
  if (options.file !== void 0) {
3565
- try {
3566
- return await readFile3(options.file, "utf8");
3567
- } catch (error) {
3568
- if (findErrorCode4(error, "ENOENT")) {
3569
- throw new Error(`Input file not found: ${options.file}`);
3570
- }
3571
- throw error;
3572
- }
3595
+ return await readInputFileText("--file", options.file);
3573
3596
  }
3574
3597
  if (ctx.readInput !== void 0) {
3575
3598
  return await ctx.readInput();
@@ -3908,7 +3931,7 @@ async function assertWorkspaceInitialized4(basouRoot) {
3908
3931
  try {
3909
3932
  await assertBasouRootSafe4(basouRoot);
3910
3933
  } catch (error) {
3911
- if (findErrorCode4(error, "ENOENT")) {
3934
+ if (findErrorCode5(error, "ENOENT")) {
3912
3935
  throw new Error("Workspace not initialized. Run 'basou init' first.");
3913
3936
  }
3914
3937
  throw error;
@@ -3919,7 +3942,7 @@ async function assertWorkspaceInitialized4(basouRoot) {
3919
3942
  import {
3920
3943
  assertBasouRootSafe as assertBasouRootSafe5,
3921
3944
  basouPaths as basouPaths7,
3922
- findErrorCode as findErrorCode5,
3945
+ findErrorCode as findErrorCode6,
3923
3946
  readMarkdownFile as readMarkdownFile4,
3924
3947
  renderDecisions as renderDecisions2,
3925
3948
  renderWithMarkers as renderWithMarkers2,
@@ -3961,7 +3984,7 @@ async function assertWorkspaceInitialized5(basouRoot) {
3961
3984
  try {
3962
3985
  await assertBasouRootSafe5(basouRoot);
3963
3986
  } catch (error) {
3964
- if (findErrorCode5(error, "ENOENT")) {
3987
+ if (findErrorCode6(error, "ENOENT")) {
3965
3988
  throw new Error("Workspace not initialized. Run 'basou init' first.");
3966
3989
  }
3967
3990
  throw error;
@@ -3993,6 +4016,24 @@ import {
3993
4016
  writeObservedDuration,
3994
4017
  writeYamlFile
3995
4018
  } from "@basou/core";
4019
+
4020
+ // src/lib/signal-exit-code.ts
4021
+ import { constants } from "os";
4022
+ var PROMISED_SIGNAL_NUMBERS = {
4023
+ SIGHUP: 1,
4024
+ SIGINT: 2,
4025
+ SIGQUIT: 3,
4026
+ SIGKILL: 9,
4027
+ SIGTERM: 15
4028
+ };
4029
+ var UNNUMBERED_SIGNAL_EXIT_CODE = 255;
4030
+ function signalToExitCode(sig) {
4031
+ if (sig === null) return 1;
4032
+ const num = PROMISED_SIGNAL_NUMBERS[sig] ?? constants.signals[sig];
4033
+ return num === void 0 ? UNNUMBERED_SIGNAL_EXIT_CODE : 128 + num;
4034
+ }
4035
+
4036
+ // src/commands/exec.ts
3996
4037
  function registerExecCommand(program) {
3997
4038
  program.command("exec <command> [args...]").description("Execute a command and record it as a Basou session").passThroughOptions().option("--timeout <duration>", "Kill the child after this duration (e.g. 30s, 5m, 1h)").option("--no-snapshot", "Skip git_snapshot before/after the command").option("--cwd <path>", "Run from a Basou root other than process.cwd()").option("-v, --verbose", "Show error causes").action(async (command, args, options) => {
3998
4039
  try {
@@ -4189,18 +4230,6 @@ function decideFinalStatus(result, signalReceived) {
4189
4230
  if (result.exit_code === 0) return "completed";
4190
4231
  return "failed";
4191
4232
  }
4192
- var SIGNUM_MAP = {
4193
- SIGHUP: 1,
4194
- SIGINT: 2,
4195
- SIGQUIT: 3,
4196
- SIGKILL: 9,
4197
- SIGTERM: 15
4198
- };
4199
- function signalToExitCode(sig) {
4200
- if (sig === null) return 1;
4201
- const num = SIGNUM_MAP[sig] ?? 1;
4202
- return 128 + num;
4203
- }
4204
4233
  async function tryAppendGitSnapshot(sessionDir, sessionId, repoRoot, now, appendEvent) {
4205
4234
  let snapshot;
4206
4235
  try {
@@ -4312,7 +4341,7 @@ async function finalizeSessionAsFailed(paths, sessionDir, sessionId, appendEvent
4312
4341
  import {
4313
4342
  assertBasouRootSafe as assertBasouRootSafe7,
4314
4343
  basouPaths as basouPaths9,
4315
- findErrorCode as findErrorCode6,
4344
+ findErrorCode as findErrorCode7,
4316
4345
  readMarkdownFile as readMarkdownFile5,
4317
4346
  renderHandoff as renderHandoff2,
4318
4347
  renderWithMarkers as renderWithMarkers3,
@@ -4370,7 +4399,7 @@ async function assertWorkspaceInitialized6(basouRoot) {
4370
4399
  try {
4371
4400
  await assertBasouRootSafe7(basouRoot);
4372
4401
  } catch (error) {
4373
- if (findErrorCode6(error, "ENOENT")) {
4402
+ if (findErrorCode7(error, "ENOENT")) {
4374
4403
  throw new Error("Workspace not initialized. Run 'basou init' first.");
4375
4404
  }
4376
4405
  throw error;
@@ -4621,7 +4650,7 @@ async function loadProtocolsConfig(configPath = DEFAULT_PROTOCOLS_CONFIG_PATH) {
4621
4650
  import {
4622
4651
  assertBasouRootSafe as assertBasouRootSafe8,
4623
4652
  basouPaths as basouPaths10,
4624
- findErrorCode as findErrorCode7,
4653
+ findErrorCode as findErrorCode8,
4625
4654
  renderOrientation as renderOrientation2,
4626
4655
  writeMarkdownFile as writeMarkdownFile4
4627
4656
  } from "@basou/core";
@@ -4778,7 +4807,7 @@ async function assertWorkspaceInitialized7(basouRoot) {
4778
4807
  try {
4779
4808
  await assertBasouRootSafe8(basouRoot);
4780
4809
  } catch (error) {
4781
- if (findErrorCode7(error, "ENOENT")) {
4810
+ if (findErrorCode8(error, "ENOENT")) {
4782
4811
  throw new Error("Workspace not initialized. Run 'basou init' first.");
4783
4812
  }
4784
4813
  throw error;
@@ -5833,7 +5862,6 @@ function renderGitignoreWarning(error, verbose) {
5833
5862
  }
5834
5863
 
5835
5864
  // src/commands/note.ts
5836
- import { readFile as readFile5 } from "fs/promises";
5837
5865
  import { homedir as homedir8 } from "os";
5838
5866
  import { resolve as resolve8 } from "path";
5839
5867
  import {
@@ -5843,7 +5871,7 @@ import {
5843
5871
  basouPaths as basouPaths12,
5844
5872
  createAdHocSessionWithEvent as createAdHocSessionWithEvent2,
5845
5873
  EVENT_SCHEMA_VERSION as EVENT_SCHEMA_VERSION4,
5846
- findErrorCode as findErrorCode8,
5874
+ findErrorCode as findErrorCode9,
5847
5875
  LOCAL_CLI_EVENT_SOURCE as LOCAL_CLI_EVENT_SOURCE3,
5848
5876
  readManifest as readManifest8,
5849
5877
  resolveSessionId as resolveSessionId2,
@@ -6004,22 +6032,12 @@ async function readNoteBody(bodyArgument, options, ctx, cwd) {
6004
6032
  if (bodyArgument !== void 0 && options.file !== void 0) {
6005
6033
  throw new Error("Pass the note text either as an argument or with --file, not both.");
6006
6034
  }
6035
+ refuseDashInputFile("--file", options.file, "stdin");
6007
6036
  if (bodyArgument !== void 0) {
6008
6037
  return { body: bodyArgument, source: "argument" };
6009
6038
  }
6010
6039
  if (options.file !== void 0) {
6011
- let raw;
6012
- try {
6013
- raw = await readFile5(resolve8(cwd, options.file), "utf8");
6014
- } catch (error) {
6015
- if (findErrorCode8(error, "ENOENT")) {
6016
- throw new Error("--file names a file that does not exist", { cause: error });
6017
- }
6018
- if (findErrorCode8(error, "EISDIR")) {
6019
- throw new Error("--file names a directory, not a file", { cause: error });
6020
- }
6021
- throw new Error("Could not read the file --file names", { cause: error });
6022
- }
6040
+ const raw = await readInputFileText("--file", resolve8(cwd, options.file));
6023
6041
  return { body: dropTrailingNewlines(raw), source: "file" };
6024
6042
  }
6025
6043
  if (ctx.readInput !== void 0) {
@@ -6088,7 +6106,7 @@ async function assertWorkspaceInitialized8(basouRoot) {
6088
6106
  try {
6089
6107
  await assertBasouRootSafe9(basouRoot);
6090
6108
  } catch (error) {
6091
- if (findErrorCode8(error, "ENOENT")) {
6109
+ if (findErrorCode9(error, "ENOENT")) {
6092
6110
  throw new Error("Workspace not initialized. Run 'basou init' first.");
6093
6111
  }
6094
6112
  throw error;
@@ -9417,7 +9435,7 @@ function renderProjectRetrofit(result) {
9417
9435
  }
9418
9436
 
9419
9437
  // src/commands/protocol.ts
9420
- import { readFile as readFile6, stat as stat5 } from "fs/promises";
9438
+ import { readFile as readFile5, stat as stat5 } from "fs/promises";
9421
9439
  import {
9422
9440
  carryForwardProtocolStamp,
9423
9441
  PROTOCOL_END as PROTOCOL_END2,
@@ -9474,7 +9492,7 @@ async function readProtocolSources(entries) {
9474
9492
  for (const entry of entries) {
9475
9493
  let content;
9476
9494
  try {
9477
- content = await readFile6(entry.source, "utf8");
9495
+ content = await readFile5(entry.source, "utf8");
9478
9496
  } catch (error) {
9479
9497
  if (error instanceof Error && error.code === "ENOENT") {
9480
9498
  throw new Error(
@@ -9600,7 +9618,7 @@ async function doRunProtocolUnsync(options) {
9600
9618
  import {
9601
9619
  assertBasouRootSafe as assertBasouRootSafe10,
9602
9620
  basouPaths as basouPaths14,
9603
- findErrorCode as findErrorCode10,
9621
+ findErrorCode as findErrorCode11,
9604
9622
  loadPortfolioConfig as loadPortfolioConfig5,
9605
9623
  readManifest as readManifest10
9606
9624
  } from "@basou/core";
@@ -9614,7 +9632,7 @@ import {
9614
9632
  assertApprovalStoreSafe as assertApprovalStoreSafe2,
9615
9633
  assertLockStoreSafe as assertLockStoreSafe4,
9616
9634
  assertTaskStoreSafe as assertTaskStoreSafe2,
9617
- findErrorCode as findErrorCode9
9635
+ findErrorCode as findErrorCode10
9618
9636
  } from "@basou/core";
9619
9637
  var DEFAULT_WATCH_INTERVAL_SEC = 30;
9620
9638
  var MIN_WATCH_INTERVAL_SEC = 5;
@@ -9632,7 +9650,7 @@ async function scanSourceLogs(roots) {
9632
9650
  try {
9633
9651
  entries = await readdir3(dir, { withFileTypes: true });
9634
9652
  } catch (error) {
9635
- if (findErrorCode9(error, "ENOENT") || findErrorCode9(error, "ENOTDIR")) return;
9653
+ if (findErrorCode10(error, "ENOENT") || findErrorCode10(error, "ENOTDIR")) return;
9636
9654
  throw new Error("Failed to read a source log directory", { cause: error });
9637
9655
  }
9638
9656
  for (const entry of entries) {
@@ -9644,7 +9662,7 @@ async function scanSourceLogs(roots) {
9644
9662
  const info = await stat6(full);
9645
9663
  out.set(full, { mtimeMs: info.mtimeMs, size: info.size });
9646
9664
  } catch (error) {
9647
- if (findErrorCode9(error, "ENOENT")) continue;
9665
+ if (findErrorCode10(error, "ENOENT")) continue;
9648
9666
  throw new Error("Failed to stat a source log file", { cause: error });
9649
9667
  }
9650
9668
  }
@@ -9978,7 +9996,7 @@ async function assertWorkspaceInitialized9(basouRoot) {
9978
9996
  try {
9979
9997
  await assertBasouRootSafe10(basouRoot);
9980
9998
  } catch (error) {
9981
- if (findErrorCode10(error, "ENOENT")) {
9999
+ if (findErrorCode11(error, "ENOENT")) {
9982
10000
  throw new Error("Workspace not initialized. Run 'basou init' first.");
9983
10001
  }
9984
10002
  throw error;
@@ -9990,7 +10008,7 @@ import { isAbsolute as isAbsolute4, resolve as resolve10 } from "path";
9990
10008
  import {
9991
10009
  assertBasouRootSafe as assertBasouRootSafe11,
9992
10010
  basouPaths as basouPaths15,
9993
- findErrorCode as findErrorCode11,
10011
+ findErrorCode as findErrorCode12,
9994
10012
  renderReport,
9995
10013
  writeMarkdownFile as writeMarkdownFile6
9996
10014
  } from "@basou/core";
@@ -10042,7 +10060,7 @@ async function assertWorkspaceInitialized10(basouRoot) {
10042
10060
  try {
10043
10061
  await assertBasouRootSafe11(basouRoot);
10044
10062
  } catch (error) {
10045
- if (findErrorCode11(error, "ENOENT")) {
10063
+ if (findErrorCode12(error, "ENOENT")) {
10046
10064
  throw new Error("Workspace not initialized. Run 'basou init' first.");
10047
10065
  }
10048
10066
  throw error;
@@ -10050,7 +10068,6 @@ async function assertWorkspaceInitialized10(basouRoot) {
10050
10068
  }
10051
10069
 
10052
10070
  // src/commands/review.ts
10053
- import { readFile as readFile7 } from "fs/promises";
10054
10071
  import { homedir as homedir10 } from "os";
10055
10072
  import { resolve as resolve11 } from "path";
10056
10073
  import {
@@ -10059,7 +10076,7 @@ import {
10059
10076
  buildReviewRecordedEvent,
10060
10077
  buildReviewRecordLabel,
10061
10078
  createAdHocSessionWithEvent as createAdHocSessionWithEvent3,
10062
- findErrorCode as findErrorCode12,
10079
+ findErrorCode as findErrorCode13,
10063
10080
  findUnbindableRepos,
10064
10081
  parseReviewRecordInput,
10065
10082
  readManifest as readManifest11,
@@ -10135,6 +10152,7 @@ async function runReviewRecord(options, ctx = {}) {
10135
10152
  }
10136
10153
  }
10137
10154
  async function doRunReviewRecord(options, ctx) {
10155
+ refuseDashInputFile("--file", options.file, "stdin");
10138
10156
  const cwd = ctx.cwd ?? process.cwd();
10139
10157
  const repositoryRoot = await resolveBasouRootForCommand(cwd, "review record");
10140
10158
  const paths = basouPaths16(repositoryRoot);
@@ -10193,14 +10211,7 @@ ${detail}
10193
10211
  }
10194
10212
  async function readReviewInput(options, ctx) {
10195
10213
  if (options.file !== void 0) {
10196
- try {
10197
- return await readFile7(options.file, "utf8");
10198
- } catch (error) {
10199
- if (findErrorCode12(error, "ENOENT")) {
10200
- throw new Error(`Input file not found: ${options.file}`);
10201
- }
10202
- throw error;
10203
- }
10214
+ return await readInputFileText("--file", options.file);
10204
10215
  }
10205
10216
  if (ctx.readInput !== void 0) {
10206
10217
  return await ctx.readInput();
@@ -10275,7 +10286,7 @@ async function assertWorkspaceInitialized11(basouRoot) {
10275
10286
  try {
10276
10287
  await assertBasouRootSafe12(basouRoot);
10277
10288
  } catch (error) {
10278
- if (findErrorCode12(error, "ENOENT")) {
10289
+ if (findErrorCode13(error, "ENOENT")) {
10279
10290
  throw new Error("Workspace not initialized. Run 'basou init' first.");
10280
10291
  }
10281
10292
  throw error;
@@ -10487,7 +10498,7 @@ function unattachedLines(u) {
10487
10498
  }
10488
10499
 
10489
10500
  // src/commands/run.ts
10490
- import { mkdir as mkdir3, readFile as readFile8, rm as rm3 } from "fs/promises";
10501
+ import { mkdir as mkdir3, readFile as readFile6, rm as rm3 } from "fs/promises";
10491
10502
  import { homedir as homedir11 } from "os";
10492
10503
  import { join as join14 } from "path";
10493
10504
  import {
@@ -10758,7 +10769,7 @@ async function runTrackedTool(args, options, ctx, adapter) {
10758
10769
  s.session.related_files = relatedFiles;
10759
10770
  });
10760
10771
  if (result.exit_code !== null) return result.exit_code;
10761
- return signalToExitCode2(signalReceived ?? result.signal);
10772
+ return signalToExitCode(signalReceived ?? result.signal);
10762
10773
  }
10763
10774
  function decideFinalStatus2(result, signalReceived) {
10764
10775
  if (signalReceived === "SIGINT" || signalReceived === "SIGTERM") return "interrupted";
@@ -10768,18 +10779,6 @@ function decideFinalStatus2(result, signalReceived) {
10768
10779
  if (result.exit_code === 0) return "completed";
10769
10780
  return "failed";
10770
10781
  }
10771
- var SIGNUM_MAP2 = {
10772
- SIGHUP: 1,
10773
- SIGINT: 2,
10774
- SIGQUIT: 3,
10775
- SIGKILL: 9,
10776
- SIGTERM: 15
10777
- };
10778
- function signalToExitCode2(sig) {
10779
- if (sig === null) return 1;
10780
- const num = SIGNUM_MAP2[sig] ?? 1;
10781
- return 128 + num;
10782
- }
10783
10782
  async function tryAppendGitSnapshot2(sessionDir, sessionId, repoRoot, now, appendEvent) {
10784
10783
  let snapshot;
10785
10784
  try {
@@ -10937,7 +10936,7 @@ async function noteCodexHookStatusPreSpawn(_cwd, ctx) {
10937
10936
  const hooksPath = ctx.codexHooksPath ?? DEFAULT_CODEX_HOOKS_PATH;
10938
10937
  let location;
10939
10938
  try {
10940
- location = findBasouSessionStartHook2(JSON.parse(await readFile8(hooksPath, "utf8")));
10939
+ location = findBasouSessionStartHook2(JSON.parse(await readFile6(hooksPath, "utf8")));
10941
10940
  } catch (error) {
10942
10941
  if (!(error instanceof Error && error.code === "ENOENT")) return null;
10943
10942
  location = null;
@@ -10951,7 +10950,7 @@ async function noteCodexHookStatusPreSpawn(_cwd, ctx) {
10951
10950
  }
10952
10951
 
10953
10952
  // src/commands/session.ts
10954
- import { readFile as readFile9 } from "fs/promises";
10953
+ import { readFile as readFile7 } from "fs/promises";
10955
10954
  import { basename as basename8, isAbsolute as isAbsolute5, join as join15, relative as relative4, sep as sep3 } from "path";
10956
10955
  import {
10957
10956
  acquireLock as acquireLock6,
@@ -10962,7 +10961,7 @@ import {
10962
10961
  displayPath as displayPath5,
10963
10962
  EVENT_SCHEMA_VERSION as EVENT_SCHEMA_VERSION6,
10964
10963
  enumerateSessionEntries as enumerateSessionEntries2,
10965
- findErrorCode as findErrorCode13,
10964
+ findErrorCode as findErrorCode14,
10966
10965
  importSessionFromJson as importSessionFromJson2,
10967
10966
  LOCAL_CLI_EVENT_SOURCE as LOCAL_CLI_EVENT_SOURCE4,
10968
10967
  loadSessionEntries as loadSessionEntries2,
@@ -11091,7 +11090,7 @@ async function doRunSessionShow(idInput, options, ctx) {
11091
11090
  const raw = await readYamlFile6(sessionYamlPath);
11092
11091
  session = SessionSchema3.parse(normalizeSessionTimestamps(raw));
11093
11092
  } catch (error) {
11094
- if (findErrorCode13(error, "ENOENT")) {
11093
+ if (findErrorCode14(error, "ENOENT")) {
11095
11094
  throw new Error(`Session not found: ${idInput}`);
11096
11095
  }
11097
11096
  throw new Error("Failed to read session", { cause: error });
@@ -11355,7 +11354,7 @@ async function assertWorkspaceInitialized12(basouRoot) {
11355
11354
  try {
11356
11355
  await assertBasouRootSafe14(basouRoot);
11357
11356
  } catch (error) {
11358
- if (findErrorCode13(error, "ENOENT")) {
11357
+ if (findErrorCode14(error, "ENOENT")) {
11359
11358
  throw new Error("Workspace not initialized. Run 'basou init' first.");
11360
11359
  }
11361
11360
  throw error;
@@ -11391,6 +11390,7 @@ async function runSessionImport(options, ctx = {}) {
11391
11390
  }
11392
11391
  }
11393
11392
  async function doRunSessionImport(options, ctx) {
11393
+ refuseDashInputFile("--from", options.from, { fileOnly: "the JSON" });
11394
11394
  const cwd = ctx.cwd ?? process.cwd();
11395
11395
  const repositoryRoot = await resolveRepositoryRootForSession(cwd, "import");
11396
11396
  const paths = basouPaths19(repositoryRoot);
@@ -11424,12 +11424,12 @@ async function doRunSessionImport(options, ctx) {
11424
11424
  }
11425
11425
  async function readInputFile(path) {
11426
11426
  try {
11427
- return await readFile9(path, "utf8");
11427
+ return await readFile7(path, "utf8");
11428
11428
  } catch (error) {
11429
- if (findErrorCode13(error, "ENOENT")) {
11429
+ if (findErrorCode14(error, "ENOENT")) {
11430
11430
  throw new Error("Import source not found", { cause: error });
11431
11431
  }
11432
- if (findErrorCode13(error, "EISDIR")) {
11432
+ if (findErrorCode14(error, "EISDIR")) {
11433
11433
  throw new Error("Import source is not a file", { cause: error });
11434
11434
  }
11435
11435
  throw new Error("Failed to read import source", { cause: error });
@@ -11504,9 +11504,7 @@ async function doRunSessionNote(sessionIdInput, options, ctx) {
11504
11504
  if (hasBody && hasFromFile) {
11505
11505
  throw new Error("--body and --from-file are mutually exclusive");
11506
11506
  }
11507
- if (hasFromFile && options.fromFile === "-") {
11508
- throw new Error("--from-file - (stdin) is not supported in v0.1");
11509
- }
11507
+ refuseDashInputFile("--from-file", options.fromFile, { textFlag: "--body" });
11510
11508
  const cwd = ctx.cwd ?? process.cwd();
11511
11509
  const repositoryRoot = await resolveRepositoryRootForSession(cwd, "note");
11512
11510
  const paths = basouPaths19(repositoryRoot);
@@ -11541,12 +11539,12 @@ async function doRunSessionNote(sessionIdInput, options, ctx) {
11541
11539
  }
11542
11540
  async function readNoteFile(path) {
11543
11541
  try {
11544
- return await readFile9(path, "utf8");
11542
+ return await readFile7(path, "utf8");
11545
11543
  } catch (error) {
11546
- if (findErrorCode13(error, "ENOENT")) {
11544
+ if (findErrorCode14(error, "ENOENT")) {
11547
11545
  throw new Error("Note source not found", { cause: error });
11548
11546
  }
11549
- if (findErrorCode13(error, "EISDIR")) {
11547
+ if (findErrorCode14(error, "EISDIR")) {
11550
11548
  throw new Error("Note source is not a file", { cause: error });
11551
11549
  }
11552
11550
  throw new Error("Failed to read note source", { cause: error });
@@ -11659,7 +11657,7 @@ import {
11659
11657
  assertBasouRootSafe as assertBasouRootSafe15,
11660
11658
  basouPaths as basouPaths20,
11661
11659
  computeWorkStats,
11662
- findErrorCode as findErrorCode14
11660
+ findErrorCode as findErrorCode15
11663
11661
  } from "@basou/core";
11664
11662
  function registerStatsCommand(program) {
11665
11663
  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) => {
@@ -11768,7 +11766,7 @@ async function assertWorkspaceInitialized13(basouRoot) {
11768
11766
  try {
11769
11767
  await assertBasouRootSafe15(basouRoot);
11770
11768
  } catch (error) {
11771
- if (findErrorCode14(error, "ENOENT")) {
11769
+ if (findErrorCode15(error, "ENOENT")) {
11772
11770
  throw new Error("Workspace not initialized. Run 'basou init' first.");
11773
11771
  }
11774
11772
  throw error;
@@ -11780,7 +11778,7 @@ import {
11780
11778
  assertBasouRootSafe as assertBasouRootSafe16,
11781
11779
  basouPaths as basouPaths21,
11782
11780
  buildStatusSnapshot,
11783
- findErrorCode as findErrorCode15,
11781
+ findErrorCode as findErrorCode16,
11784
11782
  readManifest as readManifest14,
11785
11783
  writeStatus
11786
11784
  } from "@basou/core";
@@ -11804,7 +11802,7 @@ async function doRunStatus(options, ctx) {
11804
11802
  try {
11805
11803
  await assertBasouRootSafe16(paths.root);
11806
11804
  } catch (error) {
11807
- if (findErrorCode15(error, "ENOENT")) {
11805
+ if (findErrorCode16(error, "ENOENT")) {
11808
11806
  throw new Error("Workspace not initialized. Run 'basou init' first.");
11809
11807
  }
11810
11808
  throw error;
@@ -11813,7 +11811,7 @@ async function doRunStatus(options, ctx) {
11813
11811
  try {
11814
11812
  manifest = await readManifest14(paths);
11815
11813
  } catch (error) {
11816
- if (findErrorCode15(error, "ENOENT")) {
11814
+ if (findErrorCode16(error, "ENOENT")) {
11817
11815
  throw new Error("Workspace not initialized. Run 'basou init' first.");
11818
11816
  }
11819
11817
  const gateMessage = formatVersionGateMessage(error);
@@ -11851,7 +11849,7 @@ function formatVersionGateMessage(error) {
11851
11849
  }
11852
11850
 
11853
11851
  // src/commands/task.ts
11854
- import { readFile as readFile10 } from "fs/promises";
11852
+ import { readFile as readFile8 } from "fs/promises";
11855
11853
  import { join as join16 } from "path";
11856
11854
  import {
11857
11855
  archiveTask,
@@ -11862,7 +11860,7 @@ import {
11862
11860
  deleteTask,
11863
11861
  editTask,
11864
11862
  enumerateArchivedTaskIds,
11865
- findErrorCode as findErrorCode16,
11863
+ findErrorCode as findErrorCode17,
11866
11864
  loadSessionEntries as loadSessionEntries3,
11867
11865
  loadTaskEntries,
11868
11866
  prefixedUlid as prefixedUlid5,
@@ -11949,9 +11947,7 @@ async function doRunTaskNew(options, ctx) {
11949
11947
  if (options.description !== void 0 && options.fromFile !== void 0) {
11950
11948
  throw new Error("--description and --from-file are mutually exclusive");
11951
11949
  }
11952
- if (options.fromFile === "-") {
11953
- throw new Error("--from-file - (stdin) is not supported in v0.1");
11954
- }
11950
+ refuseDashInputFile("--from-file", options.fromFile, { textFlag: "--description" });
11955
11951
  const initialStatus = options.status ?? "planned";
11956
11952
  if (options.completedAt !== void 0 && !isTerminalStatusForCli(initialStatus)) {
11957
11953
  throw new Error("--completed-at requires --status done or cancelled");
@@ -12868,12 +12864,12 @@ function parsePositiveInt2(raw) {
12868
12864
  }
12869
12865
  async function readDescriptionFile(path) {
12870
12866
  try {
12871
- return await readFile10(path, "utf8");
12867
+ return await readFile8(path, "utf8");
12872
12868
  } catch (error) {
12873
- if (findErrorCode16(error, "ENOENT")) {
12869
+ if (findErrorCode17(error, "ENOENT")) {
12874
12870
  throw new Error("Description source not found", { cause: error });
12875
12871
  }
12876
- if (findErrorCode16(error, "EISDIR")) {
12872
+ if (findErrorCode17(error, "EISDIR")) {
12877
12873
  throw new Error("Description source is not a file", { cause: error });
12878
12874
  }
12879
12875
  throw new Error("Failed to read description source", { cause: error });
@@ -12886,7 +12882,7 @@ async function assertWorkspaceInitialized14(basouRoot) {
12886
12882
  try {
12887
12883
  await assertBasouRootSafe17(basouRoot);
12888
12884
  } catch (error) {
12889
- if (findErrorCode16(error, "ENOENT")) {
12885
+ if (findErrorCode17(error, "ENOENT")) {
12890
12886
  throw new Error("Workspace not initialized. Run 'basou init' first.");
12891
12887
  }
12892
12888
  throw error;
@@ -12977,7 +12973,7 @@ import {
12977
12973
  assertBasouRootSafe as assertBasouRootSafe18,
12978
12974
  basouPaths as basouPaths23,
12979
12975
  enumerateSessionEntries as enumerateSessionEntries3,
12980
- findErrorCode as findErrorCode17,
12976
+ findErrorCode as findErrorCode18,
12981
12977
  resolveSessionId as resolveSessionId5,
12982
12978
  verifyEventsChain
12983
12979
  } from "@basou/core";
@@ -13064,7 +13060,7 @@ async function assertWorkspaceInitialized15(basouRoot) {
13064
13060
  try {
13065
13061
  await assertBasouRootSafe18(basouRoot);
13066
13062
  } catch (error) {
13067
- if (findErrorCode17(error, "ENOENT")) {
13063
+ if (findErrorCode18(error, "ENOENT")) {
13068
13064
  throw new Error("Workspace not initialized. Run 'basou init' first.");
13069
13065
  }
13070
13066
  throw error;
@@ -13078,7 +13074,7 @@ import { basename as basename11, dirname as dirname9, join as join20, resolve as
13078
13074
  import {
13079
13075
  assertBasouRootSafe as assertBasouRootSafe19,
13080
13076
  basouPaths as basouPaths25,
13081
- findErrorCode as findErrorCode19,
13077
+ findErrorCode as findErrorCode20,
13082
13078
  loadPortfolioConfig as loadPortfolioConfig6,
13083
13079
  readManifest as readManifest19
13084
13080
  } from "@basou/core";
@@ -13594,7 +13590,7 @@ import {
13594
13590
  boardPageUnavailable,
13595
13591
  computeWorkStats as computeWorkStats2,
13596
13592
  enumerateApprovals as enumerateApprovals2,
13597
- findErrorCode as findErrorCode18,
13593
+ findErrorCode as findErrorCode19,
13598
13594
  inspectSessionEntry as inspectSessionEntry2,
13599
13595
  isLazyExpired as isLazyExpired2,
13600
13596
  loadApproval as loadApproval2,
@@ -15543,7 +15539,7 @@ async function overview(ws, nowProvider, resolveRemoteUrl) {
15543
15539
  try {
15544
15540
  manifest = await readManifest18(ws.paths);
15545
15541
  } catch (error) {
15546
- if (findErrorCode18(error, "ENOENT")) {
15542
+ if (findErrorCode19(error, "ENOENT")) {
15547
15543
  return { initialized: false, repoRoot: ws.repoRoot };
15548
15544
  }
15549
15545
  throw error;
@@ -15953,7 +15949,7 @@ async function startListening(port, deps) {
15953
15949
  try {
15954
15950
  return await startViewServer({ port, deps });
15955
15951
  } catch (error) {
15956
- if (findErrorCode19(error, "EADDRINUSE")) {
15952
+ if (findErrorCode20(error, "EADDRINUSE")) {
15957
15953
  throw new Error(`Port ${port} is already in use. Pass --port <n> to choose another.`, {
15958
15954
  cause: error
15959
15955
  });
@@ -16006,7 +16002,7 @@ async function assertWorkspaceInitialized16(basouRoot) {
16006
16002
  try {
16007
16003
  await assertBasouRootSafe19(basouRoot);
16008
16004
  } catch (error) {
16009
- if (findErrorCode19(error, "ENOENT")) {
16005
+ if (findErrorCode20(error, "ENOENT")) {
16010
16006
  throw new Error("Workspace not initialized. Run 'basou init' first.");
16011
16007
  }
16012
16008
  throw error;
@@ -16045,7 +16041,7 @@ function installExperimentalNotice(program, names = EXPERIMENTAL_COMMANDS, write
16045
16041
  function readBuildStamp() {
16046
16042
  if (false) return void 0;
16047
16043
  try {
16048
- return JSON.parse('{"version":"0.68.3","commit":"42d94c5","committedAt":"2026-10-13T15:23:54+09:00"}');
16044
+ return JSON.parse('{"version":"0.69.0","commit":"bffcfee","committedAt":"2026-10-16T08:07:08+09:00"}');
16049
16045
  } catch {
16050
16046
  return void 0;
16051
16047
  }