@mrciphersmith/keryx 0.2.77 → 0.2.79

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 (2) hide show
  1. package/dist/cli.js +151 -14
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -589,6 +589,38 @@ description: Use FIRST for conceptual questions - how something works, why, arch
589
589
 
590
590
  # gdwiki Skill
591
591
 
592
+ ## Before you trust a page: check whether it is current
593
+
594
+ A wiki page is a claim about code that may have moved since anyone checked.
595
+ Reading a stale page and generating against it is the failure this whole
596
+ mechanism exists to prevent, so consult freshness BEFORE treating a page as
597
+ context, not after being wrong.
598
+
599
+ - MCP: \`wiki_freshness\` (read-only; pass \`page\` to ask about one).
600
+ - CLI: \`keryx wiki freshness\` \u2014 or read
601
+ \`.metaproject/data/wiki/freshness/latest.json\` directly, which is one file
602
+ and costs nothing.
603
+
604
+ How to read the answer:
605
+
606
+ - A page listed \`stale-reference\` has a Reference block that no longer matches
607
+ the graph. Its **prose may still be sound**; its API list is not. Say so
608
+ rather than quoting the list as current.
609
+ - A page listed \`stale-prose\` may describe behaviour that changed. Quote it
610
+ with the caveat, and prefer reading the code it names.
611
+ - A page listed \`unknown\` has never been verified. That is NOT the same as
612
+ stale, and NOT the same as fresh \u2014 nobody has checked.
613
+ - **An empty finding list with a non-empty \`limitations\` does not mean the
614
+ wiki is fresh.** It means the check could not run: the graph was not built,
615
+ the symbol layer was unavailable, or there is no git history. Read
616
+ \`limitations\` first, every time.
617
+
618
+ Repairing is a separate act from reading, and it belongs to a person:
619
+ \`keryx wiki refresh\` regenerates Reference blocks deterministically without a
620
+ model, and \`keryx wiki verify --page <p>\` records that someone reviewed a
621
+ page. Do not stamp provenance on a human's behalf \u2014 the field means a person
622
+ looked.
623
+
592
624
  Use this skill for project knowledge that is not a literal code detail:
593
625
  architecture, domain models, business rules, user scenarios, service/component
594
626
  responsibilities, integrations, and known decisions. The user does not need to
@@ -35431,6 +35463,7 @@ function renderProjectMetaprojectReferenceBlock({
35431
35463
  "Do not dispatch subagents until the Metaproject hard gate is complete. Every subagent prompt must include the exact project/worktree root and require reading `<project-root>/.metaproject/index.md` before searching or reading code.",
35432
35464
  "If MCP tools/resources are available for this project, prefer them for Metaproject capabilities because they provide structured tool calls. If MCP is unavailable or lacks a needed capability, fall back to the corresponding project-local skill and CLI command.",
35433
35465
  "For project navigation, file discovery, and code-related tasks, use the Metaproject gdgraph skill by default before raw file search.",
35466
+ "The graph answers from the last `keryx gdgraph build`, not from the working tree. Rebuild before relying on a graph answer when you added, renamed, deleted or moved files in this session, or when `keryx gdgraph context` reports uncommitted code files \u2014 not once per question. If you cannot rebuild, say the graph predates those changes instead of quoting it as current. Contract: .metaproject/modules/gdgraph.md (Freshness & Refresh).",
35434
35467
  "Any text, symbol, or pattern search over project code goes through `keryx ctx rg`, never a bare `rg`/`grep` \u2014 even a single targeted search, and even when gdgraph/gdwiki are skipped. Raw `rg`/`grep` is a last resort only, with a stated reason recorded in the routing audit.",
35435
35468
  "`keryx ctx rg` and the agent's `search_code` tool require ripgrep (`rg`) on PATH \u2014 install it with `brew install ripgrep` (macOS) or `apt install ripgrep` (Debian/Ubuntu). Without it, code search is unavailable; fall back to reading files directly.",
35436
35469
  "For architecture, domain models, business rules, user scenarios, auth and other flows, integrations, and known decisions, consult the Metaproject gdwiki skill and read the wiki index before deep code reads; use gdgraph to move from a wiki concept to code.",
@@ -35632,6 +35665,7 @@ function renderIndexMarkdown({
35632
35665
  enableGdskills ? "| Any repository task / unclear request | `metaproject-router` | `skills/gdskills/core/metaproject-router/SKILL.md` | Classify the intent first, then route to the narrowest capability. |" : "",
35633
35666
  enableGdskills ? "| Need context / where to start | `context-router` | `skills/gdskills/core/context-router/SKILL.md` | Choose graph, wiki, memory, health, testing, or project-skills before raw reads. |" : "",
35634
35667
  enableGdgraph ? "| Find related files, dependencies, blast radius, cycles, or orphans | `gdgraph` | `skills/gdgraph/SKILL.md`; MCP `gdgraph.*` if available | Start with graph/affected context before broad search. |" : "",
35668
+ enableGdgraph ? "| Files were added, renamed, deleted or moved; graph answers look stale | `gdgraph` | `modules/gdgraph.md` (Freshness & Refresh) | Run `keryx gdgraph build`, then answer from the rebuilt graph. |" : "",
35635
35669
  enableGdwiki ? "| Understand architecture, domain behavior, business rules, scenarios, integrations, or decisions | `gdwiki` | `skills/gdwiki/SKILL.md`; `wiki/index.md`; MCP `wiki.*` if available | Use knowledge pages first, then jump from wiki concepts to code. |" : "",
35636
35670
  enableMemory ? "| Recall past decisions, lessons, constraints, repeated mistakes, or project history | `memory` | `skills/memory/SKILL.md`; MCP `memory.search` if available | Search accepted memory before broad docs or assumptions. |" : "",
35637
35671
  enableTesting ? "| Create/change/debug tests or decide what tests to run | `testing` | `skills/testing/SKILL.md`; `data/testing/context.md` | Use test context and related-test intelligence before raw logs. |" : "",
@@ -35652,6 +35686,9 @@ function renderIndexMarkdown({
35652
35686
  "Any text, symbol, or pattern search over project code goes through `keryx ctx rg`, never a bare `rg`/`grep` \u2014 even a single targeted search, and even when gdgraph/gdwiki are skipped. Raw `rg`/`grep` is a last resort only, with a stated reason.",
35653
35687
  "`keryx ctx rg` and the agent's `search_code` tool require ripgrep (`rg`) on PATH \u2014 install it with `brew install ripgrep` (macOS) or `apt install ripgrep` (Debian/Ubuntu). Without it, code search is unavailable; fall back to reading files directly.",
35654
35688
  enableGdgraph ? "For structural questions (where is X, what files are related, what breaks if I change Y, usages, cycles, orphans) use `skills/gdgraph/SKILL.md` first, before any raw file search. The user does not need to request graph usage explicitly." : "Use relevant skills from `skills/` before raw file search.",
35689
+ ...enableGdgraph ? [
35690
+ "The graph answers from the last `keryx gdgraph build`, not from the working tree. Rebuild before relying on a graph answer when you added, renamed, deleted or moved files in this session, or when `keryx gdgraph context` reports uncommitted code files \u2014 not once per question. If you cannot rebuild, say the graph predates those changes instead of quoting it as current. Contract: `modules/gdgraph.md` (Freshness & Refresh)."
35691
+ ] : [],
35655
35692
  ...enableGdwiki ? [
35656
35693
  "For conceptual questions (how does X work, why, architecture, domain models, business rules, user scenarios, auth and other flows, integrations, known decisions) read `wiki/index.md` first via `skills/gdwiki/SKILL.md`, then use gdgraph to jump from the wiki page to code."
35657
35694
  ] : [],
@@ -37057,13 +37094,23 @@ project-owned hook lines are preserved.
37057
37094
 
37058
37095
  ## git post-commit gdgraph hook
37059
37096
 
37060
- When enabled during \`keryx init\`, the Git \`post-commit\` hook detects commits that touched files relevant to the graph and prints the explicit refresh command.
37097
+ When enabled during \`keryx init\`, the Git \`post-commit\` hook detects commits that touched files relevant to the graph and rebuilds the graph by running \`keryx gdgraph build\`.
37061
37098
 
37062
37099
  Purpose:
37063
37100
 
37064
- - prevent stale graph usage by surfacing the refresh command close to the commit;
37065
- - avoid broad raw file search when graph context is stale;
37066
- - avoid mutating versioned \`.metaproject\` artifacts after the commit is already written.
37101
+ - keep the graph in step with the committed file set, so the next agent question is not answered from the previous one;
37102
+ - avoid broad raw file search caused by a graph that silently predates the commit.
37103
+
37104
+ Behaviour:
37105
+
37106
+ - runs only inside a work tree, and only when the commit touched a graph-relevant path;
37107
+ - resolves \`keryx\` from PATH, then \`$HOME/.local/bin/keryx\`; if neither exists it prints the manual command and returns;
37108
+ - never blocks the commit: a failed or unsupported build prints a warning and still exits 0;
37109
+ - \`KERYX_GDGRAPH_HOOK_REBUILD=0\` turns the hook back into a printed reminder.
37110
+
37111
+ This hook mutates \`.metaproject\` after the commit is written. In a project that versions
37112
+ \`data/gdgraph/artifacts/\`, expect \`summary.md\` and \`module-map.json\` to be modified in the
37113
+ working tree after a graph-relevant commit \u2014 commit them separately, or opt out.
37067
37114
 
37068
37115
  ## git post-commit gdskills hook
37069
37116
 
@@ -37130,7 +37177,12 @@ Rules:
37130
37177
  }
37131
37178
  function renderGdgraphPostCommitHook() {
37132
37179
  return `keryx_gdgraph_post_commit() {
37133
- # Non-mutating: report graph staleness after graph-relevant commits.
37180
+ # Rebuild the code graph after a graph-relevant commit, so the next agent
37181
+ # question is answered from the committed file set instead of the previous one.
37182
+ # Mutating by design: it rewrites graph storage and artifacts, which in a
37183
+ # project that versions data/gdgraph/artifacts leaves them modified after the
37184
+ # commit. Set KERYX_GDGRAPH_HOOK_REBUILD=0 for the old reminder-only behaviour.
37185
+ # Never blocks: every path returns 0, including a failed build.
37134
37186
 
37135
37187
  if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
37136
37188
  return 0
@@ -37145,7 +37197,28 @@ function renderGdgraphPostCommitHook() {
37145
37197
  return 0
37146
37198
  fi
37147
37199
 
37148
- echo "keryx post-commit: gdgraph may be stale; run 'keryx gdgraph build' when you want to refresh graph artifacts"
37200
+ if [ "\${KERYX_GDGRAPH_HOOK_REBUILD:-1}" = "0" ]; then
37201
+ echo "keryx post-commit: gdgraph rebuild disabled (KERYX_GDGRAPH_HOOK_REBUILD=0); graph may be stale, run 'keryx gdgraph build'"
37202
+ return 0
37203
+ fi
37204
+
37205
+ gdm=""
37206
+ if command -v keryx >/dev/null 2>&1; then
37207
+ gdm="keryx"
37208
+ elif [ -x "$HOME/.local/bin/keryx" ]; then
37209
+ gdm="$HOME/.local/bin/keryx"
37210
+ else
37211
+ echo "keryx post-commit: keryx command not found; graph may be stale, run 'keryx gdgraph build'" >&2
37212
+ return 0
37213
+ fi
37214
+
37215
+ echo "keryx post-commit: rebuilding gdgraph after a graph-relevant commit"
37216
+ if "$gdm" gdgraph build >/dev/null 2>&1; then
37217
+ echo "keryx post-commit: gdgraph rebuilt; versioned graph artifacts may now differ from the commit"
37218
+ else
37219
+ echo "keryx post-commit: gdgraph build failed; graph may be stale, run 'keryx gdgraph build'" >&2
37220
+ fi
37221
+
37149
37222
  return 0
37150
37223
  }
37151
37224
 
@@ -37598,6 +37671,45 @@ frontend/static outputs are skipped by default.
37598
37671
  - \`keryx gdgraph query cycles | orphans\`
37599
37672
  - \`keryx gdgraph symbols <enable|disable|status>\` \u2014 opt-in tree-sitter symbol layer
37600
37673
 
37674
+ ## Freshness & Refresh
37675
+
37676
+ The graph is a snapshot of the last \`keryx gdgraph build\`, not a live view of the working tree. A
37677
+ graph answer computed after the file set moved is wrong, and nothing in the answer says so.
37678
+
37679
+ What invalidates it:
37680
+
37681
+ - a source file added, deleted, renamed or moved \u2014 the node set is stale, and \`find\`/\`orphans\`/
37682
+ \`affected\` silently answer from the old one;
37683
+ - an import added or removed \u2014 the edge set is stale, so blast radius under-reports;
37684
+ - an edit inside a file with unchanged imports \u2014 file-level graph unaffected; the opt-in symbol
37685
+ layer (\`symbol\`, \`path\` def/call data) IS stale, because signatures and call sites moved.
37686
+
37687
+ How staleness is observed:
37688
+
37689
+ \`\`\`bash
37690
+ keryx gdgraph context # last line: "freshness: working tree clean"
37691
+ # or "freshness: N uncommitted code file(s) may not be reflected"
37692
+ \`\`\`
37693
+
37694
+ That line counts uncommitted code files against \`HEAD\`; it is a heuristic, not a build ledger. It
37695
+ cannot see committed-but-not-rebuilt changes, so the post-commit hook covers that half.
37696
+
37697
+ How it is repaired:
37698
+
37699
+ \`\`\`bash
37700
+ keryx gdgraph build
37701
+ \`\`\`
37702
+
37703
+ Agent rule: do not rebuild per question \u2014 the graph is meant to be read many times per build. Do
37704
+ rebuild before relying on a graph answer when you added, renamed, deleted or moved files in this
37705
+ session, when the freshness line reports uncommitted code files, or when graph storage is missing.
37706
+ When you cannot rebuild, say the graph predates your changes instead of quoting it as current.
37707
+
37708
+ Automatic refresh: the optional Git \`post-commit\` hook rebuilds the graph after a commit that
37709
+ touched graph-relevant paths (see \`hooks/README.md\`). It never blocks the commit, and
37710
+ \`KERYX_GDGRAPH_HOOK_REBUILD=0\` turns it back into a printed reminder. In a project that versions
37711
+ \`data/gdgraph/artifacts/\`, a rebuild leaves those files modified after the commit.
37712
+
37601
37713
  ## Data
37602
37714
 
37603
37715
  - \`data/gdgraph/artifacts/summary.md\`
@@ -37676,7 +37788,7 @@ Skip gdgraph only when the request is clearly unrelated to project files, asks f
37676
37788
  1. Check whether \`.metaproject/modules/gdgraph.md\` exists.
37677
37789
  2. If the task requires finding relevant project files or understanding relationships, use graph context before any \`rg\` or reading many files. When you do need a text/symbol search, run it as \`keryx ctx rg\`, not raw \`rg\`.
37678
37790
  3. Do not rebuild the graph on every user question. Prefer existing graph storage and curated artifacts.
37679
- 4. Run build only when graph storage is missing, obviously stale, or the user explicitly asks to refresh it:
37791
+ 4. Run build when graph storage is missing, when the file set changed since the last build (you added, renamed, deleted or moved files; \`keryx gdgraph context\` reports uncommitted code files), or when the user asks to refresh it. The freshness contract is \`modules/gdgraph.md\` (Freshness & Refresh):
37680
37792
 
37681
37793
  \`\`\`bash
37682
37794
  keryx gdgraph build
@@ -37728,12 +37840,25 @@ degrades to file-level otherwise).
37728
37840
 
37729
37841
  ## Refresh Policy
37730
37842
 
37731
- Graph refresh should happen through one of these paths:
37732
-
37733
- - user or agent explicitly runs \`keryx gdgraph build\`;
37734
- - Git \`post-commit\` hook refreshes graph after relevant file changes;
37843
+ The graph answers from the last \`keryx gdgraph build\`, never from the working
37844
+ tree, and a stale answer looks exactly like a fresh one. Refresh happens through
37845
+ one of these paths:
37846
+
37847
+ - you or the user run \`keryx gdgraph build\` \u2014 required before you rely on a graph
37848
+ answer after adding, renaming, deleting or moving files in this session, or when
37849
+ \`keryx gdgraph context\` ends with \`freshness: N uncommitted code file(s) may not
37850
+ be reflected\`;
37851
+ - the optional Git \`post-commit\` hook rebuilds the graph after a commit that
37852
+ touched graph-relevant paths. It resolves \`keryx\` from PATH then
37853
+ \`$HOME/.local/bin/keryx\`, never blocks the commit (a failed build only warns),
37854
+ and is turned back into a printed reminder by \`KERYX_GDGRAPH_HOOK_REBUILD=0\`.
37855
+ In a project that versions \`data/gdgraph/artifacts/\`, the rebuild leaves those
37856
+ files modified after the commit;
37735
37857
  - graph storage is missing and the task needs graph context.
37736
37858
 
37859
+ If you cannot rebuild, say the graph predates your changes rather than quoting it
37860
+ as current. The full contract is \`modules/gdgraph.md\` (Freshness & Refresh).
37861
+
37737
37862
  ## Always-on orientation (optional)
37738
37863
 
37739
37864
  Graph usage is advisory by default. Unlike a raw \`rg\` (which the gdctx guard can
@@ -57480,7 +57605,7 @@ function buildToolRegistry() {
57480
57605
  {
57481
57606
  name: "gdgraph.affected",
57482
57607
  module: "gdgraph",
57483
- description: "List the dependencies and dependents of a file from the code graph (blast radius).",
57608
+ description: "List the dependencies and dependents of a file from the code graph (blast radius). " + "Reads the built graph, so results are as old as the last `keryx gdgraph build` and " + "reflect no file added, renamed, deleted or re-imported since it \u2014 a blast radius " + "computed after such a change under-reports. With no graph built at all the result is " + "empty rather than an error, so an empty result means either no dependents or no graph.",
57484
57609
  inputSchema: OBJECT_SCHEMA({
57485
57610
  file: { type: "string", description: "Project-relative file path." },
57486
57611
  depth: { type: "number", description: "Reserved; traversal depth." }
@@ -57972,6 +58097,18 @@ async function serveMcp(options) {
57972
58097
  await startStdioTransport(server);
57973
58098
  }
57974
58099
 
58100
+ // src/commands/mcp-serve-root.ts
58101
+ function resolveServeRoot(explicitCwd, processCwd, env) {
58102
+ if (explicitCwd !== undefined && explicitCwd.trim().length > 0) {
58103
+ return explicitCwd;
58104
+ }
58105
+ const fromRuntime = env.CLAUDE_PROJECT_DIR;
58106
+ if (fromRuntime !== undefined && fromRuntime.trim().length > 0) {
58107
+ return fromRuntime;
58108
+ }
58109
+ return processCwd;
58110
+ }
58111
+
57975
58112
  // src/commands/mcp.ts
57976
58113
  async function mcpCommand(args = [], cwd = process.cwd()) {
57977
58114
  const subcommand = args[0];
@@ -57989,7 +58126,7 @@ async function mcpCommand(args = [], cwd = process.cwd()) {
57989
58126
  }
57990
58127
  if (!subcommand || subcommand === "serve") {
57991
58128
  const http = args.includes("--http");
57992
- const projectRoot = path154.resolve(optionValue(args, "--cwd") ?? cwd);
58129
+ const projectRoot = path154.resolve(resolveServeRoot(optionValue(args, "--cwd"), cwd, process.env));
57993
58130
  try {
57994
58131
  await serveMcp({ cwd: projectRoot, http });
57995
58132
  } catch (error) {
@@ -65964,7 +66101,7 @@ import { spawnSync as spawnSync2 } from "child_process";
65964
66101
  // package.json
65965
66102
  var package_default = {
65966
66103
  name: "@mrciphersmith/keryx",
65967
- version: "0.2.77",
66104
+ version: "0.2.79",
65968
66105
  description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
65969
66106
  private: false,
65970
66107
  publishConfig: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrciphersmith/keryx",
3
- "version": "0.2.77",
3
+ "version": "0.2.79",
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": {