bantamkit-mcp 0.35.3 → 0.35.4

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.
@@ -6,7 +6,11 @@
6
6
  * reach the network (`selfupdate.py:29-31`, measured: one registry GET is 1.5x to 100x an
7
7
  * entire 0.09 s cold stdio boot), why a newer version existing is NOT a degraded condition,
8
8
  * why there is NO TTL in a reader, and why the date is sliced rather than rendered. It is not
9
- * restated here; read it there. What belongs HERE is the part that could not be copied.
9
+ * restated here; read it there. What belongs HERE is the part that could not be copied. That
10
+ * includes *Two stamps, and which one dates which number* (J62-13, 2026-09-21): an ENTRY may
11
+ * carry a `checked_at` of its own — when that registry last answered — and the record's own
12
+ * `checked_at` is the fallback for an entry that has none. `checkedDate` SELECTS one of the
13
+ * two and then applies the single shape rule to whatever it selected.
10
14
  *
11
15
  * EXACTLY ONE THING DIFFERS FROM THE REFERENCE, and it is a genuinely different object rather
12
16
  * than a different spelling of one: `KEY` is `npm` here and `pypi` there, because npm and
@@ -130,13 +134,26 @@ const DATE_PREFIX = /^([0-9]{4}-[0-9]{2}-[0-9]{2})/;
130
134
  * a different state on the two sides. Decoding the bytes with `fatal` makes it the same one.
131
135
  *
132
136
  * `ignoreBOM` IS LEFT AT ITS DEFAULT OF `false`, WHICH STRIPS A LEADING BOM, AND THAT IS LOAD
133
- * BEARING. The reference reads with `utf-8-sig` for exactly this reason: PowerShell's
134
- * `Set-Content` and `Out-File` write UTF-8 WITH a BOM by default, and a record a reader can
135
- * plainly act on is not "a shape this reader cannot act on". Setting `ignoreBOM: true` here
136
- * would leave the BOM in the string, `JSON.parse` would refuse it, and this side would call a
137
- * Windows operator's perfectly good record broken. The BOM arms in
138
- * `tools/conformance/suites/updatecheck.mjs` are what hold the two sides together on it; it is
139
- * NOT a `docs/porting.md` divergence, because there is no difference left to register.
137
+ * BEARING. The reference reads with `utf-8-sig` for exactly this reason: WHAT HAS TO BE
138
+ * ACCEPTED IS THE THREE BYTES `EF BB BF`, WHOEVER WROTE THEM, and a record a reader can plainly
139
+ * act on is not "a shape this reader cannot act on". Setting `ignoreBOM: true` here would leave
140
+ * the BOM in the string, `JSON.parse` would refuse it, and this side would call a perfectly good
141
+ * record broken. The `available|current|ahead/utf-8-bom` arms in
142
+ * `tools/conformance/suites/updatecheck.mjs`, with `unreadable/bom-not-json` as their control,
143
+ * are what hold the two sides together on it; it is NOT a `docs/porting.md` divergence, because
144
+ * there is no difference left to register.
145
+ *
146
+ * AMENDED 2026-09-21 (J62-16). This comment used to justify the setting with the sentence
147
+ * "PowerShell's `Set-Content` and `Out-File` write UTF-8 WITH a BOM by default". THAT SENTENCE
148
+ * IS VERSION-QUALIFIED AND HAD NEVER BEEN RUN. Measured in `mcr.microsoft.com/powershell:latest`
149
+ * — PowerShell 7.4.2 (Core, Ubuntu 22.04, linux/amd64) — `Set-Content`, `Out-File`, `>` and
150
+ * `Add-Content` ALL write UTF-8 with NO BOM, `-Encoding utf8` is the alias of `utf8NoBOM`, and
151
+ * `EF BB BF` appears only under an explicit `-Encoding utf8BOM`. So it is FALSE of PowerShell 6+
152
+ * on every platform, and UNMEASURED for WINDOWS PowerShell 5.1, which needs a Windows kernel
153
+ * this machine does not have. The setting does not depend on it either way: `-Encoding utf8BOM`,
154
+ * Notepad before 2019 and any editor set to "UTF-8 with BOM" all produce the same three bytes,
155
+ * and this reader's business is the bytes, not the writer. The reference's `load_record`
156
+ * docstring carries the same amendment.
140
157
  */
141
158
  const UTF8 = new TextDecoder('utf-8', { fatal: true });
142
159
  /**
@@ -220,9 +237,22 @@ function latestIn(record, key) {
220
237
  const trimmed = latest.trim();
221
238
  return VERSION.test(trimmed) ? trimmed : null;
222
239
  }
223
- /** The `YYYY-MM-DD` prefix of `checked_at`, or `null`. Sliced, never rendered. */
224
- function checkedDate(record) {
225
- const checkedAt = record['checked_at'];
240
+ /**
241
+ * The `YYYY-MM-DD` prefix of the stamp that dates THIS key's number, or `null`. Sliced, never
242
+ * rendered.
243
+ *
244
+ * ONE SELECTION, THEN ONE RULE — the reference's `_checked_date`, and its docstring carries
245
+ * the argument. `hasOwnProperty` rather than `in` is how this side spells CPython's `in` on a
246
+ * dict: `JSON.parse` hands back plain objects, so the two agree, and an entry that carries
247
+ * the name is the entry's own answer even when the value is garbage.
248
+ */
249
+ function checkedDate(record, key) {
250
+ const entry = record[key];
251
+ const own = typeof entry === 'object' &&
252
+ entry !== null &&
253
+ !Array.isArray(entry) &&
254
+ Object.prototype.hasOwnProperty.call(entry, 'checked_at');
255
+ const checkedAt = own ? entry['checked_at'] : record['checked_at'];
226
256
  if (typeof checkedAt !== 'string')
227
257
  return null;
228
258
  const found = DATE_PREFIX.exec(checkedAt.trim());
@@ -234,9 +264,9 @@ function checkedDate(record) {
234
264
  * Split from the reading so the conformance harness and the tests can construct a state
235
265
  * directly and so the only thing that touches a disk is `loadRecord`.
236
266
  *
237
- * `checked_at` is validated in EVERY arm that reached a record and not only on the `current`
238
- * path: a record that cannot say when it was written is not a record, and one rule is one thing
239
- * for the two runtimes to reproduce instead of two.
267
+ * The SELECTED `checked_at` (see `checkedDate`) is validated in EVERY arm that reached a record
268
+ * and not only on the `current` path: a record that cannot say when it was written is not a
269
+ * record, and one rule is one thing for the two runtimes to reproduce instead of two.
240
270
  */
241
271
  export function decide(installed, source, record, key = KEY) {
242
272
  if (source === SOURCE_ABSENT)
@@ -244,7 +274,7 @@ export function decide(installed, source, record, key = KEY) {
244
274
  if (source !== SOURCE_RECORD || record === null) {
245
275
  return { state: STATE_UNREADABLE, line: UPDATE_UNREADABLE };
246
276
  }
247
- const date = checkedDate(record);
277
+ const date = checkedDate(record, key);
248
278
  const latest = latestIn(record, key);
249
279
  if (date === null || latest === null) {
250
280
  return { state: STATE_UNREADABLE, line: UPDATE_UNREADABLE };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bantamkit-mcp",
3
- "version": "0.35.3",
3
+ "version": "0.35.4",
4
4
  "description": "Memory MCP server for Claude Code, Cursor, VS Code Copilot and Claude Desktop: per-person memory, JSON Schema validation, shift-work tools. Pure Node; install once with npx, run offline.",
5
5
  "keywords": [
6
6
  "mcp",