@polycode-projects/the-mechanical-code-talker 2.11.2 → 2.11.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polycode-projects/the-mechanical-code-talker",
3
- "version": "2.11.2",
3
+ "version": "2.11.4",
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; no codebase index of its own.",
@@ -140,6 +140,10 @@ const BROWSING_PREAMBLE_RE = /^(?:just\s+(?:poking\s+around|looking\s+around|bro
140
140
  /** Repeated leading hedge adverb before a polite request verb ("maybe
141
141
  * possibly tell me <Q>"). No delimiter required, unlike ACK_PREAMBLE_RE. */
142
142
  const HEDGE_ADVERB_PREAMBLE_RE = /^(?:(?:maybe|possibly|perhaps)\s+)+(.+)$/i;
143
+ /** Leading courtesy marker ("please tell me <Q>", "please, what is a dog").
144
+ * MODAL_WRAPPER_RE only strips a "please" INSIDE its own frame, so a
145
+ * sentence that leads with one never reached any wrapper. */
146
+ const PLEASE_PREAMBLE_RE = /^(?:please[\s,]+)+(.+)$/i;
143
147
  /** A floating "if it's not too much trouble" aside — a mid-sentence
144
148
  * parenthetical, stripped wherever it appears (not start-anchored). */
145
149
  const TROUBLE_ASIDE_RE = /,?\s*if\s+(?:it'?s|it\s+is|that'?s|that\s+is)\s+not\s+too\s+much\s+(?:trouble|bother|hassle)\s*,?\s*/i;
@@ -148,9 +152,14 @@ const MODAL_WRAPPER_RE = /^(?:can|could|would|will)\s+you\s+(?:please\s+)?(.+?)(
148
152
  /** "explain [to me|please]* <Q>" -> "<Q>", gated on an interrogative
149
153
  * remainder so it only unwraps a real WH-question underneath. */
150
154
  const EXPLAIN_WRAPPER_RE = /^explain\s+(?:to\s+me\s+|please\s+)*(.+?)\??$/i;
151
- /** "tell me <Q>" (bare, no "about") -> "<Q>"; "tell me about X" is a
152
- * different, untouched territory (chat.mjs's vagueTouchTermOf). */
153
- const TELL_ME_WRAPPER_RE = /^tell\s+me\s+(.+?)\??$/i;
155
+ /** "tell me [please] <Q>" (bare, no "about") -> "<Q>"; "tell me about X" is a
156
+ * different, untouched territory (chat.mjs's vagueTouchTermOf). The optional
157
+ * infix "please" mirrors MODAL_WRAPPER_RE's own. */
158
+ const TELL_ME_WRAPPER_RE = /^tell\s+me\s+(?:please\s+)?(.+?)\??$/i;
159
+ /** "[would/do you] mind telling me <Q>" -> "<Q>" — the gerund sibling of
160
+ * TELL_ME_WRAPPER_RE (MODAL_WRAPPER_RE peels a leading "would you", leaving
161
+ * the bare "mind telling me" form this also matches directly). */
162
+ const MIND_TELLING_WRAPPER_RE = /^(?:(?:would|do)\s+you\s+)?mind\s+telling\s+(?:me|us)\s+(?:please\s+)?(.+?)\??$/i;
154
163
  /** "do you know <Q>" -> "<Q>", gated on an interrogative remainder — so
155
164
  * "do you know anything about movies" (small-talk, no embedded question)
156
165
  * passes through untouched. */
@@ -213,6 +222,8 @@ export function applyPreambleFrames(text) {
213
222
  if (m) q = m[1].trim();
214
223
  m = q.match(HEDGE_ADVERB_PREAMBLE_RE);
215
224
  if (m) q = m[1].trim();
225
+ m = q.match(PLEASE_PREAMBLE_RE);
226
+ if (m) q = m[1].trim();
216
227
  m = q.match(TOPIC_SWITCH_PREAMBLE_RE);
217
228
  if (m) q = m[1].trim();
218
229
  m = q.match(MODAL_WRAPPER_RE);
@@ -221,6 +232,8 @@ export function applyPreambleFrames(text) {
221
232
  if (m && INTERROGATIVE_LEAD_RE.test(m[1].trim())) q = m[1].trim();
222
233
  m = q.match(TELL_ME_WRAPPER_RE);
223
234
  if (m && INTERROGATIVE_LEAD_RE.test(m[1].trim())) q = m[1].trim();
235
+ m = q.match(MIND_TELLING_WRAPPER_RE);
236
+ if (m && INTERROGATIVE_LEAD_RE.test(m[1].trim())) q = m[1].trim();
224
237
  m = q.match(KNOW_WRAPPER_RE);
225
238
  if (m && INTERROGATIVE_LEAD_RE.test(m[1].trim())) q = m[1].trim();
226
239
  m = q.match(WANT_KNOW_WRAPPER_RE);
@@ -3163,6 +3163,14 @@ async function unknownAdjectiveFallback(payload, { memoryDir, sessionId, lexicon
3163
3163
  if (!m) return null;
3164
3164
  const [, det, subjectRaw, verb, objectRaw] = m;
3165
3165
  if (PLACE_ADVERB_OBJECT_RE.test(objectRaw)) return null; // a place adverb is never a property
3166
+ // An ARTICLED complement ("a dog is a mammal") is a noun-phrase kind claim,
3167
+ // never an adjective property — but UNKNOWN_SUBJECT_RE strips the object's
3168
+ // article before capture, so objectRaw alone can't show the difference from
3169
+ // "the cache is bespoke". Without this re-check, a fact-grounded subject
3170
+ // silently minted the kind claim as an mgx:hasProperty garble that the isa
3171
+ // read-back then denied. Declining here lands on the honest teach-miss,
3172
+ // whose nudge already names the storable form ("every dog is a mammal").
3173
+ if (/\s+(?:is|are)\s+an?\s+[\w-]+[.!?]*\s*$/i.test(String(payload).trim())) return null;
3166
3174
  const { loadLexicon, lookupNoun, lookupAdjective, classify } = await import("../domain/grammar/lexicon.mjs");
3167
3175
  const lex = lexicon || loadLexicon();
3168
3176
  // Y already a known NOUN or a fact-grounded CLASS term — a genuine class-