@polycode-projects/seonix 0.2.1 → 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.
package/src/ask-vocab.mjs CHANGED
@@ -35,8 +35,9 @@ export const RELATIONS = {
35
35
  imports: {
36
36
  comment: "Module -> Module: subject's import graph references object (usesComplexType).",
37
37
  verbs: [
38
- // formal/neutral
39
- "couples to", "couple to", "uses", "use", "depends on", "imports", "import",
38
+ // formal/neutral ("uses"/"use" moved to the `uses` union family, 2026-07-02 —
39
+ // "uses code from" stays here: its phrasing is specifically import-flavored)
40
+ "couples to", "couple to", "depends on", "imports", "import",
40
41
  "relies on", "rely on", "requires", "require", "references", "reference",
41
42
  "pulls in", "pull in", "built on", "builds on", "build on", "uses code from",
42
43
  // casual/colloquial
@@ -46,6 +47,21 @@ export const RELATIONS = {
46
47
  "importing",
47
48
  ],
48
49
  },
50
+ // "uses" is a QUERY-side union family, not a stored predicate (2026-07-02 query
51
+ // families): "what uses X" honestly means BOTH the import graph and the call
52
+ // graph, so ask.mjs traverses it as imports + calls + callsSymbol together
53
+ // (KIND_UNIONS there). The verbs moved here FROM imports — "which modules use X"
54
+ // still answers with the importing modules (the asked Module grain filters the
55
+ // union down to module-grain subjects), and "what uses <function>" now also
56
+ // reaches the symbol-grain callers instead of silently ignoring them.
57
+ uses: {
58
+ comment: "query-side union: imports (Module->Module) + calls (Module->Module) + callsSymbol (fn->fn).",
59
+ verbs: [
60
+ "uses", "use", "used by", "makes use of", "make use of",
61
+ // gerund (g-drop normalization — §3.5)
62
+ "using",
63
+ ],
64
+ },
49
65
  calls: {
50
66
  comment: "Function/Method -> Function/Class (symbol-grain) or Module -> Module (coarse): subject invokes object.",
51
67
  verbs: [
@@ -104,6 +120,27 @@ export const RELATIONS = {
104
120
  "was changed in", "were changed in", "was edited in", "were edited in",
105
121
  "was modified by", "were modified by", "was tweaked in", "were tweaked in",
106
122
  "got changed in", "got edited in",
123
+ // commit-question forms (2026-07-02, viewer commit-chat fix): the same touch
124
+ // relation asked from the commit's side — "which changes touch commit <sha>",
125
+ // "what did commit <sha> touch", "which functions changed in <sha>", "which
126
+ // changes landed in commit <sha>", "what was touched by commit <sha>". Bare
127
+ // "touch" completes the touched/touches pair for the "did … touch" auxiliary
128
+ // form; the "by"/"in" phrases are the passive/locative counterparts of forms
129
+ // already above (curated per register spread, not a thesaurus dump).
130
+ "touch", "touched by", "modified by", "changed by", "changed in",
131
+ "landed in", "land in",
132
+ // contents-of-a-commit forms (2026-07-02, operator screenshot: "what was in
133
+ // commit <sha>" missed on the live site). "was in"/"went into" only read as
134
+ // touch questions when the object is a commit — the sha-shaped object keeps
135
+ // them from firing on structural questions ("is X in the graph" has no verb
136
+ // match anyway). Judgment call: "is in" omitted — too generic without the
137
+ // past-tense anchor and risks matching containment phrasings.
138
+ "was in", "were in", "went into", "included in",
139
+ // when-question forms (2026-07-02 query families): "when was X last
140
+ // updated/edited" — bare past participles that only read naturally in the
141
+ // temporal shape; the when template routes them, but they are ordinary
142
+ // touches verbs so "which modules were updated ..." keeps working too.
143
+ "updated", "edited",
107
144
  // gerund (g-drop normalization — §3.5)
108
145
  "touching",
109
146
  ],
@@ -118,15 +155,31 @@ export const RELATIONS = {
118
155
  ],
119
156
  },
120
157
  reexports: {
121
- comment: "Module -> Module: subject re-exports a name it imported from object.",
158
+ comment: "Module -> exported symbol: subject's public API surface (__all__/export list).",
122
159
  verbs: [
123
160
  "exports", "export", "re-exports", "re-export", "passes through", "pass through",
161
+ // API-surface phrasing (2026-07-02 query families): "what does <module>
162
+ // expose". Bare "exposed" is NOT listed — the lemma tier maps it here when
163
+ // an adapter is present, and "how does the API get exposed" has no
164
+ // traversal either way (pinned as an honest miss in the tests).
165
+ "exposes", "expose",
124
166
  // gerund (g-drop normalization — §3.5)
125
167
  "exporting",
126
168
  ],
127
169
  },
128
170
  };
129
171
 
172
+ // ---- where/when/mentions markers (2026-07-02 query families) — the location and
173
+ // prose-mention questions carry NO relation verb ("where is X defined", "where is
174
+ // X mentioned"), so ask.mjs routes them by these marker words instead of
175
+ // VERB_TO_KIND. Closed lists, same curation discipline as everything above. ----
176
+
177
+ /** Definition-location markers: "where is X <marker>" (or bare "where is X"). */
178
+ export const WHERE_MARKERS = Object.freeze(["defined", "declared", "located", "implemented"]);
179
+
180
+ /** Prose-mention markers: "where is X <marker>" -> the prose/mentions surface. */
181
+ export const MENTION_MARKERS = Object.freeze(["mentioned", "referenced"]);
182
+
130
183
  /** relation token -> flat verb-phrase list, the shape ask.mjs's VERB_TO_KIND
131
184
  * table needs (phrase -> kind), derived once from RELATIONS. */
132
185
  export const VERB_TO_KIND = Object.freeze(
@@ -142,6 +195,18 @@ export const ENTITY_TO_TYPE = Object.freeze({
142
195
  module: "Module", modules: "Module", file: "Module", files: "Module",
143
196
  attribute: "Attribute", attributes: "Attribute", field: "Attribute", fields: "Attribute",
144
197
  variable: "GlobalVariable", variables: "GlobalVariable", global: "GlobalVariable", globals: "GlobalVariable",
198
+ // "changes" in a touch question ("which changes touch commit <sha>") means the
199
+ // code entities on the other end of the touch edges, at WHATEVER grain the graph
200
+ // recorded — module (touches) and symbol (touchesSymbol) together when the commit
201
+ // is the given side, and the touching commits themselves when a module/symbol is
202
+ // the given side. Mapped to the pseudo-type "Change" (not a node class): ask.mjs's
203
+ // traverse() reads it as a wildcard over the touch traversal's results rather than
204
+ // aliasing it to ONE real class and silently dropping the other grain of the
205
+ // answer. Listed BEFORE commit/commits: findPhrase (ask.mjs) takes the first
206
+ // same-length phrase in table order, so in "which changes touch commit <sha>" the
207
+ // entity slot must consume "changes" and leave "commit <sha>" intact as the
208
+ // object term.
209
+ change: "Change", changes: "Change",
145
210
  commit: "Commit", commits: "Commit",
146
211
  });
147
212
 
@@ -173,6 +238,83 @@ export const CONTRACTIONS = Object.freeze({
173
238
  "gimme": "give me",
174
239
  });
175
240
 
241
+ // ---- misspellings and wrong words (2026-07-02, two-level fuzzy work) — these are
242
+ // CORRECTIONS, not synonyms: the asker typed a broken or incorrect surface form of
243
+ // a word this grammar already owns, and we restore the canonical form BEFORE
244
+ // parsing (normalizeQuery applies both tables like CONTRACTIONS: word-boundary,
245
+ // longest key first, case-insensitive). Synonyms belong in RELATIONS/ENTITY_TO_TYPE;
246
+ // these tables exist so a typo'd or misused word maps to canonical language
247
+ // deterministically, ahead of (and more precisely than) ask.mjs's bounded
248
+ // edit-distance fallback. ask.mjs's correction regex refuses to rewrite a word
249
+ // glued to a dotted extension ("revision.mjs" stays a module name), since
250
+ // WRONG_WORDS entries are real English words that plausibly name modules; a
251
+ // bare standalone token that happens to be a real identifier remains the
252
+ // accepted residual exposure, same as CONTRACTIONS. ----
253
+
254
+ /** Curated common typos of THIS vocabulary's own keywords — entity nouns, relation
255
+ * verbs, and the grammar's anchor words (which/what/does/the): a typo'd anchor
256
+ * kills the anchored templates outright, so anchors earn entries too. Values are
257
+ * always the canonical word. Judgment calls logged: "calss" maps to "class" (the
258
+ * doubled-s slip of "class"), NOT "calls", though both are edit-distance 1 — the
259
+ * exact tie the generic fuzzy tier must refuse to break; a curated table is where
260
+ * that call is made deliberately. "dose" is a real English word, but at a word
261
+ * boundary in this closed question grammar ("dose X import Y") the intent is
262
+ * unambiguous. */
263
+ export const MISSPELLINGS = Object.freeze({
264
+ // entity nouns
265
+ "funtion": "function", "funtions": "functions",
266
+ "fucntion": "function", "fucntions": "functions",
267
+ "functoin": "function", "functoins": "functions",
268
+ "calss": "class", "calsses": "classes", "classs": "class", "clases": "classes",
269
+ "modul": "module", "moduls": "modules",
270
+ "moduel": "module", "moduels": "modules",
271
+ "moudle": "module", "moudles": "modules",
272
+ "methdo": "method", "methdos": "methods",
273
+ "mehtod": "method", "mehtods": "methods",
274
+ "comit": "commit", "comits": "commits",
275
+ "commmit": "commit", "commmits": "commits",
276
+ "varaible": "variable", "varaibles": "variables",
277
+ "varibale": "variable", "varibales": "variables",
278
+ "atribute": "attribute", "atributes": "attributes",
279
+ // relation verbs
280
+ "improt": "import", "improts": "imports",
281
+ "imoprt": "import", "imoprts": "imports",
282
+ "inherts": "inherits", "inheirts": "inherits",
283
+ "extands": "extends", "extneds": "extends",
284
+ "depnds": "depends",
285
+ "touchs": "touches", "tuoches": "touches", "touhced": "touched",
286
+ "chagned": "changed", "chnaged": "changed",
287
+ "chagnes": "changes", "chnages": "changes",
288
+ "calles": "calls",
289
+ "exprot": "export", "exprots": "exports",
290
+ "tets": "tests",
291
+ // grammar anchor words
292
+ "whcih": "which", "wich": "which", "whihc": "which",
293
+ "waht": "what",
294
+ "dose": "does", "doess": "does",
295
+ "teh": "the",
296
+ });
297
+
298
+ /** Words used INCORRECTLY but with clear intent, mapped to the canonical schema
299
+ * term — used like synonyms by the asker, but they are corrections of usage, not
300
+ * alternative names (which is why they live here and not in ENTITY_TO_TYPE).
301
+ * Only mapped where intent is unambiguous in a code-graph question; words
302
+ * deliberately NOT mapped are logged in the omitted-on-purpose block at the end
303
+ * of this file. */
304
+ export const WRONG_WORDS = Object.freeze({
305
+ // neither a folder nor a directory grain exists in this graph — in "which
306
+ // folders import X" the only honest referent is the module/file grain.
307
+ "folder": "module", "folders": "modules",
308
+ "directory": "module", "directories": "modules",
309
+ // unambiguous abbreviation of an entity noun this grammar owns
310
+ "func": "function", "funcs": "functions",
311
+ // VCS terms whose canonical schema class here is Commit
312
+ "changeset": "commit", "changesets": "commits",
313
+ "revision": "commit", "revisions": "commits",
314
+ // code-graph "property" is the Attribute grain in this schema
315
+ "property": "attribute", "properties": "attributes",
316
+ });
317
+
176
318
  /** Trailing g-drop ("callin'", "hittin'") — a plain suffix restore, not a
177
319
  * lemmatiser: -in' -> -ing, applied per-word during normalization. The
178
320
  * apostrophe is REQUIRED (not optional): bare "-in" endings with no
@@ -223,6 +365,27 @@ export const NEGATION_FRAMES = Object.freeze([
223
365
  { re: /\b(?:nobody|nothing|no one)\s+(\S.*?)(?:,?\s+does\s+it\??|,?\s+do\s+they\??)?$/i, to: (m) => `what ${m[1]}` },
224
366
  ]);
225
367
 
368
+ // ---- commit-content frames (2026-07-02, operator screenshot: "what was in commit
369
+ // ef74e44e25c8" missed on the live site) — "what was/is in commit <sha>", "what's
370
+ // in <sha>" (the contraction table has already expanded "what's" by the time
371
+ // frames run), "what went into <sha>", "what made it into commit <sha>" all mean
372
+ // the canonical commit-subject question "what did <sha> touch", so they are
373
+ // REWRITTEN to it before either parse strategy runs: the same mechanism and scope
374
+ // discipline as NEGATION_FRAMES (a small closed pattern set, first match wins),
375
+ // which also makes both strategies parse the family for free. The sha-shaped tail
376
+ // is REQUIRED so these frames only ever fire on an actual commit reference: over a
377
+ // non-sha object ("what was in walk.mjs") the frame does not match and the text is
378
+ // left for the ordinary grammar to handle as it already does, rather than being
379
+ // bent into a commit-subject touches query that would then blank. ----
380
+ export const COMMIT_CONTENT_FRAMES = Object.freeze([
381
+ // "what was in commit ef74e44e25c8" / "what is in ef74e44e" / "what's in commit <sha>"
382
+ { re: /^what\s+(?:is|was|were|are)\s+in\s+((?:commit\s+)?[0-9a-f]{7,40})\??$/i, to: (m) => `what did ${m[1]} touch` },
383
+ // "what went into commit ef74e44e25c8" / casual "what got into <sha>"
384
+ { re: /^what\s+(?:went|got)\s+into\s+((?:commit\s+)?[0-9a-f]{7,40})\??$/i, to: (m) => `what did ${m[1]} touch` },
385
+ // "what made it into commit ef74e44e25c8"
386
+ { re: /^what\s+made\s+it\s+into\s+((?:commit\s+)?[0-9a-f]{7,40})\??$/i, to: (m) => `what did ${m[1]} touch` },
387
+ ]);
388
+
226
389
  // ---- §7 meta-vocabulary — trigger phrases for the "meta" query shape (asking what a
227
390
  // graph vocabulary term itself means: "what does cochange mean", "what does mgx:
228
391
  // callsSymbol mean"). Deliberately NOT folded into RELATIONS/VERB_TO_KIND: these
@@ -256,3 +419,9 @@ export const META_MEANING_VERBS = Object.freeze([
256
419
  // alongside"), so g-drop normalization has no bare stem to dialectally
257
420
  // contract in the first place; only relations with a genuinely bare-verb
258
421
  // casual form ("call", "touch") needed one.
422
+ // WRONG_WORDS not mapped (judgment calls): "script(s)" (routinely names a real
423
+ // module/identifier — rewriting it could corrupt an object term, and file/files
424
+ // already covers the honest synonym); "package(s)" (a genuinely coarser grain
425
+ // this graph doesn't model — mapping it to module would silently answer a
426
+ // different question than the one asked); "fn" (too short and too often a real
427
+ // identifier fragment to rewrite at a word boundary).