@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.
@@ -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
- 'check',
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(Boolean));
281
- return b
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(Boolean)
285
- .some((token) => aTokens.has(token));
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
- return import.meta.url === `file://${process.argv[1]}`;
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
- ## KGraph Workflow
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 "$ARGUMENTS" --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.
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 "$ARGUMENTS"\` to show who or what created a knowledge atom, the source command/session/commit, evidence refs, and lifecycle links.
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 "$ARGUMENTS" --capture-file <path> --capture-symbol <name>\` when the session produced reusable engineering knowledge. Use low-level \`kgraph conclude "$ARGUMENTS"\` 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.
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 "$ARGUMENTS"\` to show matched files/symbols, import users, callers, callees, related knowledge atoms, and risk hints.
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 "$ARGUMENTS"\` to display processed cognition sessions. Summarize who contributed what and when. Use \`--last <n>\` to limit entries.
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 ? `${block}\n\n${normalized}\n` : `${block}\n`;
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 9-step numbered workflow for skill/agent/command files.
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
- function inboxStep(agentName) {
12
- return `If the previous command output contains "pending inbox" or a \`pendingInbox\` field with count > 0, you MUST run \`kgraph "<topic>" --agent ${agentName}\` or \`kgraph update\` immediately before proceeding. Do not skip this step.`;
13
- }
14
- function packStep(agentName) {
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 9-step numbered workflow for skill/agent/command files.
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. ${inboxStep(agentName)}
36
- 4. ${ROUTING_STEP}
37
- 5. Use the returned files, symbols, relationships, and cognition before broad exploration.
38
- 6. ${EXPLORATION_BOUNDARY_STEP}
39
- 7. ${VERIFY_EDIT_STEP}
40
- 8. ${smartRootStep(agentName)}
41
- 9. ${packStep(agentName)}
42
- 10. ${KNOWLEDGE_STEP}
43
- 11. ${DOCTOR_STEP}
44
- 12. ${STALE_STEP}
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
- 15. ${REPAIR_STEP}
51
- 16. ${COMPACT_STEP}
52
- 17. Run \`kgraph visualize\` when the user wants to inspect the dependency graph — opens an interactive graph at http://localhost:4242 with PNG export.
53
- 18. ${HISTORY_STEP}`;
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
- - ${inboxStep(agentName)}
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 at http://localhost:4242 with PNG export.
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('\n').entries()) {
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('/').pop() ?? 'Repository');
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>');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kentwynn/kgraph",
3
- "version": "0.2.31",
3
+ "version": "0.2.32",
4
4
  "description": "Persistent repo intelligence for AI coding assistants.",
5
5
  "type": "module",
6
6
  "bin": {