@polycode-projects/the-mechanical-code-talker 2.10.3 → 2.11.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.
Files changed (52) hide show
  1. package/README.md +68 -12
  2. package/bin/tmct.mjs +5 -2
  3. package/corpus/sprites/src/sprite-facts.jsonl +18 -0
  4. package/corpus/worlds/manifest.json +5 -5
  5. package/corpus/worlds/shards/ashcombe-hall.jsonl.gz +0 -0
  6. package/corpus/worlds/src/ashcombe-hall.jsonl +27 -0
  7. package/data/sprites/book-icon.toml +12 -0
  8. package/data/sprites/cellar-icon.toml +12 -0
  9. package/data/sprites/drawing-room-icon.toml +13 -0
  10. package/data/sprites/garden-icon.toml +12 -0
  11. package/data/sprites/kitchen-icon.toml +13 -0
  12. package/data/sprites/library-icon.toml +12 -0
  13. package/data/sprites/pan-icon.toml +11 -0
  14. package/data/sprites/study-icon.toml +12 -0
  15. package/package.json +7 -2
  16. package/src/adapters/corpus/wikipedia-live.mjs +182 -26
  17. package/src/adapters/corpus/worlds-pack.mjs +8 -2
  18. package/src/adapters/memory/core.mjs +8 -1
  19. package/src/adapters/toml-config.mjs +6 -0
  20. package/src/domain/cli-verbs.mjs +2 -0
  21. package/src/domain/memory/trust.mjs +32 -2
  22. package/src/domain/sense-split.mjs +203 -0
  23. package/src/domain/worlds-pack.mjs +50 -0
  24. package/src/services/adventure-autoplay.mjs +5 -2
  25. package/src/services/adventure-viz.mjs +301 -33
  26. package/src/services/adventure.mjs +162 -14
  27. package/src/services/chat-page-viz.mjs +341 -197
  28. package/src/services/chat-session.mjs +24 -9
  29. package/src/services/chat.mjs +580 -47
  30. package/src/services/code-explorer-viz.mjs +198 -76
  31. package/src/services/extract-facts.mjs +384 -82
  32. package/src/services/fold.mjs +1 -1
  33. package/src/services/ingest-viz.mjs +637 -0
  34. package/src/services/ledger-viz.mjs +209 -0
  35. package/src/services/memory-panel-viz.mjs +159 -0
  36. package/src/services/research.mjs +266 -0
  37. package/src/services/sentences.mjs +19 -0
  38. package/src/services/session-log-format.mjs +64 -0
  39. package/src/services/sessions.mjs +56 -22
  40. package/src/services/spider-fly-turn.mjs +54 -1
  41. package/src/services/spider-fly-viz.mjs +41 -23
  42. package/src/surfaces/web/adventure-browser-entry.mjs +9 -5
  43. package/src/surfaces/web/chat-browser-entry.mjs +32 -11
  44. package/src/surfaces/web/code-explorer-browser-entry.mjs +27 -11
  45. package/src/surfaces/web/ingest-browser-entry.mjs +208 -0
  46. package/src/surfaces/web/ledger-browser-entry.mjs +24 -5
  47. package/src/surfaces/web/memory-ask-browser.bundle.js +134 -125
  48. package/src/surfaces/web/memory-stats.mjs +53 -0
  49. package/src/tools/definitions.mjs +14 -0
  50. package/src/tools/handlers/index.mjs +2 -0
  51. package/src/tools/handlers/tmct-ingest.mjs +43 -0
  52. package/src/tools/server.mjs +5 -2
package/README.md CHANGED
@@ -120,13 +120,18 @@ tmct> /exit
120
120
 
