@polycode-projects/the-mechanical-code-talker 0.6.0 → 0.7.1
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 +31 -3
- package/ROADMAP.md +45 -0
- package/bin/tmct.mjs +8 -2
- package/corpus/conceptnet/README.md +59 -52
- package/corpus/conceptnet/filter-dump.mjs +59 -2
- package/corpus/conceptnet/slice.jsonl +31067 -0
- package/corpus/seon/relations.jsonl +8 -0
- package/data/templates/responses.jsonl +3 -2
- package/package.json +6 -3
- package/src/ask.mjs +2 -2
- package/src/chat.mjs +314 -39
- package/src/concept.mjs +393 -0
- package/src/corpus/conceptnet.mjs +18 -13
- package/src/init.mjs +12 -9
- package/src/interpret/normalize.mjs +42 -0
- package/src/interpret/pipeline.mjs +2 -2
- package/src/memory/core.mjs +84 -0
- package/src/tui/app.mjs +26 -2
package/README.md
CHANGED
|
@@ -49,6 +49,31 @@ under a guard that proves the protected spans came through byte-for-byte. Today
|
|
|
49
49
|
that pass fixes the a/an article defect; broader voice and agreement rules are
|
|
50
50
|
implemented but parked until they earn their place on the benchmark.
|
|
51
51
|
|
|
52
|
+
## How it guides you
|
|
53
|
+
|
|
54
|
+
When you touch a **concept** without asking a precise question — "what is a
|
|
55
|
+
class", "what about imports", "what calls are there" — tmct answers in three
|
|
56
|
+
bands instead of dead-ending:
|
|
57
|
+
|
|
58
|
+
1. the **definition** (a plain-English one-liner: *"A class is a template that
|
|
59
|
+
defines the structure and behaviour of objects."* / *"To import is to bring
|
|
60
|
+
another module's definitions into the current one."*);
|
|
61
|
+
2. **real instances from your graph** — *"In this codebase, for example: Record,
|
|
62
|
+
Task and User (10 classes)"*, or actual edges *"src/core/store.mjs imports
|
|
63
|
+
src/core/model.mjs (18 import edges)"*;
|
|
64
|
+
3. **guided follow-ups** — two or three concrete next questions, each one
|
|
65
|
+
*pre-checked against your graph* so every suggestion is guaranteed to resolve:
|
|
66
|
+
*"Want to go deeper? Try: which classes inherit from Record / what does Task
|
|
67
|
+
contain / where is User defined"*.
|
|
68
|
+
|
|
69
|
+
It fires for both **noun** concepts (class, module, function, method) and
|
|
70
|
+
**relation** concepts (imports, calls, contains, inherits, tests), and only when
|
|
71
|
+
tmct genuinely knows the concept *and* has instances of it — otherwise the honest
|
|
72
|
+
miss stands. The effect is a conversation that drills down from a vague opener to
|
|
73
|
+
a useful answer without ever hitting a wall. Natural phrasings are routed to the
|
|
74
|
+
capability you meant: *"what functions are in Task"* → its members, *"what
|
|
75
|
+
defined saveStore"* → where it's defined.
|
|
76
|
+
|
|
52
77
|
## How it remembers
|
|
53
78
|
|
|
54
79
|
tmct's memory has two layers, both fed by every parsed request and response and
|
|
@@ -60,9 +85,12 @@ by cleaned session logs:
|
|
|
60
85
|
relevance rather than loaded wholesale.
|
|
61
86
|
|
|
62
87
|
With no graph at all, tmct starts empty and remembers what you tell it — the
|
|
63
|
-
`.tmct/` graph is created from the conversation.
|
|
64
|
-
vocabulary
|
|
65
|
-
|
|
88
|
+
`.tmct/` graph is created from the conversation. On a first run it seeds the
|
|
89
|
+
committed vocabulary so it knows what it's talking about from turn one: a curated
|
|
90
|
+
**SEON** software ontology plus the whole filtered **ConceptNet slice**
|
|
91
|
+
(CC-BY-SA 4.0) — every term carries an English definition, so "what is a cache?"
|
|
92
|
+
answers offline, from disk, on turn one. `--ephemeral` (used by the shipped
|
|
93
|
+
`npm run example:*` demos) reads a graph but writes nothing back.
|
|
66
94
|
|
|
67
95
|
### Provenance and trust
|
|
68
96
|
|
package/ROADMAP.md
CHANGED
|
@@ -550,6 +550,51 @@ Repository Interface library-surface work (Phase 8) settling the extraction boun
|
|
|
550
550
|
`PLAN_OSS_ACE_PARSER.md`. Sibling publish-candidates (the bounded-Damerau fuzzy matcher, the
|
|
551
551
|
PageRank+IDF block ranker) may follow the same path if there is demand.
|
|
552
552
|
|
|
553
|
+
## Phase 10 — Conversational competence & onboarding (0.6.0 → 0.7.0)
|
|
554
|
+
|
|
555
|
+
*(Operator-directed, from live new-user testing.)* Once a graph is loaded the engine is strong;
|
|
556
|
+
the weak surfaces were the FIRST RUN and the VAGUE question. This phase makes the miss graceful,
|
|
557
|
+
the empty state honest, and the vague touch a guided answer — realising item 1's "tolerant, guides
|
|
558
|
+
you toward precision" promise on the conversational surface.
|
|
559
|
+
|
|
560
|
+
- **Onboarding UX (shipped 0.6.0):** the grammar wall moved behind `/help` (a short, tailored miss
|
|
561
|
+
instead); intent lanes for memory/teach ("remember that X"), meta/self ("what is this codebase",
|
|
562
|
+
"what do you know"), routed only when a graph query would miss; empty/degenerate-graph
|
|
563
|
+
orientation that distinguishes CODE STRUCTURE (needs a `.tmct/graph.json` via a producer or
|
|
564
|
+
`--repo`; tmct reads graphs, it does not index code) from VOCABULARY (`tmct init`/bootstrap seeds
|
|
565
|
+
concepts); `TMCT_GRAPH_FILE` honoured by chat; slash-optional commands (`stats`≡`/stats`);
|
|
566
|
+
`/memory` explore hooks; up/down-arrow prompt history in the TUI.
|
|
567
|
+
- **Knowledge (shipped 0.6.0 → 0.7.0):** the curated `corpus/seon` ontology — a software-sense
|
|
568
|
+
definition for EVERY lexicon term, language-neutral (Java/C#/Python `class` → one concept); the
|
|
569
|
+
ConceptNet slice quality-filtered (word-sense noise cut) and regrown to ~40k facts; tier-2
|
|
570
|
+
specialised corpuses (aws/python/java) with `tmct init --corpus`; batched `appendFacts` (one
|
|
571
|
+
write, 419s→2.5s) enabling **seed-all** so a fresh repo knows the whole curated vocabulary.
|
|
572
|
+
- **The concept force (shipped 0.7.0):** a vague touch on a concept X, where tmct knows X and has instances,
|
|
573
|
+
answers in three bands — **the definition** (from `corpus/seon`), **the examples** (real code-graph
|
|
574
|
+
+ memory instances of X), and **a soft guided follow-up** ("Want to go deeper?" + 2–3 questions
|
|
575
|
+
built from the real instances × the query shapes valid for that kind, each pre-validated to
|
|
576
|
+
resolve). Applies to NOUN concepts (`what is a class` → define + Base/Widget/Button + drill-ins)
|
|
577
|
+
AND **RELATION concepts** (`what about imports` / `what calls are there` → the verb definition +
|
|
578
|
+
example edges + guided queries), fixing the vague-query dead-ends. Fact rendering is
|
|
579
|
+
de-anthropomorphised (no first-person "i learned:" over-claim — corpus facts read as data +
|
|
580
|
+
provenance; `you told me` stays for operator-asserted facts); listings cap at 32 with a "say
|
|
581
|
+
'more'" pagination that holds the remainder in session state.
|
|
582
|
+
- **Dead-end routing + read-only demos (shipped 0.7.0):** natural drill-down phrasings are routed
|
|
583
|
+
onto the canonical shapes they mean — `what functions are in X` → members-of-class, `what defined
|
|
584
|
+
X` → where-is-X-defined, a no-context `what about X` → the concept/relation force (the discourse
|
|
585
|
+
continuation still wins when there IS a prior answer). `tmct chat --ephemeral` (and the
|
|
586
|
+
`npm run example:*` demos) reads a graph but writes nothing back, so a checked-in example is never
|
|
587
|
+
dirtied by a demo run.
|
|
588
|
+
- **The dialogue-flow loop (`SKILL_CHAT_PLAYTEST.md`, 0.7.0):** a fast, qualitative tuning loop that
|
|
589
|
+
complements the LLM-judge benchmark — Claude plays a curious user, hunts *dead-ends* (walls,
|
|
590
|
+
"unknown qualifier", phrasing-misses, invited follow-ups the engine can't take), fixes them by
|
|
591
|
+
ROUTING to existing capabilities, replays the same conversations until they flow, freezes them as
|
|
592
|
+
regression transcripts, then ratchets the complexity tier. The drill-down transcript above is its
|
|
593
|
+
first frozen fixture (`test/chatflow-drilldown.test.mjs`).
|
|
594
|
+
- **Measured** by the version-matched benchmark (`CHATBENCH_<version>` per `SKILL_TUNING_CYCLE.md`),
|
|
595
|
+
with new graded cells for the miss / empty-graph / concept-touch surfaces so these become
|
|
596
|
+
regression-protected levers, not one-off polish.
|
|
597
|
+
|
|
553
598
|
## Phase LATER — recognized, deferred, not now
|
|
554
599
|
|
|
555
600
|
Features we have deliberately shaped seams for but will not build until the phases above have
|
package/bin/tmct.mjs
CHANGED
|
@@ -34,6 +34,7 @@ software repository. No model calls; no codebase index of its own.
|
|
|
34
34
|
Usage:
|
|
35
35
|
tmct interactive chat (the headline surface)
|
|
36
36
|
tmct chat [--repo <abs>] chat over a specific repo's graph
|
|
37
|
+
[--ephemeral] read the graph but write nothing back (demo/read-only)
|
|
37
38
|
[--plain] force the plain readline shell (the default when
|
|
38
39
|
stdin/stdout is not a terminal)
|
|
39
40
|
tmct memory [--repo <abs>] what tmct remembers: facts, utterances, sessions,
|
|
@@ -267,16 +268,21 @@ async function main() {
|
|
|
267
268
|
const rest = process.argv.slice(3);
|
|
268
269
|
const i = rest.indexOf("--repo");
|
|
269
270
|
const repoPath = i !== -1 ? rest[i + 1] : undefined;
|
|
271
|
+
// `--ephemeral` (used by the shipped `npm run example:*` scripts): read the
|
|
272
|
+
// target graph but write nothing back — no session folded into the committed
|
|
273
|
+
// code graph, no .tmct/memory dropped under it. A demo you can run repeatedly
|
|
274
|
+
// on a checked-in example without ever dirtying it.
|
|
275
|
+
const ephemeral = rest.includes("--ephemeral");
|
|
270
276
|
// The shell gate: a real terminal gets the full-screen Ink TUI; `--plain` or a
|
|
271
277
|
// non-TTY stream (pipes, scripts, the test suite) gets the readline shell. Both
|
|
272
278
|
// drive the same createSession sink — only the drawing differs.
|
|
273
279
|
const plain = rest.includes("--plain") || !process.stdin.isTTY || !process.stdout.isTTY;
|
|
274
280
|
if (plain) {
|
|
275
281
|
const { runChat } = await import("../src/chat.mjs");
|
|
276
|
-
await runChat({ repoPath });
|
|
282
|
+
await runChat({ repoPath, ephemeral });
|
|
277
283
|
} else {
|
|
278
284
|
const { runTui } = await import("../src/tui/app.mjs");
|
|
279
|
-
await runTui({ repoPath });
|
|
285
|
+
await runTui({ repoPath, ephemeral });
|
|
280
286
|
}
|
|
281
287
|
return;
|
|
282
288
|
}
|
|
@@ -15,7 +15,9 @@ see `LICENSE-NOTICE` in this directory for the full attribution.
|
|
|
15
15
|
- **Source:** ConceptNet 5.7.0 assertions dump,
|
|
16
16
|
`https://s3.amazonaws.com/conceptnet/downloads/2019/edges/conceptnet-assertions-5.7.0.csv.gz`
|
|
17
17
|
(published 2019-07-03).
|
|
18
|
-
- **Retrieved + filtered:** 2026-07-04
|
|
18
|
+
- **Retrieved + filtered:** 2026-07-04; **regrown to the ~40k tier-1 target on
|
|
19
|
+
2026-07-05** (same dump, same licence) by widening the tech-seed domain and
|
|
20
|
+
raising the size budget — see "Growing the slice" below.
|
|
19
21
|
- **Why the dump, not the API:** the public API (`api.conceptnet.io`) was
|
|
20
22
|
hard-down (HTTP 502 from its nginx front-end on every request across ~15
|
|
21
23
|
attempts over 10+ minutes on 2026-07-04), so the slice was stream-filtered
|
|
@@ -33,12 +35,16 @@ see `LICENSE-NOTICE` in this directory for the full attribution.
|
|
|
33
35
|
policy: `/r/EtymologicallyRelatedTo`, `/r/EtymologicallyDerivedFrom`,
|
|
34
36
|
`/r/ExternalURL` (etymology noise and link-outs — no consumer in tmct).
|
|
35
37
|
3. **Tech-domain seed terms**: at least one endpoint's bare term is in the
|
|
36
|
-
|
|
38
|
+
tech seed list — the ~90-term base `SEED_TERMS` exported from
|
|
37
39
|
`fetch-slice.mjs` (software, computer, program, code, module, function,
|
|
38
40
|
database, server, network, bug, test, file, memory, algorithm, keyboard,
|
|
39
|
-
programmer, repository, commit, …)
|
|
41
|
+
programmer, repository, commit, …) **plus** the ~230-term `EXTRA_SEEDS`
|
|
42
|
+
growth list in `filter-dump.mjs` (programming languages, frameworks, data
|
|
43
|
+
structures, cloud/infra, protocols, tools, ML — python, java, docker,
|
|
44
|
+
kubernetes, git, neural_network, tcp, kernel, hashtable, …), added
|
|
45
|
+
2026-07-05 to reach the ~40k tier-1 target while staying in the tech domain.
|
|
40
46
|
4. **Dedupe** by `(start, rel, end)`, keeping the higher weight.
|
|
41
|
-
5. **Size budget** (committed slice ≤
|
|
47
|
+
5. **Size budget** (committed slice ≤ 5 MB; target ~4.3 MB), **two-tier**:
|
|
42
48
|
assertions whose relation maps to an ACE-OWL pattern (`ace != "none"` in
|
|
43
49
|
`conceptnet-map.toml`) are kept first, weight-descending; `ace = "none"`
|
|
44
50
|
relations (`RelatedTo`, `Synonym`, …) fill the remaining budget — they
|
|
@@ -46,7 +52,7 @@ see `LICENSE-NOTICE` in this directory for the full attribution.
|
|
|
46
52
|
facts.
|
|
47
53
|
6. Deterministic output order: `(rel, start, end)`.
|
|
48
54
|
|
|
49
|
-
## Quality-filter pass (2026-07-05)
|
|
55
|
+
## Quality-filter pass (regrown slice, 2026-07-05)
|
|
50
56
|
|
|
51
57
|
`filter-dump.mjs` keeps the DATA honest (tech-seed match, canonical relations,
|
|
52
58
|
budget) but not the SEMANTICS: ConceptNet's crowd-sourced "Verbosity"/Open-Mind
|
|
@@ -66,66 +72,66 @@ row):
|
|
|
66
72
|
evidence-based set (`elegance, evil, gloom, unreality, universalism, dumb,
|
|
67
73
|
free, junk`) — never a class
|
|
68
74
|
|
|
69
|
-
**Result:
|
|
70
|
-
reason: sentence-fragment
|
|
71
|
-
definitional-phrase
|
|
72
|
-
|
|
73
|
-
disappeared entirely (the drift guard stays
|
|
75
|
+
**Result (2026-07-05 regrow): 45,633 → 44,947 rows (686 cut), 4,308,850 →
|
|
76
|
+
4,220,629 bytes.** Cuts by reason: sentence-fragment 613, single-char 48,
|
|
77
|
+
numeric 11, opinion-object 8, definitional-phrase 6. Of the seedable (mapped,
|
|
78
|
+
`ace≠none`) facts, the clean slice carries **6,255** — up from 3,884 in the
|
|
79
|
+
1.35 MB slice. No relation disappeared entirely (the drift guard stays
|
|
80
|
+
satisfied). Re-run any time with:
|
|
74
81
|
|
|
75
82
|
```bash
|
|
76
83
|
node corpus/conceptnet/quality-filter.mjs --in-place corpus/conceptnet/slice.jsonl
|
|
77
84
|
```
|
|
78
85
|
|
|
79
|
-
## Growing the slice toward ~40k
|
|
86
|
+
## Growing the slice toward the ~40k tier-1 target (done 2026-07-05)
|
|
80
87
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
`
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
The operator's ~40k-fact tier-1 target is **shipped**: the slice was regrown
|
|
89
|
+
from the same ConceptNet dump by (a) widening the tech domain with the
|
|
90
|
+
`EXTRA_SEEDS` list in `filter-dump.mjs` (~230 tech terms — languages,
|
|
91
|
+
frameworks, data structures, cloud/infra, protocols, tools, ML) and (b) raising
|
|
92
|
+
`MAX_BYTES` in `filter-dump.mjs` from 1.4 MB to 4.5 MB with the matching test
|
|
93
|
+
budget assertion (`test/corpus-conceptnet.test.mjs`) raised from 1.5 MB to
|
|
94
|
+
5 MB. The widened seed set matched **45,633 unique en→en assertions** (all under
|
|
95
|
+
budget, so no tier-trimming was needed this pass), and the quality filter
|
|
96
|
+
trimmed them to the committed **44,947 clean facts**. Regenerate with:
|
|
89
97
|
|
|
90
98
|
```bash
|
|
91
|
-
# 1.
|
|
99
|
+
# 1. stream-filter the dump (widened seeds + raised budget already live in filter-dump.mjs)
|
|
92
100
|
curl -s https://s3.amazonaws.com/conceptnet/downloads/2019/edges/conceptnet-assertions-5.7.0.csv.gz \
|
|
93
101
|
| gunzip -c | node corpus/conceptnet/filter-dump.mjs > corpus/conceptnet/slice.jsonl
|
|
94
102
|
# 2. re-apply the semantic quality filter
|
|
95
103
|
node corpus/conceptnet/quality-filter.mjs --in-place corpus/conceptnet/slice.jsonl
|
|
96
|
-
# 3. raise the test's budget assertion to match
|
|
97
104
|
```
|
|
98
105
|
|
|
99
|
-
## Row counts (
|
|
106
|
+
## Row counts (regrown slice, 2026-07-05)
|
|
100
107
|
|
|
101
|
-
**
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
**44,947 clean assertions, 4,220,629 bytes** — the quality-filtered committed
|
|
109
|
+
slice (raw filter-dump output was 45,633 rows / 4,308,850 bytes; 34,074,917 dump
|
|
110
|
+
lines scanned; 45,633 unique en→en seed assertions matched = 6,670 mappable +
|
|
111
|
+
38,963 `ace="none"`; ALL kept under the 4.5 MB budget, then 686 noise rows cut).
|
|
112
|
+
30 of the 31 non-filtered canonical relations are present; **6,255 seedable
|
|
113
|
+
(`ace≠none`) facts**:
|
|
107
114
|
|
|
108
115
|
| Relation | Rows | | Relation | Rows |
|
|
109
116
|
|---|---|---|---|---|
|
|
110
|
-
| `/r/RelatedTo` |
|
|
111
|
-
| `/r/HasContext` |
|
|
112
|
-
| `/r/IsA` |
|
|
113
|
-
| `/r/DerivedFrom` |
|
|
114
|
-
| `/r/
|
|
115
|
-
| `/r/
|
|
116
|
-
| `/r/
|
|
117
|
-
| `/r/
|
|
118
|
-
| `/r/CapableOf` |
|
|
119
|
-
| `/r/MannerOf` |
|
|
120
|
-
| `/r/PartOf` |
|
|
121
|
-
| `/r/
|
|
122
|
-
| `/r/
|
|
123
|
-
| `/r/
|
|
124
|
-
| | | | `/r/
|
|
125
|
-
|
|
126
|
-
Absent from the slice (nothing matched the seed terms): `/r/ObstructedBy
|
|
127
|
-
|
|
128
|
-
surfaces them stays covered.
|
|
117
|
+
| `/r/RelatedTo` | 29016 | | `/r/HasSubevent` | 42 |
|
|
118
|
+
| `/r/HasContext` | 4376 | | `/r/DistinctFrom` | 32 |
|
|
119
|
+
| `/r/IsA` | 4173 | | `/r/HasProperty` | 30 |
|
|
120
|
+
| `/r/DerivedFrom` | 3388 | | `/r/ReceivesAction` | 27 |
|
|
121
|
+
| `/r/Synonym` | 1126 | | `/r/MotivatedByGoal` | 26 |
|
|
122
|
+
| `/r/AtLocation` | 642 | | `/r/MadeOf` | 20 |
|
|
123
|
+
| `/r/FormOf` | 528 | | `/r/Causes` | 18 |
|
|
124
|
+
| `/r/UsedFor` | 378 | | `/r/CreatedBy` | 15 |
|
|
125
|
+
| `/r/CapableOf` | 231 | | `/r/CausesDesire` | 13 |
|
|
126
|
+
| `/r/MannerOf` | 230 | | `/r/Desires` | 9 |
|
|
127
|
+
| `/r/PartOf` | 196 | | `/r/HasLastSubevent` | 8 |
|
|
128
|
+
| `/r/Antonym` | 155 | | `/r/HasFirstSubevent` | 7 |
|
|
129
|
+
| `/r/HasPrerequisite` | 108 | | `/r/LocatedNear` | 3 |
|
|
130
|
+
| `/r/SimilarTo` | 102 | | `/r/DefinedAs` | 2 |
|
|
131
|
+
| `/r/HasA` | 45 | | `/r/SymbolOf` | 1 |
|
|
132
|
+
|
|
133
|
+
Absent from the slice (nothing matched the seed terms): `/r/ObstructedBy` — it
|
|
134
|
+
still has a mapping row, so a regenerated slice that surfaces it stays covered.
|
|
129
135
|
|
|
130
136
|
## How to regenerate / extend
|
|
131
137
|
|
|
@@ -139,11 +145,12 @@ curl -s https://s3.amazonaws.com/conceptnet/downloads/2019/edges/conceptnet-asse
|
|
|
139
145
|
| node corpus/conceptnet/filter-dump.mjs > corpus/conceptnet/slice.jsonl
|
|
140
146
|
```
|
|
141
147
|
|
|
142
|
-
To extend the domain, add seed terms to `
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
To extend the domain, add seed terms to `EXTRA_SEEDS` in `filter-dump.mjs` (the
|
|
149
|
+
dump route that produces the committed slice) or `SEED_TERMS` in
|
|
150
|
+
`fetch-slice.mjs` (the API route) and re-run. `npm test` guards the contract:
|
|
151
|
+
every relation present in the slice must have a row in
|
|
152
|
+
`src/corpus/conceptnet-map.toml` (drift guard), en→en shape and the ≤ 5 MB
|
|
153
|
+
budget are asserted, and the seeding path is exercised end-to-end.
|
|
147
154
|
|
|
148
155
|
## Consumers
|
|
149
156
|
|
|
@@ -30,8 +30,65 @@ import { createInterface } from "node:readline";
|
|
|
30
30
|
import { SEED_TERMS, CANONICAL_RELS, FILTERED_RELS, bareEnTerm } from "./fetch-slice.mjs";
|
|
31
31
|
import { loadMap } from "../../src/corpus/conceptnet.mjs";
|
|
32
32
|
|
|
33
|
-
const MAX_BYTES =
|
|
34
|
-
|
|
33
|
+
const MAX_BYTES = 4_500_000; // committed-slice budget (hard cap 5 MB), grown for the ~40k tier-1 target
|
|
34
|
+
|
|
35
|
+
// Tier-1 growth seeds (2026-07-05): the original SEED_TERMS in fetch-slice.mjs
|
|
36
|
+
// stay the canonical ~90-term base; this list WIDENS the tech domain toward the
|
|
37
|
+
// ~40k-fact target without leaving the software/tech world — languages,
|
|
38
|
+
// frameworks, data structures, cloud/infra, protocols, tools, ML. Kept here (an
|
|
39
|
+
// owned maintainer file) rather than in fetch-slice.mjs so the API route's seed
|
|
40
|
+
// contract is untouched. Union with SEED_TERMS below.
|
|
41
|
+
const EXTRA_SEEDS = [
|
|
42
|
+
// programming languages & ecosystems
|
|
43
|
+
"python", "java", "javascript", "typescript", "ruby", "perl", "php", "golang",
|
|
44
|
+
"rust", "kotlin", "swift", "scala", "haskell", "lisp", "clojure", "erlang",
|
|
45
|
+
"fortran", "cobol", "pascal", "assembly", "sql", "html", "css", "json", "xml",
|
|
46
|
+
"yaml", "markdown", "bash", "powershell",
|
|
47
|
+
// paradigms & concepts
|
|
48
|
+
"programming", "coding", "recursion", "iteration", "inheritance",
|
|
49
|
+
"polymorphism", "abstraction", "encapsulation", "concurrency", "parallelism",
|
|
50
|
+
"multithreading", "asynchronous", "synchronization", "serialization",
|
|
51
|
+
"optimization", "refactoring", "debugging", "compilation", "runtime",
|
|
52
|
+
"object_oriented", "functional_programming", "computer_science",
|
|
53
|
+
"software_engineering", "computer_programming",
|
|
54
|
+
// data structures & algorithms
|
|
55
|
+
"hash", "hashtable", "tree", "graph", "list", "tuple", "dictionary", "heap",
|
|
56
|
+
"matrix", "vector", "node", "recursion", "sorting", "searching", "linked_list",
|
|
57
|
+
"binary_tree", "hash_table", "data_type", "datatype",
|
|
58
|
+
// frameworks, tools & platforms
|
|
59
|
+
"git", "github", "docker", "kubernetes", "jenkins", "react", "angular",
|
|
60
|
+
"nodejs", "django", "flask", "spring", "rails", "tensorflow", "pytorch",
|
|
61
|
+
"hadoop", "kafka", "redis", "mongodb", "mysql", "postgresql", "sqlite",
|
|
62
|
+
"elasticsearch", "apache", "nginx", "wordpress", "eclipse", "vim", "emacs",
|
|
63
|
+
// hardware & systems
|
|
64
|
+
"kernel", "driver", "register", "transistor", "semiconductor", "motherboard",
|
|
65
|
+
"microprocessor", "microcontroller", "gpu", "ram", "rom", "ssd", "firmware",
|
|
66
|
+
"bootloader", "filesystem", "partition", "peripheral", "microchip",
|
|
67
|
+
"circuit_board", "integrated_circuit", "hard_drive", "graphics_card",
|
|
68
|
+
// networking & protocols
|
|
69
|
+
"packet", "bandwidth", "latency", "router", "firewall", "gateway", "proxy",
|
|
70
|
+
"dns", "tcp", "ftp", "smtp", "ssh", "ssl", "vpn", "ethernet", "wifi",
|
|
71
|
+
"bluetooth", "socket", "port", "packet_switching", "ip_address",
|
|
72
|
+
// web & the net
|
|
73
|
+
"url", "cookie", "session", "webpage", "hyperlink", "frontend", "backend",
|
|
74
|
+
"webserver", "webservice", "hosting", "domain", "html5", "ajax",
|
|
75
|
+
// cloud, infra & devops
|
|
76
|
+
"cloud_computing", "container", "virtualization", "serverless",
|
|
77
|
+
"microservice", "deployment", "devops", "pipeline", "infrastructure",
|
|
78
|
+
"datacenter", "cluster", "scalability", "availability", "redundancy",
|
|
79
|
+
// security
|
|
80
|
+
"authentication", "authorization", "cryptography", "hashing", "firewall",
|
|
81
|
+
"malware", "virus", "vulnerability", "cybersecurity", "cipher",
|
|
82
|
+
// data & ml
|
|
83
|
+
"dataset", "database", "datastore", "query", "index", "schema", "transaction",
|
|
84
|
+
"neural_network", "deep_learning", "classification", "regression",
|
|
85
|
+
"clustering", "training", "inference", "algorithm", "computation",
|
|
86
|
+
"big_data", "data_mining", "data_science", "analytics",
|
|
87
|
+
// concurrency & os primitives
|
|
88
|
+
"semaphore", "mutex", "deadlock", "scheduler", "interrupt", "syscall",
|
|
89
|
+
"daemon", "multitasking", "buffer", "pipe",
|
|
90
|
+
];
|
|
91
|
+
const SEEDS = new Set([...SEED_TERMS, ...EXTRA_SEEDS]);
|
|
35
92
|
const termOf = (uri) => uri.slice("/c/en/".length);
|
|
36
93
|
|
|
37
94
|
const byKey = new Map(); // "start rel end" -> row
|