Files
claude code agent 8ad42a1a45 fix(logs): seed reconnect boundary state from resume params; extract+test since parser (F10,F11)
F10: the content-exact reconnect dedup rebuilt boundaryLines only from lines
     surviving the current batch, so after one reconnect at a shared timestamp it
     forgot the dropped line — a SECOND reconnect at the same nanosecond then
     re-emitted both as duplicates. Seed lastTimestamp/boundaryLines from
     skipUntilTimestamp/skipBoundaryContents so the boundary set accumulates all
     lines ever seen at the resume ts. Regression test (fails before, passes after).
F11: extract rfc3339ToUnixNanoSince into a testable logHelper module (sinceTimestamp.ts)
     and cover it (standard ns, no fraction, sub-9 pad, >9 truncate); the controller
     imports the single shared function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:42:32 +03:00

27 lines
1.1 KiB
TypeScript

// Build Docker's `since` param as a Unix timestamp with a nanosecond fraction
// ("<seconds>.<nanos>") from an RFC3339Nano timestamp. Both the initial connect
// and reconnect use this one form so we never mix unix-seconds and RFC3339 —
// some proxies / pinned API versions accept them inconsistently. The fraction
// needs string precision (a JS number cannot hold nanoseconds), hence `since`
// is returned as a string.
//
// Docker emits a fixed-width RFC3339Nano prefix: "2006-01-02T15:04:05.000000000Z".
// We parse the second-precision prefix in UTC for the integer seconds, then take
// the fractional digits verbatim: short fractions (e.g. ".5") are right-padded
// to 9 digits, longer ones are truncated to 9 (nanosecond precision).
export function rfc3339ToUnixNanoSince(rfc3339: string): string {
const seconds = Math.floor(
Date.parse(`${rfc3339.substring(0, 19)}Z`) / 1000
);
const dot = rfc3339.indexOf('.');
const nanos =
dot >= 0
? rfc3339
.substring(dot + 1)
.replace(/[^0-9]/g, '')
.padEnd(9, '0')
.substring(0, 9)
: '000000000';
return `${seconds}.${nanos}`;
}