@polycode-projects/the-mechanical-code-talker 5.0.7 → 5.0.9

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/README.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # tmct — The Mechanical Code Talker
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@polycode-projects/the-mechanical-code-talker)](https://www.npmjs.com/package/@polycode-projects/the-mechanical-code-talker)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@polycode-projects/the-mechanical-code-talker)](https://www.npmjs.com/package/@polycode-projects/the-mechanical-code-talker)
5
+ [![licence](https://img.shields.io/npm/l/@polycode-projects/the-mechanical-code-talker)](https://gitlab.com/polycode-projects/the-mechanical-code-talker/-/blob/main/LICENSE)
6
+ [![live demos](https://img.shields.io/badge/demos-tmct.polycode.co.uk-blue)](https://tmct.polycode.co.uk)
7
+
8
+ > Canonical home: [GitLab](https://gitlab.com/polycode-projects/the-mechanical-code-talker).
9
+ > Installs come from [npm](https://www.npmjs.com/package/@polycode-projects/the-mechanical-code-talker).
10
+ > The [GitHub repo](https://github.com/polycode-public/the-mechanical-code-talker) is a
11
+ > read-only mirror, synced hourly. Issues and merge requests go to GitLab.
12
+
3
13
  `@polycode-projects/the-mechanical-code-talker`
4
14
 
5
15
  A pure-JS, **no-LLM**, offline, **$0** chatbot in the ELIZA/PARRY lineage.
@@ -1499,6 +1509,11 @@ hardened:
1499
1509
  - A nightly **`npm audit` + OSV-Scanner** job watches dependencies.
1500
1510
  - Releases are published with **npm provenance** (`--provenance`).
1501
1511
 
1512
+ The npm tarball carries Sigstore-signed provenance naming the GitLab pipeline
1513
+ that built it. Every published version also gets a GitLab release tag pinned to
1514
+ the exact commit that pipeline ran against. Follow both and an install traces
1515
+ back to the source it was built from.
1516
+
1502
1517
  The content-address hash is single-sourced in `src/domain/hash.mjs`, so the
1503
1518
  cross-version-stable fact-id contract has exactly one definition.
1504
1519
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polycode-projects/the-mechanical-code-talker",
3
- "version": "5.0.7",
3
+ "version": "5.0.9",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "The Mechanical Code Talker (tmct) — a tolerant, offline, $0 chat surface that guides you toward precision queries about a software repository. ELIZA/PARRY-style but domain-obsessed with code. No model calls; indexes a repo on request (tmct index) or reads any producer's graph.",
@@ -96,6 +96,7 @@
96
96
  "check:readme": "TMCT_CHECK_README=1 node --disable-warning=ExperimentalWarning --test test-e2e/readme-examples.test.mjs",
97
97
  "e2e:browsers": "playwright install chromium",
98
98
  "gen:screenshots": "node scripts/gen-screenshots.mjs",
99
+ "gen:og-images": "node scripts/gen-og-images.mjs",
99
100
  "check:links": "node scripts/check-links.mjs",
100
101
  "check:pii": "node scripts/pii-lint.mjs",
101
102
  "check:pack": "node scripts/check-pack-manifest.mjs",
@@ -154,6 +155,7 @@
154
155
  "audit": "npm audit --audit-level=high",
155
156
  "audit:fix": "npm audit fix",
156
157
  "demo:build": "node scripts/build-demo-site.mjs",
158
+ "bench:receipts": "node scripts/bench-receipts.mjs",
157
159
  "roll": "node scripts/roll.mjs",
158
160
  "build:ask-bundle": "node scripts/build-ask-bundle.mjs",
159
161
  "build:chat-bundle": "node scripts/build-chat-bundle.mjs",
@@ -235,6 +235,10 @@ const WONDERING_WRAPPER_RE = /^i(?:\s+was|\s+am|'m)?\s+(?:just\s+)?(?:wonder(?:i
235
235
  * ("what the parser does with X …") is never re-inverted. */
236
236
  const EMBEDDED_WHATIS_RE = /^what\s+((?:an?\s+|the\s+)?[\w'-]+(?:\s+[\w'-]+){0,2})\s+(is|are)\??$/i;
237
237
  const EMBEDDED_MEANS_RE = /^what\s+((?:an?\s+|the\s+)?[\w'-]+(?:\s+[\w'-]+){0,2})\s+means\??$/i;
238
+ /** The memory-question sibling: "tell me what you know about X" peels to
239
+ * "what you know about X", which keeps the same declarative order and misses
240
+ * the memory lane's own "what do you know about X" shape. */
241
+ const EMBEDDED_KNOW_ABOUT_RE = /^what\s+you\s+(know|remember)\s+about\s+(.+?)\??$/i;
238
242
  /** show/give-me presentation bridge: a kind-listing remainder is left
239
243
  * untouched, a relation/interrogative remainder unwraps to itself, anything
240
244
  * else bridges to "describe <thing>". */
@@ -309,6 +313,8 @@ export function applyPreambleFrames(text) {
309
313
  if (m) q = `what ${m[2].toLowerCase()} ${m[1].trim()}`;
310
314
  m = q.match(EMBEDDED_MEANS_RE);
311
315
  if (m) q = `what does ${m[1].trim()} mean`;
316
+ m = q.match(EMBEDDED_KNOW_ABOUT_RE);
317
+ if (m) q = `what do you ${m[1].toLowerCase()} about ${m[2].trim()}`;
312
318
  m = q.match(SHOW_GIVE_ME_RE);
313
319
  if (m) {
314
320
  const rest = m[1].trim();
@@ -14071,14 +14071,27 @@ async function runAsk(query, { config, source, graph, focus, last, templates, me
14071
14071
  // graph entity.
14072
14072
  // Contraction-expanded, so "what's X" earns the same offer "what is X"
14073
14073
  // does. Both shapes below anchor on the written-out copula.
14074
- const offerSrc = expandContractions(String(query).trim());
14075
- const knowAboutTerm = offerSrc.match(KNOW_ABOUT_RE)?.[1]?.trim();
14074
+ //
14076
14075
  // "who is grelb" asks about a term the same way "what is grelb" does, and
14077
14076
  // a name is exactly what a person teaches next — without this the who-form
14078
14077
  // dead-ends on the bare grammar wall while its what-form twin offers the
14079
14078
  // teach phrasing.
14080
- const whoTerm = shortTermQuestionTerm(offerSrc) ? offerSrc.match(WHO_IS_BARE_RE)?.[1]?.trim() : null;
14081
- const offerTerm = knowAboutTerm || metaTermOf(offerSrc, envelope) || whoTerm;
14079
+ const teachableTermOf = (src) => {
14080
+ const knowAbout = src.match(KNOW_ABOUT_RE)?.[1]?.trim();
14081
+ const who = shortTermQuestionTerm(src) ? src.match(WHO_IS_BARE_RE)?.[1]?.trim() : null;
14082
+ return { knowAbout, term: knowAbout || metaTermOf(src, envelope) || who };
14083
+ };
14084
+ const offerSrc = expandContractions(String(query).trim());
14085
+ // All three shapes anchor at the start of the string, so a politeness or
14086
+ // modal wrapper ("please tell me what a grelb is") hides the term from
14087
+ // every one of them and the turn dead-ends on the bare wall instead. The
14088
+ // peeled form is a fallback, tried only when the raw one names nothing, so
14089
+ // a query that already matched resolves exactly as before.
14090
+ let { knowAbout: knowAboutTerm, term: offerTerm } = teachableTermOf(offerSrc);
14091
+ if (!offerTerm) {
14092
+ const peeledSrc = applyPreambleFrames(offerSrc);
14093
+ if (peeledSrc !== offerSrc) ({ knowAbout: knowAboutTerm, term: offerTerm } = teachableTermOf(peeledSrc));
14094
+ }
14082
14095
  // A term that LEADS with a bindable anaphor ("it used for", from an
14083
14096
  // unresolved "what is it used for") is a pronoun that failed to bind,
14084
14097
  // not a teachable subject — offering to learn facts about it would echo