@kentwynn/kgraph 0.2.31 → 0.2.32
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/commands/workflow.js +26 -9
- package/dist/cli/index.js +3 -1
- package/dist/integrations/adapters/copilot.js +5 -1
- package/dist/integrations/agent-skills.js +5 -5
- package/dist/integrations/instruction-blocks.js +2 -2
- package/dist/integrations/workflow-steps.d.ts +1 -1
- package/dist/integrations/workflow-steps.js +22 -31
- package/dist/knowledge/atom-store.js +1 -1
- package/dist/visualization/html-template.js +1 -1
- package/package.json +1 -1
|
@@ -3,8 +3,8 @@ import { concludeTopic } from '../../cognition/conclusion.js';
|
|
|
3
3
|
import { loadConfig } from '../../config/config.js';
|
|
4
4
|
import { queryContext } from '../../context/context-query.js';
|
|
5
5
|
import { refreshKnowledgeAtomStatuses } from '../../knowledge/atom-store.js';
|
|
6
|
-
import { getWorkingTreeChanges } from '../../scanner/git-utils.js';
|
|
7
6
|
import { shouldExclude } from '../../scanner/file-classifier.js';
|
|
7
|
+
import { getWorkingTreeChanges } from '../../scanner/git-utils.js';
|
|
8
8
|
import { scanRepository } from '../../scanner/repo-scanner.js';
|
|
9
9
|
import { assertSessionAgent, recordSessionEvent, } from '../../session/session-store.js';
|
|
10
10
|
import { listInboxNotes } from '../../storage/cognition-store.js';
|
|
@@ -104,8 +104,7 @@ export async function runDefaultWorkflow(query, options = {}) {
|
|
|
104
104
|
atomsProcessed: update.processed.length,
|
|
105
105
|
pendingInbox: pendingInbox.length,
|
|
106
106
|
activeAtoms: activeAtoms.length,
|
|
107
|
-
needsReviewAtoms: atoms.filter((atom) => atom.status === 'needs-review')
|
|
108
|
-
.length,
|
|
107
|
+
needsReviewAtoms: atoms.filter((atom) => atom.status === 'needs-review').length,
|
|
109
108
|
staleAtoms: atoms.filter((atom) => atom.status === 'stale').length,
|
|
110
109
|
highConfidenceMissingEvidence: activeAtoms.filter((atom) => atom.confidence === 'high' && atom.evidenceRefs.length === 0).length,
|
|
111
110
|
captureRequired: captureCheck.required,
|
|
@@ -250,17 +249,33 @@ function meaningfulTopicOverlap(a, b) {
|
|
|
250
249
|
const weakTokens = new Set([
|
|
251
250
|
'add',
|
|
252
251
|
'after',
|
|
252
|
+
'and',
|
|
253
253
|
'behavior',
|
|
254
254
|
'change',
|
|
255
255
|
'changed',
|
|
256
|
+
'check',
|
|
257
|
+
'code',
|
|
258
|
+
'current',
|
|
259
|
+
'file',
|
|
260
|
+
'fix',
|
|
261
|
+
'for',
|
|
262
|
+
'from',
|
|
263
|
+
'get',
|
|
264
|
+
'into',
|
|
256
265
|
'new',
|
|
266
|
+
'not',
|
|
257
267
|
'old',
|
|
258
268
|
'review',
|
|
259
|
-
'
|
|
260
|
-
'current',
|
|
269
|
+
'run',
|
|
261
270
|
'session',
|
|
271
|
+
'set',
|
|
262
272
|
'smoke',
|
|
273
|
+
'test',
|
|
274
|
+
'that',
|
|
275
|
+
'the',
|
|
276
|
+
'this',
|
|
263
277
|
'update',
|
|
278
|
+
'use',
|
|
264
279
|
'with',
|
|
265
280
|
]);
|
|
266
281
|
const aTokens = new Set(a
|
|
@@ -277,12 +292,14 @@ function tokenOverlap(a, b) {
|
|
|
277
292
|
const aTokens = new Set(a
|
|
278
293
|
.toLowerCase()
|
|
279
294
|
.split(/[^a-z0-9]+/)
|
|
280
|
-
.filter(
|
|
281
|
-
|
|
295
|
+
.filter((token) => token.length >= 4));
|
|
296
|
+
if (aTokens.size === 0)
|
|
297
|
+
return false;
|
|
298
|
+
const matches = b
|
|
282
299
|
.toLowerCase()
|
|
283
300
|
.split(/[^a-z0-9]+/)
|
|
284
|
-
.filter(
|
|
285
|
-
|
|
301
|
+
.filter((token) => token.length >= 4 && aTokens.has(token));
|
|
302
|
+
return matches.length >= 2;
|
|
286
303
|
}
|
|
287
304
|
function matchingInvalidatedAtoms(atoms, topic) {
|
|
288
305
|
const tokens = new Set((topic ?? '')
|
package/dist/cli/index.js
CHANGED
|
@@ -130,6 +130,8 @@ function isCliEntrypoint() {
|
|
|
130
130
|
realpathSync(process.argv[1]));
|
|
131
131
|
}
|
|
132
132
|
catch {
|
|
133
|
-
|
|
133
|
+
const argv1 = process.argv[1].replace(/\\/g, '/');
|
|
134
|
+
return (import.meta.url === `file://${argv1}` ||
|
|
135
|
+
import.meta.url === `file:///${argv1}`);
|
|
134
136
|
}
|
|
135
137
|
}
|
|
@@ -16,7 +16,11 @@ ${numberedWorkflow('copilot')}
|
|
|
16
16
|
description: Use KGraph persistent repo intelligence — runs kgraph before answering to provide file maps, symbols, relationships, and durable knowledge atoms.
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
# KGraph Agent
|
|
20
|
+
|
|
21
|
+
You are the KGraph agent. You use the \`kgraph\` CLI via the terminal to provide persistent repo intelligence before answering questions or making edits.
|
|
22
|
+
|
|
23
|
+
## Workflow
|
|
20
24
|
|
|
21
25
|
${numberedWorkflow('copilot')}
|
|
22
26
|
`,
|
|
@@ -45,7 +45,7 @@ name: kgraph-pack
|
|
|
45
45
|
description: Build a budget-aware KGraph context pack
|
|
46
46
|
---
|
|
47
47
|
|
|
48
|
-
Run \`kgraph pack "
|
|
48
|
+
Run \`kgraph pack "<topic>" --budget 8000 --json --agent $AGENT\` to build a machine-readable context pack and record lightweight session context. Summarize token use, included files, symbols, relationships, git changes, session history, atoms, and omitted items with the inclusion reasons. When a symbol item includes an \`excerpt\` field, you already have the source — do not read that file for the symbol.
|
|
49
49
|
`,
|
|
50
50
|
},
|
|
51
51
|
{
|
|
@@ -75,7 +75,7 @@ name: kgraph-blame
|
|
|
75
75
|
description: Show KGraph atom provenance and evidence
|
|
76
76
|
---
|
|
77
77
|
|
|
78
|
-
Run \`kgraph blame
|
|
78
|
+
Run \`kgraph blame <atom-id>\` to show who or what created a knowledge atom, the source command/session/commit, evidence refs, and lifecycle links.
|
|
79
79
|
`,
|
|
80
80
|
},
|
|
81
81
|
{
|
|
@@ -127,7 +127,7 @@ name: kgraph-conclude
|
|
|
127
127
|
description: Store a typed durable KGraph engineering conclusion
|
|
128
128
|
---
|
|
129
129
|
|
|
130
|
-
Prefer \`kgraph "<topic>" --capture "
|
|
130
|
+
Prefer \`kgraph "<topic>" --capture "<durable conclusion>" --capture-file <path> --capture-symbol <name>\` when the session produced reusable engineering knowledge. Use low-level \`kgraph conclude "<topic>" --note "<conclusion>"\` only when the user explicitly asks for the conclude command. Choose one type from finding, decision, gotcha, summary, relationship, and one confidence from high, medium, low. Add file or symbol evidence whenever possible; high-confidence conclusions require evidence. Store only durable conclusions, not raw chain-of-thought, temporary reasoning, speculative exploration, or low-value observations.
|
|
131
131
|
`,
|
|
132
132
|
},
|
|
133
133
|
{
|
|
@@ -137,7 +137,7 @@ name: kgraph-impact
|
|
|
137
137
|
description: Show KGraph change impact for a file, symbol, or topic
|
|
138
138
|
---
|
|
139
139
|
|
|
140
|
-
Run \`kgraph impact "
|
|
140
|
+
Run \`kgraph impact "<file-or-symbol>"\` to show matched files/symbols, import users, callers, callees, related knowledge atoms, and risk hints.
|
|
141
141
|
`,
|
|
142
142
|
},
|
|
143
143
|
{
|
|
@@ -157,7 +157,7 @@ name: kgraph-history
|
|
|
157
157
|
description: Show timeline of KGraph cognition sessions with git attribution
|
|
158
158
|
---
|
|
159
159
|
|
|
160
|
-
Run \`kgraph history\` or \`kgraph history "
|
|
160
|
+
Run \`kgraph history\` or \`kgraph history "<topic>"\` to display processed cognition sessions. Summarize who contributed what and when. Use \`--last <n>\` to limit entries.
|
|
161
161
|
`,
|
|
162
162
|
},
|
|
163
163
|
];
|
|
@@ -9,7 +9,7 @@ export function upsertManagedBlock(content, integrationName, instructions) {
|
|
|
9
9
|
if (pattern.test(content)) {
|
|
10
10
|
return content.replace(pattern, block);
|
|
11
11
|
}
|
|
12
|
-
return normalized ? `${
|
|
12
|
+
return normalized ? `${normalized}\n\n${block}\n` : `${block}\n`;
|
|
13
13
|
}
|
|
14
14
|
export function removeManagedBlock(content, integrationName) {
|
|
15
15
|
return (content
|
|
@@ -25,7 +25,7 @@ function renderManagedBlock(integrationName, instructions) {
|
|
|
25
25
|
].join('\n');
|
|
26
26
|
}
|
|
27
27
|
function managedBlockPattern(integrationName) {
|
|
28
|
-
return new RegExp(`${escapeRegExp(MARKER_PREFIX)} BEGIN KGRAPH ${escapeRegExp(integrationName)} ${escapeRegExp(MARKER_SUFFIX)}[\\s\\S]*?${escapeRegExp(MARKER_PREFIX)} END KGRAPH ${escapeRegExp(integrationName)} ${escapeRegExp(MARKER_SUFFIX)}\\n?`, 'm');
|
|
28
|
+
return new RegExp(`${escapeRegExp(MARKER_PREFIX)} BEGIN KGRAPH ${escapeRegExp(integrationName)} ${escapeRegExp(MARKER_SUFFIX)}[\\s\\S]*?${escapeRegExp(MARKER_PREFIX)} END KGRAPH ${escapeRegExp(integrationName)} ${escapeRegExp(MARKER_SUFFIX)}\\r?\\n?`, 'm');
|
|
29
29
|
}
|
|
30
30
|
function escapeRegExp(value) {
|
|
31
31
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
@@ -7,7 +7,7 @@ export interface WorkflowOptions {
|
|
|
7
7
|
sessionQualifier?: string;
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
|
-
* Returns the
|
|
10
|
+
* Returns the numbered workflow for skill/agent/command files.
|
|
11
11
|
* Used by: copilot (agent file), codex (skill file), claude-code (command file).
|
|
12
12
|
*/
|
|
13
13
|
export declare function numberedWorkflow(agentName: string, options?: WorkflowOptions): string;
|
|
@@ -8,49 +8,41 @@ const REPAIR_STEP = `Run \`kgraph repair --dry-run\` before cleanup when stale/n
|
|
|
8
8
|
const COMPACT_STEP = `Run \`kgraph compact --dry-run\` when cognition looks duplicated, noisy, or stale. Run \`kgraph compact\` only when the user asks to merge/archive cognition.`;
|
|
9
9
|
const HISTORY_STEP = `Run \`kgraph history\` or \`kgraph history "<topic>"\` to review past cognition sessions with git author attribution.`;
|
|
10
10
|
const KNOWLEDGE_STEP = `Run \`kgraph knowledge list --topic "<topic>"\` or \`kgraph knowledge get <atom-id>\` when the user asks what KGraph remembers or atom provenance/lifecycle matters.`;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return `For normal coding context, treat \`kgraph pack "<task>" --budget 8000 --json --agent ${agentName}\` as the machine-readable context contract: use atoms, source ranges, git changes, omitted items, and inclusion reasons from the ContextPack before reading files.`;
|
|
16
|
-
}
|
|
11
|
+
const STALE_STEP = `Run \`kgraph stale\` when changed or deleted code may have invalidated durable knowledge. Run \`kgraph blame <atom-id>\` when provenance or evidence for a memory matters.`;
|
|
12
|
+
const EXPLORATION_BOUNDARY_STEP = `Keep exploration bounded by the task. For simple edits, use KGraph to identify the likely file, then read only that file or a narrow range and make the edit. Do not keep searching after the target file is found, do not retry malformed shell commands with broader variants, and do not run broad \`find\`, recursive \`grep\`, or repeated full-file dumps after KGraph already returned candidate files.`;
|
|
13
|
+
const VERIFY_EDIT_STEP = `After editing, verify the change actually landed before claiming completion. Prefer a narrow read of the changed range or \`git diff -- <path>\`; if there is no diff or the expected text is missing, say the edit did not apply and fix it before summarizing.`;
|
|
14
|
+
const SCAN_STEP = `After bulk file creation, deletion, or rename (3+ files), run \`kgraph scan\` before the next \`kgraph pack\` so maps stay accurate.`;
|
|
17
15
|
function smartRootStep(agentName) {
|
|
18
16
|
return `Use the root workflow when refresh or memory processing matters: run \`kgraph "<topic>" --agent ${agentName}\` to refresh maps, process inbox notes, and return a briefing; run \`kgraph "<topic>" --final --agent ${agentName}\` before the final answer when repository files changed; run \`kgraph "<topic>" --capture "<durable conclusion>" --capture-file <path> --capture-symbol <name> --agent ${agentName}\` when the final check requires durable knowledge.`;
|
|
19
17
|
}
|
|
20
|
-
const STALE_STEP = `Run \`kgraph stale\` when changed or deleted code may have invalidated durable knowledge. Run \`kgraph blame <atom-id>\` when provenance or evidence for a memory matters.`;
|
|
21
|
-
const EXPLORATION_BOUNDARY_STEP = `Keep exploration bounded by the task. For simple edits, use KGraph to identify the likely file, then read only that file or a narrow range and make the edit. Do not keep searching after the target file is found, do not retry malformed shell commands with broader variants, and do not run broad \`find\`, recursive \`grep\`, or repeated full-file dumps after KGraph already returned candidate files. Use \`rg --files\` and quoted paths when a path must be located.`;
|
|
22
|
-
const VERIFY_EDIT_STEP = `After editing, verify the change actually landed before claiming completion. Prefer a narrow read of the changed range or \`git diff -- <path>\`; if there is no diff or the expected text is missing, say the edit did not apply and fix it before summarizing.`;
|
|
23
|
-
const ROUTING_STEP = `Route explicit KGraph requests to the matching command before any default context lookup: history/prior work -> \`kgraph history "<topic>"\`; inbox/pending capture/process notes/update cognition -> \`kgraph "<topic>"\` or \`kgraph update\`; remembered knowledge/atoms/provenance -> \`kgraph knowledge list --topic "<topic>"\` or \`kgraph knowledge get <atom-id>\`; setup/health -> \`kgraph doctor\`.`;
|
|
24
18
|
function sessionStep(agentName, qualifier) {
|
|
25
19
|
const base = `Track meaningful session activity with \`kgraph session start --agent ${agentName}\`, \`kgraph session read <path> --agent ${agentName}\`, \`kgraph session write <path> --agent ${agentName}\`, and \`kgraph session end --agent ${agentName} --conclude --topic "<topic>"\` when durable session memory is useful`;
|
|
26
20
|
return qualifier ? `${base} ${qualifier}.` : `${base}.`;
|
|
27
21
|
}
|
|
28
22
|
/**
|
|
29
|
-
* Returns the
|
|
23
|
+
* Returns the numbered workflow for skill/agent/command files.
|
|
30
24
|
* Used by: copilot (agent file), codex (skill file), claude-code (command file).
|
|
31
25
|
*/
|
|
32
26
|
export function numberedWorkflow(agentName, options = {}) {
|
|
33
27
|
return `1. Infer the topic from the user's request.
|
|
34
28
|
2. {{KGRAPH_CONTEXT_POLICY}}
|
|
35
|
-
3.
|
|
36
|
-
4. ${
|
|
37
|
-
5.
|
|
38
|
-
6. ${
|
|
39
|
-
7. ${
|
|
40
|
-
8. ${
|
|
41
|
-
9. ${
|
|
42
|
-
10. ${
|
|
43
|
-
11. ${
|
|
44
|
-
12. ${
|
|
45
|
-
13. ${sessionStep(agentName, options.sessionQualifier)}
|
|
46
|
-
14. ${IMPACT_STEP}
|
|
29
|
+
3. When the pack includes a symbol with an \`excerpt\` field, you already have the source code — do not read that file again for that symbol. Items in the \`omitted\` array were evaluated and excluded — do not manually search for them unless the user explicitly asks.
|
|
30
|
+
4. ${EXPLORATION_BOUNDARY_STEP}
|
|
31
|
+
5. ${VERIFY_EDIT_STEP}
|
|
32
|
+
6. ${smartRootStep(agentName)}
|
|
33
|
+
7. ${KNOWLEDGE_STEP}
|
|
34
|
+
8. ${DOCTOR_STEP}
|
|
35
|
+
9. ${STALE_STEP}
|
|
36
|
+
10. ${SCAN_STEP}
|
|
37
|
+
11. ${sessionStep(agentName, options.sessionQualifier)}
|
|
38
|
+
12. ${IMPACT_STEP}
|
|
47
39
|
|
|
48
40
|
{{KGRAPH_CAPTURE_POLICY}}
|
|
49
41
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
42
|
+
13. ${REPAIR_STEP}
|
|
43
|
+
14. ${COMPACT_STEP}
|
|
44
|
+
15. Run \`kgraph visualize\` when the user wants to inspect the dependency graph — opens an interactive graph locally with PNG export.
|
|
45
|
+
16. ${HISTORY_STEP}`;
|
|
54
46
|
}
|
|
55
47
|
/**
|
|
56
48
|
* Returns the bullet-list workflow for rules files.
|
|
@@ -58,20 +50,19 @@ export function numberedWorkflow(agentName, options = {}) {
|
|
|
58
50
|
*/
|
|
59
51
|
export function bulletWorkflow(agentName, options = {}) {
|
|
60
52
|
return `- {{KGRAPH_CONTEXT_POLICY}}
|
|
61
|
-
-
|
|
62
|
-
- ${ROUTING_STEP}
|
|
53
|
+
- When the pack includes a symbol with an \`excerpt\` field, you already have the source code — do not read that file again for that symbol. Items in the \`omitted\` array were evaluated and excluded — do not manually search for them unless the user explicitly asks.
|
|
63
54
|
- ${EXPLORATION_BOUNDARY_STEP}
|
|
64
55
|
- ${VERIFY_EDIT_STEP}
|
|
65
56
|
- ${smartRootStep(agentName)}
|
|
66
|
-
- ${packStep(agentName)}
|
|
67
57
|
- ${KNOWLEDGE_STEP}
|
|
68
58
|
- ${DOCTOR_STEP}
|
|
69
59
|
- ${STALE_STEP}
|
|
60
|
+
- ${SCAN_STEP}
|
|
70
61
|
- ${sessionStep(agentName, options.sessionQualifier)}
|
|
71
62
|
- ${IMPACT_STEP}
|
|
72
63
|
{{KGRAPH_CAPTURE_POLICY}}
|
|
73
64
|
- ${REPAIR_STEP}
|
|
74
65
|
- ${COMPACT_STEP}
|
|
75
|
-
- Run \`kgraph visualize\` to open the interactive dependency graph
|
|
66
|
+
- Run \`kgraph visualize\` to open the interactive dependency graph locally with PNG export.
|
|
76
67
|
- ${HISTORY_STEP}`;
|
|
77
68
|
}
|
|
@@ -33,7 +33,7 @@ export async function readAtomsFile(workspace) {
|
|
|
33
33
|
}
|
|
34
34
|
export function parseAtomsJsonl(raw) {
|
|
35
35
|
const atoms = [];
|
|
36
|
-
for (const [index, line] of raw.split(
|
|
36
|
+
for (const [index, line] of raw.split(/\r?\n/).entries()) {
|
|
37
37
|
if (!line.trim())
|
|
38
38
|
continue;
|
|
39
39
|
try {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export function renderHtml(graphData, rootPath) {
|
|
2
|
-
const repoName = escAttr(rootPath.split(
|
|
2
|
+
const repoName = escAttr(rootPath.split(/[\\/]/).pop() ?? 'Repository');
|
|
3
3
|
const { meta } = graphData;
|
|
4
4
|
// Prevent </script> tag injection from embedded JSON
|
|
5
5
|
const safeData = JSON.stringify(graphData).replace(/<\/script>/gi, '<\\/script>');
|