@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/index.js CHANGED
@@ -1950,7 +1950,8 @@ It prints a declaration of the newest board_version, in the language the
1950
1950
  manifest declares for the workspace's own repo: a title from the workspace's
1951
1951
  name, the six stages with a meaning each, one lane to cut again, nothing to
1952
1952
  observe, no component registered, an axis of version 1, and the effort from
1953
- the day of the first session, in this host's time zone. It writes nothing:
1953
+ the day of the first session, in this host's time zone, with no milestone
1954
+ (a comment says what one holds). It writes nothing:
1954
1955
  save it, from the workspace's own repo, only where no board is, through a file
1955
1956
  of its own:
1956
1957
 
@@ -2957,7 +2958,6 @@ async function doRunChannelClear(face, options) {
2957
2958
  }
2958
2959
 
2959
2960
  // src/commands/decision.ts
2960
- import { readFile as readFile3 } from "fs/promises";
2961
2961
  import { homedir as homedir3 } from "os";
2962
2962
  import { join as join7, resolve as resolve4 } from "path";
2963
2963
  import {
@@ -2970,7 +2970,7 @@ import {
2970
2970
  createAdHocSessionWithEvent,
2971
2971
  displayPath as displayPath4,
2972
2972
  EVENT_SCHEMA_VERSION as EVENT_SCHEMA_VERSION2,
2973
- findErrorCode as findErrorCode4,
2973
+ findErrorCode as findErrorCode5,
2974
2974
  isValidPrefixedId,
2975
2975
  LOCAL_CLI_EVENT_SOURCE as LOCAL_CLI_EVENT_SOURCE2,
2976
2976
  loadSessionEntries,
@@ -2982,6 +2982,35 @@ import {
2982
2982
  } from "@basou/core";
2983
2983
  import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
2984
2984
 
2985
+ // src/lib/input-file.ts
2986
+ import { readFile as readFile3 } from "fs/promises";
2987
+ import { findErrorCode as findErrorCode4 } from "@basou/core";
2988
+ function refuseDashInputFile(flag, value, alternative) {
2989
+ if (value !== "-") return;
2990
+ if (alternative === "stdin") {
2991
+ throw new Error(
2992
+ `${flag} - is refused: - is reserved for standard input. Omit ${flag} to read stdin, or pass ${flag} ./- to read a file named -.`
2993
+ );
2994
+ }
2995
+ 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}`;
2996
+ throw new Error(
2997
+ `${flag} - is refused: - is reserved for standard input, which this command does not read. ${toFile}; a file named - is read with ${flag} ./-.`
2998
+ );
2999
+ }
3000
+ async function readInputFileText(flag, path) {
3001
+ try {
3002
+ return await readFile3(path, "utf8");
3003
+ } catch (error) {
3004
+ if (findErrorCode4(error, "ENOENT")) {
3005
+ throw new Error(`${flag} names a file that does not exist`, { cause: error });
3006
+ }
3007
+ if (findErrorCode4(error, "EISDIR")) {
3008
+ throw new Error(`${flag} names a directory, not a file`, { cause: error });
3009
+ }
3010
+ throw new Error(`Could not read the file ${flag} names`, { cause: error });
3011
+ }
3012
+ }
3013
+
2985
3014
  // src/commands/decision-gaps.ts
2986
3015
  import {
2987
3016
  basouPaths as basouPaths5,
@@ -3349,6 +3378,7 @@ async function runDecisionCapture(options, ctx = {}) {
3349
3378
  }
3350
3379
  }
3351
3380
  async function doRunDecisionCapture(options, ctx) {
3381
+ refuseDashInputFile("--file", options.file, "stdin");
3352
3382
  const cwd = ctx.cwd ?? process.cwd();
3353
3383
  const repositoryRoot = await resolveBasouRootForCommand(cwd, "decision capture");
3354
3384
  const paths = basouPaths6(repositoryRoot);
@@ -3564,14 +3594,7 @@ function parseReason(raw) {
3564
3594
  }
3565
3595
  async function readCaptureInput(options, ctx) {
3566
3596
  if (options.file !== void 0) {
3567
- try {
3568
- return await readFile3(options.file, "utf8");
3569
- } catch (error) {
3570
- if (findErrorCode4(error, "ENOENT")) {
3571
- throw new Error(`Input file not found: ${options.file}`);
3572
- }
3573
- throw error;
3574
- }
3597
+ return await readInputFileText("--file", options.file);
3575
3598
  }
3576
3599
  if (ctx.readInput !== void 0) {
3577
3600
  return await ctx.readInput();
@@ -3910,7 +3933,7 @@ async function assertWorkspaceInitialized4(basouRoot) {
3910
3933
  try {
3911
3934
  await assertBasouRootSafe4(basouRoot);
3912
3935
  } catch (error) {
3913
- if (findErrorCode4(error, "ENOENT")) {
3936
+ if (findErrorCode5(error, "ENOENT")) {
3914
3937
  throw new Error("Workspace not initialized. Run 'basou init' first.");
3915
3938
  }
3916
3939
  throw error;
@@ -3921,7 +3944,7 @@ async function assertWorkspaceInitialized4(basouRoot) {
3921
3944
  import {
3922
3945
  assertBasouRootSafe as assertBasouRootSafe5,
3923
3946
  basouPaths as basouPaths7,
3924
- findErrorCode as findErrorCode5,
3947
+ findErrorCode as findErrorCode6,
3925
3948
  readMarkdownFile as readMarkdownFile4,
3926
3949
  renderDecisions as renderDecisions2,
3927
3950
  renderWithMarkers as renderWithMarkers2,
@@ -3963,7 +3986,7 @@ async function assertWorkspaceInitialized5(basouRoot) {
3963
3986
  try {
3964
3987
  await assertBasouRootSafe5(basouRoot);
3965
3988
  } catch (error) {
3966
- if (findErrorCode5(error, "ENOENT")) {
3989
+ if (findErrorCode6(error, "ENOENT")) {
3967
3990
  throw new Error("Workspace not initialized. Run 'basou init' first.");
3968
3991
  }
3969
3992
  throw error;
@@ -3995,6 +4018,24 @@ import {
3995
4018
  writeObservedDuration,
3996
4019
  writeYamlFile
3997
4020
  } from "@basou/core";
4021
+
4022
+ // src/lib/signal-exit-code.ts
4023
+ import { constants } from "os";
4024
+ var PROMISED_SIGNAL_NUMBERS = {
4025
+ SIGHUP: 1,
4026
+ SIGINT: 2,
4027
+ SIGQUIT: 3,
4028
+ SIGKILL: 9,
4029
+ SIGTERM: 15
4030
+ };
4031
+ var UNNUMBERED_SIGNAL_EXIT_CODE = 255;
4032
+ function signalToExitCode(sig) {
4033
+ if (sig === null) return 1;
4034
+ const num = PROMISED_SIGNAL_NUMBERS[sig] ?? constants.signals[sig];
4035
+ return num === void 0 ? UNNUMBERED_SIGNAL_EXIT_CODE : 128 + num;
4036
+ }
4037
+
4038
+ // src/commands/exec.ts
3998
4039
  function registerExecCommand(program2) {
3999
4040
  program2.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) => {
4000
4041
  try {
@@ -4191,18 +4232,6 @@ function decideFinalStatus(result, signalReceived) {
4191
4232
  if (result.exit_code === 0) return "completed";
4192
4233
  return "failed";
4193
4234
  }
4194
- var SIGNUM_MAP = {
4195
- SIGHUP: 1,
4196
- SIGINT: 2,
4197
- SIGQUIT: 3,
4198
- SIGKILL: 9,
4199
- SIGTERM: 15
4200
- };
4201
- function signalToExitCode(sig) {
4202
- if (sig === null) return 1;
4203
- const num = SIGNUM_MAP[sig] ?? 1;
4204
- return 128 + num;
4205
- }
4206
4235
  async function tryAppendGitSnapshot(sessionDir, sessionId, repoRoot, now, appendEvent) {
4207
4236
  let snapshot;
4208
4237
  try {
@@ -4314,7 +4343,7 @@ async function finalizeSessionAsFailed(paths, sessionDir, sessionId, appendEvent
4314
4343
  import {
4315
4344
  assertBasouRootSafe as assertBasouRootSafe7,
4316
4345
  basouPaths as basouPaths9,
4317
- findErrorCode as findErrorCode6,
4346
+ findErrorCode as findErrorCode7,
4318
4347
  readMarkdownFile as readMarkdownFile5,
4319
4348
  renderHandoff as renderHandoff2,
4320
4349
  renderWithMarkers as renderWithMarkers3,
@@ -4372,7 +4401,7 @@ async function assertWorkspaceInitialized6(basouRoot) {
4372
4401
  try {
4373
4402
  await assertBasouRootSafe7(basouRoot);
4374
4403
  } catch (error) {
4375
- if (findErrorCode6(error, "ENOENT")) {
4404
+ if (findErrorCode7(error, "ENOENT")) {
4376
4405
  throw new Error("Workspace not initialized. Run 'basou init' first.");
4377
4406
  }
4378
4407
  throw error;
@@ -4623,7 +4652,7 @@ async function loadProtocolsConfig(configPath = DEFAULT_PROTOCOLS_CONFIG_PATH) {
4623
4652
  import {
4624
4653
  assertBasouRootSafe as assertBasouRootSafe8,
4625
4654
  basouPaths as basouPaths10,
4626
- findErrorCode as findErrorCode7,
4655
+ findErrorCode as findErrorCode8,
4627
4656
  renderOrientation as renderOrientation2,
4628
4657
  writeMarkdownFile as writeMarkdownFile4
4629
4658
  } from "@basou/core";
@@ -4780,7 +4809,7 @@ async function assertWorkspaceInitialized7(basouRoot) {
4780
4809
  try {
4781
4810
  await assertBasouRootSafe8(basouRoot);
4782
4811
  } catch (error) {
4783
- if (findErrorCode7(error, "ENOENT")) {
4812
+ if (findErrorCode8(error, "ENOENT")) {
4784
4813
  throw new Error("Workspace not initialized. Run 'basou init' first.");
4785
4814
  }
4786
4815
  throw error;
@@ -5835,7 +5864,6 @@ function renderGitignoreWarning(error, verbose) {
5835
5864
  }
5836
5865
 
5837
5866
  // src/commands/note.ts
5838
- import { readFile as readFile5 } from "fs/promises";
5839
5867
  import { homedir as homedir8 } from "os";
5840
5868
  import { resolve as resolve8 } from "path";
5841
5869
  import {
@@ -5845,7 +5873,7 @@ import {
5845
5873
  basouPaths as basouPaths12,
5846
5874
  createAdHocSessionWithEvent as createAdHocSessionWithEvent2,
5847
5875
  EVENT_SCHEMA_VERSION as EVENT_SCHEMA_VERSION4,
5848
- findErrorCode as findErrorCode8,
5876
+ findErrorCode as findErrorCode9,
5849
5877
  LOCAL_CLI_EVENT_SOURCE as LOCAL_CLI_EVENT_SOURCE3,
5850
5878
  readManifest as readManifest8,
5851
5879
  resolveSessionId as resolveSessionId2,
@@ -6006,22 +6034,12 @@ async function readNoteBody(bodyArgument, options, ctx, cwd) {
6006
6034
  if (bodyArgument !== void 0 && options.file !== void 0) {
6007
6035
  throw new Error("Pass the note text either as an argument or with --file, not both.");
6008
6036
  }
6037
+ refuseDashInputFile("--file", options.file, "stdin");
6009
6038
  if (bodyArgument !== void 0) {
6010
6039
  return { body: bodyArgument, source: "argument" };
6011
6040
  }
6012
6041
  if (options.file !== void 0) {
6013
- let raw;
6014
- try {
6015
- raw = await readFile5(resolve8(cwd, options.file), "utf8");
6016
- } catch (error) {
6017
- if (findErrorCode8(error, "ENOENT")) {
6018
- throw new Error("--file names a file that does not exist", { cause: error });
6019
- }
6020
- if (findErrorCode8(error, "EISDIR")) {
6021
- throw new Error("--file names a directory, not a file", { cause: error });
6022
- }
6023
- throw new Error("Could not read the file --file names", { cause: error });
6024
- }
6042
+ const raw = await readInputFileText("--file", resolve8(cwd, options.file));
6025
6043
  return { body: dropTrailingNewlines(raw), source: "file" };
6026
6044
  }
6027
6045
  if (ctx.readInput !== void 0) {
@@ -6090,7 +6108,7 @@ async function assertWorkspaceInitialized8(basouRoot) {
6090
6108
  try {
6091
6109
  await assertBasouRootSafe9(basouRoot);
6092
6110
  } catch (error) {
6093
- if (findErrorCode8(error, "ENOENT")) {
6111
+ if (findErrorCode9(error, "ENOENT")) {
6094
6112
  throw new Error("Workspace not initialized. Run 'basou init' first.");
6095
6113
  }
6096
6114
  throw error;
@@ -9419,7 +9437,7 @@ function renderProjectRetrofit(result) {
9419
9437
  }
9420
9438
 
9421
9439
  // src/commands/protocol.ts
9422
- import { readFile as readFile6, stat as stat5 } from "fs/promises";
9440
+ import { readFile as readFile5, stat as stat5 } from "fs/promises";
9423
9441
  import {
9424
9442
  carryForwardProtocolStamp,
9425
9443
  PROTOCOL_END as PROTOCOL_END2,
@@ -9476,7 +9494,7 @@ async function readProtocolSources(entries) {
9476
9494
  for (const entry of entries) {
9477
9495
  let content;
9478
9496
  try {
9479
- content = await readFile6(entry.source, "utf8");
9497
+ content = await readFile5(entry.source, "utf8");
9480
9498
  } catch (error) {
9481
9499
  if (error instanceof Error && error.code === "ENOENT") {
9482
9500
  throw new Error(
@@ -9602,7 +9620,7 @@ async function doRunProtocolUnsync(options) {
9602
9620
  import {
9603
9621
  assertBasouRootSafe as assertBasouRootSafe10,
9604
9622
  basouPaths as basouPaths14,
9605
- findErrorCode as findErrorCode10,
9623
+ findErrorCode as findErrorCode11,
9606
9624
  loadPortfolioConfig as loadPortfolioConfig5,
9607
9625
  readManifest as readManifest10
9608
9626
  } from "@basou/core";
@@ -9616,7 +9634,7 @@ import {
9616
9634
  assertApprovalStoreSafe as assertApprovalStoreSafe2,
9617
9635
  assertLockStoreSafe as assertLockStoreSafe4,
9618
9636
  assertTaskStoreSafe as assertTaskStoreSafe2,
9619
- findErrorCode as findErrorCode9
9637
+ findErrorCode as findErrorCode10
9620
9638
  } from "@basou/core";
9621
9639
  var DEFAULT_WATCH_INTERVAL_SEC = 30;
9622
9640
  var MIN_WATCH_INTERVAL_SEC = 5;
@@ -9634,7 +9652,7 @@ async function scanSourceLogs(roots) {
9634
9652
  try {
9635
9653
  entries = await readdir3(dir, { withFileTypes: true });
9636
9654
  } catch (error) {
9637
- if (findErrorCode9(error, "ENOENT") || findErrorCode9(error, "ENOTDIR")) return;
9655
+ if (findErrorCode10(error, "ENOENT") || findErrorCode10(error, "ENOTDIR")) return;
9638
9656
  throw new Error("Failed to read a source log directory", { cause: error });
9639
9657
  }
9640
9658
  for (const entry of entries) {
@@ -9646,7 +9664,7 @@ async function scanSourceLogs(roots) {
9646
9664
  const info = await stat6(full);
9647
9665
  out.set(full, { mtimeMs: info.mtimeMs, size: info.size });
9648
9666
  } catch (error) {
9649
- if (findErrorCode9(error, "ENOENT")) continue;
9667
+ if (findErrorCode10(error, "ENOENT")) continue;
9650
9668
  throw new Error("Failed to stat a source log file", { cause: error });
9651
9669
  }
9652
9670
  }
@@ -9980,7 +9998,7 @@ async function assertWorkspaceInitialized9(basouRoot) {
9980
9998
  try {
9981
9999
  await assertBasouRootSafe10(basouRoot);
9982
10000
  } catch (error) {
9983
- if (findErrorCode10(error, "ENOENT")) {
10001
+ if (findErrorCode11(error, "ENOENT")) {
9984
10002
  throw new Error("Workspace not initialized. Run 'basou init' first.");
9985
10003
  }
9986
10004
  throw error;
@@ -9992,7 +10010,7 @@ import { isAbsolute as isAbsolute4, resolve as resolve10 } from "path";
9992
10010
  import {
9993
10011
  assertBasouRootSafe as assertBasouRootSafe11,
9994
10012
  basouPaths as basouPaths15,
9995
- findErrorCode as findErrorCode11,
10013
+ findErrorCode as findErrorCode12,
9996
10014
  renderReport,
9997
10015
  writeMarkdownFile as writeMarkdownFile6
9998
10016
  } from "@basou/core";
@@ -10044,7 +10062,7 @@ async function assertWorkspaceInitialized10(basouRoot) {
10044
10062
  try {
10045
10063
  await assertBasouRootSafe11(basouRoot);
10046
10064
  } catch (error) {
10047
- if (findErrorCode11(error, "ENOENT")) {
10065
+ if (findErrorCode12(error, "ENOENT")) {
10048
10066
  throw new Error("Workspace not initialized. Run 'basou init' first.");
10049
10067
  }
10050
10068
  throw error;
@@ -10052,7 +10070,6 @@ async function assertWorkspaceInitialized10(basouRoot) {
10052
10070
  }
10053
10071
 
10054
10072
  // src/commands/review.ts
10055
- import { readFile as readFile7 } from "fs/promises";
10056
10073
  import { homedir as homedir10 } from "os";
10057
10074
  import { resolve as resolve11 } from "path";
10058
10075
  import {
@@ -10061,7 +10078,7 @@ import {
10061
10078
  buildReviewRecordedEvent,
10062
10079
  buildReviewRecordLabel,
10063
10080
  createAdHocSessionWithEvent as createAdHocSessionWithEvent3,
10064
- findErrorCode as findErrorCode12,
10081
+ findErrorCode as findErrorCode13,
10065
10082
  findUnbindableRepos,
10066
10083
  parseReviewRecordInput,
10067
10084
  readManifest as readManifest11,
@@ -10137,6 +10154,7 @@ async function runReviewRecord(options, ctx = {}) {
10137
10154
  }
10138
10155
  }
10139
10156
  async function doRunReviewRecord(options, ctx) {
10157
+ refuseDashInputFile("--file", options.file, "stdin");
10140
10158
  const cwd = ctx.cwd ?? process.cwd();
10141
10159
  const repositoryRoot = await resolveBasouRootForCommand(cwd, "review record");
10142
10160
  const paths = basouPaths16(repositoryRoot);
@@ -10195,14 +10213,7 @@ ${detail}
10195
10213
  }
10196
10214
  async function readReviewInput(options, ctx) {
10197
10215
  if (options.file !== void 0) {
10198
- try {
10199
- return await readFile7(options.file, "utf8");
10200
- } catch (error) {
10201
- if (findErrorCode12(error, "ENOENT")) {
10202
- throw new Error(`Input file not found: ${options.file}`);
10203
- }
10204
- throw error;
10205
- }
10216
+ return await readInputFileText("--file", options.file);
10206
10217
  }
10207
10218
  if (ctx.readInput !== void 0) {
10208
10219
  return await ctx.readInput();
@@ -10277,7 +10288,7 @@ async function assertWorkspaceInitialized11(basouRoot) {
10277
10288
  try {
10278
10289
  await assertBasouRootSafe12(basouRoot);
10279
10290
  } catch (error) {
10280
- if (findErrorCode12(error, "ENOENT")) {
10291
+ if (findErrorCode13(error, "ENOENT")) {
10281
10292
  throw new Error("Workspace not initialized. Run 'basou init' first.");
10282
10293
  }
10283
10294
  throw error;
@@ -10489,7 +10500,7 @@ function unattachedLines(u) {
10489
10500
  }
10490
10501
 
10491
10502
  // src/commands/run.ts
10492
- import { mkdir as mkdir3, readFile as readFile8, rm as rm3 } from "fs/promises";
10503
+ import { mkdir as mkdir3, readFile as readFile6, rm as rm3 } from "fs/promises";
10493
10504
  import { homedir as homedir11 } from "os";
10494
10505
  import { join as join14 } from "path";
10495
10506
  import {
@@ -10760,7 +10771,7 @@ async function runTrackedTool(args, options, ctx, adapter) {
10760
10771
  s.session.related_files = relatedFiles;
10761
10772
  });
10762
10773
  if (result.exit_code !== null) return result.exit_code;
10763
- return signalToExitCode2(signalReceived ?? result.signal);
10774
+ return signalToExitCode(signalReceived ?? result.signal);
10764
10775
  }
10765
10776
  function decideFinalStatus2(result, signalReceived) {
10766
10777
  if (signalReceived === "SIGINT" || signalReceived === "SIGTERM") return "interrupted";
@@ -10770,18 +10781,6 @@ function decideFinalStatus2(result, signalReceived) {
10770
10781
  if (result.exit_code === 0) return "completed";
10771
10782
  return "failed";
10772
10783
  }
10773
- var SIGNUM_MAP2 = {
10774
- SIGHUP: 1,
10775
- SIGINT: 2,
10776
- SIGQUIT: 3,
10777
- SIGKILL: 9,
10778
- SIGTERM: 15
10779
- };
10780
- function signalToExitCode2(sig) {
10781
- if (sig === null) return 1;
10782
- const num = SIGNUM_MAP2[sig] ?? 1;
10783
- return 128 + num;
10784
- }
10785
10784
  async function tryAppendGitSnapshot2(sessionDir, sessionId, repoRoot, now, appendEvent) {
10786
10785
  let snapshot;
10787
10786
  try {
@@ -10939,7 +10938,7 @@ async function noteCodexHookStatusPreSpawn(_cwd, ctx) {
10939
10938
  const hooksPath = ctx.codexHooksPath ?? DEFAULT_CODEX_HOOKS_PATH;
10940
10939
  let location;
10941
10940
  try {
10942
- location = findBasouSessionStartHook2(JSON.parse(await readFile8(hooksPath, "utf8")));
10941
+ location = findBasouSessionStartHook2(JSON.parse(await readFile6(hooksPath, "utf8")));
10943
10942
  } catch (error) {
10944
10943
  if (!(error instanceof Error && error.code === "ENOENT")) return null;
10945
10944
  location = null;
@@ -10953,7 +10952,7 @@ async function noteCodexHookStatusPreSpawn(_cwd, ctx) {
10953
10952
  }
10954
10953
 
10955
10954
  // src/commands/session.ts
10956
- import { readFile as readFile9 } from "fs/promises";
10955
+ import { readFile as readFile7 } from "fs/promises";
10957
10956
  import { basename as basename8, isAbsolute as isAbsolute5, join as join15, relative as relative4, sep as sep3 } from "path";
10958
10957
  import {
10959
10958
  acquireLock as acquireLock6,
@@ -10964,7 +10963,7 @@ import {
10964
10963
  displayPath as displayPath5,
10965
10964
  EVENT_SCHEMA_VERSION as EVENT_SCHEMA_VERSION6,
10966
10965
  enumerateSessionEntries as enumerateSessionEntries2,
10967
- findErrorCode as findErrorCode13,
10966
+ findErrorCode as findErrorCode14,
10968
10967
  importSessionFromJson as importSessionFromJson2,
10969
10968
  LOCAL_CLI_EVENT_SOURCE as LOCAL_CLI_EVENT_SOURCE4,
10970
10969
  loadSessionEntries as loadSessionEntries2,
@@ -11093,7 +11092,7 @@ async function doRunSessionShow(idInput, options, ctx) {
11093
11092
  const raw = await readYamlFile6(sessionYamlPath);
11094
11093
  session = SessionSchema3.parse(normalizeSessionTimestamps(raw));
11095
11094
  } catch (error) {
11096
- if (findErrorCode13(error, "ENOENT")) {
11095
+ if (findErrorCode14(error, "ENOENT")) {
11097
11096
  throw new Error(`Session not found: ${idInput}`);
11098
11097
  }
11099
11098
  throw new Error("Failed to read session", { cause: error });
@@ -11357,7 +11356,7 @@ async function assertWorkspaceInitialized12(basouRoot) {
11357
11356
  try {
11358
11357
  await assertBasouRootSafe14(basouRoot);
11359
11358
  } catch (error) {
11360
- if (findErrorCode13(error, "ENOENT")) {
11359
+ if (findErrorCode14(error, "ENOENT")) {
11361
11360
  throw new Error("Workspace not initialized. Run 'basou init' first.");
11362
11361
  }
11363
11362
  throw error;
@@ -11393,6 +11392,7 @@ async function runSessionImport(options, ctx = {}) {
11393
11392
  }
11394
11393
  }
11395
11394
  async function doRunSessionImport(options, ctx) {
11395
+ refuseDashInputFile("--from", options.from, { fileOnly: "the JSON" });
11396
11396
  const cwd = ctx.cwd ?? process.cwd();
11397
11397
  const repositoryRoot = await resolveRepositoryRootForSession(cwd, "import");
11398
11398
  const paths = basouPaths19(repositoryRoot);
@@ -11426,12 +11426,12 @@ async function doRunSessionImport(options, ctx) {
11426
11426
  }
11427
11427
  async function readInputFile(path) {
11428
11428
  try {
11429
- return await readFile9(path, "utf8");
11429
+ return await readFile7(path, "utf8");
11430
11430
  } catch (error) {
11431
- if (findErrorCode13(error, "ENOENT")) {
11431
+ if (findErrorCode14(error, "ENOENT")) {
11432
11432
  throw new Error("Import source not found", { cause: error });
11433
11433
  }
11434
- if (findErrorCode13(error, "EISDIR")) {
11434
+ if (findErrorCode14(error, "EISDIR")) {
11435
11435
  throw new Error("Import source is not a file", { cause: error });
11436
11436
  }
11437
11437
  throw new Error("Failed to read import source", { cause: error });
@@ -11506,9 +11506,7 @@ async function doRunSessionNote(sessionIdInput, options, ctx) {
11506
11506
  if (hasBody && hasFromFile) {
11507
11507
  throw new Error("--body and --from-file are mutually exclusive");
11508
11508
  }
11509
- if (hasFromFile && options.fromFile === "-") {
11510
- throw new Error("--from-file - (stdin) is not supported in v0.1");
11511
- }
11509
+ refuseDashInputFile("--from-file", options.fromFile, { textFlag: "--body" });
11512
11510
  const cwd = ctx.cwd ?? process.cwd();
11513
11511
  const repositoryRoot = await resolveRepositoryRootForSession(cwd, "note");
11514
11512
  const paths = basouPaths19(repositoryRoot);
@@ -11543,12 +11541,12 @@ async function doRunSessionNote(sessionIdInput, options, ctx) {
11543
11541
  }
11544
11542
  async function readNoteFile(path) {
11545
11543
  try {
11546
- return await readFile9(path, "utf8");
11544
+ return await readFile7(path, "utf8");
11547
11545
  } catch (error) {
11548
- if (findErrorCode13(error, "ENOENT")) {
11546
+ if (findErrorCode14(error, "ENOENT")) {
11549
11547
  throw new Error("Note source not found", { cause: error });
11550
11548
  }
11551
- if (findErrorCode13(error, "EISDIR")) {
11549
+ if (findErrorCode14(error, "EISDIR")) {
11552
11550
  throw new Error("Note source is not a file", { cause: error });
11553
11551
  }
11554
11552
  throw new Error("Failed to read note source", { cause: error });
@@ -11661,7 +11659,7 @@ import {
11661
11659
  assertBasouRootSafe as assertBasouRootSafe15,
11662
11660
  basouPaths as basouPaths20,
11663
11661
  computeWorkStats,
11664
- findErrorCode as findErrorCode14
11662
+ findErrorCode as findErrorCode15
11665
11663
  } from "@basou/core";
11666
11664
  function registerStatsCommand(program2) {
11667
11665
  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) => {
@@ -11770,7 +11768,7 @@ async function assertWorkspaceInitialized13(basouRoot) {
11770
11768
  try {
11771
11769
  await assertBasouRootSafe15(basouRoot);
11772
11770
  } catch (error) {
11773
- if (findErrorCode14(error, "ENOENT")) {
11771
+ if (findErrorCode15(error, "ENOENT")) {
11774
11772
  throw new Error("Workspace not initialized. Run 'basou init' first.");
11775
11773
  }
11776
11774
  throw error;
@@ -11782,7 +11780,7 @@ import {
11782
11780
  assertBasouRootSafe as assertBasouRootSafe16,
11783
11781
  basouPaths as basouPaths21,
11784
11782
  buildStatusSnapshot,
11785
- findErrorCode as findErrorCode15,
11783
+ findErrorCode as findErrorCode16,
11786
11784
  readManifest as readManifest14,
11787
11785
  writeStatus
11788
11786
  } from "@basou/core";
@@ -11806,7 +11804,7 @@ async function doRunStatus(options, ctx) {
11806
11804
  try {
11807
11805
  await assertBasouRootSafe16(paths.root);
11808
11806
  } catch (error) {
11809
- if (findErrorCode15(error, "ENOENT")) {
11807
+ if (findErrorCode16(error, "ENOENT")) {
11810
11808
  throw new Error("Workspace not initialized. Run 'basou init' first.");
11811
11809
  }
11812
11810
  throw error;
@@ -11815,7 +11813,7 @@ async function doRunStatus(options, ctx) {
11815
11813
  try {
11816
11814
  manifest = await readManifest14(paths);
11817
11815
  } catch (error) {
11818
- if (findErrorCode15(error, "ENOENT")) {
11816
+ if (findErrorCode16(error, "ENOENT")) {
11819
11817
  throw new Error("Workspace not initialized. Run 'basou init' first.");
11820
11818
  }
11821
11819
  const gateMessage = formatVersionGateMessage(error);
@@ -11853,7 +11851,7 @@ function formatVersionGateMessage(error) {
11853
11851
  }
11854
11852
 
11855
11853
  // src/commands/task.ts
11856
- import { readFile as readFile10 } from "fs/promises";
11854
+ import { readFile as readFile8 } from "fs/promises";
11857
11855
  import { join as join16 } from "path";
11858
11856
  import {
11859
11857
  archiveTask,
@@ -11864,7 +11862,7 @@ import {
11864
11862
  deleteTask,
11865
11863
  editTask,
11866
11864
  enumerateArchivedTaskIds,
11867
- findErrorCode as findErrorCode16,
11865
+ findErrorCode as findErrorCode17,
11868
11866
  loadSessionEntries as loadSessionEntries3,
11869
11867
  loadTaskEntries,
11870
11868
  prefixedUlid as prefixedUlid5,
@@ -11951,9 +11949,7 @@ async function doRunTaskNew(options, ctx) {
11951
11949
  if (options.description !== void 0 && options.fromFile !== void 0) {
11952
11950
  throw new Error("--description and --from-file are mutually exclusive");
11953
11951
  }
11954
- if (options.fromFile === "-") {
11955
- throw new Error("--from-file - (stdin) is not supported in v0.1");
11956
- }
11952
+ refuseDashInputFile("--from-file", options.fromFile, { textFlag: "--description" });
11957
11953
  const initialStatus = options.status ?? "planned";
11958
11954
  if (options.completedAt !== void 0 && !isTerminalStatusForCli(initialStatus)) {
11959
11955
  throw new Error("--completed-at requires --status done or cancelled");
@@ -12870,12 +12866,12 @@ function parsePositiveInt2(raw) {
12870
12866
  }
12871
12867
  async function readDescriptionFile(path) {
12872
12868
  try {
12873
- return await readFile10(path, "utf8");
12869
+ return await readFile8(path, "utf8");
12874
12870
  } catch (error) {
12875
- if (findErrorCode16(error, "ENOENT")) {
12871
+ if (findErrorCode17(error, "ENOENT")) {
12876
12872
  throw new Error("Description source not found", { cause: error });
12877
12873
  }
12878
- if (findErrorCode16(error, "EISDIR")) {
12874
+ if (findErrorCode17(error, "EISDIR")) {
12879
12875
  throw new Error("Description source is not a file", { cause: error });
12880
12876
  }
12881
12877
  throw new Error("Failed to read description source", { cause: error });
@@ -12888,7 +12884,7 @@ async function assertWorkspaceInitialized14(basouRoot) {
12888
12884
  try {
12889
12885
  await assertBasouRootSafe17(basouRoot);
12890
12886
  } catch (error) {
12891
- if (findErrorCode16(error, "ENOENT")) {
12887
+ if (findErrorCode17(error, "ENOENT")) {
12892
12888
  throw new Error("Workspace not initialized. Run 'basou init' first.");
12893
12889
  }
12894
12890
  throw error;
@@ -12979,7 +12975,7 @@ import {
12979
12975
  assertBasouRootSafe as assertBasouRootSafe18,
12980
12976
  basouPaths as basouPaths23,
12981
12977
  enumerateSessionEntries as enumerateSessionEntries3,
12982
- findErrorCode as findErrorCode17,
12978
+ findErrorCode as findErrorCode18,
12983
12979
  resolveSessionId as resolveSessionId5,
12984
12980
  verifyEventsChain
12985
12981
  } from "@basou/core";
@@ -13066,7 +13062,7 @@ async function assertWorkspaceInitialized15(basouRoot) {
13066
13062
  try {
13067
13063
  await assertBasouRootSafe18(basouRoot);
13068
13064
  } catch (error) {
13069
- if (findErrorCode17(error, "ENOENT")) {
13065
+ if (findErrorCode18(error, "ENOENT")) {
13070
13066
  throw new Error("Workspace not initialized. Run 'basou init' first.");
13071
13067
  }
13072
13068
  throw error;
@@ -13080,7 +13076,7 @@ import { basename as basename11, dirname as dirname9, join as join20, resolve as
13080
13076
  import {
13081
13077
  assertBasouRootSafe as assertBasouRootSafe19,
13082
13078
  basouPaths as basouPaths25,
13083
- findErrorCode as findErrorCode19,
13079
+ findErrorCode as findErrorCode20,
13084
13080
  loadPortfolioConfig as loadPortfolioConfig6,
13085
13081
  readManifest as readManifest19
13086
13082
  } from "@basou/core";
@@ -13596,7 +13592,7 @@ import {
13596
13592
  boardPageUnavailable,
13597
13593
  computeWorkStats as computeWorkStats2,
13598
13594
  enumerateApprovals as enumerateApprovals2,
13599
- findErrorCode as findErrorCode18,
13595
+ findErrorCode as findErrorCode19,
13600
13596
  inspectSessionEntry as inspectSessionEntry2,
13601
13597
  isLazyExpired as isLazyExpired2,
13602
13598
  loadApproval as loadApproval2,
@@ -15545,7 +15541,7 @@ async function overview(ws, nowProvider, resolveRemoteUrl) {
15545
15541
  try {
15546
15542
  manifest = await readManifest18(ws.paths);
15547
15543
  } catch (error) {
15548
- if (findErrorCode18(error, "ENOENT")) {
15544
+ if (findErrorCode19(error, "ENOENT")) {
15549
15545
  return { initialized: false, repoRoot: ws.repoRoot };
15550
15546
  }
15551
15547
  throw error;
@@ -15955,7 +15951,7 @@ async function startListening(port, deps) {
15955
15951
  try {
15956
15952
  return await startViewServer({ port, deps });
15957
15953
  } catch (error) {
15958
- if (findErrorCode19(error, "EADDRINUSE")) {
15954
+ if (findErrorCode20(error, "EADDRINUSE")) {
15959
15955
  throw new Error(`Port ${port} is already in use. Pass --port <n> to choose another.`, {
15960
15956
  cause: error
15961
15957
  });
@@ -16008,7 +16004,7 @@ async function assertWorkspaceInitialized16(basouRoot) {
16008
16004
  try {
16009
16005
  await assertBasouRootSafe19(basouRoot);
16010
16006
  } catch (error) {
16011
- if (findErrorCode19(error, "ENOENT")) {
16007
+ if (findErrorCode20(error, "ENOENT")) {
16012
16008
  throw new Error("Workspace not initialized. Run 'basou init' first.");
16013
16009
  }
16014
16010
  throw error;
@@ -16047,7 +16043,7 @@ function installExperimentalNotice(program2, names = EXPERIMENTAL_COMMANDS, writ
16047
16043
  function readBuildStamp() {
16048
16044
  if (false) return void 0;
16049
16045
  try {
16050
- return JSON.parse('{"version":"0.68.3","commit":"42d94c5","committedAt":"2026-10-13T15:23:54+09:00"}');
16046
+ return JSON.parse('{"version":"0.69.0","commit":"bffcfee","committedAt":"2026-10-16T08:07:08+09:00"}');
16051
16047
  } catch {
16052
16048
  return void 0;
16053
16049
  }