@kage-core/kage-graph-mcp 1.1.3 → 1.1.4
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/kernel.js +61 -12
- package/package.json +1 -1
package/dist/kernel.js
CHANGED
|
@@ -180,11 +180,23 @@ Keep captures concise and future-facing. Do not store raw transcripts.
|
|
|
180
180
|
|
|
181
181
|
## End-Of-Task Proposal
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
After meaningful file changes, call \`kage_refresh\` so indexes, code graph,
|
|
184
|
+
memory graph, metrics, and stale-memory checks are current.
|
|
184
185
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
Before finishing a task that changed files, call \`kage_pr_summarize\` or
|
|
187
|
+
\`kage_propose_from_diff\`, then call \`kage_pr_check\`.
|
|
188
|
+
|
|
189
|
+
\`kage_pr_summarize\` writes a branch review summary and a repo-local
|
|
190
|
+
change-memory packet. \`kage_pr_check\` verifies validation, graph freshness,
|
|
191
|
+
stale packets, and whether repo memory changed with the branch. If the check
|
|
192
|
+
fails, explain the required actions instead of hiding the failure. Git or PR
|
|
193
|
+
review is the repo-level review boundary.
|
|
194
|
+
|
|
195
|
+
## Package Updates
|
|
196
|
+
|
|
197
|
+
If the user asks to update Kage, run \`kage upgrade\`, then verify setup with
|
|
198
|
+
\`kage setup verify-agent --agent <agent> --project <repo>\`. Tell the user to
|
|
199
|
+
restart the agent when MCP tools need to reload.
|
|
188
200
|
|
|
189
201
|
## Feedback
|
|
190
202
|
|
|
@@ -210,7 +222,9 @@ For normal coding tasks:
|
|
|
210
222
|
4. \`kage_graph\` for remembered decisions, bugs, workflows, and conventions
|
|
211
223
|
5. Work on the task
|
|
212
224
|
6. \`kage_learn\` for concrete learnings
|
|
213
|
-
7. \`
|
|
225
|
+
7. \`kage_refresh\` after meaningful file changes
|
|
226
|
+
8. \`kage_pr_summarize\` or \`kage_propose_from_diff\` before the final response to create repo-local change memory
|
|
227
|
+
9. \`kage_pr_check\` before final handoff or merge readiness claims
|
|
214
228
|
|
|
215
229
|
For quick factual questions, \`kage_recall\` alone is enough. For status or demo requests, call \`kage_metrics\`.
|
|
216
230
|
${AGENTS_POLICY_END}
|
|
@@ -3414,22 +3428,42 @@ Before making code changes or answering implementation questions:
|
|
|
3414
3428
|
3. Call kage_code_graph for file, symbol, route, test, or dependency questions.
|
|
3415
3429
|
4. Call kage_graph for decisions, bugs, workflows, and conventions.
|
|
3416
3430
|
When you learn something reusable: kage_learn.
|
|
3417
|
-
|
|
3431
|
+
After meaningful file changes: kage_refresh.
|
|
3432
|
+
Before finishing a task that changed files: kage_pr_summarize or kage_propose_from_diff, then kage_pr_check.
|
|
3418
3433
|
If recalled memory helped: kage_feedback helpful. If wrong or stale: kage_feedback wrong or stale."
|
|
3419
3434
|
fi
|
|
3420
3435
|
|
|
3421
3436
|
KAGE_MSG="$POLICY" python3 -c "import json,os; print(json.dumps({'systemMessage': os.environ['KAGE_MSG']}))"
|
|
3437
|
+
`;
|
|
3438
|
+
const stopHookScript = `#!/usr/bin/env bash
|
|
3439
|
+
# Kage Stop hook — best-effort repo memory refresh before Claude Code finishes.
|
|
3440
|
+
# Silent if Kage is not initialized in the current project or no git changes exist.
|
|
3441
|
+
set -euo pipefail
|
|
3442
|
+
|
|
3443
|
+
PAYLOAD="$(cat || true)"
|
|
3444
|
+
CWD="$(printf "%s" "$PAYLOAD" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('cwd',''))" 2>/dev/null || echo "")"
|
|
3445
|
+
|
|
3446
|
+
[[ -d "$CWD/.agent_memory" ]] || exit 0
|
|
3447
|
+
command -v kage >/dev/null 2>&1 || exit 0
|
|
3448
|
+
|
|
3449
|
+
if git -C "$CWD" status --porcelain -uall >/dev/null 2>&1 && [[ -n "$(git -C "$CWD" status --porcelain -uall)" ]]; then
|
|
3450
|
+
kage refresh --project "$CWD" --json >/dev/null 2>&1 || true
|
|
3451
|
+
kage pr summarize --project "$CWD" --json >/dev/null 2>&1 || true
|
|
3452
|
+
fi
|
|
3453
|
+
|
|
3454
|
+
exit 0
|
|
3422
3455
|
`;
|
|
3423
3456
|
const settingsPath = (0, node_path_1.join)(home, ".claude", "settings.json");
|
|
3424
3457
|
const hookEntry = {
|
|
3425
3458
|
hooks: {
|
|
3426
3459
|
SessionStart: [{ matcher: "", hooks: [{ type: "command", command: "bash ~/.claude/kage/hooks/session-start.sh", timeout: 5 }] }],
|
|
3460
|
+
Stop: [{ matcher: "", hooks: [{ type: "command", command: "bash ~/.claude/kage/hooks/stop.sh", timeout: 20 }] }],
|
|
3427
3461
|
},
|
|
3428
3462
|
};
|
|
3429
3463
|
setSnippet(path, JSON.stringify({ mcpServers: { kage: server } }, null, 2), [
|
|
3430
3464
|
"Add the MCP server to ~/.claude.json, then restart Claude Code.",
|
|
3431
3465
|
"alwaysLoad: true makes Kage tools immediately visible without requiring ToolSearch.",
|
|
3432
|
-
`Also create ${hookDir}/session-start.sh with the hook
|
|
3466
|
+
`Also create ${hookDir}/session-start.sh and ${hookDir}/stop.sh with the hook scripts and add SessionStart/Stop hooks to ~/.claude/settings.json.`,
|
|
3433
3467
|
"Run `kage init --project <repo>` inside each repo to install the ambient memory policy.",
|
|
3434
3468
|
], true);
|
|
3435
3469
|
if (options.write) {
|
|
@@ -3437,6 +3471,7 @@ KAGE_MSG="$POLICY" python3 -c "import json,os; print(json.dumps({'systemMessage'
|
|
|
3437
3471
|
// Install the ambient session-start hook
|
|
3438
3472
|
(0, node_fs_1.mkdirSync)(hookDir, { recursive: true });
|
|
3439
3473
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(hookDir, "session-start.sh"), hookScript, { mode: 0o755 });
|
|
3474
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(hookDir, "stop.sh"), stopHookScript, { mode: 0o755 });
|
|
3440
3475
|
upsertJsonSettings(settingsPath, hookEntry);
|
|
3441
3476
|
result.wrote = true;
|
|
3442
3477
|
}
|
|
@@ -3862,11 +3897,25 @@ function distillSession(projectDir, sessionId) {
|
|
|
3862
3897
|
function createDiffChangeMemory(projectDir, summary) {
|
|
3863
3898
|
const branch = summary.branch ?? "detached";
|
|
3864
3899
|
const head = summary.head ?? "unknown";
|
|
3865
|
-
const fingerprint = (0, node_crypto_1.createHash)("sha256")
|
|
3866
|
-
.update(`${branch}\n${head}\n${summary.changed_files.join("\n")}\n${summary.diff_stat}`)
|
|
3867
|
-
.digest("hex")
|
|
3868
|
-
.slice(0, 10);
|
|
3869
3900
|
const title = `Change memory: ${branch}`;
|
|
3901
|
+
// Remove any stale change-memory packets for this branch so propose_from_diff
|
|
3902
|
+
// replaces rather than accumulates. The stable ID (branch-only, no fingerprint)
|
|
3903
|
+
// makes writePacket idempotent going forward; this sweep handles packets that
|
|
3904
|
+
// were written with the old fingerprint-based ID.
|
|
3905
|
+
const stalePrefix = `workflow-${slugify(title)}-`;
|
|
3906
|
+
const stableId = makePacketId(projectDir, "workflow", title);
|
|
3907
|
+
const stableFileName = `${stalePrefix}${(0, node_crypto_1.createHash)("sha256").update(stableId).digest("hex").slice(0, 8)}.json`;
|
|
3908
|
+
try {
|
|
3909
|
+
const existing = (0, node_fs_1.readdirSync)(packetsDir(projectDir)).filter((name) => name.startsWith(stalePrefix) && name !== stableFileName);
|
|
3910
|
+
for (const name of existing) {
|
|
3911
|
+
const stale = (0, node_path_1.join)(packetsDir(projectDir), name);
|
|
3912
|
+
const stalePacket = readJson(stale);
|
|
3913
|
+
if (stalePacket?.type === "workflow" && stalePacket?.title === title) {
|
|
3914
|
+
(0, node_fs_1.unlinkSync)(stale);
|
|
3915
|
+
}
|
|
3916
|
+
}
|
|
3917
|
+
}
|
|
3918
|
+
catch { /* non-fatal */ }
|
|
3870
3919
|
const verifyCommands = npmScriptCommands(projectDir)
|
|
3871
3920
|
.filter((command) => /(test|check|lint|build|type|verify)/i.test(command))
|
|
3872
3921
|
.slice(0, 8);
|
|
@@ -3900,7 +3949,7 @@ function createDiffChangeMemory(projectDir, summary) {
|
|
|
3900
3949
|
const now = nowIso();
|
|
3901
3950
|
const packet = {
|
|
3902
3951
|
schema_version: exports.PACKET_SCHEMA_VERSION,
|
|
3903
|
-
id:
|
|
3952
|
+
id: stableId,
|
|
3904
3953
|
title,
|
|
3905
3954
|
summary: `Repo-local context for ${summary.changed_files.length} changed repo path${summary.changed_files.length === 1 ? "" : "s"} on ${branch}.`,
|
|
3906
3955
|
body,
|