121
121
  **[Try it live in your browser →](https://polycode-projects.gitlab.io/the-mechanical-code-talker/)**
122
122
  runs the actual query engine client-side. No server, no install. The landing
123
- page answers codebase questions live, and six more pages each ground their
124
- own domain: a full chat seeded with 19,228 facts (the same nine bands as
125
- `npm run init:xl`, capped to a 22.8 MB download), the **memory ledger**
126
- (every fact as a readable sentence; drill by clicking the terms inside), a
127
- Towers-of-Hanoi plan replayed move by move, the spider-and-fly and
128
- text-adventure games, and a sprite gallery whose chat dock answers from
129
- 1,033 generated sprite facts.
123
+ page answers codebase questions live, and eight more pages each ground their
124
+ own domain: a full chat seeded with 32,646 facts (the same nine bands as
125
+ `npm run init:xl`, capped to a 38.7 MB download, 2.1 MB on the wire), the
126
+ **memory ledger** (every fact as a readable sentence; drill by clicking the
127
+ terms inside), the **code explorer** (the same ledger UI refocused on a code
128
+ graph, with a hint rail of suggested next questions), an **ingest page** that
129
+ turns pasted or dropped text into grounded facts and downloads them as
130
+ canonical JSONL, a Towers-of-Hanoi plan replayed move by move, the
131
+ spider-and-fly and text-adventure games, and a sprite gallery whose chat dock
132
+ answers from 1,033 generated sprite facts. The chat page and the ledger take
133
+ the same paste-or-drop text in place; every page that holds a fact store
134
+ exports it as JSONL.
130
135
  The site hosts its own copy of wink-nlp, ships its assets precompressed,
131
136
  and a service worker precaches the big ones, so a second visit works
132
137
  offline. `tmct chat --render spider-fly|adventure|sprites [--output <path>]`
@@ -137,7 +142,7 @@ offline before it deploys. The example graph, the chat seed, the pages, and
137
142
  the engine copy land in `public/`. The in-page chat's query bundle is rebuilt
138
143
  from the same `src/` the CLI runs:
139
144
 
140
- ```bash e2e cwd=repo
145
+ ```bash e2e heavy cwd=repo
141
146
  npm run demo:build # public/: demo graph, memory, ledger page, engine copy
142
147
  npm run build:ask-bundle # the browser query bundle the in-page chat runs
143
148
  ```
@@ -166,6 +171,11 @@ over the same graph. A hint rail suggests the next question from what the graph
166
171
  actually holds — "what does X import", "which functions call Y", "list
167
172
  functions" — so every suggestion resolves to a real answer.
168
173
 
174
+ The identical page also runs as a plain hosted page, over the demo code
175
+ graph — **[try it live →](https://polycode-projects.gitlab.io/the-mechanical-code-talker/code.html)**
176
+ — for a look with nothing to install. The desktop build below is for
177
+ exploring your own repo or graph, which the hosted page cannot reach.
178
+
169
179
  Electron is a dev-only dependency and never ships in the npm package. Because
170
180
  `.npmrc` sets `ignore-scripts=true`, installing it does not fetch the runtime
171
181
  binary; fetch it once, then build and launch:
@@ -469,6 +479,11 @@ cited read-out, CC BY-SA, pinned to the revision it read (provenance
469
479
  `reference:wikipedia-live:<Title>@<revid>`). A failed lookup (no matching
470
480
  title, a timeout, a rate limit) leaves the honest miss byte-identical.
471
481
 
482
+ A live article carries its own source-type prior (`referenceLive`, 0.5) below
483
+ the curated revision-pinned pack (`reference`, 0.6). A fact fetched live never
484
+ outranks the shipped article on the same term, and a fact you teach outranks
485
+ both.
486
+
472
487
  ## How it remembers
473
488
 
474
489
  tmct's memory has two layers, both fed by every parsed request and response and
@@ -479,6 +494,11 @@ by cleaned session logs:
479
494
  - **text blocks under a PageRank-style index**, pulled into context on
480
495
  relevance rather than loaded wholesale.
481
496
 
497
+ Every session also writes its own human-readable transcript,
498
+ `.tmct/session-<id>.md` — a glow-friendly Markdown file with one heading per
499
+ turn, the question as a blockquote, the reply in a fenced block. The
500
+ browser chat page's "export .md" button writes the same shape.
501
+
482
502
  With no graph at all, tmct starts empty and remembers what you tell it. The
483
503
  `.tmct/` graph is created from the conversation. On a first run it seeds the
484
504
  committed vocabulary so it knows what it's talking about from turn one: an
@@ -531,6 +551,17 @@ rather than the code graph. A taught class answers both shapes too: after
531
551
  "dog is a kind of animal", "how many animals are there" counts its members and
532
552
  "list all animals" reads them back, each cited to where it came from.
533
553
 
554
+ When you ask about a term, the read-back shows each "is a kind of" object with
555
+ its own superclass chain: "what is rover" answers "rover is a kind of dog →
556
+ canine → mammal → animal". If one label carries two unrelated senses — you
557
+ taught "rover is a dog" and a corpus row says "rover is a scout" — the answer
558
+ groups by concept ("rover, the dog:" / "rover, the scout:") instead of listing
559
+ two unrelated lines as if they were one thing. The split is deterministic over
560
+ the stored hierarchy: two senses part when a stored disjointness separates
561
+ their ancestors, when their chains never meet, or when they meet only at the
562
+ very top. When the evidence is thin the answer stays a flat list — grouping is
563
+ presentation, and it never retracts or reranks a fact.
564
+
534
565
  Teaching doesn't have to be typed, either. `tmct extract` runs a plain text
535
566
  file through the same recognizer the chat's teach lane uses. Sentences the
536
567
  recognizer grounds become fact rows; everything else is skipped and counted,
@@ -551,6 +582,20 @@ Pass `--repo <path>` instead to write the recognized facts straight into
551
582
  that repo's memory, or `--out <file.jsonl>` to save the rows. Each one
552
583
  carries an `extracted:<file>` provenance tag at its own trust tier.
553
584
 
585
+ `--optimistic` adds a second, lower-trust tier over the sentences the strict
586
+ recognizer skips: a copula or a known relation verb flanked by two nouns
587
+ becomes a candidate triple, stored under its own `optimistic-extract:<file>`
588
+ provenance (prior 0.35, below every curated pack) with no operator tag riding
589
+ alongside — so a fuzzy guess can never corroborate a curated fact. It is an
590
+ attempt, not full NLU: a sentence with no clean pair yields nothing.
591
+ `--canonical` prints each grounded fact as a triple, noting how each endpoint
592
+ already links into the store.
593
+
594
+ The same pipeline is one library seam, `ingestText(text, options)` (exported
595
+ as `@polycode-projects/the-mechanical-code-talker/ingest`), and one cold tool,
596
+ `tmct_ingest` — so a browser page, a script, or a tool-calling agent can ground
597
+ text without the CLI.
598
+
554
599
  ### Provenance and trust
555
600
 
556
601
  Every fact and text block records **where it came from and when**. Sources are
@@ -571,8 +616,15 @@ provenance** rather than silently picking a winner.
571
616
  batch: a forward-chaining materialisation over the memory's OWL 2 RL rule
572
617
  kernels (the classical syllogism is one of them, and the verb keeps Aristotle's
573
618
  broader sense; see the bibliography) that writes new **entailed** facts. They
574
- are low-trust and retractable, never outranking a stated fact, and this never
575
- runs on the chat's hot path.
619
+ are low-trust and retractable, never outranking a stated fact.
620
+
621
+ The full-store batch is a maintenance job, off the chat's hot path. One bounded
622
+ sibling does run inline: when a learn-on-miss load pulls new facts in (a child
623
+ pack, a reference or live-Wikipedia article), a small focus-scoped pass around
624
+ the loaded term connects those new facts to what's already remembered, so a load
625
+ becomes durable knowledge rather than an island. It shares the same kernels, the
626
+ same `entailed:*` provenance and the same low, retractable trust; only its scope
627
+ and budget shrink.
576
628
 
577
629
  ## Install & use
578
630
 
@@ -711,6 +763,9 @@ above — the same teach recognizer, reading a file instead of your typing:
711
763
  [--repo <abs>] write the facts into that repo's own tmct memory; without
712
764
  it nothing on disk is mutated and the facts print as JSONL
713
765
  [--out <file.jsonl>] write that JSONL to a file instead of stdout
766
+ [--optimistic] also run a lower-trust fuzzy tier over the sentences the
767
+ strict recognizer skips; candidates rank below every curated pack
768
+ [--canonical] print each grounded fact as a triple linked into the store
714
769
  ```
715
770
 
716
771
  `tmct extend --validate` checks a third-party extension pack's declared resources
@@ -814,7 +869,7 @@ the wordnet-xl corpus (~72,000 facts); `init:xxl` swaps wordnet-xl for the
814
869
  full WordNet slice plus namenet (~239,000 facts, the biggest committed
815
870
  vocabulary — expect its imports to take a minute). The xl chain, spelled out:
816
871
 
817
- ```bash e2e
872
+ ```bash e2e heavy
818
873
  npx tmct init --persona-size large # npm run init:xl runs this whole chain from a clone
819
874
  npx tmct import --corpus seon
820
875
  npx tmct import --corpus conceptnet
@@ -1009,7 +1064,7 @@ loads a repo's graph into a `{ dispatch, resolve, graph }` context,
1009
1064
 
1010
1065
  ## The tool surface
1011
1066
 
1012
- Everything above runs on the same 24 tools. Each one is read-only, answers one question in a single call, and returns bounded output. None of them calls a model. A tool that cannot ground an answer says so — the same honest miss you get everywhere else in tmct.
1067
+ Everything above runs on the same 25 tools. Each one is read-only, answers one question in a single call, and returns bounded output. None of them calls a model. A tool that cannot ground an answer says so — the same honest miss you get everywhere else in tmct.
1013
1068
 
1014
1069
  Three of them are **hot**: their schemas stay resident, so an agent driving tmct sees them every turn and reaches for one call instead of a Read/Grep loop.
1015
1070
 
@@ -1082,6 +1137,7 @@ The remaining tools are **cold**: still served, but not billed to an agent every
1082
1137
  | `tmct_cochanges` | Modules that historically change in the same commit as a symbol's module (git co-change). | `symbol` (required) |
1083
1138
  | `tmct_context_more` | The bundle sections a lean tmct_context omitted (siblings / tests / cochange / class members / re-exports). | `symbol` (required) |
1084
1139
  | `tmct_export` | Every stored memory fact as JSONL (subject/predicate/object/provenance) — the shape `tmct extract` emits, for backup or audit. | none |
1140
+ | `tmct_ingest` | Ground plain text into memory facts with the same deterministic recognizer the chat teach lane uses — the strict tier, plus an optional lower-trust fuzzy tier — and report the canonical triples. | `text` (required), `optimistic` |
1085
1141
 
1086
1142
  Add `repo_path` to any of them to point at a repository other than the working directory. `tmct init` also writes this catalog, with a worked invocation per tool, to `.tmct/TOOLS.md` inside the repo it indexed.
1087
1143
 
package/bin/tmct.mjs CHANGED
@@ -55,7 +55,7 @@ Usage:
55
55
  ${renderUsage()}
56
56
 
57
57
  On a terminal, chat opens the full-screen TUI; piped input gets the plain shell.
58
- In chat: /help lists slash-commands; /exit leaves. Session log → <repo>/.tmct/session-<id>.log.
58
+ In chat: /help lists slash-commands; /exit leaves. Session log → <repo>/.tmct/session-<id>.md.
59
59
 
60
60
  Shared graph-path precedence (chat/serve/cli; see src/services/cli-args.mjs): --graph flag(s) >
61
61
  TMCT_GRAPH_FILE env > tmct.toml graph_file/graph_files > --repo-derived
@@ -266,7 +266,10 @@ async function runCliMode() {
266
266
  }
267
267
  const config = await configFor(args.repo_path);
268
268
  try {
269
- const text = await dispatchTool(sub, args, { config });
269
+ // The recognizer seam a tool like tmct_ingest needs: injected here (bin
270
+ // sits above the service layer) rather than imported by the tool layer.
271
+ const { ingestText } = await import("../src/services/extract-facts.mjs");
272
+ const text = await dispatchTool(sub, args, { config, ingest: ingestText });
270
273
  process.stdout.write(text + "\n");
271
274
  } catch (e) {
272
275
  process.stderr.write(`tmct: ${e?.message || e}\n`);
@@ -19,6 +19,7 @@
19
19
  {"subject":"birthday sprite","predicate":"rdf:type","object":"sprite class"}
20
20
  {"subject":"boat sprite","predicate":"rdf:type","object":"sprite class"}
21
21
  {"subject":"body of water sprite","predicate":"rdf:type","object":"sprite class"}
22
+ {"subject":"book sprite","predicate":"rdf:type","object":"sprite class"}
22
23
  {"subject":"boss sprite","predicate":"rdf:type","object":"sprite class"}
23
24
  {"subject":"boy sprite","predicate":"rdf:type","object":"sprite class"}
24
25
  {"subject":"bread sprite","predicate":"rdf:type","object":"sprite class"}
@@ -31,6 +32,7 @@
31
32
  {"subject":"car sprite","predicate":"rdf:type","object":"sprite class"}
32
33
  {"subject":"castle sprite","predicate":"rdf:type","object":"sprite class"}
33
34
  {"subject":"cat sprite","predicate":"rdf:type","object":"sprite class"}
35
+ {"subject":"cellar sprite","predicate":"rdf:type","object":"sprite class"}
34
36
  {"subject":"chair sprite","predicate":"rdf:type","object":"sprite class"}
35
37
  {"subject":"champion sprite","predicate":"rdf:type","object":"sprite class"}
36
38
  {"subject":"cheese sprite","predicate":"rdf:type","object":"sprite class"}
@@ -52,6 +54,7 @@
52
54
  {"subject":"dinner sprite","predicate":"rdf:type","object":"sprite class"}
53
55
  {"subject":"doctor sprite","predicate":"rdf:type","object":"sprite class"}
54
56
  {"subject":"dog sprite","predicate":"rdf:type","object":"sprite class"}
57
+ {"subject":"drawing-room sprite","predicate":"rdf:type","object":"sprite class"}
55
58
  {"subject":"dress sprite","predicate":"rdf:type","object":"sprite class"}
56
59
  {"subject":"drink sprite","predicate":"rdf:type","object":"sprite class"}
57
60
  {"subject":"driver sprite","predicate":"rdf:type","object":"sprite class"}
@@ -128,6 +131,7 @@
128
131
  {"subject":"office sprite","predicate":"rdf:type","object":"sprite class"}
129
132
  {"subject":"officer sprite","predicate":"rdf:type","object":"sprite class"}
130
133
  {"subject":"owl sprite","predicate":"rdf:type","object":"sprite class"}
134
+ {"subject":"pan sprite","predicate":"rdf:type","object":"sprite class"}
131
135
  {"subject":"parent sprite","predicate":"rdf:type","object":"sprite class"}
132
136
  {"subject":"park sprite","predicate":"rdf:type","object":"sprite class"}
133
137
  {"subject":"person sprite","predicate":"rdf:type","object":"sprite class"}
@@ -168,6 +172,7 @@
168
172
  {"subject":"stranger sprite","predicate":"rdf:type","object":"sprite class"}
169
173
  {"subject":"street sprite","predicate":"rdf:type","object":"sprite class"}
170
174
  {"subject":"student sprite","predicate":"rdf:type","object":"sprite class"}
175
+ {"subject":"study sprite","predicate":"rdf:type","object":"sprite class"}
171
176
  {"subject":"sugar sprite","predicate":"rdf:type","object":"sprite class"}
172
177
  {"subject":"summer sprite","predicate":"rdf:type","object":"sprite class"}
173
178
  {"subject":"sun sprite","predicate":"rdf:type","object":"sprite class"}
@@ -198,26 +203,34 @@
198
203
  {"subject":"writer sprite","predicate":"rdf:type","object":"sprite class"}
199
204
  {"subject":"adventurer sprite","predicate":"mgx:render-at","object":"icon tier"}
200
205
  {"subject":"animal sprite","predicate":"mgx:render-at","object":"icon tier"}
206
+ {"subject":"book sprite","predicate":"mgx:render-at","object":"icon tier"}
201
207
  {"subject":"butler sprite","predicate":"mgx:render-at","object":"icon tier"}
202
208
  {"subject":"cabinet sprite","predicate":"mgx:render-at","object":"icon tier"}
209
+ {"subject":"cellar sprite","predicate":"mgx:render-at","object":"icon tier"}
203
210
  {"subject":"container sprite","predicate":"mgx:render-at","object":"icon tier"}
204
211
  {"subject":"cook sprite","predicate":"mgx:render-at","object":"icon tier"}
205
212
  {"subject":"desk sprite","predicate":"mgx:render-at","object":"icon tier"}
206
213
  {"subject":"dog sprite","predicate":"mgx:render-at","object":"icon tier"}
214
+ {"subject":"drawing-room sprite","predicate":"mgx:render-at","object":"icon tier"}
207
215
  {"subject":"egg sprite","predicate":"mgx:render-at","object":"icon tier"}
208
216
  {"subject":"fly sprite","predicate":"mgx:render-at","object":"icon tier"}
209
217
  {"subject":"furniture sprite","predicate":"mgx:render-at","object":"icon tier"}
218
+ {"subject":"garden sprite","predicate":"mgx:render-at","object":"icon tier"}
210
219
  {"subject":"gardener sprite","predicate":"mgx:render-at","object":"icon tier"}
211
220
  {"subject":"housekeeper sprite","predicate":"mgx:render-at","object":"icon tier"}
212
221
  {"subject":"key sprite","predicate":"mgx:render-at","object":"icon tier"}
222
+ {"subject":"kitchen sprite","predicate":"mgx:render-at","object":"icon tier"}
213
223
  {"subject":"lamp sprite","predicate":"mgx:render-at","object":"icon tier"}
214
224
  {"subject":"letter sprite","predicate":"mgx:render-at","object":"icon tier"}
225
+ {"subject":"library sprite","predicate":"mgx:render-at","object":"icon tier"}
226
+ {"subject":"pan sprite","predicate":"mgx:render-at","object":"icon tier"}
215
227
  {"subject":"person sprite","predicate":"mgx:render-at","object":"icon tier"}
216
228
  {"subject":"poodle sprite","predicate":"mgx:render-at","object":"icon tier"}
217
229
  {"subject":"portable sprite","predicate":"mgx:render-at","object":"icon tier"}
218
230
  {"subject":"portrait sprite","predicate":"mgx:render-at","object":"icon tier"}
219
231
  {"subject":"room sprite","predicate":"mgx:render-at","object":"icon tier"}
220
232
  {"subject":"spider sprite","predicate":"mgx:render-at","object":"icon tier"}
233
+ {"subject":"study sprite","predicate":"mgx:render-at","object":"icon tier"}
221
234
  {"subject":"adult sprite","predicate":"mgx:render-at","object":"sprite tier"}
222
235
  {"subject":"adventurer sprite","predicate":"mgx:render-at","object":"sprite tier"}
223
236
  {"subject":"airport sprite","predicate":"mgx:render-at","object":"sprite tier"}
@@ -239,6 +252,7 @@
239
252
  {"subject":"birthday sprite","predicate":"mgx:render-at","object":"sprite tier"}
240
253
  {"subject":"boat sprite","predicate":"mgx:render-at","object":"sprite tier"}
241
254
  {"subject":"body of water sprite","predicate":"mgx:render-at","object":"sprite tier"}
255
+ {"subject":"book sprite","predicate":"mgx:render-at","object":"sprite tier"}
242
256
  {"subject":"boss sprite","predicate":"mgx:render-at","object":"sprite tier"}
243
257
  {"subject":"boy sprite","predicate":"mgx:render-at","object":"sprite tier"}
244
258
  {"subject":"bread sprite","predicate":"mgx:render-at","object":"sprite tier"}
@@ -251,6 +265,7 @@
251
265
  {"subject":"car sprite","predicate":"mgx:render-at","object":"sprite tier"}
252
266
  {"subject":"castle sprite","predicate":"mgx:render-at","object":"sprite tier"}
253
267
  {"subject":"cat sprite","predicate":"mgx:render-at","object":"sprite tier"}
268
+ {"subject":"cellar sprite","predicate":"mgx:render-at","object":"sprite tier"}
254
269
  {"subject":"chair sprite","predicate":"mgx:render-at","object":"sprite tier"}
255
270
  {"subject":"champion sprite","predicate":"mgx:render-at","object":"sprite tier"}
256
271
  {"subject":"cheese sprite","predicate":"mgx:render-at","object":"sprite tier"}
@@ -272,6 +287,7 @@
272
287
  {"subject":"dinner sprite","predicate":"mgx:render-at","object":"sprite tier"}
273
288
  {"subject":"doctor sprite","predicate":"mgx:render-at","object":"sprite tier"}
274
289
  {"subject":"dog sprite","predicate":"mgx:render-at","object":"sprite tier"}
290
+ {"subject":"drawing-room sprite","predicate":"mgx:render-at","object":"sprite tier"}
275
291
  {"subject":"dress sprite","predicate":"mgx:render-at","object":"sprite tier"}
276
292
  {"subject":"drink sprite","predicate":"mgx:render-at","object":"sprite tier"}
277
293
  {"subject":"driver sprite","predicate":"mgx:render-at","object":"sprite tier"}
@@ -348,6 +364,7 @@
348
364
  {"subject":"office sprite","predicate":"mgx:render-at","object":"sprite tier"}
349
365
  {"subject":"officer sprite","predicate":"mgx:render-at","object":"sprite tier"}
350
366
  {"subject":"owl sprite","predicate":"mgx:render-at","object":"sprite tier"}
367
+ {"subject":"pan sprite","predicate":"mgx:render-at","object":"sprite tier"}
351
368
  {"subject":"parent sprite","predicate":"mgx:render-at","object":"sprite tier"}
352
369
  {"subject":"park sprite","predicate":"mgx:render-at","object":"sprite tier"}
353
370
  {"subject":"person sprite","predicate":"mgx:render-at","object":"sprite tier"}
@@ -388,6 +405,7 @@
388
405
  {"subject":"stranger sprite","predicate":"mgx:render-at","object":"sprite tier"}
389
406
  {"subject":"street sprite","predicate":"mgx:render-at","object":"sprite tier"}
390
407
  {"subject":"student sprite","predicate":"mgx:render-at","object":"sprite tier"}
408
+ {"subject":"study sprite","predicate":"mgx:render-at","object":"sprite tier"}
391
409
  {"subject":"sugar sprite","predicate":"mgx:render-at","object":"sprite tier"}
392
410
  {"subject":"summer sprite","predicate":"mgx:render-at","object":"sprite tier"}
393
411
  {"subject":"sun sprite","predicate":"mgx:render-at","object":"sprite tier"}
@@ -3,7 +3,7 @@
3
3
  "generated": "by scripts/build-worlds-pack.mjs from corpus/worlds/src/",
4
4
  "counts": {
5
5
  "worlds": 2,
6
- "facts": 548,
6
+ "facts": 575,
7
7
  "rules": 19
8
8
  },
9
9
  "budgets": {
@@ -14,8 +14,8 @@
14
14
  "sources": [
15
15
  {
16
16
  "file": "src/ashcombe-hall.jsonl",
17
- "bytes": 8795,
18
- "sha256": "771ed4e7a5e9046235e8dc193b2696f83e6ef92a556ca1ca126dd070927912ce"
17
+ "bytes": 11754,
18
+ "sha256": "18e58700a59ae3876dd4f949ede7fa17e19f3a8c2dc8ae4644dbddf98c138524"
19
19
  },
20
20
  {
21
21
  "file": "src/spider-fly.jsonl",
@@ -31,8 +31,8 @@
31
31
  },
32
32
  {
33
33
  "file": "shards/ashcombe-hall.jsonl.gz",
34
- "bytes": 1020,
35
- "sha256": "1255ea52149c3941fafd4ee462239bae8e10175c8e7db2e54c2c2dc1a2e0d924"
34
+ "bytes": 1292,
35
+ "sha256": "a8e61a93ebf992a8b87221c5a9a9f53bf92b7798cee86fb9d6915a1844d960dd"
36
36
  },
37
37
  {
38
38
  "file": "shards/spider-fly.jsonl.gz",
@@ -54,6 +54,33 @@
54
54
  {"world":"ashcombe-hall","kind":"fact","subject":"ashcombe hall","predicate":"mgx:hasA","object":"6 rooms"}
55
55
  {"world":"ashcombe-hall","kind":"fact","subject":"player","predicate":"mgx:hasA","object":"satchel"}
56
56
  {"world":"ashcombe-hall","kind":"fact","subject":"satchel","predicate":"mgx:usedFor","object":"carrying what the player takes"}
57
+ {"world":"ashcombe-hall","kind":"fact","subject":"room","predicate":"rdfs:subClassOf","object":"space"}
58
+ {"world":"ashcombe-hall","kind":"fact","subject":"outdoor-space","predicate":"rdfs:subClassOf","object":"space"}
59
+ {"world":"ashcombe-hall","kind":"fact","subject":"underground-space","predicate":"rdfs:subClassOf","object":"space"}
60
+ {"world":"ashcombe-hall","kind":"fact","subject":"garden","predicate":"rdf:type","object":"outdoor-space"}
61
+ {"world":"ashcombe-hall","kind":"fact","subject":"cellar","predicate":"rdf:type","object":"underground-space"}
62
+ {"world":"ashcombe-hall","kind":"fact","subject":"portrait","predicate":"rdfs:subClassOf","object":"painting"}
63
+ {"world":"ashcombe-hall","kind":"fact","subject":"painting","predicate":"mgx:default-plane","object":"wall"}
64
+ {"world":"ashcombe-hall","kind":"fact","subject":"furniture","predicate":"mgx:default-plane","object":"floor"}
65
+ {"world":"ashcombe-hall","kind":"fact","subject":"portable","predicate":"mgx:default-plane","object":"floor"}
66
+ {"world":"ashcombe-hall","kind":"fact","subject":"lamp","predicate":"mgx:on-top-of","object":"desk"}
67
+ {"world":"ashcombe-hall","kind":"fact","subject":"book","predicate":"rdfs:subClassOf","object":"portable"}
68
+ {"world":"ashcombe-hall","kind":"fact","subject":"pan","predicate":"rdfs:subClassOf","object":"portable"}
69
+ {"world":"ashcombe-hall","kind":"fact","subject":"library","predicate":"mgx:default-contains","object":"book"}
70
+ {"world":"ashcombe-hall","kind":"fact","subject":"kitchen","predicate":"mgx:default-contains","object":"pan"}
71
+ {"world":"ashcombe-hall","kind":"fact","subject":"gardener","predicate":"mgx:knows-where","object":"letter"}
72
+ {"world":"ashcombe-hall","kind":"fact","subject":"housekeeper","predicate":"mgx:knows-where","object":"key"}
73
+ {"world":"ashcombe-hall","kind":"fact","subject":"butler","predicate":"mgx:knows-objective","object":"letter"}
74
+ {"world":"ashcombe-hall","kind":"fact","subject":"butler","predicate":"mgx:knows-where","object":"housekeeper"}
75
+ {"world":"ashcombe-hall","kind":"fact","subject":"butler","predicate":"mgx:knows-where","object":"cook"}
76
+ {"world":"ashcombe-hall","kind":"fact","subject":"butler","predicate":"mgx:knows-where","object":"gardener"}
77
+ {"world":"ashcombe-hall","kind":"fact","subject":"cook","predicate":"mgx:knows-where","object":"gardener"}
78
+ {"world":"ashcombe-hall","kind":"fact","subject":"gardener","predicate":"mgx:knows-about","object":"garden"}
79
+ {"world":"ashcombe-hall","kind":"fact","subject":"housekeeper","predicate":"mgx:knows-about","object":"study"}
80
+ {"world":"ashcombe-hall","kind":"fact","subject":"butler","predicate":"mgx:knows-about","object":"drawing-room"}
81
+ {"world":"ashcombe-hall","kind":"fact","subject":"cook","predicate":"mgx:knows-about","object":"kitchen"}
82
+ {"world":"ashcombe-hall","kind":"fact","subject":"garden","predicate":"mgx:hasA","object":"old apple tree"}
83
+ {"world":"ashcombe-hall","kind":"fact","subject":"kitchen","predicate":"mgx:usedFor","object":"cooking the hall's meals"}
57
84
  {"world":"ashcombe-hall","kind":"rule","name":"go","ruleKind":"action-signature","slots":{"subjectClass":"adventurer","targetClass":"room"}}
58
85
  {"world":"ashcombe-hall","kind":"rule","name":"go","ruleKind":"action-signature","slots":{"subjectClass":"person","targetClass":"room"}}
59
86
  {"world":"ashcombe-hall","kind":"rule","name":"go","ruleKind":"action-effect","slots":{"predicate":"currently-in","subjectRole":"subject","objectRole":"target"}}
@@ -0,0 +1,12 @@
1
+ # book — the library's default portable: a closed hardback seen spine-on, the
2
+ # cover boards and a page block, so a taken book reads as its own thing rather
3
+ # than the generic portable box.
4
+ classes = ["book"]
5
+ svg = """
6
+ <svg viewBox="0 0 24 24" aria-hidden="true">
7
+ <path d="M6 3 H18 A1 1 0 0 1 19 4 V20 A1 1 0 0 1 18 21 H6 Z" fill="currentColor"/>
8
+ <rect x="6" y="3" width="1.8" height="18" fill="currentColor" opacity="0.4"/>
9
+ <path d="M9.4 3 V21" stroke="currentColor" stroke-width="0.5" opacity="0.35"/>
10
+ <path d="M11 7.5 H17 M11 10 H17 M11 12.5 H15" stroke="#000000" stroke-width="0.5" opacity="0.3"/>
11
+ </svg>
12
+ """
@@ -0,0 +1,12 @@
1
+ # cellar — an underground space: a room box with a stair stepping down and
2
+ # stone coursing, so the room-kind icon reads as below ground rather than a
3
+ # plain room, matching the underground border.
4
+ classes = ["cellar"]
5
+ svg = """
6
+ <svg viewBox="0 0 24 24" aria-hidden="true">
7
+ <rect x="3" y="3" width="18" height="18" rx="1" fill="currentColor" opacity="0.14"/>
8
+ <rect x="3" y="3" width="18" height="18" rx="1" fill="none" stroke="currentColor" stroke-width="1.6"/>
9
+ <path d="M6 8 H10 V11 H14 V14 H18 V18 H6 Z" fill="currentColor" opacity="0.55"/>
10
+ <path d="M3 12 H21 M3 16.5 H21" stroke="currentColor" stroke-width="0.5" opacity="0.4"/>
11
+ </svg>
12
+ """
@@ -0,0 +1,13 @@
1
+ # drawing-room — a room floor plan marked by a framed picture on the wall (the
2
+ # portrait hangs here), so the room-kind icon reads as the drawing room rather
3
+ # than a plain room.
4
+ classes = ["drawing-room"]
5
+ svg = """
6
+ <svg viewBox="0 0 24 24" aria-hidden="true">
7
+ <rect x="3" y="3" width="18" height="18" rx="1" fill="currentColor" opacity="0.14"/>
8
+ <rect x="3" y="3" width="18" height="18" rx="1" fill="none" stroke="currentColor" stroke-width="1.6"/>
9
+ <rect x="8.5" y="7" width="7" height="6" rx="0.4" fill="none" stroke="currentColor" stroke-width="1.3"/>
10
+ <circle cx="12" cy="9.4" r="1.1" fill="currentColor" opacity="0.7"/>
11
+ <path d="M9.6 12.4 C9.6 10.9 10.6 10 12 10 C13.4 10 14.4 10.9 14.4 12.4 Z" fill="currentColor" opacity="0.7"/>
12
+ </svg>
13
+ """
@@ -0,0 +1,12 @@
1
+ # garden — an outdoor space, so no room box: a tree over a ground line reads
2
+ # as open air rather than an interior, matching the outdoor room-kind border.
3
+ classes = ["garden"]
4
+ svg = """
5
+ <svg viewBox="0 0 24 24" aria-hidden="true">
6
+ <path d="M3 20 H21" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
7
+ <path d="M12 20 V12" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
8
+ <circle cx="12" cy="8.5" r="5" fill="currentColor" opacity="0.7"/>
9
+ <circle cx="7.5" cy="17" r="1" fill="currentColor" opacity="0.5"/>
10
+ <circle cx="16.5" cy="17" r="1" fill="currentColor" opacity="0.5"/>
11
+ </svg>
12
+ """
@@ -0,0 +1,13 @@
1
+ # kitchen — a room floor plan marked by a stove with two burners, the same
2
+ # distinguishing cue the large tier uses, so the room-kind icon reads as a
3
+ # kitchen rather than a plain room.
4
+ classes = ["kitchen"]
5
+ svg = """
6
+ <svg viewBox="0 0 24 24" aria-hidden="true">
7
+ <rect x="3" y="3" width="18" height="18" rx="1" fill="currentColor" opacity="0.14"/>
8
+ <rect x="3" y="3" width="18" height="18" rx="1" fill="none" stroke="currentColor" stroke-width="1.6"/>
9
+ <rect x="8" y="10" width="8" height="7" rx="0.6" fill="none" stroke="currentColor" stroke-width="1.2"/>
10
+ <circle cx="10.5" cy="12.6" r="1" fill="currentColor" opacity="0.7"/>
11
+ <circle cx="13.5" cy="12.6" r="1" fill="currentColor" opacity="0.7"/>
12
+ </svg>
13
+ """
@@ -0,0 +1,12 @@
1
+ # library — a room floor plan marked by an open book, so the room-kind icon
2
+ # reads as a library rather than a plain room: the washed square is room.toml's
3
+ # own shape, the two-page V is the same open-book cue the large tier uses.
4
+ classes = ["library"]
5
+ svg = """
6
+ <svg viewBox="0 0 24 24" aria-hidden="true">
7
+ <rect x="3" y="3" width="18" height="18" rx="1" fill="currentColor" opacity="0.14"/>
8
+ <rect x="3" y="3" width="18" height="18" rx="1" fill="none" stroke="currentColor" stroke-width="1.6"/>
9
+ <path d="M12 9 C10.4 7.9 8.2 7.6 6.4 8.1 V15.6 C8.2 15.1 10.4 15.4 12 16.5 C13.6 15.4 15.8 15.1 17.6 15.6 V8.1 C15.8 7.6 13.6 7.9 12 9 Z" fill="currentColor" opacity="0.75"/>
10
+ <path d="M12 9 V16.5" stroke="currentColor" stroke-width="0.5" opacity="0.5"/>
11
+ </svg>
12
+ """
@@ -0,0 +1,11 @@
1
+ # pan — the kitchen's default portable: a frying pan seen from above with a
2
+ # long handle, so a taken pan reads as its own thing rather than the generic
3
+ # portable box.
4
+ classes = ["pan"]
5
+ svg = """
6
+ <svg viewBox="0 0 24 24" aria-hidden="true">
7
+ <circle cx="10" cy="14" r="6" fill="currentColor"/>
8
+ <circle cx="10" cy="14" r="3.6" fill="currentColor" opacity="0.35"/>
9
+ <rect x="15" y="13" width="7" height="2" rx="1" fill="currentColor"/>
10
+ </svg>
11
+ """
@@ -0,0 +1,12 @@
1
+ # study — a room floor plan marked by a writing desk against one wall, so the
2
+ # room-kind icon reads as the study you start in rather than a plain room.
3
+ classes = ["study"]
4
+ svg = """
5
+ <svg viewBox="0 0 24 24" aria-hidden="true">
6
+ <rect x="3" y="3" width="18" height="18" rx="1" fill="currentColor" opacity="0.14"/>
7
+ <rect x="3" y="3" width="18" height="18" rx="1" fill="none" stroke="currentColor" stroke-width="1.6"/>
8
+ <rect x="7" y="11" width="10" height="2.4" fill="currentColor" opacity="0.7"/>
9
+ <path d="M8 13.4 V17 M16 13.4 V17" stroke="currentColor" stroke-width="1.2"/>
10
+ <rect x="9.6" y="7.6" width="4.8" height="3" fill="none" stroke="currentColor" stroke-width="1"/>
11
+ </svg>
12
+ """
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polycode-projects/the-mechanical-code-talker",
3
- "version": "2.10.3",
3
+ "version": "2.11.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.",
@@ -45,6 +45,7 @@
45
45
  "./plan": "./src/domain/router/drive.mjs",
46
46
  "./generateCompletion": "./src/services/completions.mjs",
47
47
  "./createCompletionsGraphAdapter": "./src/services/completions.mjs",
48
+ "./ingest": "./src/services/extract-facts.mjs",
48
49
  "./repository-interface": "./src/adapters/repository-interface.mjs",
49
50
  "./conformance": "./src/tools/conformance.mjs"
50
51
  },
@@ -85,8 +86,11 @@
85
86
  "test": "node --disable-warning=ExperimentalWarning --test --test-concurrency=8 \"test/**/*.test.mjs\"",
86
87
  "test:smoke": "node --disable-warning=ExperimentalWarning --test test/smoke/*.test.mjs",
87
88
  "test:fast": "node --disable-warning=ExperimentalWarning --test --test-concurrency=8 test/smoke/*.test.mjs test/fast/*.test.mjs test/tools/ask.test.mjs test/tools/server.test.mjs test/estate/import-layers.test.mjs",
88
- "test:e2e": "node --disable-warning=ExperimentalWarning --test \"e2e/**/*.test.mjs\"",
89
+ "test:e2e": "node --disable-warning=ExperimentalWarning --test \"e2e/*.test.mjs\"",
90
+ "test:e2e:heavy": "node --disable-warning=ExperimentalWarning --test \"e2e/heavy/*.test.mjs\"",
91
+ "check:readme": "TMCT_CHECK_README=1 node --disable-warning=ExperimentalWarning --test e2e/readme-examples.test.mjs",
89
92
  "e2e:browsers": "playwright install chromium",
93
+ "gen:screenshots": "node scripts/gen-screenshots.mjs",
90
94
  "check:links": "node scripts/check-links.mjs",
91
95
  "check:pii": "node scripts/pii-lint.mjs",
92
96
  "check:pack": "node scripts/check-pack-manifest.mjs",
@@ -139,6 +143,7 @@
139
143
  "build:spider-fly-bundle": "node scripts/build-spider-fly-bundle.mjs",
140
144
  "build:plan-bundle": "node scripts/build-plan-bundle.mjs",
141
145
  "build:ledger-bundle": "node scripts/build-ledger-bundle.mjs",
146
+ "build:ingest-bundle": "node scripts/build-ingest-bundle.mjs",
142
147
  "build:code-explorer-bundle": "node scripts/build-code-explorer-bundle.mjs",
143
148
  "build:electron": "node scripts/build-electron-app.mjs",
144
149
  "electron": "electron electron/main.mjs",