@basou/core 0.43.0 → 0.44.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.d.ts CHANGED
@@ -5803,11 +5803,11 @@ declare const SchemaVersionSchema: z.ZodString;
5803
5803
  /**
5804
5804
  * ISO 8601 timestamp with explicit timezone offset (e.g. `+09:00`).
5805
5805
  *
5806
- * Parsing goes through `.refine`, which is opaque to JSON Schema generation,
5807
- * so the `.meta` mirrors the same expression as a representable `pattern` —
5808
- * the way the prefixed-ID schemas below do. Both are built from the single
5809
- * {@link ISO_TIMESTAMP_PATTERN} constant, so the artifact cannot drift from
5810
- * what the runtime actually accepts.
5806
+ * The gate is `.regex`, not a `.refine`: zod emits a regex check as the
5807
+ * artifact's `pattern`, so there is one expression rather than a runtime check
5808
+ * and a `.meta` restating it. A `.refine` is opaque to JSON Schema generation
5809
+ * and would need the pattern written a second time, which is a second place to
5810
+ * forget. {@link SchemaVersionSchema} takes the same form for the same reason.
5811
5811
  *
5812
5812
  * It deliberately does NOT declare `format: "date-time"`. That format names
5813
5813
  * RFC 3339, and the two sets cross rather than nest: basou takes a timestamp
package/dist/index.js CHANGED
@@ -365,11 +365,8 @@ var SchemaVersionSchema = z.string().regex(/^0\.\d+\.\d+$/, {
365
365
  var CacheVersionSchema = z.literal("0.1.0");
366
366
  var ISO_TIMESTAMP_PATTERN = "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$";
367
367
  var isoTimestampRegex = new RegExp(ISO_TIMESTAMP_PATTERN);
368
- var IsoTimestampSchema = z.string().refine((value) => isoTimestampRegex.test(value), {
369
- message: "Expected an ISO 8601 timestamp with a timezone offset"
370
- }).meta({
371
- description: "Timestamp with an offset or Z. The pattern is normative: RFC 3339 date-time with uppercase designators, no leap second, and optional seconds.",
372
- pattern: ISO_TIMESTAMP_PATTERN
368
+ var IsoTimestampSchema = z.string().regex(isoTimestampRegex, "Expected an ISO 8601 timestamp with a timezone offset").meta({
369
+ description: "Timestamp with an offset or Z. The pattern is normative under ECMA-262 semantics: RFC 3339 date-time with uppercase designators, no leap second, and optional seconds."
373
370
  });
374
371
  var createPrefixedIdSchema = (prefix) => {
375
372
  const refiner = (value) => isValidPrefixedId(value) && value.startsWith(`${prefix}_`);
@@ -1893,6 +1890,11 @@ async function readAllEvents(sessionDir, options = {}) {
1893
1890
  return out;
1894
1891
  }
1895
1892
 
1893
+ // src/lib/one-line.ts
1894
+ function oneLine(text) {
1895
+ return text.replace(/\s+/g, " ").trim();
1896
+ }
1897
+
1896
1898
  // src/project/relative-path.ts
1897
1899
  function normalizeRelativePath(p) {
1898
1900
  const trimmed = p.trim();
@@ -3105,13 +3107,13 @@ async function formatDecisionsBody(args) {
3105
3107
  for (const d of args.decisions) {
3106
3108
  const trackMark = d.kind === "track" ? " [TRACK]" : "";
3107
3109
  if (d.voided !== void 0) {
3108
- lines.push(`## ~~${d.decisionId}: ${d.title}~~ [VOIDED]${trackMark}`);
3110
+ lines.push(`## ~~${d.decisionId}: ${oneLine(d.title)}~~ [VOIDED]${trackMark}`);
3109
3111
  lines.push("");
3110
3112
  const supersededBy = d.voided.supersededBy !== void 0 ? `, superseded by ${d.voided.supersededBy}` : "";
3111
3113
  const reason = typeof d.voided.reason === "string" && d.voided.reason.length > 0 ? `: ${d.voided.reason}` : "";
3112
3114
  lines.push(`- \u26A0 VOIDED${reason}${supersededBy}`);
3113
3115
  } else {
3114
- lines.push(`## ${d.decisionId}: ${d.title}${trackMark}`);
3116
+ lines.push(`## ${d.decisionId}: ${oneLine(d.title)}${trackMark}`);
3115
3117
  lines.push("");
3116
3118
  }
3117
3119
  const occurredDate = d.occurredAt.slice(0, 10);
@@ -3120,7 +3122,7 @@ async function formatDecisionsBody(args) {
3120
3122
  lines.push(t.decisions.trackKindLine);
3121
3123
  }
3122
3124
  lines.push(`- session: ${shortDecisionSessionId(d.sessionId)}`);
3123
- lines.push(`- ${t.decisions.decisionLabel}: ${d.title}`);
3125
+ lines.push(`- ${t.decisions.decisionLabel}: ${oneLine(d.title)}`);
3124
3126
  if (typeof d.rationale === "string" && d.rationale.length > 0) {
3125
3127
  lines.push(`- rationale: ${d.rationale}`);
3126
3128
  }
@@ -3142,7 +3144,7 @@ async function formatDecisionsBody(args) {
3142
3144
  async (path2) => await args.fileExists(path2) ? path2 : `${path2} (missing)`
3143
3145
  )
3144
3146
  );
3145
- lines.push(`- linked_files: ${parts.join(", ")}`);
3147
+ lines.push(`- linked_files: ${oneLine(parts.join(", "))}`);
3146
3148
  }
3147
3149
  lines.push("");
3148
3150
  }
@@ -5602,7 +5604,7 @@ function formatHandoffBody(args) {
5602
5604
  const label = args.latestSession.session.session.label;
5603
5605
  const shortId2 = shortIdWithPrefix(args.latestSession.sessionId);
5604
5606
  if (label !== void 0 && label !== "") {
5605
- lines.push(`- ${t.common.lastSessionLabel}: ${label} (${status}) [${shortId2}]`);
5607
+ lines.push(`- ${t.common.lastSessionLabel}: ${oneLine(label)} (${status}) [${shortId2}]`);
5606
5608
  } else {
5607
5609
  lines.push(`- ${t.common.lastSessionLabel}: ${shortId2} (${status})`);
5608
5610
  }
@@ -5614,7 +5616,7 @@ function formatHandoffBody(args) {
5614
5616
  const linkedCount = args.latestTaskDoc?.task.task.linked_sessions?.length;
5615
5617
  const linkedSuffix = linkedCount !== void 0 && linkedCount > 1 ? `, linked_sessions: ${linkedCount}` : "";
5616
5618
  lines.push(
5617
- `- ${t.handoff.lastTaskLabel}: ${args.latestActivityRecord.title} (${statusLabel}${linkedSuffix}) [${shortIdWithPrefix(args.latestActivityRecord.taskId)}]`
5619
+ `- ${t.handoff.lastTaskLabel}: ${oneLine(args.latestActivityRecord.title)} (${statusLabel}${linkedSuffix}) [${shortIdWithPrefix(args.latestActivityRecord.taskId)}]`
5618
5620
  );
5619
5621
  } else {
5620
5622
  lines.push(`- ${t.handoff.lastTaskLabel}: (no tasks recorded yet)`);
@@ -5635,7 +5637,7 @@ function formatHandoffBody(args) {
5635
5637
  lines.push("(no decisions recorded yet)");
5636
5638
  } else {
5637
5639
  const last = args.latestDecision;
5638
- lines.push(`- ${last.title} [${last.decisionId}]`);
5640
+ lines.push(`- ${oneLine(last.title)} [${last.decisionId}]`);
5639
5641
  if (args.latestActivityAt !== null && isTrailingStale(args.latestActivityAt, last.occurredAt)) {
5640
5642
  lines.push(` - ${t.handoff.decisionStaleNote}`);
5641
5643
  }
@@ -5653,7 +5655,7 @@ function formatHandoffBody(args) {
5653
5655
  lines.push(t.handoff.headingOpenTracks);
5654
5656
  lines.push("");
5655
5657
  for (const track of shown) {
5656
- lines.push(`- ${track.title} [${track.decisionId}]`);
5658
+ lines.push(`- ${oneLine(track.title)} [${track.decisionId}]`);
5657
5659
  if (track.rationale !== null && track.rationale.trim() !== "") {
5658
5660
  lines.push(` - ${t.common.trackWhyLabel}: ${handoffRationale(track.rationale)}`);
5659
5661
  }
@@ -5687,7 +5689,7 @@ function formatHandoffBody(args) {
5687
5689
  } else {
5688
5690
  for (const t2 of args.pendingTasks) {
5689
5691
  lines.push(
5690
- `- ${t2.task.task.title} (${t2.task.task.status}) [${shortIdWithPrefix(t2.task.task.id)}]`
5692
+ `- ${oneLine(t2.task.task.title)} (${t2.task.task.status}) [${shortIdWithPrefix(t2.task.task.id)}]`
5691
5693
  );
5692
5694
  }
5693
5695
  }
@@ -5709,7 +5711,7 @@ function formatHandoffBody(args) {
5709
5711
  const sid = shortHandoffId(e.sessionId);
5710
5712
  const status = e.session.session.status + suspectLabel(e.suspectReason);
5711
5713
  const startedAt = e.session.session.started_at;
5712
- const label = e.session.session.label ?? "";
5714
+ const label = tableCell(e.session.session.label ?? "");
5713
5715
  lines.push(`| ${sid} | ${status} | ${startedAt} | ${label} |`);
5714
5716
  }
5715
5717
  }
@@ -5723,7 +5725,7 @@ function formatHandoffBody(args) {
5723
5725
  const sid = shortHandoffId(e.sessionId);
5724
5726
  const status = e.session.session.status + suspectLabel(e.suspectReason);
5725
5727
  const startedAt = e.session.session.started_at;
5726
- const label = e.session.session.label ?? "";
5728
+ const label = tableCell(e.session.session.label ?? "");
5727
5729
  lines.push(`| ${sid} | ${status} | ${startedAt} | ${label} |`);
5728
5730
  }
5729
5731
  }
@@ -5749,8 +5751,11 @@ function formatHandoffBody(args) {
5749
5751
  }
5750
5752
  var HANDOFF_TRACK_RATIONALE_MAX = 240;
5751
5753
  function handoffRationale(rationale) {
5752
- const oneLine = rationale.replace(/\s+/g, " ").trim();
5753
- return oneLine.length > HANDOFF_TRACK_RATIONALE_MAX ? `${oneLine.slice(0, HANDOFF_TRACK_RATIONALE_MAX - 1)}\u2026` : oneLine;
5754
+ const collapsed = oneLine(rationale);
5755
+ return collapsed.length > HANDOFF_TRACK_RATIONALE_MAX ? `${collapsed.slice(0, HANDOFF_TRACK_RATIONALE_MAX - 1)}\u2026` : collapsed;
5756
+ }
5757
+ function tableCell(text) {
5758
+ return oneLine(text).replace(/([\\|])/g, "\\$1");
5754
5759
  }
5755
5760
  function suspectLabel(reason) {
5756
5761
  if (reason === "events_say_ended_but_yaml_running") return " \u26A0 ended (yaml stale)";
@@ -6241,7 +6246,7 @@ function formatOrientationBody(summary, opts) {
6241
6246
  const sid = shortId(s.sessionId);
6242
6247
  if (s.label !== null && s.label !== "") {
6243
6248
  lines.push(
6244
- `- ${t.common.lastSessionLabel}: ${s.label} (${s.status}) [${sid}]${hostSuffix(s.host)}`
6249
+ `- ${t.common.lastSessionLabel}: ${oneLine(s.label)} (${s.status}) [${sid}]${hostSuffix(s.host)}`
6245
6250
  );
6246
6251
  } else {
6247
6252
  lines.push(`- ${t.common.lastSessionLabel}: ${sid} (${s.status})${hostSuffix(s.host)}`);
@@ -6253,7 +6258,7 @@ function formatOrientationBody(summary, opts) {
6253
6258
  const dec = summary.latestDecision;
6254
6259
  const decAge = t.relativeAge(dec.occurredAt, now);
6255
6260
  lines.push(
6256
- `- ${t.common.latestDecisionLabel}: ${dec.title} [${dec.decisionId}] (${decAge})${hostSuffix(dec.host)}`
6261
+ `- ${t.common.latestDecisionLabel}: ${oneLine(dec.title)} [${dec.decisionId}] (${decAge})${hostSuffix(dec.host)}`
6257
6262
  );
6258
6263
  const activityAt = summary.freshness.latestActivityAt;
6259
6264
  if (activityAt !== null && isTrailingStale(activityAt, dec.occurredAt)) {
@@ -6299,7 +6304,7 @@ function formatOrientationBody(summary, opts) {
6299
6304
  for (const s of summary.recentDirection) {
6300
6305
  const sid = shortId(s.sessionId);
6301
6306
  const age = t.relativeAge(s.occurredAt, now);
6302
- const head = s.label !== null && s.label !== "" ? s.label : sid;
6307
+ const head = s.label !== null && s.label !== "" ? oneLine(s.label) : sid;
6303
6308
  lines.push(`- ${head} (${age})${hostSuffix(s.host)}`);
6304
6309
  if (s.decisions.length > 0) {
6305
6310
  const more = s.decisionsOverflow > 0 ? ` (+${s.decisionsOverflow})` : "";
@@ -6324,7 +6329,7 @@ function formatOrientationBody(summary, opts) {
6324
6329
  } else {
6325
6330
  for (const t2 of summary.inFlightTasks) {
6326
6331
  const linkedSuffix = t2.linkedSessions > 1 ? ` \u2014 linked_sessions: ${t2.linkedSessions}` : "";
6327
- lines.push(`- ${t2.title} (${t2.status}) [${shortId(t2.id)}]${linkedSuffix}`);
6332
+ lines.push(`- ${oneLine(t2.title)} (${t2.status}) [${shortId(t2.id)}]${linkedSuffix}`);
6328
6333
  }
6329
6334
  }
6330
6335
  lines.push("");
@@ -6335,7 +6340,7 @@ function formatOrientationBody(summary, opts) {
6335
6340
  for (const a of summary.pendingApprovals) {
6336
6341
  const expired = a.expired ? " (expired)" : "";
6337
6342
  lines.push(
6338
- `- [${a.risk}] ${a.kind}: ${a.reason} \u2014 session ${shortId(a.sessionId)}, since ${a.createdAt}${expired}`
6343
+ `- [${a.risk}] ${a.kind}: ${oneLine(a.reason)} \u2014 session ${shortId(a.sessionId)}, since ${a.createdAt}${expired}`
6339
6344
  );
6340
6345
  }
6341
6346
  }
@@ -6360,7 +6365,9 @@ function formatOrientationBody(summary, opts) {
6360
6365
  lines.push(t.orientation.openTracksHeading(summary.openTracks.length));
6361
6366
  for (const track of shownTracks) {
6362
6367
  const trackAge = t.relativeAge(track.occurredAt, now);
6363
- lines.push(`- ${track.title} [${track.decisionId}] (${trackAge})${hostSuffix(track.host)}`);
6368
+ lines.push(
6369
+ `- ${oneLine(track.title)} [${track.decisionId}] (${trackAge})${hostSuffix(track.host)}`
6370
+ );
6364
6371
  if (track.rationale !== null && track.rationale.trim() !== "") {
6365
6372
  lines.push(` - ${t.common.trackWhyLabel}: ${trackRationale(track.rationale)}`);
6366
6373
  }
@@ -6382,7 +6389,7 @@ function formatOrientationBody(summary, opts) {
6382
6389
  }
6383
6390
  }
6384
6391
  for (const task of summary.plannedTasks) {
6385
- lines.push(`- ${task.title} [${shortId(task.id)}]`);
6392
+ lines.push(`- ${oneLine(task.title)} [${shortId(task.id)}]`);
6386
6393
  }
6387
6394
  if (summary.openTracks.length === 0 && summary.latestNote === null && summary.plannedTasks.length === 0) {
6388
6395
  const dec = summary.latestDecision;
@@ -6390,10 +6397,10 @@ function formatOrientationBody(summary, opts) {
6390
6397
  lines.push("- (no planned tasks or recorded next step yet)");
6391
6398
  } else if (isTrailingStale(summary.freshness.latestActivityAt, dec.occurredAt)) {
6392
6399
  lines.push(t.orientation.fallbackStaleDirection);
6393
- lines.push(` - ${t.orientation.fallbackStaleReferenceLabel}: ${dec.title}`);
6400
+ lines.push(` - ${t.orientation.fallbackStaleReferenceLabel}: ${oneLine(dec.title)}`);
6394
6401
  } else {
6395
6402
  lines.push("- (no planned tasks \u2014 direction is inferred from recent decisions)");
6396
- lines.push(` - ${t.common.latestDecisionLabel}: ${dec.title}`);
6403
+ lines.push(` - ${t.common.latestDecisionLabel}: ${oneLine(dec.title)}`);
6397
6404
  }
6398
6405
  if (dec !== null) {
6399
6406
  lines.push(` - ${t.orientation.trackNudge}`);
@@ -6512,13 +6519,13 @@ var NOTES_PER_DIGEST = 2;
6512
6519
  var FILES_PER_DIGEST = 3;
6513
6520
  var NOTE_SUMMARY_MAX = 200;
6514
6521
  function noteSummary(body) {
6515
- const oneLine = body.replace(/\s+/g, " ").trim();
6516
- return oneLine.length > NOTE_SUMMARY_MAX ? `${oneLine.slice(0, NOTE_SUMMARY_MAX - 1)}\u2026` : oneLine;
6522
+ const collapsed = oneLine(body);
6523
+ return collapsed.length > NOTE_SUMMARY_MAX ? `${collapsed.slice(0, NOTE_SUMMARY_MAX - 1)}\u2026` : collapsed;
6517
6524
  }
6518
6525
  var TRACK_RATIONALE_MAX = 240;
6519
6526
  function trackRationale(rationale) {
6520
- const oneLine = rationale.replace(/\s+/g, " ").trim();
6521
- return oneLine.length > TRACK_RATIONALE_MAX ? `${oneLine.slice(0, TRACK_RATIONALE_MAX - 1)}\u2026` : oneLine;
6527
+ const collapsed = oneLine(rationale);
6528
+ return collapsed.length > TRACK_RATIONALE_MAX ? `${collapsed.slice(0, TRACK_RATIONALE_MAX - 1)}\u2026` : collapsed;
6522
6529
  }
6523
6530
  function suspectText(reason) {
6524
6531
  if (reason === "events_say_ended_but_yaml_running") return "ended (yaml stale)";
@@ -7754,7 +7761,7 @@ function tallyTaskStatus(items) {
7754
7761
  }
7755
7762
  function formatReportBody(data, t) {
7756
7763
  const lines = [];
7757
- const titleSuffix = data.title !== void 0 ? ` \u2014 ${data.title}` : "";
7764
+ const titleSuffix = data.title !== void 0 ? ` \u2014 ${oneLine(data.title)}` : "";
7758
7765
  lines.push(`# Report${titleSuffix}`);
7759
7766
  lines.push("");
7760
7767
  const periodSuffix = data.period.from !== null && data.period.to !== null ? ` (${data.period.from.slice(0, 10)}..${data.period.to.slice(0, 10)})` : "";
@@ -7801,7 +7808,7 @@ function formatReportBody(data, t) {
7801
7808
  for (const d of shown) {
7802
7809
  const trackTag = d.track === true ? " [track]" : "";
7803
7810
  const voidedTag = d.voided === true ? " (voided)" : "";
7804
- lines.push(`- ${d.occurredAt.slice(0, 10)} \xB7 ${d.title}${trackTag}${voidedTag}`);
7811
+ lines.push(`- ${d.occurredAt.slice(0, 10)} \xB7 ${oneLine(d.title)}${trackTag}${voidedTag}`);
7805
7812
  }
7806
7813
  }
7807
7814
  lines.push("");
@@ -7816,7 +7823,7 @@ function formatReportBody(data, t) {
7816
7823
  );
7817
7824
  lines.push("");
7818
7825
  for (const item of data.approvals.items.slice(0, APPROVALS_MARKDOWN_LIMIT)) {
7819
- lines.push(`- ${item.reason} (${item.status}, ${item.riskLevel})`);
7826
+ lines.push(`- ${oneLine(item.reason)} (${item.status}, ${item.riskLevel})`);
7820
7827
  }
7821
7828
  const overflow = data.approvals.items.length - APPROVALS_MARKDOWN_LIMIT;
7822
7829
  if (overflow > 0) lines.push(`- ... +${overflow} more`);
@@ -7831,7 +7838,7 @@ function formatReportBody(data, t) {
7831
7838
  lines.push(`Tasks: ${data.tasks.total} (${breakdown})`);
7832
7839
  lines.push("");
7833
7840
  for (const item of data.tasks.items.slice(0, TASKS_MARKDOWN_LIMIT)) {
7834
- lines.push(`- ${item.title} (${item.status})`);
7841
+ lines.push(`- ${oneLine(item.title)} (${item.status})`);
7835
7842
  }
7836
7843
  const overflow = data.tasks.items.length - TASKS_MARKDOWN_LIMIT;
7837
7844
  if (overflow > 0) lines.push(`- ... +${overflow} more`);
@@ -9261,9 +9268,21 @@ function parseMarkers(content, markers = DEFAULT_MARKERS) {
9261
9268
  const after = body.slice(endLineEnd);
9262
9269
  return { kind: "ok", before, generated, after };
9263
9270
  }
9271
+ function defuseMarkerLines(body, markers) {
9272
+ const isMarker = (line) => {
9273
+ const bare = line.endsWith("\r") ? line.slice(0, -1) : line;
9274
+ return bare === markers.start || bare === markers.end;
9275
+ };
9276
+ const lines = body.split("\n");
9277
+ if (!lines.some(isMarker)) return body;
9278
+ return lines.map((line) => isMarker(line) ? ` ${line}` : line).join("\n");
9279
+ }
9264
9280
  function renderWithMarkers(existing, generated, fileLabel, markers = DEFAULT_MARKERS) {
9265
- const normalized = generated.endsWith("\n") ? generated : `${generated}
9266
- `;
9281
+ const normalized = defuseMarkerLines(
9282
+ generated.endsWith("\n") ? generated : `${generated}
9283
+ `,
9284
+ markers
9285
+ );
9267
9286
  if (existing === null) {
9268
9287
  return `${markers.start}
9269
9288
  ${normalized}${markers.end}