PCLI2

v1.16.0

v1.16.0 Jul 31 2026 at 00:53 UTC

Changed

  • folder geometric-match --format xls now refuses a report too tall for a worksheet, instead of failing deep inside the workbook writer - An Excel worksheet holds 1,048,576 rows; this report spends two of them on its header band, leaving 1,048,574 for data. A real run produced 1,293,068 rows, which cannot be represented. The command now fails immediately after matching with the report has 1293068 rows, more than the 1048574 an Excel worksheet can hold - use '--format csv' for the complete report, before building a single row. Truncating to fit was considered and rejected: a workbook silently missing a quarter of its rows looks complete to whoever opens it. Use --format csv, which has no such limit.

Security

  • The stored-credentials file is now owner-only (0600) - With the default dev-keyring feature, the client secret and access token are kept in plain text in dev_credentials.json. Written under the process umask it landed at 0644, readable by every other account and every unprivileged process on the machine. The mode is now set explicitly on every write, and an existing file is tightened the first time it is read, so credentials written by an earlier version are repaired rather than left exposed until the next login. Unix only; Windows has no equivalent mode bits and inherits directory ACLs.

Fixed

  • auth login now prompts when the stored credentials are empty, instead of failing with invalid_client - An empty stored client ID or secret was treated as a usable credential and sent to the auth server, which rejected it with an error pointing at the user's credentials when the actual problem was local state. Empty is now treated as absent, falling through to the interactive prompt — matching what the prompt path itself already did.
  • Report building no longer materializes an intermediate copy of every match - folder geometric-match built a Vec<GeometricMatchPair> before building rows, cloning each reference asset — metadata HashMap included — once per row, only ever to read a path and a UUID back out of it. On a 1.29M-row report that intermediate took seconds to build and a further nine seconds to drop, with the progress display parked at 99% for the whole teardown. Both passes now iterate borrowed data. Output is unchanged.
  • The progress bar no longer flashes 0/0 (0%) when a counted phase starts - The steady-tick thread could redraw in the window between the counter style being applied and the row count being set. Length is now set first.