@polycode-projects/the-mechanical-code-talker 1.10.14 → 1.11.5
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 +121 -114
- package/ROADMAP.md +14 -4
- package/bin/tmct.mjs +167 -77
- package/data/games/crates.txt +24 -0
- package/data/games/hanoi-3.txt +30 -0
- package/data/games/river.txt +33 -0
- package/package.json +1 -1
- package/src/ask.mjs +119 -6
- package/src/chat.mjs +1515 -52
- package/src/codegraph.mjs +24 -11
- package/src/domain.mjs +350 -0
- package/src/import-file.mjs +86 -0
- package/src/init.mjs +46 -1
- package/src/interpret/normalize.mjs +46 -0
- package/src/interpret/strategies/keywords.mjs +13 -9
- package/src/ledger-viz.mjs +635 -0
- package/src/memory/core.mjs +100 -17
- package/src/memory/shacl.mjs +20 -7
- package/src/memory-ask-browser-entry.mjs +9 -7
- package/src/memory-ask-browser.bundle.js +5648 -1177
- package/src/plan-viz.mjs +409 -0
- package/src/router/drive.mjs +122 -13
- package/src/router/guardrail.mjs +5 -0
- package/src/router/registry.mjs +55 -11
- package/src/router/resolver.mjs +13 -0
- package/src/router/taught.mjs +84 -0
- package/src/sentences.mjs +19 -0
- package/src/syllogise.mjs +154 -38
- package/src/viz-theme.mjs +66 -0
- package/src/wink-model.mjs +12 -6
- package/src/ask-browser-entry.mjs +0 -19
- package/src/ask-browser.bundle.js +0 -5411
- package/src/viz.mjs +0 -959
|
@@ -92,13 +92,14 @@ export function parseKeywordSpot(text, nlp = null) {
|
|
|
92
92
|
verbHit = findPhrase(lemmaWords, VERB_TO_KIND);
|
|
93
93
|
if (verbHit) canonWords = lemmaWords;
|
|
94
94
|
}
|
|
95
|
+
let fuzzyVerb = false;
|
|
95
96
|
if (!verbHit) {
|
|
96
97
|
// tier 3: bounded-edit-distance rewrite toward verb/modifier keywords only
|
|
97
98
|
// ("impotr" -> "import"); ≥4-char words only — below that the bound covers
|
|
98
99
|
// half of English (and "and" is 1 edit from the "land in" constituent).
|
|
99
100
|
const fuzzyWords = lcWords.map((w) => (w.length >= 4 && eligibleForCanon(w) ? fuzzyVocabWord(w) || w : w));
|
|
100
101
|
verbHit = findPhrase(fuzzyWords, VERB_TO_KIND);
|
|
101
|
-
if (verbHit) canonWords = fuzzyWords;
|
|
102
|
+
if (verbHit) { canonWords = fuzzyWords; fuzzyVerb = true; }
|
|
102
103
|
}
|
|
103
104
|
if (!verbHit && lcWords.includes("by")) {
|
|
104
105
|
// A participle with no active verb entry still marks a passive when a passive
|
|
@@ -109,6 +110,9 @@ export function parseKeywordSpot(text, nlp = null) {
|
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
if (!verbHit) return null;
|
|
113
|
+
// A tier-3 verb is a REPAIR, not a reading — downstream consumers (the teach
|
|
114
|
+
// lane's canonical receipt) need to know the difference, so it rides the AST.
|
|
115
|
+
const stamp = (ast) => (fuzzyVerb ? { ...ast, fuzzyVerb: true } : ast);
|
|
112
116
|
// POS rescue (Node-side only): a relation word used as a NOUN in a "the
|
|
113
117
|
// <imports> of <term>" frame would otherwise misparse; only fires inside this
|
|
114
118
|
// exact det+NOUN+"of" shape, since the same word tags NOUN in genuine verb use too.
|
|
@@ -119,7 +123,7 @@ export function parseKeywordSpot(text, nlp = null) {
|
|
|
119
123
|
const tags = nlp.posTags(words);
|
|
120
124
|
if (tags[i] === "NOUN") {
|
|
121
125
|
const objText = words.slice(i + 2).filter((w, j) => !STOPWORDS.has(lcWords[i + 2 + j])).join(" ").trim();
|
|
122
|
-
if (objText) return { shape: "forward", entityType: null, modifier: "direct", kind: verbHit.kind, object: objText };
|
|
126
|
+
if (objText) return stamp({ shape: "forward", entityType: null, modifier: "direct", kind: verbHit.kind, object: objText });
|
|
123
127
|
}
|
|
124
128
|
}
|
|
125
129
|
}
|
|
@@ -154,7 +158,7 @@ export function parseKeywordSpot(text, nlp = null) {
|
|
|
154
158
|
// "when" turns a touches decomposition temporal; other verbs fall through.
|
|
155
159
|
if (kind === "touches" && lcWords.includes("when")) {
|
|
156
160
|
const objText = beforeText || afterText;
|
|
157
|
-
if (objText) return { shape: "when", entityType: null, modifier: "direct", kind: "touches", object: objText };
|
|
161
|
+
if (objText) return stamp({ shape: "when", entityType: null, modifier: "direct", kind: "touches", object: objText });
|
|
158
162
|
}
|
|
159
163
|
|
|
160
164
|
// "who last touched X" would otherwise list every touching commit's author,
|
|
@@ -162,7 +166,7 @@ export function parseKeywordSpot(text, nlp = null) {
|
|
|
162
166
|
// stopwords and wouldn't survive into beforeText/afterText.
|
|
163
167
|
if (kind === "touches" && lcWords.includes("who") && lcWords.includes("last")) {
|
|
164
168
|
const objText = beforeText || afterText;
|
|
165
|
-
if (objText) return { shape: "whoLast", entityType: null, modifier: "direct", kind: "touches", object: objText };
|
|
169
|
+
if (objText) return stamp({ shape: "whoLast", entityType: null, modifier: "direct", kind: "touches", object: objText });
|
|
166
170
|
}
|
|
167
171
|
|
|
168
172
|
// Reversible passive ("PATIENT is VERBed BY AGENT"): a passive auxiliary plus a
|
|
@@ -190,7 +194,7 @@ export function parseKeywordSpot(text, nlp = null) {
|
|
|
190
194
|
nextAfterBy = lcWords[i]; break;
|
|
191
195
|
}
|
|
192
196
|
const agentNamed = nextAfterBy != null && !WH_WORDS.has(nextAfterBy) && !ENTITY_TO_TYPE[nextAfterBy];
|
|
193
|
-
return { shape: agentNamed ? "forward" : "reverse", entityType, modifier, kind, object };
|
|
197
|
+
return stamp({ shape: agentNamed ? "forward" : "reverse", entityType, modifier, kind, object });
|
|
194
198
|
}
|
|
195
199
|
}
|
|
196
200
|
|
|
@@ -201,19 +205,19 @@ export function parseKeywordSpot(text, nlp = null) {
|
|
|
201
205
|
let subject = beforeText;
|
|
202
206
|
let object = afterText;
|
|
203
207
|
if (INHERITS_REVERSE_VERBS.includes(verbPhrase)) [subject, object] = [object, subject];
|
|
204
|
-
return { shape: "ask", entityType: null, modifier: "direct", kind, subject, object };
|
|
208
|
+
return stamp({ shape: "ask", entityType: null, modifier: "direct", kind, subject, object });
|
|
205
209
|
}
|
|
206
|
-
if (afterText) return { shape: "reverse", entityType, modifier, kind, object: afterText };
|
|
210
|
+
if (afterText) return stamp({ shape: "reverse", entityType, modifier, kind, object: afterText });
|
|
207
211
|
// "what is a kind of class": when the object is itself an entity-type noun, the
|
|
208
212
|
// entity match swallows the whole post-verb span as a grain qualifier, leaving
|
|
209
213
|
// afterText empty — re-read that span as the object instead.
|
|
210
214
|
if (kind === "inherits" && !beforeText && entityHit && entityHit.start === verbHit.end) {
|
|
211
215
|
const entityText = canonWords.slice(entityHit.start, entityHit.end).join(" ");
|
|
212
|
-
if (entityText) return { shape: "reverse", entityType: null, modifier, kind, object: entityText };
|
|
216
|
+
if (entityText) return stamp({ shape: "reverse", entityType: null, modifier, kind, object: entityText });
|
|
213
217
|
}
|
|
214
218
|
// forward keeps the spotted entityType (traverse()'s commit-as-subject grain
|
|
215
219
|
// selection); modifier stays hardcoded since no forward closure traversal exists.
|
|
216
|
-
if (beforeText) return { shape: "forward", entityType, modifier: "direct", kind, object: beforeText };
|
|
220
|
+
if (beforeText) return stamp({ shape: "forward", entityType, modifier: "direct", kind, object: beforeText });
|
|
217
221
|
return null;
|
|
218
222
|
}
|
|
219
223
|
|