@kentwynn/kgraph 0.2.16 → 0.2.18
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/README.md +4 -2
- package/dist/cli/commands/pack.d.ts +2 -0
- package/dist/cli/commands/pack.js +60 -13
- package/dist/context/context-pack.js +59 -0
- package/dist/integrations/adapters/codex.js +3 -21
- package/dist/integrations/adapters/copilot.js +3 -168
- package/dist/integrations/agent-skills.d.ts +15 -0
- package/dist/integrations/agent-skills.js +186 -0
- package/dist/integrations/instruction-blocks.js +5 -5
- package/dist/integrations/integration-store.js +35 -4
- package/dist/integrations/workflow-steps.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -121,12 +121,14 @@ After useful AI work, assistants save durable runtime-capture notes into `.kgrap
|
|
|
121
121
|
Normal agent flow is intentionally small:
|
|
122
122
|
|
|
123
123
|
```bash
|
|
124
|
-
kgraph "topic"
|
|
124
|
+
kgraph pack "topic" --budget 8000 --json
|
|
125
125
|
# work normally
|
|
126
126
|
# if repo files changed, write an inbox note before the final refresh
|
|
127
127
|
kgraph
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
+
`kgraph "<topic>"` remains the human-readable briefing. Agents should prefer `kgraph pack "<topic>" --budget 8000 --json` because it returns the stable `ContextPack` contract with atoms, source ranges, git changes, omitted items, token estimates, and inclusion reasons.
|
|
131
|
+
|
|
130
132
|
Use `kgraph doctor` after setup and before trusting a repo's saved intelligence. It checks initialization, maps, pending inbox notes, integration targets, and actionable quality problems. Use `kgraph doctor --quality` and `kgraph repair --dry-run` when stale or noisy atom references start making context harder to trust.
|
|
131
133
|
|
|
132
134
|
Agents can also report session activity so KGraph can estimate token waste:
|
|
@@ -249,7 +251,7 @@ kgraph pack "auth token refresh" --budget 8000
|
|
|
249
251
|
kgraph pack "auth token refresh" --budget 8000 --json
|
|
250
252
|
```
|
|
251
253
|
|
|
252
|
-
Build a budget-aware context pack from files, symbols, relationships, git changes, session history, and knowledge atoms. JSON output is the stable machine-readable contract for agents.
|
|
254
|
+
Build a budget-aware context pack from files, source ranges, symbols, relationships, git changes, session history, and knowledge atoms. JSON output is the stable machine-readable contract for agents; text output is an Atom Core briefing for humans.
|
|
253
255
|
|
|
254
256
|
```bash
|
|
255
257
|
kgraph compact --dry-run
|
|
@@ -31,19 +31,66 @@ export function registerPackCommand(program) {
|
|
|
31
31
|
console.log(JSON.stringify(pack, null, 2));
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
|
-
console.log(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
console.log(renderPackText(pack));
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
export function renderPackText(pack) {
|
|
38
|
+
const lines = [
|
|
39
|
+
`KGraph Pack · ${pack.task}`,
|
|
40
|
+
`local-first · budget-aware · machine contract: --json`,
|
|
41
|
+
``,
|
|
42
|
+
`● Budget`,
|
|
43
|
+
` used ${pack.usedTokens} / ${pack.budget}`,
|
|
44
|
+
` included ${pack.items.length}`,
|
|
45
|
+
` omitted ${pack.omitted.length}`,
|
|
46
|
+
``,
|
|
47
|
+
];
|
|
48
|
+
appendGroup(lines, 'Atoms', pack.items.filter((item) => item.kind === 'atom'));
|
|
49
|
+
appendGroup(lines, 'Git Changes', pack.items.filter((item) => item.kind === 'git-change'));
|
|
50
|
+
appendGroup(lines, 'Source Ranges', pack.items.filter((item) => item.kind === 'file-range'));
|
|
51
|
+
appendGroup(lines, 'Symbols', pack.items.filter((item) => item.kind === 'symbol'));
|
|
52
|
+
appendGroup(lines, 'Files', pack.items.filter((item) => item.kind === 'file'));
|
|
53
|
+
appendGroup(lines, 'Graph', pack.items.filter((item) => item.kind === 'relationship'));
|
|
54
|
+
lines.push(`● Omitted`);
|
|
55
|
+
const omitted = pack.omitted.slice(0, 8);
|
|
56
|
+
if (omitted.length === 0) {
|
|
57
|
+
lines.push('- None');
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
for (const item of omitted) {
|
|
61
|
+
lines.push(` ◌ ${item.kind} ${item.title} (~${item.tokenEstimate} tokens)`);
|
|
43
62
|
}
|
|
44
|
-
if (pack.omitted.length >
|
|
45
|
-
|
|
46
|
-
console.log(`Omitted: ${pack.omitted.length} item(s) over budget`);
|
|
63
|
+
if (pack.omitted.length > omitted.length) {
|
|
64
|
+
lines.push(` ◌ ${pack.omitted.length - omitted.length} more omitted items`);
|
|
47
65
|
}
|
|
48
|
-
}
|
|
66
|
+
}
|
|
67
|
+
lines.push('', '● Next', ' agents should consume this command with --json for the full ContextPack contract');
|
|
68
|
+
return lines.join('\n');
|
|
69
|
+
}
|
|
70
|
+
function appendGroup(lines, title, items) {
|
|
71
|
+
lines.push(`● ${title}`);
|
|
72
|
+
if (items.length === 0) {
|
|
73
|
+
lines.push('- None', '');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
for (const item of items.slice(0, 6)) {
|
|
77
|
+
lines.push(` ● ${item.title} (~${item.tokenEstimate} tokens)`);
|
|
78
|
+
lines.push(` because ${formatReasons(item.reasons)}`);
|
|
79
|
+
if (item.kind === 'file-range') {
|
|
80
|
+
const data = item.data;
|
|
81
|
+
if (data.path && data.startLine != null && data.endLine != null) {
|
|
82
|
+
lines.push(` range ${data.path}:${data.startLine}-${data.endLine}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (items.length > 6)
|
|
87
|
+
lines.push(` ◌ ${items.length - 6} more ${title.toLowerCase()} omitted from display`);
|
|
88
|
+
lines.push('');
|
|
89
|
+
}
|
|
90
|
+
function formatReasons(reasons) {
|
|
91
|
+
if (reasons.length === 0)
|
|
92
|
+
return 'included by pack ranking';
|
|
93
|
+
const shown = reasons.slice(0, 3);
|
|
94
|
+
const remaining = reasons.length - shown.length;
|
|
95
|
+
return remaining > 0 ? `${shown.join('; ')}; and ${remaining} more` : shown.join('; ');
|
|
49
96
|
}
|
|
@@ -53,10 +53,15 @@ export function buildContextPack(response, budget, rootPath) {
|
|
|
53
53
|
})),
|
|
54
54
|
];
|
|
55
55
|
const orderedCandidates = candidates.sort(comparePackCandidates);
|
|
56
|
+
const strongPaths = strongPackPaths(candidates);
|
|
56
57
|
const items = [];
|
|
57
58
|
const omitted = [];
|
|
58
59
|
let usedTokens = 0;
|
|
59
60
|
for (const candidate of orderedCandidates) {
|
|
61
|
+
if (isLowSignalCandidate(candidate, strongPaths)) {
|
|
62
|
+
omitted.push(candidate);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
60
65
|
if (usedTokens + candidate.tokenEstimate <= budget) {
|
|
61
66
|
items.push(candidate);
|
|
62
67
|
usedTokens += candidate.tokenEstimate;
|
|
@@ -102,6 +107,60 @@ function packPriority(item) {
|
|
|
102
107
|
score -= Math.floor(item.tokenEstimate / 2000);
|
|
103
108
|
return score;
|
|
104
109
|
}
|
|
110
|
+
function strongPackPaths(candidates) {
|
|
111
|
+
const paths = new Set();
|
|
112
|
+
for (const candidate of candidates) {
|
|
113
|
+
if (candidate.kind === 'file-range' || candidate.kind === 'git-change') {
|
|
114
|
+
const pathValue = candidatePath(candidate);
|
|
115
|
+
if (pathValue)
|
|
116
|
+
paths.add(pathValue);
|
|
117
|
+
}
|
|
118
|
+
if (candidate.kind === 'file' && hasStrongReason(candidate)) {
|
|
119
|
+
const pathValue = candidatePath(candidate);
|
|
120
|
+
if (pathValue)
|
|
121
|
+
paths.add(pathValue);
|
|
122
|
+
}
|
|
123
|
+
if (candidate.kind === 'atom') {
|
|
124
|
+
const atom = candidate.data;
|
|
125
|
+
for (const file of atom?.relatedFiles ?? [])
|
|
126
|
+
paths.add(file);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return paths;
|
|
130
|
+
}
|
|
131
|
+
function isLowSignalCandidate(candidate, strongPaths) {
|
|
132
|
+
if (strongPaths.size === 0)
|
|
133
|
+
return false;
|
|
134
|
+
if (candidate.kind === 'atom' || candidate.kind === 'git-change' || candidate.kind === 'file-range') {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
if (hasStrongReason(candidate))
|
|
138
|
+
return false;
|
|
139
|
+
if (candidateTouchesStrongPath(candidate, strongPaths))
|
|
140
|
+
return false;
|
|
141
|
+
return candidate.kind === 'file' || candidate.kind === 'symbol' || candidate.kind === 'relationship';
|
|
142
|
+
}
|
|
143
|
+
function hasStrongReason(candidate) {
|
|
144
|
+
return candidate.reasons.some((reason) => reason.includes('matched atom') ||
|
|
145
|
+
reason.includes('current git change') ||
|
|
146
|
+
reason.includes('changed in recent commits') ||
|
|
147
|
+
reason.includes('unstaged change') ||
|
|
148
|
+
reason.includes('staged change'));
|
|
149
|
+
}
|
|
150
|
+
function candidateTouchesStrongPath(candidate, strongPaths) {
|
|
151
|
+
const pathValue = candidatePath(candidate);
|
|
152
|
+
if (pathValue && strongPaths.has(pathValue))
|
|
153
|
+
return true;
|
|
154
|
+
if (candidate.kind !== 'relationship')
|
|
155
|
+
return false;
|
|
156
|
+
const relationship = candidate.data;
|
|
157
|
+
return [...strongPaths].some((strongPath) => relationship.sourceId?.includes(strongPath) ||
|
|
158
|
+
relationship.targetId?.includes(strongPath));
|
|
159
|
+
}
|
|
160
|
+
function candidatePath(candidate) {
|
|
161
|
+
const data = candidate.data;
|
|
162
|
+
return data?.path ?? data?.filePath;
|
|
163
|
+
}
|
|
105
164
|
const GENERIC_RANGE_TOKENS = new Set([
|
|
106
165
|
'app',
|
|
107
166
|
'code',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { agentSkillFiles } from '../agent-skills.js';
|
|
2
2
|
export const codexAdapter = {
|
|
3
3
|
name: 'codex',
|
|
4
4
|
label: 'Codex',
|
|
@@ -7,24 +7,6 @@ export const codexAdapter = {
|
|
|
7
7
|
|
|
8
8
|
{{KGRAPH_CONTEXT_POLICY}} The /kgraph skill handles the full automated workflow. Run \`kgraph pack "<task>" --budget 8000 --json\` for a machine-readable token-budgeted context pack, \`kgraph knowledge list\` or \`kgraph knowledge get <atom-id>\` to inspect durable atoms, \`kgraph stale\` and \`kgraph blame <atom-id>\` when lifecycle/provenance matters, \`kgraph conclude\` for durable typed engineering memory, and \`kgraph compact --dry-run\` when cognition looks duplicated or stale. Run \`kgraph doctor\` when setup or generated maps look wrong. Run \`kgraph scan\`, \`kgraph update\`, and \`kgraph context\` manually only when you need one specific step.
|
|
9
9
|
`,
|
|
10
|
-
commandFiles:
|
|
11
|
-
|
|
12
|
-
path: '.agents/skills/kgraph/SKILL.md',
|
|
13
|
-
content: `---
|
|
14
|
-
name: kgraph
|
|
15
|
-
description: Use KGraph persistent repo intelligence according to the configured integration mode. Use when asked about repo structure, debugging context, architecture decisions, or to avoid rediscovering what is already known.
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
# KGraph Skill
|
|
19
|
-
|
|
20
|
-
Workflow:
|
|
21
|
-
|
|
22
|
-
${numberedWorkflow('codex')}
|
|
23
|
-
`,
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
obsoleteCommandFiles: [
|
|
27
|
-
'.agents/skills/kgraph-scan/SKILL.md',
|
|
28
|
-
'.agents/skills/kgraph-update/SKILL.md',
|
|
29
|
-
],
|
|
10
|
+
commandFiles: agentSkillFiles('codex'),
|
|
11
|
+
obsoleteCommandFiles: [],
|
|
30
12
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { agentSkillFiles } from '../agent-skills.js';
|
|
1
2
|
import { numberedWorkflow } from '../workflow-steps.js';
|
|
2
3
|
export const copilotAdapter = {
|
|
3
4
|
name: 'copilot',
|
|
@@ -7,172 +8,6 @@ export const copilotAdapter = {
|
|
|
7
8
|
|
|
8
9
|
${numberedWorkflow('copilot')}
|
|
9
10
|
`,
|
|
10
|
-
commandFiles:
|
|
11
|
-
|
|
12
|
-
path: '.github/prompts/kgraph-doctor.prompt.md',
|
|
13
|
-
content: `---
|
|
14
|
-
description: Check KGraph workspace health and next actions
|
|
15
|
-
agent: agent
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
Run \`kgraph doctor\` to check whether the workspace is initialized, maps exist, inbox notes are pending, and configured integrations point to real files. Use \`kgraph doctor --quality\` when the user asks about stale or noisy cognition references. Summarize any failed checks and the next command to run.
|
|
19
|
-
`,
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
path: '.github/prompts/kgraph-repair.prompt.md',
|
|
23
|
-
content: `---
|
|
24
|
-
description: Preview or clean stale/noisy KGraph cognition references
|
|
25
|
-
agent: agent
|
|
26
|
-
argument-hint: "--dry-run or apply"
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
Run \`kgraph repair --dry-run\` first and summarize the proposed atom-reference cleanup. Run \`kgraph repair\` only when the user asks to apply the cleanup.
|
|
30
|
-
`,
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
path: '.github/prompts/kgraph-compact.prompt.md',
|
|
34
|
-
content: `---
|
|
35
|
-
description: Merge duplicate KGraph cognition and archive stale low-value entries
|
|
36
|
-
agent: agent
|
|
37
|
-
argument-hint: "--dry-run or apply"
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
Run \`kgraph compact --dry-run\` first and summarize duplicate cognition groups and stale low-confidence notes. Run \`kgraph compact\` only when the user asks to apply compaction.
|
|
41
|
-
`,
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
path: '.github/prompts/kgraph-pack.prompt.md',
|
|
45
|
-
content: `---
|
|
46
|
-
description: Build a budget-aware KGraph context pack
|
|
47
|
-
agent: agent
|
|
48
|
-
argument-hint: "Task description"
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
Run \`kgraph pack "$ARGUMENTS" --budget 8000 --json\` to build a machine-readable context pack. Summarize token use, included files, symbols, relationships, git changes, session history, atoms, and omitted items with the inclusion reasons.
|
|
52
|
-
`,
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
path: '.github/prompts/kgraph-knowledge.prompt.md',
|
|
56
|
-
content: `---
|
|
57
|
-
description: Inspect or manage KGraph canonical knowledge atoms
|
|
58
|
-
agent: agent
|
|
59
|
-
argument-hint: "list, get <atom-id>, archive <atom-id>, or supersede <old-id> <new-id>"
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
Use \`kgraph knowledge list\` and \`kgraph knowledge get <atom-id>\` to inspect durable atoms, evidence, provenance, and lifecycle. Run \`kgraph knowledge archive <atom-id>\` or \`kgraph knowledge supersede <old-id> <new-id>\` only when the user explicitly asks to mutate atom lifecycle.
|
|
63
|
-
`,
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
path: '.github/prompts/kgraph-stale.prompt.md',
|
|
67
|
-
content: `---
|
|
68
|
-
description: Show KGraph knowledge invalidated by changed or missing refs
|
|
69
|
-
agent: agent
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
Run \`kgraph stale\` to refresh atom status against the current scan and summarize stale or needs-review atoms with invalidation reasons.
|
|
73
|
-
`,
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
path: '.github/prompts/kgraph-blame.prompt.md',
|
|
77
|
-
content: `---
|
|
78
|
-
description: Show KGraph atom provenance and evidence
|
|
79
|
-
agent: agent
|
|
80
|
-
argument-hint: "Atom id"
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
Run \`kgraph blame "$ARGUMENTS"\` to show who or what created a knowledge atom, the source command/session/commit, evidence refs, and lifecycle links.
|
|
84
|
-
`,
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
path: '.github/prompts/kgraph-scan.prompt.md',
|
|
88
|
-
content: `---
|
|
89
|
-
description: Refresh KGraph file, symbol, import, and relationship maps
|
|
90
|
-
agent: agent
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
Run \`kgraph scan\` to refresh the repository maps, then summarize what changed.
|
|
94
|
-
`,
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
path: '.github/prompts/kgraph-update.prompt.md',
|
|
98
|
-
content: `---
|
|
99
|
-
description: Process KGraph inbox notes into durable cognition
|
|
100
|
-
agent: agent
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
Run \`kgraph update\` to process any pending Markdown notes in \`.kgraph/inbox/\` into durable cognition.
|
|
104
|
-
`,
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
path: '.github/prompts/kgraph-visualize.prompt.md',
|
|
108
|
-
content: `---
|
|
109
|
-
description: Open interactive KGraph dependency graph in browser
|
|
110
|
-
agent: agent
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
Run \`kgraph visualize\` to start the interactive dependency graph at http://localhost:4242, then summarize what nodes and connections are visible.
|
|
114
|
-
`,
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
path: '.github/prompts/kgraph-capture.prompt.md',
|
|
118
|
-
content: `---
|
|
119
|
-
description: Save what was just built or changed into KGraph cognition
|
|
120
|
-
agent: agent
|
|
121
|
-
argument-hint: "Brief description of what was done"
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
Capture this session into KGraph cognition.
|
|
125
|
-
|
|
126
|
-
{{KGRAPH_CAPTURE_POLICY}}
|
|
127
|
-
`,
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
path: '.github/prompts/kgraph-conclude.prompt.md',
|
|
131
|
-
content: `---
|
|
132
|
-
description: Store a typed durable KGraph engineering conclusion
|
|
133
|
-
agent: agent
|
|
134
|
-
argument-hint: "Topic plus optional type, confidence, files, and symbols"
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
Use \`kgraph conclude "$ARGUMENTS"\` when the session produced reusable engineering knowledge. Choose one type from finding, decision, gotcha, summary, relationship, and one confidence from high, medium, low. Store only durable conclusions, not raw chain-of-thought, temporary reasoning, speculative exploration, or low-value observations.
|
|
138
|
-
`,
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
path: '.github/prompts/kgraph-impact.prompt.md',
|
|
142
|
-
content: `---
|
|
143
|
-
description: Show KGraph change impact for a file, symbol, or topic
|
|
144
|
-
agent: agent
|
|
145
|
-
argument-hint: "File, symbol, or topic"
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
Run \`kgraph impact "$ARGUMENTS"\` to show matched files/symbols, import users, callers, callees, related knowledge atoms, and risk hints.
|
|
149
|
-
`,
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
path: '.github/prompts/kgraph-session.prompt.md',
|
|
153
|
-
content: `---
|
|
154
|
-
description: Track KGraph session read/write activity and token estimates
|
|
155
|
-
agent: agent
|
|
156
|
-
argument-hint: "start, read <path>, write <path>, end, or status"
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
Use \`kgraph session\` to inspect current session activity. Record meaningful events with \`kgraph session start --agent copilot\`, \`kgraph session read <path> --agent copilot\`, \`kgraph session write <path> --agent copilot\`, and \`kgraph session end --agent copilot --conclude --topic "<topic>"\` when durable session memory is useful.
|
|
160
|
-
`,
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
path: '.github/prompts/kgraph-history.prompt.md',
|
|
164
|
-
content: `---
|
|
165
|
-
description: Show timeline of KGraph cognition sessions with git attribution
|
|
166
|
-
agent: agent
|
|
167
|
-
argument-hint: "Optional topic"
|
|
168
|
-
---
|
|
169
|
-
|
|
170
|
-
Run \`kgraph history\` or \`kgraph history "$ARGUMENTS"\` to display processed cognition sessions. Summarize who contributed what and when. Use \`--last <n>\` to limit entries.
|
|
171
|
-
`,
|
|
172
|
-
},
|
|
173
|
-
],
|
|
174
|
-
obsoleteCommandFiles: [
|
|
175
|
-
'.github/prompts/kgraph.prompt.md',
|
|
176
|
-
'.github/kgraph.agent.md',
|
|
177
|
-
],
|
|
11
|
+
commandFiles: agentSkillFiles('copilot'),
|
|
12
|
+
obsoleteCommandFiles: [],
|
|
178
13
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared agent skill definitions used by any integration that writes
|
|
3
|
+
* `.agents/skills/` SKILL.md files (copilot, codex, etc.).
|
|
4
|
+
*
|
|
5
|
+
* Per-command skills are agent-name-agnostic.
|
|
6
|
+
* The main kgraph workflow skill is parameterised by agent name.
|
|
7
|
+
*/
|
|
8
|
+
import type { IntegrationCommandFile } from './integration-registry.js';
|
|
9
|
+
/** Per-command skills shared across all agent-skill integrations. */
|
|
10
|
+
export declare const SHARED_AGENT_SKILLS: IntegrationCommandFile[];
|
|
11
|
+
/**
|
|
12
|
+
* Build the full agent skill list for an adapter: the main workflow skill
|
|
13
|
+
* (parameterised by agent name) plus all shared per-command skills.
|
|
14
|
+
*/
|
|
15
|
+
export declare function agentSkillFiles(agentName: string): IntegrationCommandFile[];
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared agent skill definitions used by any integration that writes
|
|
3
|
+
* `.agents/skills/` SKILL.md files (copilot, codex, etc.).
|
|
4
|
+
*
|
|
5
|
+
* Per-command skills are agent-name-agnostic.
|
|
6
|
+
* The main kgraph workflow skill is parameterised by agent name.
|
|
7
|
+
*/
|
|
8
|
+
import { numberedWorkflow } from './workflow-steps.js';
|
|
9
|
+
/** Per-command skills shared across all agent-skill integrations. */
|
|
10
|
+
export const SHARED_AGENT_SKILLS = [
|
|
11
|
+
{
|
|
12
|
+
path: '.agents/skills/kgraph-doctor/SKILL.md',
|
|
13
|
+
content: `---
|
|
14
|
+
name: kgraph-doctor
|
|
15
|
+
description: Check KGraph workspace health and next actions
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
Run \`kgraph doctor\` to check whether the workspace is initialized, maps exist, inbox notes are pending, and configured integrations point to real files. Use \`kgraph doctor --quality\` when the user asks about stale or noisy cognition references. Summarize any failed checks and the next command to run.
|
|
19
|
+
`,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
path: '.agents/skills/kgraph-repair/SKILL.md',
|
|
23
|
+
content: `---
|
|
24
|
+
name: kgraph-repair
|
|
25
|
+
description: Preview or clean stale/noisy KGraph cognition references
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
Run \`kgraph repair --dry-run\` first and summarize the proposed atom-reference cleanup. Run \`kgraph repair\` only when the user asks to apply the cleanup.
|
|
29
|
+
`,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
path: '.agents/skills/kgraph-compact/SKILL.md',
|
|
33
|
+
content: `---
|
|
34
|
+
name: kgraph-compact
|
|
35
|
+
description: Merge duplicate KGraph cognition and archive stale low-value entries
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
Run \`kgraph compact --dry-run\` first and summarize duplicate cognition groups and stale low-confidence notes. Run \`kgraph compact\` only when the user asks to apply compaction.
|
|
39
|
+
`,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
path: '.agents/skills/kgraph-pack/SKILL.md',
|
|
43
|
+
content: `---
|
|
44
|
+
name: kgraph-pack
|
|
45
|
+
description: Build a budget-aware KGraph context pack
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
Run \`kgraph pack "$ARGUMENTS" --budget 8000 --json\` to build a machine-readable context pack. Summarize token use, included files, symbols, relationships, git changes, session history, atoms, and omitted items with the inclusion reasons.
|
|
49
|
+
`,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
path: '.agents/skills/kgraph-knowledge/SKILL.md',
|
|
53
|
+
content: `---
|
|
54
|
+
name: kgraph-knowledge
|
|
55
|
+
description: Inspect or manage KGraph canonical knowledge atoms
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
Use \`kgraph knowledge list\` and \`kgraph knowledge get <atom-id>\` to inspect durable atoms, evidence, provenance, and lifecycle. Run \`kgraph knowledge archive <atom-id>\` or \`kgraph knowledge supersede <old-id> <new-id>\` only when the user explicitly asks to mutate atom lifecycle.
|
|
59
|
+
`,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
path: '.agents/skills/kgraph-stale/SKILL.md',
|
|
63
|
+
content: `---
|
|
64
|
+
name: kgraph-stale
|
|
65
|
+
description: Show KGraph knowledge invalidated by changed or missing refs
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
Run \`kgraph stale\` to refresh atom status against the current scan and summarize stale or needs-review atoms with invalidation reasons.
|
|
69
|
+
`,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
path: '.agents/skills/kgraph-blame/SKILL.md',
|
|
73
|
+
content: `---
|
|
74
|
+
name: kgraph-blame
|
|
75
|
+
description: Show KGraph atom provenance and evidence
|
|
76
|
+
---
|
|
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.
|
|
79
|
+
`,
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
path: '.agents/skills/kgraph-scan/SKILL.md',
|
|
83
|
+
content: `---
|
|
84
|
+
name: kgraph-scan
|
|
85
|
+
description: Refresh KGraph file, symbol, import, and relationship maps
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
Run \`kgraph scan\` to refresh the repository maps, then summarize what changed.
|
|
89
|
+
`,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
path: '.agents/skills/kgraph-update/SKILL.md',
|
|
93
|
+
content: `---
|
|
94
|
+
name: kgraph-update
|
|
95
|
+
description: Process KGraph inbox notes into durable cognition
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
Run \`kgraph update\` to process any pending Markdown notes in \`.kgraph/inbox/\` into durable cognition.
|
|
99
|
+
`,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
path: '.agents/skills/kgraph-visualize/SKILL.md',
|
|
103
|
+
content: `---
|
|
104
|
+
name: kgraph-visualize
|
|
105
|
+
description: Open interactive KGraph dependency graph in browser
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
Run \`kgraph visualize\` to start the interactive dependency graph at http://localhost:4242, then summarize what nodes and connections are visible.
|
|
109
|
+
`,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
path: '.agents/skills/kgraph-capture/SKILL.md',
|
|
113
|
+
content: `---
|
|
114
|
+
name: kgraph-capture
|
|
115
|
+
description: Save what was just built or changed into KGraph cognition
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
Capture this session into KGraph cognition.
|
|
119
|
+
|
|
120
|
+
{{KGRAPH_CAPTURE_POLICY}}
|
|
121
|
+
`,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
path: '.agents/skills/kgraph-conclude/SKILL.md',
|
|
125
|
+
content: `---
|
|
126
|
+
name: kgraph-conclude
|
|
127
|
+
description: Store a typed durable KGraph engineering conclusion
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
Use \`kgraph conclude "$ARGUMENTS"\` when the session produced reusable engineering knowledge. Choose one type from finding, decision, gotcha, summary, relationship, and one confidence from high, medium, low. Store only durable conclusions, not raw chain-of-thought, temporary reasoning, speculative exploration, or low-value observations.
|
|
131
|
+
`,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
path: '.agents/skills/kgraph-impact/SKILL.md',
|
|
135
|
+
content: `---
|
|
136
|
+
name: kgraph-impact
|
|
137
|
+
description: Show KGraph change impact for a file, symbol, or topic
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
Run \`kgraph impact "$ARGUMENTS"\` to show matched files/symbols, import users, callers, callees, related knowledge atoms, and risk hints.
|
|
141
|
+
`,
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
path: '.agents/skills/kgraph-session/SKILL.md',
|
|
145
|
+
content: `---
|
|
146
|
+
name: kgraph-session
|
|
147
|
+
description: Track KGraph session read/write activity and token estimates
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
Use \`kgraph session\` to inspect current session activity. Record meaningful events with \`kgraph session start --agent $AGENT\`, \`kgraph session read <path> --agent $AGENT\`, \`kgraph session write <path> --agent $AGENT\`, and \`kgraph session end --agent $AGENT --conclude --topic "<topic>"\` when durable session memory is useful.
|
|
151
|
+
`,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
path: '.agents/skills/kgraph-history/SKILL.md',
|
|
155
|
+
content: `---
|
|
156
|
+
name: kgraph-history
|
|
157
|
+
description: Show timeline of KGraph cognition sessions with git attribution
|
|
158
|
+
---
|
|
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.
|
|
161
|
+
`,
|
|
162
|
+
},
|
|
163
|
+
];
|
|
164
|
+
/**
|
|
165
|
+
* Build the full agent skill list for an adapter: the main workflow skill
|
|
166
|
+
* (parameterised by agent name) plus all shared per-command skills.
|
|
167
|
+
*/
|
|
168
|
+
export function agentSkillFiles(agentName) {
|
|
169
|
+
return [
|
|
170
|
+
{
|
|
171
|
+
path: '.agents/skills/kgraph/SKILL.md',
|
|
172
|
+
content: `---
|
|
173
|
+
name: kgraph
|
|
174
|
+
description: Use KGraph persistent repo intelligence according to the configured integration mode. Use when asked about repo structure, debugging context, architecture decisions, or to avoid rediscovering what is already known.
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
# KGraph Skill
|
|
178
|
+
|
|
179
|
+
Workflow:
|
|
180
|
+
|
|
181
|
+
${numberedWorkflow(agentName)}
|
|
182
|
+
`,
|
|
183
|
+
},
|
|
184
|
+
...SHARED_AGENT_SKILLS,
|
|
185
|
+
];
|
|
186
|
+
}
|
|
@@ -36,17 +36,17 @@ export function applyContextPolicy(content, mode) {
|
|
|
36
36
|
.replaceAll(KGRAPH_CAPTURE_POLICY_PLACEHOLDER, renderCapturePolicy());
|
|
37
37
|
}
|
|
38
38
|
export function renderContextPolicy(mode) {
|
|
39
|
-
const useResultBoundary = 'Use the returned KGraph
|
|
39
|
+
const useResultBoundary = 'Use the returned KGraph ContextPack items as the first-pass source of truth. Prefer source ranges, atoms, git changes, and inclusion reasons from the pack before broad repository search. Do not rerun the same KGraph query just to tail or reformat output, do not continue broad repository search after the target file or range is identified, do not retry malformed shell commands with broader variants, and do not run broad `find`, recursive `grep`, or repeated full-file dumps after KGraph has narrowed the target.';
|
|
40
40
|
switch (mode) {
|
|
41
41
|
case 'always':
|
|
42
|
-
return `Every chat in this repository must start by running \`kgraph "<topic>"\` before answering or exploring files. Infer the topic from the user's message; no exceptions, including simple or conversational requests. ${useResultBoundary}`;
|
|
42
|
+
return `Every chat in this repository must start by running \`kgraph pack "<topic>" --budget 8000 --json\` before answering or exploring files. Infer the topic from the user's message; no exceptions, including simple or conversational requests. Use \`kgraph "<topic>"\` only when a human-readable briefing is explicitly needed. ${useResultBoundary}`;
|
|
43
43
|
case 'manual':
|
|
44
|
-
return 'Do not run KGraph automatically. Run `kgraph "<topic>"` only when the user explicitly asks for KGraph context or
|
|
44
|
+
return 'Do not run KGraph automatically. Run `kgraph pack "<topic>" --budget 8000 --json` only when the user explicitly asks for KGraph context, invokes KGraph, or needs a machine-readable repo-memory pack.';
|
|
45
45
|
case 'off':
|
|
46
46
|
return 'KGraph is disabled for this integration.';
|
|
47
47
|
case 'smart':
|
|
48
48
|
default:
|
|
49
|
-
return `For repo-specific coding, debugging, architecture, refactor, review, or file-exploration requests, run \`kgraph "<topic>"\` before broad repository exploration. Infer the topic from the user's message. Skip KGraph for simple conversational requests that do not depend on repo knowledge. ${useResultBoundary}`;
|
|
49
|
+
return `For repo-specific coding, debugging, architecture, refactor, review, or file-exploration requests, run \`kgraph pack "<topic>" --budget 8000 --json\` before broad repository exploration. Infer the topic from the user's message. Skip KGraph for simple conversational requests that do not depend on repo knowledge. Use \`kgraph "<topic>"\` only when a human-readable briefing is explicitly needed. ${useResultBoundary}`;
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
export function renderCapturePolicy() {
|
|
@@ -56,7 +56,7 @@ export function renderCapturePolicy() {
|
|
|
56
56
|
- Use \`.kgraph/inbox/<slug>.md\` only when a longer structured note is clearer than a single \`kgraph conclude\` command.
|
|
57
57
|
- A \`.kgraph/inbox/*.md\` note is KGraph runtime capture, not project documentation. It is allowed by this workflow unless the user explicitly says not to capture to KGraph.
|
|
58
58
|
- Do not skip capture for meaningful UI text, button, link, route, styling, or small file edits. Skip capture only when no reusable repository knowledge was created.
|
|
59
|
-
- Do not run KGraph repeatedly. Run it once at the start with \`kgraph "<topic>"
|
|
59
|
+
- Do not run KGraph repeatedly. Run it once at the start with \`kgraph pack "<topic>" --budget 8000 --json\` for agent-readable context. If repo files changed, write the inbox note first, then run \`kgraph\` once at the end.
|
|
60
60
|
- After the final \`kgraph\` run, mention whether durable cognition was stored or processed.
|
|
61
61
|
|
|
62
62
|
When using an inbox note, use this structure:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
1
|
+
import { mkdir, readdir, readFile, rm, rmdir, writeFile, } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { loadConfig, saveConfig } from '../config/config.js';
|
|
4
4
|
import { pathExists } from '../storage/kgraph-paths.js';
|
|
@@ -19,6 +19,7 @@ export async function addIntegrations(workspace, names, mode = 'always') {
|
|
|
19
19
|
const config = await loadConfig(workspace);
|
|
20
20
|
const byName = new Map(config.integrations.map((integration) => [integration.name, integration]));
|
|
21
21
|
const changed = [];
|
|
22
|
+
const writtenCommandFiles = new Set();
|
|
22
23
|
for (const name of names) {
|
|
23
24
|
const adapter = getIntegrationAdapter(name);
|
|
24
25
|
const next = {
|
|
@@ -34,10 +35,14 @@ export async function addIntegrations(workspace, names, mode = 'always') {
|
|
|
34
35
|
}
|
|
35
36
|
else {
|
|
36
37
|
await writeIntegrationInstructions(workspace.rootPath, adapter.targetPath, adapter.name, applyContextPolicy(adapter.instructions, mode));
|
|
37
|
-
|
|
38
|
+
const deduped = (adapter.commandFiles ?? []).filter((file) => !writtenCommandFiles.has(file.path));
|
|
39
|
+
await writeIntegrationCommandFiles(workspace.rootPath, deduped.map((file) => ({
|
|
38
40
|
...file,
|
|
39
41
|
content: applyContextPolicy(file.content, mode),
|
|
40
42
|
})));
|
|
43
|
+
for (const file of adapter.commandFiles ?? []) {
|
|
44
|
+
writtenCommandFiles.add(file.path);
|
|
45
|
+
}
|
|
41
46
|
}
|
|
42
47
|
await removeIntegrationCommandFiles(workspace.rootPath, adapter.obsoleteCommandFiles ?? []);
|
|
43
48
|
changed.push(next);
|
|
@@ -53,10 +58,21 @@ export async function removeIntegrations(workspace, names) {
|
|
|
53
58
|
const config = await loadConfig(workspace);
|
|
54
59
|
const removeNames = new Set(names);
|
|
55
60
|
const removed = [];
|
|
61
|
+
// Collect command-file paths still owned by remaining enabled integrations
|
|
62
|
+
const retainedPaths = new Set();
|
|
63
|
+
for (const integration of config.integrations) {
|
|
64
|
+
if (removeNames.has(integration.name) || !integration.enabled) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const adapter = getIntegrationAdapter(integration.name);
|
|
68
|
+
for (const file of adapter.commandFiles ?? []) {
|
|
69
|
+
retainedPaths.add(file.path);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
56
72
|
for (const name of removeNames) {
|
|
57
73
|
const adapter = getIntegrationAdapter(name);
|
|
58
74
|
await removeIntegrationInstructions(workspace.rootPath, adapter.targetPath, adapter.name);
|
|
59
|
-
await removeIntegrationCommandFiles(workspace.rootPath, adapter.commandFiles ?? []);
|
|
75
|
+
await removeIntegrationCommandFiles(workspace.rootPath, (adapter.commandFiles ?? []).filter((file) => !retainedPaths.has(file.path)));
|
|
60
76
|
await removeIntegrationCommandFiles(workspace.rootPath, adapter.obsoleteCommandFiles ?? []);
|
|
61
77
|
removed.push(adapter.name);
|
|
62
78
|
}
|
|
@@ -96,6 +112,21 @@ async function writeIntegrationCommandFiles(rootPath, files) {
|
|
|
96
112
|
async function removeIntegrationCommandFiles(rootPath, files) {
|
|
97
113
|
for (const file of files) {
|
|
98
114
|
const filePath = typeof file === 'string' ? file : file.path;
|
|
99
|
-
|
|
115
|
+
const fullPath = path.join(rootPath, filePath);
|
|
116
|
+
await rm(fullPath, { force: true, recursive: true });
|
|
117
|
+
// Remove empty parent directories up to (but not including) rootPath
|
|
118
|
+
let dir = path.dirname(fullPath);
|
|
119
|
+
while (dir !== rootPath && dir.startsWith(rootPath)) {
|
|
120
|
+
try {
|
|
121
|
+
const entries = await readdir(dir);
|
|
122
|
+
if (entries.length > 0)
|
|
123
|
+
break;
|
|
124
|
+
await rmdir(dir);
|
|
125
|
+
dir = path.dirname(dir);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
100
131
|
}
|
|
101
132
|
}
|
|
@@ -8,7 +8,7 @@ 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
|
-
const PACK_STEP = `
|
|
11
|
+
const PACK_STEP = `Treat \`kgraph pack "<task>" --budget 8000 --json\` as the primary agent contract: use atoms, source ranges, git changes, omitted items, and inclusion reasons from the ContextPack before reading files. Use human \`kgraph "<topic>"\` output only when the user explicitly wants a briefing.`;
|
|
12
12
|
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.`;
|
|
13
13
|
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.`;
|
|
14
14
|
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.`;
|