@mrciphersmith/keryx 0.2.112 → 0.2.114

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 (4) hide show
  1. package/README.md +13 -0
  2. package/dist/cli.js +2901 -879
  3. package/dist/core.js +104 -3
  4. package/package.json +1 -1
package/dist/core.js CHANGED
@@ -8678,6 +8678,21 @@ var init_evidence = __esm(() => {
8678
8678
  CLAIM_TYPES = new Set(["observation", "hypothesis", "decision", "instruction"]);
8679
8679
  });
8680
8680
 
8681
+ // src/wiki/think-tags.ts
8682
+ function maskCodeRegions(text) {
8683
+ const maskMatch = (m) => "\x00".repeat(m.length);
8684
+ return text.replace(FENCE_RE2, maskMatch).replace(INLINE_CODE_RE, maskMatch);
8685
+ }
8686
+ function containsThinkTags(text) {
8687
+ return STRAY_THINK_TAG_RE.test(maskCodeRegions(text));
8688
+ }
8689
+ var STRAY_THINK_TAG_RE, FENCE_RE2, INLINE_CODE_RE;
8690
+ var init_think_tags = __esm(() => {
8691
+ STRAY_THINK_TAG_RE = /<\/?think(?:ing)?>/i;
8692
+ FENCE_RE2 = /```[\s\S]*?```/g;
8693
+ INLINE_CODE_RE = /``[^`\n]*?``|`[^`\n]*?`/g;
8694
+ });
8695
+
8681
8696
  // src/wiki/templates.ts
8682
8697
  function templateKindForPageType(type) {
8683
8698
  return WIKI_TEMPLATE_CONTRACTS.find((contract) => contract.pageTypes.includes(type))?.kind ?? null;
@@ -9099,6 +9114,7 @@ __export(exports_service3, {
9099
9114
  collectGraphWikiCandidates: () => collectGraphWikiCandidates,
9100
9115
  createGdWikiService: () => createGdWikiService,
9101
9116
  extractModuleApi: () => extractModuleApi,
9117
+ isTestSourceFile: () => isTestSourceFile,
9102
9118
  moduleNameFromProjectPath: () => moduleNameFromProjectPath,
9103
9119
  validModuleNames: () => validModuleNames,
9104
9120
  wikiCheckLinks: () => wikiCheckLinks,
@@ -9137,9 +9153,22 @@ async function wikiStatus(cwd) {
9137
9153
  count: pages.filter((page) => page.pageType === type).length
9138
9154
  })),
9139
9155
  lastIndexGeneratedAt: await readIndexGeneratedAt(cwd),
9140
- lastLinkCheck: await readLinkCheckState(cwd)
9156
+ lastLinkCheck: await readLinkCheckState(cwd),
9157
+ pagesWithThinkTags: await findPagesWithThinkTags(pages)
9141
9158
  };
9142
9159
  }
9160
+ async function findPagesWithThinkTags(pages) {
9161
+ const flagged = [];
9162
+ for (const page of pages) {
9163
+ try {
9164
+ const content = await readFile20(page.absolutePath, "utf8");
9165
+ if (containsThinkTags(content)) {
9166
+ flagged.push(page.relativePath);
9167
+ }
9168
+ } catch {}
9169
+ }
9170
+ return flagged;
9171
+ }
9143
9172
  async function wikiCreatePage(input) {
9144
9173
  const typeConfig = WIKI_PAGE_TYPES.find((entry) => entry.type === input.type);
9145
9174
  if (!typeConfig) {
@@ -9472,6 +9501,7 @@ async function collectGraphWikiCandidates(cwd, generatedAt, limit, onlyModules)
9472
9501
  const fileOut = new Map;
9473
9502
  const moduleDeps = new Map;
9474
9503
  const moduleDependents = new Map;
9504
+ const excludedTestEdges = new Map;
9475
9505
  let edges = 0;
9476
9506
  let imports = 0;
9477
9507
  let unresolved = 0;
@@ -9492,6 +9522,11 @@ async function collectGraphWikiCandidates(cwd, generatedAt, limit, onlyModules)
9492
9522
  const fromModule = fileToModule.get(from) ?? moduleNameFromProjectPath(from);
9493
9523
  const toModule = fileToModule.get(to) ?? moduleNameFromProjectPath(to);
9494
9524
  if (fromModule && toModule && fromModule !== toModule) {
9525
+ if (isTestSourceFile(from)) {
9526
+ recordExcludedTestEdge(excludedTestEdges, fromModule, from);
9527
+ recordExcludedTestEdge(excludedTestEdges, toModule, from);
9528
+ continue;
9529
+ }
9495
9530
  bumpNestedCount(moduleDeps, fromModule, toModule);
9496
9531
  bumpNestedCount(moduleDependents, toModule, fromModule);
9497
9532
  }
@@ -9551,6 +9586,12 @@ async function collectGraphWikiCandidates(cwd, generatedAt, limit, onlyModules)
9551
9586
  pushRef("Key files", keyFiles.map((entry) => "- `" + entry.file + "` - imported by " + entry.incoming + ", imports " + entry.outgoing));
9552
9587
  pushRef("Depends on", deps.map(([target, count]) => "- `" + target + "` - " + count + " import(s)"));
9553
9588
  pushRef("Depended on by", dependents.map(([source, count]) => "- `" + source + "` - " + count + " import(s)"));
9589
+ const dropped = excludedTestEdges.get(moduleName);
9590
+ if (dropped) {
9591
+ pushRef("Dependency basis", [
9592
+ "- Production imports only: " + dropped.count + " import(s) from test file(s) (e.g. `" + dropped.example + "`) excluded from the two sections above in both directions."
9593
+ ]);
9594
+ }
9554
9595
  pushRef("Entry points", entryFiles.map((file) => "- `" + file + "`"));
9555
9596
  if (readme) {
9556
9597
  pushRef("Module README", [readme]);
@@ -9593,6 +9634,13 @@ function bumpNestedCount(map, key, inner) {
9593
9634
  bucket.set(inner, (bucket.get(inner) ?? 0) + 1);
9594
9635
  map.set(key, bucket);
9595
9636
  }
9637
+ function isTestSourceFile(filePath) {
9638
+ return TEST_SOURCE_FILE.test(filePath);
9639
+ }
9640
+ function recordExcludedTestEdge(map, moduleName, testFile) {
9641
+ const current = map.get(moduleName);
9642
+ map.set(moduleName, { count: (current?.count ?? 0) + 1, example: current?.example ?? testFile });
9643
+ }
9596
9644
  function sumCounts(bucket) {
9597
9645
  if (!bucket) {
9598
9646
  return 0;
@@ -10196,7 +10244,7 @@ function compareSemver(a, b) {
10196
10244
  }
10197
10245
  return 0;
10198
10246
  }
10199
- var EXTERNAL_LINK, DEFAULT_COLLECT_LIMIT = 500, MIN_MODULE_FILES = 2, DEFAULT_EVIDENCE_BUDGET_TOKENS = 4000, DEFAULT_EVIDENCE_MAX_ITEMS = 8, WIKI_PAGE_PRODUCERS;
10247
+ var EXTERNAL_LINK, DEFAULT_COLLECT_LIMIT = 500, MIN_MODULE_FILES = 2, DEFAULT_EVIDENCE_BUDGET_TOKENS = 4000, DEFAULT_EVIDENCE_MAX_ITEMS = 8, WIKI_PAGE_PRODUCERS, TEST_SOURCE_FILE;
10200
10248
  var init_service2 = __esm(() => {
10201
10249
  init_fs();
10202
10250
  init_guard();
@@ -10207,6 +10255,7 @@ var init_service2 = __esm(() => {
10207
10255
  init_section_index();
10208
10256
  init_section_tombstone();
10209
10257
  init_staleness2();
10258
+ init_think_tags();
10210
10259
  init_templates();
10211
10260
  init_types2();
10212
10261
  EXTERNAL_LINK = /^(https?:|mailto:|tel:)/i;
@@ -10217,6 +10266,7 @@ var init_service2 = __esm(() => {
10217
10266
  path: /^decisions\/sac-[a-z]+-[0-9a-f]+\.md$/
10218
10267
  }
10219
10268
  ];
10269
+ TEST_SOURCE_FILE = /(?:^|\/)[^/]*\.(?:test|spec)\.[cm]?[jt]sx?$/;
10220
10270
  });
10221
10271
 
10222
10272
  // src/gdgraph/wiki-layer.ts
@@ -22819,6 +22869,54 @@ function readToolCalls(value) {
22819
22869
  }
22820
22870
  return calls.length > 0 ? calls : undefined;
22821
22871
  }
22872
+ function readReplayItems(value) {
22873
+ if (!Array.isArray(value)) {
22874
+ return;
22875
+ }
22876
+ const items = [];
22877
+ for (const entry of value) {
22878
+ if (entry === null || typeof entry !== "object") {
22879
+ continue;
22880
+ }
22881
+ const record = entry;
22882
+ const { providerId, kind } = record;
22883
+ if (typeof providerId !== "string" || providerId.length === 0) {
22884
+ continue;
22885
+ }
22886
+ if (typeof kind !== "string" || kind.length === 0) {
22887
+ continue;
22888
+ }
22889
+ if (!("data" in record)) {
22890
+ continue;
22891
+ }
22892
+ items.push({ providerId, kind, data: record.data });
22893
+ }
22894
+ return items.length > 0 ? items : undefined;
22895
+ }
22896
+ function readReasoning(value) {
22897
+ if (value === null || typeof value !== "object") {
22898
+ return;
22899
+ }
22900
+ const record = value;
22901
+ const out = {};
22902
+ if (typeof record.text === "string" && record.text.length > 0) {
22903
+ out.text = record.text;
22904
+ }
22905
+ if (record.redacted === true) {
22906
+ out.redacted = true;
22907
+ }
22908
+ const replay = readReplayItems(record.replay);
22909
+ if (replay !== undefined) {
22910
+ out.replay = replay;
22911
+ }
22912
+ if (typeof record.durationMs === "number" && Number.isFinite(record.durationMs) && record.durationMs >= 0) {
22913
+ out.durationMs = record.durationMs;
22914
+ }
22915
+ if (typeof record.tokens === "number" && Number.isFinite(record.tokens) && record.tokens >= 0) {
22916
+ out.tokens = record.tokens;
22917
+ }
22918
+ return Object.keys(out).length > 0 ? out : undefined;
22919
+ }
22822
22920
  function nowIso2() {
22823
22921
  return new Date().toISOString();
22824
22922
  }
@@ -22891,12 +22989,15 @@ function readJsonl2(file) {
22891
22989
  continue;
22892
22990
  }
22893
22991
  const toolCalls = readToolCalls(o.toolCalls);
22992
+ const reasoning = readReasoning(o.reasoning);
22894
22993
  out.push({
22895
22994
  role: o.role,
22896
22995
  content: o.content,
22897
22996
  ...o.provenance === "trusted" || o.provenance === "project" || o.provenance === "model" || o.provenance === "tool" ? { provenance: o.provenance } : {},
22898
22997
  ...toolCalls !== undefined ? { toolCalls } : {},
22899
- ...typeof o.toolCallId === "string" && o.toolCallId.length > 0 ? { toolCallId: o.toolCallId } : {}
22998
+ ...typeof o.toolCallId === "string" && o.toolCallId.length > 0 ? { toolCallId: o.toolCallId } : {},
22999
+ ...typeof o.ts === "string" && o.ts.length > 0 ? { ts: o.ts } : {},
23000
+ ...reasoning !== undefined ? { reasoning } : {}
22900
23001
  });
22901
23002
  } catch {}
22902
23003
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrciphersmith/keryx",
3
- "version": "0.2.112",
3
+ "version": "0.2.114",
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": {