@mrciphersmith/keryx 0.3.16 → 0.3.18
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/dist/cli.js +1403 -689
- package/dist/core.js +50 -8
- package/package.json +1 -1
- package/src/gdgraph/service.ts +7 -0
package/dist/core.js
CHANGED
|
@@ -1327,6 +1327,23 @@ function tokenize(text) {
|
|
|
1327
1327
|
function tokenSet(text) {
|
|
1328
1328
|
return new Set(tokenize(text));
|
|
1329
1329
|
}
|
|
1330
|
+
function stem(token) {
|
|
1331
|
+
let base = token;
|
|
1332
|
+
if (base.length >= 6 && base.endsWith("ies")) {
|
|
1333
|
+
base = `${base.slice(0, -3)}y`;
|
|
1334
|
+
} else {
|
|
1335
|
+
for (const suffix of ["ing", "edly", "ed", "es", "s"]) {
|
|
1336
|
+
if (base.length - suffix.length >= 3 && base.endsWith(suffix)) {
|
|
1337
|
+
base = base.slice(0, base.length - suffix.length);
|
|
1338
|
+
break;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
if (base.length >= 4 && base.endsWith("e")) {
|
|
1343
|
+
base = base.slice(0, -1);
|
|
1344
|
+
}
|
|
1345
|
+
return base;
|
|
1346
|
+
}
|
|
1330
1347
|
function jaccard(a, b) {
|
|
1331
1348
|
if (a.size === 0 || b.size === 0) {
|
|
1332
1349
|
return 0;
|
|
@@ -1749,7 +1766,7 @@ var init_lifecycle = __esm(() => {
|
|
|
1749
1766
|
function searchEntries(entries, query, filters, config, now) {
|
|
1750
1767
|
validateQuery(query);
|
|
1751
1768
|
validateSearchFilters(filters, now);
|
|
1752
|
-
const queryTokens = [...new Set(tokenize(query))];
|
|
1769
|
+
const queryTokens = [...new Set(tokenize(query).map(stem))];
|
|
1753
1770
|
const today = now.toISOString().slice(0, 10);
|
|
1754
1771
|
const filtered = entries.filter((entry) => matchesFilters(entry, filters) && classMatch(entry, filters.class) && temporalMatch(entry, filters.asOf ?? null, config, today, Boolean(filters.status)));
|
|
1755
1772
|
const scored = filtered.map((entry) => scoreEntry(entry, queryTokens, filters, config, now));
|
|
@@ -1758,7 +1775,7 @@ function searchEntries(entries, query, filters, config, now) {
|
|
|
1758
1775
|
function candidatePool(entries, query, filters, config, now, k) {
|
|
1759
1776
|
validateQuery(query);
|
|
1760
1777
|
validateSearchFilters(filters, now);
|
|
1761
|
-
const queryTokens = [...new Set(tokenize(query))];
|
|
1778
|
+
const queryTokens = [...new Set(tokenize(query).map(stem))];
|
|
1762
1779
|
const today = now.toISOString().slice(0, 10);
|
|
1763
1780
|
return entries.filter((entry) => matchesFilters(entry, filters) && classMatch(entry, filters.class) && temporalMatch(entry, filters.asOf ?? null, config, today, Boolean(filters.status))).map((entry) => scoreEntry(entry, queryTokens, filters, config, now)).sort((a, b) => b.score - a.score).slice(0, Math.min(MAX_GENERAL_RESULTS, Math.max(0, k)));
|
|
1764
1781
|
}
|
|
@@ -1809,8 +1826,8 @@ function temporalMatch(entry, asOf, config, today, hasStatusFilter) {
|
|
|
1809
1826
|
}, new Date(`${today}T00:00:00.000Z`)).current;
|
|
1810
1827
|
}
|
|
1811
1828
|
function scoreEntry(entry, queryTokens, filters, config, now) {
|
|
1812
|
-
const bodyTokens = tokenSet(`${entry.title} ${entry.summary} ${entry.details} ${entry.tags.join(" ")}`);
|
|
1813
|
-
const titleTokens = tokenSet(entry.title);
|
|
1829
|
+
const bodyTokens = new Set([...tokenSet(`${entry.title} ${entry.summary} ${entry.details} ${entry.tags.join(" ")}`)].map(stem));
|
|
1830
|
+
const titleTokens = new Set([...tokenSet(entry.title)].map(stem));
|
|
1814
1831
|
let hits = 0;
|
|
1815
1832
|
let titleHits = 0;
|
|
1816
1833
|
for (const token of queryTokens) {
|
|
@@ -20454,6 +20471,7 @@ __export(exports_service4, {
|
|
|
20454
20471
|
createMemoryService: () => createMemoryService,
|
|
20455
20472
|
filterEntriesForHarness: () => filterEntriesForHarness,
|
|
20456
20473
|
isMemoryHarnessId: () => isMemoryHarnessId,
|
|
20474
|
+
loadEmbeddingIndex: () => loadEmbeddingIndex,
|
|
20457
20475
|
memoryAllowedRelativePaths: () => memoryAllowedRelativePaths,
|
|
20458
20476
|
memoryHandoff: () => memoryHandoff,
|
|
20459
20477
|
memoryHarnessVisibilityByPath: () => memoryHarnessVisibilityByPath,
|
|
@@ -20775,6 +20793,7 @@ var init_service5 = __esm(() => {
|
|
|
20775
20793
|
init_harness_identity();
|
|
20776
20794
|
init_embedding();
|
|
20777
20795
|
init_types();
|
|
20796
|
+
init_embedding();
|
|
20778
20797
|
});
|
|
20779
20798
|
|
|
20780
20799
|
// src/wiki/ask.ts
|
|
@@ -27208,6 +27227,7 @@ var exports_service6 = {};
|
|
|
27208
27227
|
__export(exports_service6, {
|
|
27209
27228
|
UnknownGraphTargetError: () => UnknownGraphTargetError,
|
|
27210
27229
|
buildAffectedReport: () => buildAffectedReport,
|
|
27230
|
+
checkGraphStaleness: () => checkGraphStaleness,
|
|
27211
27231
|
createGdgraphService: () => createGdgraphService
|
|
27212
27232
|
});
|
|
27213
27233
|
|
|
@@ -28124,6 +28144,7 @@ async function writeRepomap(cwd, graph, config, options = {}) {
|
|
|
28124
28144
|
|
|
28125
28145
|
// src/gdgraph/service.ts
|
|
28126
28146
|
init_affected_report();
|
|
28147
|
+
init_staleness();
|
|
28127
28148
|
|
|
28128
28149
|
class UnknownGraphTargetError extends Error {
|
|
28129
28150
|
target;
|
|
@@ -28169,7 +28190,8 @@ init_json();
|
|
|
28169
28190
|
var exports_service7 = {};
|
|
28170
28191
|
__export(exports_service7, {
|
|
28171
28192
|
createCodeHealthService: () => createCodeHealthService,
|
|
28172
|
-
gateExitCode: () => gateExitCode
|
|
28193
|
+
gateExitCode: () => gateExitCode,
|
|
28194
|
+
readWikiFreshnessMetric: () => readWikiFreshnessMetric
|
|
28173
28195
|
});
|
|
28174
28196
|
import path95 from "path";
|
|
28175
28197
|
|
|
@@ -28331,7 +28353,8 @@ function computeGate2(input) {
|
|
|
28331
28353
|
}
|
|
28332
28354
|
const missingOptional = sources.filter((s) => !s.required && s.status === "missing");
|
|
28333
28355
|
for (const source of missingOptional) {
|
|
28334
|
-
|
|
28356
|
+
const detail = source.error ? `: ${source.error}` : "";
|
|
28357
|
+
reasons.push(`OPTIONAL: ${source.source} source missing${detail}`);
|
|
28335
28358
|
}
|
|
28336
28359
|
const brokenOptional = sources.filter((s) => !s.required && s.status === "configured-but-failed");
|
|
28337
28360
|
if (brokenOptional.length > 0) {
|
|
@@ -30148,6 +30171,12 @@ function errorCodeSuffix(error) {
|
|
|
30148
30171
|
const code = safeErrorCode(error);
|
|
30149
30172
|
return code ? ` (${code})` : "";
|
|
30150
30173
|
}
|
|
30174
|
+
function missingSourceReason(sourceId) {
|
|
30175
|
+
if (sourceId === "tests") {
|
|
30176
|
+
return "no `bun` binary found (checked node_modules/.bin and PATH)";
|
|
30177
|
+
}
|
|
30178
|
+
return;
|
|
30179
|
+
}
|
|
30151
30180
|
var KNOWN_VALIDATION_ERRORS = new Set([
|
|
30152
30181
|
"ESLint JSON format was not recognized",
|
|
30153
30182
|
"ESLint JSON parse failed",
|
|
@@ -30189,7 +30218,8 @@ async function runAdapter(adapter, ctx, cfg, stamp) {
|
|
|
30189
30218
|
};
|
|
30190
30219
|
}
|
|
30191
30220
|
if (status === "skipped" || status === "missing") {
|
|
30192
|
-
|
|
30221
|
+
const reason = missingSourceReason(adapter.id);
|
|
30222
|
+
return { info: { ...base, status, ...reason !== undefined ? { error: reason } : {} }, findings: [] };
|
|
30193
30223
|
}
|
|
30194
30224
|
let raw;
|
|
30195
30225
|
try {
|
|
@@ -30203,7 +30233,7 @@ async function runAdapter(adapter, ctx, cfg, stamp) {
|
|
|
30203
30233
|
} catch (error) {
|
|
30204
30234
|
if (error instanceof NoImportError) {
|
|
30205
30235
|
if (adapter.id === "tests") {
|
|
30206
|
-
return { info: { ...base, status
|
|
30236
|
+
return { info: { ...base, status }, findings: [] };
|
|
30207
30237
|
}
|
|
30208
30238
|
raw = await adapter.run(ctx);
|
|
30209
30239
|
} else {
|
|
@@ -37016,6 +37046,18 @@ var HELP_GROUPS = [
|
|
|
37016
37046
|
summary: "Grouped command help by task \u2014 keryx help [group|command]."
|
|
37017
37047
|
},
|
|
37018
37048
|
{ kind: "slash", name: "/help", group: "Start here", summary: "Show available commands, grouped by task." },
|
|
37049
|
+
{
|
|
37050
|
+
kind: "cli",
|
|
37051
|
+
name: "doctor",
|
|
37052
|
+
group: "Start here",
|
|
37053
|
+
summary: "One-page health check: version, Bun floor, ripgrep, sandbox, providers, MCP, integrations, standard, worktrees, graph/wiki freshness."
|
|
37054
|
+
},
|
|
37055
|
+
{
|
|
37056
|
+
kind: "slash",
|
|
37057
|
+
name: "/doctor",
|
|
37058
|
+
group: "Start here",
|
|
37059
|
+
summary: "Same one-page health check, inside the session."
|
|
37060
|
+
},
|
|
37019
37061
|
{
|
|
37020
37062
|
kind: "cli",
|
|
37021
37063
|
name: "auth",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.18",
|
|
4
4
|
"description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
package/src/gdgraph/service.ts
CHANGED
|
@@ -18,6 +18,13 @@ import type { GraphData } from "./types";
|
|
|
18
18
|
// facade rule).
|
|
19
19
|
export { buildAffectedReport, type AffectedReport, type AffectedReportOptions } from "./affected-report";
|
|
20
20
|
|
|
21
|
+
// Flow 353 (P0 W5, AC1): re-exported so `commands/doctor.ts`'s aggregate
|
|
22
|
+
// "graph/wiki freshness" check can ask the SAME staleness question
|
|
23
|
+
// `commands/gdgraph.ts` already does, through this facade rather than a
|
|
24
|
+
// second direct edge into `gdgraph/staleness.ts` (the same facade rule
|
|
25
|
+
// `buildAffectedReport` above already follows).
|
|
26
|
+
export { checkGraphStaleness, type StalenessCheck, type StalenessStatus } from "./staleness";
|
|
27
|
+
|
|
21
28
|
export interface GdgraphService {
|
|
22
29
|
build(cwd: string): Promise<{ nodes: number; edges: number; summaryPath: string }>;
|
|
23
30
|
loadGraph(cwd: string): Promise<GraphData>;
|