@polycode-projects/the-mechanical-code-talker 0.9.0 → 0.9.2
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/package.json +1 -1
- package/src/ask.mjs +20 -11
- package/src/chat.mjs +6 -0
- package/src/tui/app.mjs +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polycode-projects/the-mechanical-code-talker",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
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.",
|
package/src/ask.mjs
CHANGED
|
@@ -821,15 +821,19 @@ function parseRelationalOrQualified(w, lc, nlp, depth) {
|
|
|
821
821
|
while (i < lc.length && QUALIFIERS[lc[i]]) { quals.push(lc[i]); i += 1; }
|
|
822
822
|
const noun = i < lc.length ? entityNoun(lc[i]) : null;
|
|
823
823
|
if (!noun) {
|
|
824
|
-
//
|
|
825
|
-
//
|
|
826
|
-
//
|
|
827
|
-
//
|
|
828
|
-
//
|
|
829
|
-
//
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
824
|
+
// An unknown adjective sitting in the qualifier slot, right before a known entity
|
|
825
|
+
// noun ("list payment modules", "which shiny methods") — try it as a predicate-find
|
|
826
|
+
// fuzzy term FIRST ("payment" filtering Module labels/attributes) before declaring
|
|
827
|
+
// it an unrecognized qualifier: a real, honest answer beats an error message, and a
|
|
828
|
+
// genuine zero-hit still renders find's own honest "no <noun> found matching <term>"
|
|
829
|
+
// miss (never a confident-wrong guess either way — same discipline as everywhere
|
|
830
|
+
// else this AST node is produced). STOPWORDS are excluded so a normal question
|
|
831
|
+
// auxiliary in that position ("what DID commit X touch") is left for the existing
|
|
832
|
+
// parser, not mistaken for a term.
|
|
833
|
+
const nextNoun = i + 1 < lc.length ? entityNoun(lc[i + 1]) : null;
|
|
834
|
+
if ((framed || quals.length) && nextNoun && /^[a-z]+$/.test(lc[i])
|
|
835
|
+
&& !VERB_TO_KIND[lc[i]] && !STOPWORDS.has(lc[i])) {
|
|
836
|
+
return { node: "find", entityType: nextNoun.entityType, term: w[i] };
|
|
833
837
|
}
|
|
834
838
|
return null; // no subject entity → not this shape
|
|
835
839
|
}
|
|
@@ -2286,11 +2290,16 @@ function renderCore(parsed, result) {
|
|
|
2286
2290
|
}
|
|
2287
2291
|
if (result.ambiguous) {
|
|
2288
2292
|
// the candidates say what KIND of thing is ambiguous — a shared commit-sha
|
|
2289
|
-
// prefix must read "more than one commit", not "module".
|
|
2293
|
+
// prefix must read "more than one commit", not "module". Name the actual
|
|
2294
|
+
// candidates in the prose (not just the structured `candidates` field) —
|
|
2295
|
+
// "narrow the term" is not itself actionable if the reader can't see what
|
|
2296
|
+
// it's ambiguous between; mirrors the mentionsShape branch's listing above.
|
|
2290
2297
|
const pool = [result.objMatch, ...(result.candidates || [])].filter(Boolean);
|
|
2291
2298
|
const noun = pool.length && pool.every((i) => i.class === "Commit") ? "commit" : "module";
|
|
2299
|
+
const shown = pool.slice(0, OVERFLOW_CAP).map((i) => i.label);
|
|
2300
|
+
const extra = pool.length > OVERFLOW_CAP ? `, …and ${pool.length - OVERFLOW_CAP} more` : "";
|
|
2292
2301
|
return {
|
|
2293
|
-
content: `"${parsed.object}" matches more than one ${noun} ambiguously —
|
|
2302
|
+
content: `"${parsed.object}" matches more than one ${noun} ambiguously — did you mean ${listJoin(shown)}${extra}? Try one of those.`,
|
|
2294
2303
|
miss: false, ambiguous: true, candidates: pool.map((i) => i.label),
|
|
2295
2304
|
};
|
|
2296
2305
|
}
|
package/src/chat.mjs
CHANGED
|
@@ -2987,6 +2987,12 @@ export async function runChat({
|
|
|
2987
2987
|
gitRoot = gitToplevel,
|
|
2988
2988
|
ephemeral = false,
|
|
2989
2989
|
} = {}) {
|
|
2990
|
+
// createSession's first-run seed (~2-3s, corpus/seon + ConceptNet) produces ZERO
|
|
2991
|
+
// output until it fully resolves — found live: an operator reported `npm run chat`
|
|
2992
|
+
// appearing to hang with total silence. This one line is cheap on every run (a
|
|
2993
|
+
// fast subsequent run just flashes it briefly) and removes the "is this even
|
|
2994
|
+
// running" uncertainty during the one case that's genuinely slow.
|
|
2995
|
+
output.write("tmct — starting…\n");
|
|
2990
2996
|
const session = await createSession({ repoPath, source, env, cwd, gitRoot, ephemeral });
|
|
2991
2997
|
|
|
2992
2998
|
const dim = (s) => (env.NO_COLOR || !output.isTTY ? s : `\x1b[2m${s}\x1b[0m`);
|
package/src/tui/app.mjs
CHANGED
|
@@ -231,6 +231,12 @@ export function App({ session }) {
|
|
|
231
231
|
* which also triggers the memory fold — stream flush). Returns
|
|
232
232
|
* { logFile, sidecarFile, turns } exactly like runChat. */
|
|
233
233
|
export async function runTui({ repoPath, stdout = process.stdout, stdin = process.stdin, ...sessionOpts } = {}) {
|
|
234
|
+
// Same reasoning as runChat's equivalent line (src/chat.mjs): createSession's
|
|
235
|
+
// first-run seed is silent for ~2-3s, and nothing is written to the terminal
|
|
236
|
+
// (not even the alternate-screen switch below) until it resolves — this was
|
|
237
|
+
// reported live as an apparent hang. One cheap line on the PRIMARY screen,
|
|
238
|
+
// before the alt-screen switch, so there's visible proof of life immediately.
|
|
239
|
+
stdout.write("tmct — starting…\n");
|
|
234
240
|
const session = await createSession({ repoPath, ...sessionOpts });
|
|
235
241
|
stdout.write("\x1b[?1049h\x1b[H"); // alternate screen buffer + home — a clean full-screen canvas
|
|
236
242
|
const app = render(h(App, { session }), { stdout, stdin, exitOnCtrlC: true });
|