@polycode-projects/the-mechanical-code-talker 0.2.0 → 0.3.0

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.
@@ -0,0 +1,231 @@
1
+ # software-phrases.txt — the SE phrase book (ROADMAP items 4+7).
2
+ #
3
+ # One phrase pattern per line; {x}/{y} are entity slots the matcher binds to
4
+ # names in the graph. Lines starting with `~` declare a SYNONYM FAMILY: words
5
+ # and short phrases the matcher may treat as interchangeable when normalizing
6
+ # input. `#` starts a comment; blank lines are ignored.
7
+ # Parsed by src/corpus/templates.mjs loadPhrasebook().
8
+
9
+ # --- synonym families: the interchangeable vocabulary of asking about code ---
10
+ ~ call, invoke, use, execute, run, trigger, talk to
11
+ ~ import, include, require, pull in, depend on, load
12
+ ~ module, file, source file, unit
13
+ ~ function, fn, func, routine, procedure, method
14
+ ~ class, type, struct, record, interface
15
+ ~ test, spec, unit test, test case, check
16
+ ~ bug, defect, fault, issue, problem, glitch
17
+ ~ fix, repair, patch, resolve, correct
18
+ ~ change, modify, edit, touch, update, alter, rework
19
+ ~ delete, remove, drop, kill, strip out, get rid of
20
+ ~ create, add, make, introduce, write, define
21
+ ~ rename, relabel, move, relocate
22
+ ~ commit, change set, checkin, revision
23
+ ~ author, committer, contributor, developer, dev, engineer, programmer
24
+ ~ big, large, huge, long, giant
25
+ ~ small, tiny, short, little, lean
26
+ ~ recent, latest, newest, last, fresh
27
+ ~ old, oldest, ancient, stale, legacy
28
+ ~ broken, failing, red, busted, dead
29
+ ~ working, passing, green, healthy, fine
30
+ ~ central, core, important, key, load-bearing, critical
31
+ ~ unused, dead, orphaned, abandoned, unreferenced
32
+ ~ caller, call site, consumer, client
33
+ ~ callee, target, dependency
34
+ ~ parent, superclass, base class, ancestor
35
+ ~ child, subclass, derived class, descendant
36
+ ~ member, field, attribute, property
37
+ ~ argument, parameter, param, arg, input
38
+ ~ return, result, output, yield
39
+ ~ error, exception, failure, crash, panic
40
+ ~ codebase, repo, repository, project, source tree, code
41
+
42
+ # --- call graph: what calls what ---
43
+ what calls {x}
44
+ what does {x} call
45
+ who calls {x}
46
+ who is calling {x}
47
+ which functions call {x}
48
+ which modules call {x}
49
+ what invokes {x}
50
+ callers of {x}
51
+ call sites of {x}
52
+ where is {x} called
53
+ where is {x} called from
54
+ is {x} called anywhere
55
+ is {x} ever called
56
+ does anything call {x}
57
+ does {x} call {y}
58
+ what talks to {x}
59
+ what does {x} talk to
60
+ what depends on {x}
61
+ what does {x} depend on
62
+ show me the call graph around {x}
63
+
64
+ # --- imports and dependencies ---
65
+ who imports {x}
66
+ what imports {x}
67
+ which modules import {x}
68
+ what does {x} import
69
+ where is {x} imported
70
+ is {x} imported anywhere
71
+ does {x} import {y}
72
+ what requires {x}
73
+ what uses {x}
74
+ what does {x} use
75
+ what pulls in {x}
76
+ dependencies of {x}
77
+ dependents of {x}
78
+ what breaks if {x} changes
79
+ what would be affected by changing {x}
80
+ impact of changing {x}
81
+ blast radius of {x}
82
+
83
+ # --- definition and location: where things live ---
84
+ where is {x}
85
+ where is {x} defined
86
+ where does {x} live
87
+ which file defines {x}
88
+ which module defines {x}
89
+ what is defined in {x}
90
+ what does {x} define
91
+ what lives in {x}
92
+ find {x}
93
+ show me {x}
94
+ is there a {x}
95
+ do we have a {x}
96
+ does {x} exist
97
+ where is {x} importable from
98
+ what does {x} export
99
+ what is the public api of {x}
100
+ what is in the {x} package
101
+
102
+ # --- description: what things are ---
103
+ what is {x}
104
+ what is {x} for
105
+ what does {x} do
106
+ describe {x}
107
+ tell me about {x}
108
+ explain {x}
109
+ what kind of thing is {x}
110
+ is {x} a module or a function
111
+ what type is {x}
112
+ what does {x} return
113
+ what arguments does {x} take
114
+ what parameters does {x} take
115
+ what is the signature of {x}
116
+ what exceptions does {x} throw
117
+ what does {x} raise
118
+ what does {x} catch
119
+ is {x} public or private
120
+ is {x} deprecated
121
+
122
+ # --- structure: classes, members, inheritance ---
123
+ what does {x} contain
124
+ what members does {x} have
125
+ what methods does {x} have
126
+ what fields does {x} have
127
+ what is inside {x}
128
+ what does {x} inherit from
129
+ what extends {x}
130
+ what subclasses {x}
131
+ subclasses of {x}
132
+ superclass of {x}
133
+ parents of {x}
134
+ children of {x}
135
+ is {x} a subclass of {y}
136
+ what implements {x}
137
+ implementations of {x}
138
+
139
+ # --- tests ---
140
+ is {x} tested
141
+ does {x} have tests
142
+ what tests {x}
143
+ what tests cover {x}
144
+ which tests exercise {x}
145
+ where are the tests for {x}
146
+ test coverage of {x}
147
+ what does {x} test
148
+ is there a test for {x}
149
+ how well tested is {x}
150
+ what has no tests
151
+ which modules are untested
152
+ do the tests pass
153
+ are the tests green
154
+
155
+ # --- history: commits, authors, change ---
156
+ who wrote {x}
157
+ who authored {x}
158
+ who last touched {x}
159
+ who changed {x}
160
+ when was {x} last changed
161
+ when was {x} added
162
+ what changed recently
163
+ what changed in the last commit
164
+ what did {x} change
165
+ what commits touched {x}
166
+ history of {x}
167
+ how often does {x} change
168
+ what changes together with {x}
169
+ what usually changes with {x}
170
+ is {x} new
171
+ is {x} stale
172
+ who knows about {x}
173
+ who owns {x}
174
+
175
+ # --- size, count, shape ---
176
+ how many modules are there
177
+ how many functions are there
178
+ how many classes are there
179
+ how many tests are there
180
+ how big is {x}
181
+ how big is the codebase
182
+ how many lines is {x}
183
+ what is the biggest module
184
+ what is the biggest function
185
+ what is the most complex module
186
+ what is the most central module
187
+ what is the most imported module
188
+ what is the most called function
189
+ what has the most dependencies
190
+ what has no dependencies
191
+ what is unused
192
+ what is dead code
193
+ list the modules
194
+ list the classes
195
+ list everything you know about {x}
196
+
197
+ # --- bugs, quality, health ---
198
+ is {x} broken
199
+ why is {x} failing
200
+ what is wrong with {x}
201
+ does {x} have known bugs
202
+ is {x} safe to change
203
+ is {x} safe to delete
204
+ what is risky about {x}
205
+ what smells in {x}
206
+ is {x} too big
207
+ does {x} do too much
208
+
209
+ # --- memory: what tmct itself was told ---
210
+ what did i tell you about {x}
211
+ what do you know about {x}
212
+ what do you remember about {x}
213
+ what have i told you
214
+ what did i ask you before
215
+ did i mention {x}
216
+ remember that {x}
217
+ forget about {x}
218
+ what did you just say
219
+ what was your last answer
220
+ what did we talk about
221
+ summarise this session
222
+
223
+ # --- meta: about the graph and tmct ---
224
+ what can you answer
225
+ what do you know
226
+ how much do you know
227
+ what is in your graph
228
+ when was your graph built
229
+ where does your graph come from
230
+ what can i ask you
231
+ help me ask a better question
@@ -0,0 +1,55 @@
1
+ {"id":"describe-entity-terse","class":"describe","register":"terse","template":"{subject}: {kind} in {location}."}
2
+ {"id":"describe-entity-friendly","class":"describe","register":"friendly","template":"{subject} is a {kind} living in {location}."}
3
+ {"id":"describe-entity-with-doc","class":"describe","register":"friendly","template":"{subject} is a {kind} in {location} — \"{doc}\"."}
4
+ {"id":"describe-module-imports","class":"describe","register":"friendly","template":"{subject} imports {objects}."}
5
+ {"id":"describe-module-imported-by","class":"describe","register":"friendly","template":"{subject} is imported by {objects}."}
6
+ {"id":"describe-callers","class":"describe","register":"friendly","template":"{subject} is called by {objects}."}
7
+ {"id":"describe-callers-terse","class":"describe","register":"terse","template":"{subject} <- {objects}."}
8
+ {"id":"describe-callees","class":"describe","register":"friendly","template":"{subject} calls {objects}."}
9
+ {"id":"describe-members","class":"describe","register":"friendly","template":"{subject} contains {objects}."}
10
+ {"id":"describe-superclass","class":"describe","register":"friendly","template":"{subject} inherits from {object}."}
11
+ {"id":"describe-tested-by","class":"describe","register":"friendly","template":"{subject} is exercised by {objects}."}
12
+ {"id":"describe-untested","class":"describe","register":"friendly","template":"I can't see any test that imports {subject} — that may just mean the coverage is indirect."}
13
+ {"id":"describe-history","class":"describe","register":"friendly","template":"{subject} was last touched by {commit} ({when}): \"{message}\"."}
14
+ {"id":"describe-relation-fact","class":"describe","register":"terse","template":"{subject} {predicate} {object}."}
15
+ {"id":"describe-isa-fact","class":"describe","register":"friendly","template":"As I understand it, a {subject} is a kind of {object}."}
16
+ {"id":"count-plain","class":"count","register":"terse","template":"{count} {noun}."}
17
+ {"id":"count-sentence","class":"count","register":"friendly","template":"There are {count} {noun} in {scope}."}
18
+ {"id":"count-one","class":"count","register":"friendly","template":"There is exactly one {noun} in {scope}: {subject}."}
19
+ {"id":"count-zero","class":"count","register":"friendly","template":"I can't find any {noun} in {scope}."}
20
+ {"id":"count-with-sample","class":"count","register":"friendly","template":"{count} {noun} in {scope} — for example {examples}."}
21
+ {"id":"count-compared","class":"count","register":"friendly","template":"{count} {noun} — {comparison} for a codebase of this size."}
22
+ {"id":"miss-plain","class":"miss","register":"terse","template":"No match for \"{query}\"."}
23
+ {"id":"miss-honest","class":"miss","register":"friendly","template":"I couldn't ground \"{query}\" in anything I know. I'd rather say so than guess."}
24
+ {"id":"miss-rephrase-name","class":"miss","register":"friendly","template":"I don't recognise \"{query}\". If you name a module, function, or class I know about, I can work from there."}
25
+ {"id":"miss-rephrase-pattern","class":"miss","register":"friendly","template":"\"{query}\" didn't match anything. Try a shape like \"{example}\" — that's a question I can answer precisely."}
26
+ {"id":"miss-nearest","class":"miss","register":"friendly","template":"Nothing matches \"{query}\" exactly. The nearest name I know is {nearest} — is that what you meant?"}
27
+ {"id":"miss-nearest-terse","class":"miss","register":"terse","template":"No \"{query}\". Nearest: {nearest}."}
28
+ {"id":"miss-empty-graph","class":"miss","register":"friendly","template":"My graph is empty right now, so I can't answer \"{query}\" yet. Tell me things and I'll remember them."}
29
+ {"id":"miss-out-of-domain","class":"miss","register":"friendly","template":"That sounds like it's outside my patch — I only really know about {scope}. Ask me about the code and I'm much more useful."}
30
+ {"id":"ambiguity-two","class":"ambiguity","register":"friendly","template":"That could go two ways. If you mean {a} then {aAnswer}; if you mean {b} then {bAnswer}."}
31
+ {"id":"ambiguity-two-terse","class":"ambiguity","register":"terse","template":"{a}: {aAnswer} / {b}: {bAnswer}."}
32
+ {"id":"ambiguity-three","class":"ambiguity","register":"friendly","template":"I see three readings. If you mean {a} then {aAnswer}; if you mean {b} then {bAnswer}; if you mean {c} then {cAnswer}."}
33
+ {"id":"ambiguity-name-clash","class":"ambiguity","register":"friendly","template":"\"{query}\" names more than one thing here: {candidates}. Which one do you mean?"}
34
+ {"id":"ambiguity-name-clash-terse","class":"ambiguity","register":"terse","template":"\"{query}\" is ambiguous: {candidates}."}
35
+ {"id":"ambiguity-class-split","class":"ambiguity","register":"friendly","template":"Reading \"{query}\" as a {a} gives one answer, reading it as a {b} gives another. Say which and I'll commit."}
36
+ {"id":"assume-scope","class":"assumption","register":"friendly","template":"I'll assume you're asking about {assumed} — say otherwise and I'll drop that."}
37
+ {"id":"assume-scope-terse","class":"assumption","register":"terse","template":"Assuming {assumed}."}
38
+ {"id":"assume-spelling","class":"assumption","register":"friendly","template":"I read \"{query}\" as {assumed} (closest name I know). {answer}"}
39
+ {"id":"assume-this-repo","class":"assumption","register":"friendly","template":"I'm assuming \"{query}\" is about this repository. {answer}"}
40
+ {"id":"assume-latest","class":"assumption","register":"friendly","template":"You didn't say which {noun}, so I took the most recent one: {assumed}."}
41
+ {"id":"assume-singular","class":"assumption","register":"friendly","template":"Several things match; I picked the strongest, {assumed}. The runners-up were {others}."}
42
+ {"id":"recall-plain","class":"recall","register":"friendly","template":"You told me earlier that {fact}."}
43
+ {"id":"recall-plain-terse","class":"recall","register":"terse","template":"Earlier: {fact}."}
44
+ {"id":"recall-with-when","class":"recall","register":"friendly","template":"Earlier in this session ({when}) you said \"{utterance}\"."}
45
+ {"id":"recall-prior-session","class":"recall","register":"friendly","template":"In a previous session you told me that {fact} — I'm going on that."}
46
+ {"id":"recall-corpus","class":"recall","register":"friendly","template":"My corpus says {fact} — that's background knowledge, not something you told me."}
47
+ {"id":"recall-conflict","class":"recall","register":"friendly","template":"Careful — you told me earlier that {fact}, which doesn't sit well with \"{query}\". Which should I keep?"}
48
+ {"id":"recall-similar-question","class":"recall","register":"friendly","template":"You asked something similar before (\"{utterance}\") and the answer was: {answer}"}
49
+ {"id":"recall-nothing","class":"recall","register":"friendly","template":"You haven't told me anything about {subject} yet."}
50
+ {"id":"stored-fact","class":"stored","register":"friendly","template":"Noted: {subject} {predicate} {object}. I'll remember that."}
51
+ {"id":"stored-fact-terse","class":"stored","register":"terse","template":"Stored: {subject} {predicate} {object}."}
52
+ {"id":"stored-duplicate","class":"stored","register":"friendly","template":"I already knew that {subject} {predicate} {object} — nothing new to store."}
53
+ {"id":"nudge-precision","class":"nudge","register":"friendly","template":"The closer you get to a shape like \"{example}\", the sharper my answer gets."}
54
+ {"id":"nudge-commands","class":"nudge","register":"friendly","template":"If prose fails you, the slash commands always work — try {command}."}
55
+ {"id":"nudge-narrower","class":"nudge","register":"friendly","template":"That matched {count} things — too many to be useful. Narrow it with a module or class name."}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polycode-projects/the-mechanical-code-talker",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
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.",
@@ -29,18 +29,27 @@
29
29
  "src/",
30
30
  "README.md",
31
31
  "ROADMAP.md",
32
- "LICENSE"
32
+ "LICENSE",
33
+ "corpus/",
34
+ "data/"
33
35
  ],
34
36
  "publishConfig": {
35
37
  "access": "public"
36
38
  },
37
39
  "dependencies": {
40
+ "ink": "^7.1.0",
41
+ "react": "^19.2.7",
38
42
  "smol-toml": "^1.7.0",
39
43
  "wink-eng-lite-web-model": "^1.8.1",
40
44
  "wink-nlp": "^2.4.0"
41
45
  },
42
46
  "scripts": {
43
47
  "test": "node --test \"test/**/*.test.mjs\"",
44
- "chat": "node bin/tmct.mjs"
48
+ "chat": "node bin/tmct.mjs",
49
+ "chatbench:run": "node chatbench/run.mjs",
50
+ "chatbench:judge": "node chatbench/judge.mjs"
51
+ },
52
+ "devDependencies": {
53
+ "ink-testing-library": "^4.0.0"
45
54
  }
46
55
  }
package/src/ask-nlp.mjs CHANGED
@@ -42,6 +42,20 @@ export function nlpAdapter() {
42
42
  return w.toLowerCase();
43
43
  }
44
44
  },
45
+ /** True when wink's lexicon flags the word as an English stop word
46
+ * ("anyway", "well", "also", …). Consulted by the noise-strip strategy
47
+ * (interpret/strategies/noise-strip.mjs) as its wink tier — the strategy's
48
+ * own KEEP set screens out the grammar's load-bearing words (which/what/
49
+ * does/…) BEFORE this is asked, so wink flagging a question word is
50
+ * harmless by construction. False on any surprise, never a throw. */
51
+ isStopWord(word) {
52
+ try {
53
+ const out = nlp.readDoc(String(word || "")).tokens().out(its.stopWordFlag);
54
+ return out[0] === true;
55
+ } catch {
56
+ return false;
57
+ }
58
+ },
45
59
  /** UPOS tags aligned to the CALLER's word array. wink re-tokenizes (it
46
60
  * splits "walk.mjs" into three tokens), so each input word is greedily
47
61
  * matched to the run of wink tokens that spell it and takes its FIRST
package/src/ask-vocab.mjs CHANGED
@@ -295,7 +295,13 @@ export const MISSPELLINGS = Object.freeze({
295
295
  "tets": "tests",
296
296
  // grammar anchor words
297
297
  "whcih": "which", "wich": "which", "whihc": "which",
298
- "waht": "what",
298
+ // "wat" (chatbench cycle 2, tf-wat-calls): the internet-casual spelling of
299
+ // "what" — neither curated noise nor a restorable trigger typo, so "wat calls
300
+ // fnAlpha" used to die as "couldn't resolve one of the terms". Restored here
301
+ // so BOTH parse strategies and the relaxation cascade see the canonical
302
+ // anchor; the correction regex's dotted-extension guard keeps a module
303
+ // literally named "wat.mjs" untouched, same residual trade as every entry.
304
+ "waht": "what", "wat": "what",
299
305
  "dose": "does", "doess": "does",
300
306
  "teh": "the",
301
307
  // aggregate/list TRIGGER words (2026-07-02, trigger-typo work) — a typo of a count
@@ -626,6 +632,12 @@ export const CASCADE_NOISE = Object.freeze([
626
632
  // vocatives / terms of address (the "matey" of the worked example, and its kin)
627
633
  "matey", "mate", "buddy", "pal", "dude", "man", "bro", "bru", "fam",
628
634
  "friend", "sir", "maam", "folks", "guys", "everyone", "dear",
635
+ // the product's OWN name used as an address (chatbench cycle 2, ns-hey-tmct:
636
+ // "hey tmct, what calls fnAlpha thanks") — a vocative like "matey", stripped
637
+ // by the same rules: relaxParse's resolvesExact guard still protects a module
638
+ // literally named "tmct", and noise-strip's template/keyword-spot acceptance
639
+ // bounds the cost of a mid-question strip to an honest object-miss.
640
+ "tmct",
629
641
  // presentation frames — the keyword-spotting strategy's blind spot: the
630
642
  // compositional grammar skips these as FRAME_WORDS, but "show me what imports X"
631
643
  // otherwise decomposes (via keyword-spot) to ask{subject:"show me"}. Stripping