@kentwynn/kgraph 0.2.10 → 0.2.11
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 +33 -2
- package/dist/cli/commands/blame.d.ts +2 -0
- package/dist/cli/commands/blame.js +52 -0
- package/dist/cli/commands/doctor.js +17 -0
- package/dist/cli/commands/init.js +2 -0
- package/dist/cli/commands/knowledge.d.ts +2 -0
- package/dist/cli/commands/knowledge.js +137 -0
- package/dist/cli/commands/pack.d.ts +2 -0
- package/dist/cli/commands/pack.js +49 -0
- package/dist/cli/commands/stale.d.ts +2 -0
- package/dist/cli/commands/stale.js +33 -0
- package/dist/cli/help.js +6 -0
- package/dist/cli/index.js +8 -0
- package/dist/cognition/cognition-updater.js +14 -0
- package/dist/cognition/compact.js +129 -28
- package/dist/cognition/conclusion.d.ts +2 -0
- package/dist/cognition/conclusion.js +22 -0
- package/dist/context/context-pack.d.ts +3 -0
- package/dist/context/context-pack.js +71 -0
- package/dist/context/context-query.js +53 -28
- package/dist/integrations/adapters/claude-code.js +21 -1
- package/dist/integrations/adapters/codex.js +1 -1
- package/dist/integrations/adapters/copilot.js +44 -1
- package/dist/integrations/workflow-steps.js +16 -7
- package/dist/knowledge/atom-store.d.ts +60 -0
- package/dist/knowledge/atom-store.js +484 -0
- package/dist/storage/kgraph-paths.js +5 -2
- package/dist/types/config.d.ts +1 -0
- package/dist/types/knowledge.d.ts +92 -0
- package/dist/types/knowledge.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -222,12 +222,39 @@ kgraph conclude "auth refresh requires rotating the session cookie" \
|
|
|
222
222
|
|
|
223
223
|
Store durable engineering memory directly. Cognition is typed as `finding`, `decision`, `gotcha`, `summary`, or `relationship`, and confidence is `high`, `medium`, or `low`. Keep conclusions concise: preserve expensive-to-rediscover knowledge, not raw chain-of-thought, speculative exploration, or temporary reasoning.
|
|
224
224
|
|
|
225
|
+
KGraph stores these conclusions as canonical knowledge atoms under `.kgraph/knowledge/` while keeping existing Markdown cognition files readable for compatibility.
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
kgraph knowledge list
|
|
229
|
+
kgraph knowledge list --type finding --topic auth --json
|
|
230
|
+
kgraph knowledge get <atom-id>
|
|
231
|
+
kgraph knowledge archive <atom-id>
|
|
232
|
+
kgraph knowledge supersede <old-id> <new-id>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Inspect and manage canonical knowledge atoms. Archive and supersede update lifecycle metadata; they do not delete history.
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
kgraph stale
|
|
239
|
+
kgraph stale --json
|
|
240
|
+
kgraph blame <atom-id>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Refresh atom lifecycle status against the current scan and inspect atom provenance. Changed file hashes move atoms to `needs-review`; deleted files or missing symbols move atoms to `stale`; `blame` shows the source command, agent/session/commit, evidence refs, and lifecycle links.
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
kgraph pack "auth token refresh" --budget 8000
|
|
247
|
+
kgraph pack "auth token refresh" --budget 8000 --json
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
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.
|
|
251
|
+
|
|
225
252
|
```bash
|
|
226
253
|
kgraph compact --dry-run
|
|
227
254
|
kgraph compact
|
|
228
255
|
```
|
|
229
256
|
|
|
230
|
-
Merge duplicate
|
|
257
|
+
Merge duplicate knowledge atoms and archive low-confidence stale entries. Compaction operates on `.kgraph/knowledge/atoms.jsonl` first, then regenerates indexes and compatibility domain records so future context responses use the atom lifecycle as the source of truth.
|
|
231
258
|
|
|
232
259
|
## Optional Step Commands
|
|
233
260
|
|
|
@@ -327,10 +354,14 @@ All runtime data lives under `.kgraph/`:
|
|
|
327
354
|
├── domains/
|
|
328
355
|
├── interactions/processed/
|
|
329
356
|
├── sessions/
|
|
357
|
+
├── knowledge/
|
|
358
|
+
│ ├── atoms.jsonl
|
|
359
|
+
│ ├── schema.json
|
|
360
|
+
│ └── indexes/
|
|
330
361
|
└── context/
|
|
331
362
|
```
|
|
332
363
|
|
|
333
|
-
The files are local, inspectable, and human-readable. Core KGraph functionality is free. There is no database, telemetry, cloud service, account, API key, embedding service, model provider, or source-code upload.
|
|
364
|
+
The files are local, inspectable, and human-readable. `knowledge/atoms.jsonl` is the canonical durable-memory store; Markdown cognition remains a compatibility and input layer. Core KGraph functionality is free. There is no database, telemetry, cloud service, account, API key, embedding service, model provider, or source-code upload.
|
|
334
365
|
|
|
335
366
|
## Language Support
|
|
336
367
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { readKnowledgeAtoms } from '../../knowledge/atom-store.js';
|
|
2
|
+
import { assertWorkspace } from '../../storage/kgraph-paths.js';
|
|
3
|
+
import { KGraphError, runCommand } from '../errors.js';
|
|
4
|
+
export function registerBlameCommand(program) {
|
|
5
|
+
program
|
|
6
|
+
.command('blame <atomId>')
|
|
7
|
+
.description('Show who or what created a knowledge atom and why it exists')
|
|
8
|
+
.option('--json', 'Print JSON output')
|
|
9
|
+
.action((atomId, options) => runCommand(async () => {
|
|
10
|
+
const workspace = await assertWorkspace(process.cwd());
|
|
11
|
+
const atom = (await readKnowledgeAtoms(workspace)).find((candidate) => candidate.id === atomId);
|
|
12
|
+
if (!atom)
|
|
13
|
+
throw new KGraphError(`Knowledge atom not found: ${atomId}`);
|
|
14
|
+
const result = {
|
|
15
|
+
id: atom.id,
|
|
16
|
+
topic: atom.topic,
|
|
17
|
+
claim: atom.claim,
|
|
18
|
+
provenance: atom.provenance,
|
|
19
|
+
evidenceRefs: atom.evidenceRefs,
|
|
20
|
+
lifecycle: atom.lifecycle,
|
|
21
|
+
};
|
|
22
|
+
if (options.json) {
|
|
23
|
+
console.log(JSON.stringify(result, null, 2));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.log(`# ${atom.topic}`);
|
|
27
|
+
console.log('');
|
|
28
|
+
console.log(`ID: ${atom.id}`);
|
|
29
|
+
console.log(`Claim: ${atom.claim}`);
|
|
30
|
+
console.log(`Source: ${atom.provenance.sourceCommand}`);
|
|
31
|
+
if (atom.provenance.agent)
|
|
32
|
+
console.log(`Agent: ${atom.provenance.agent}`);
|
|
33
|
+
if (atom.provenance.sessionId) {
|
|
34
|
+
console.log(`Session: ${atom.provenance.sessionId}`);
|
|
35
|
+
}
|
|
36
|
+
if (atom.provenance.commit)
|
|
37
|
+
console.log(`Commit: ${atom.provenance.commit}`);
|
|
38
|
+
console.log(`Created: ${atom.provenance.createdAt}`);
|
|
39
|
+
if (atom.provenance.updatedAt)
|
|
40
|
+
console.log(`Updated: ${atom.provenance.updatedAt}`);
|
|
41
|
+
console.log('');
|
|
42
|
+
console.log('Evidence:');
|
|
43
|
+
for (const ref of atom.evidenceRefs) {
|
|
44
|
+
console.log(`- ${JSON.stringify(ref)}`);
|
|
45
|
+
}
|
|
46
|
+
if (atom.lifecycle.supersededBy || atom.lifecycle.supersedes.length > 0) {
|
|
47
|
+
console.log('');
|
|
48
|
+
console.log('Lifecycle:');
|
|
49
|
+
console.log(JSON.stringify(atom.lifecycle, null, 2));
|
|
50
|
+
}
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import { analyzeCognitionQuality, } from '../../cognition/cognition-quality.js';
|
|
4
4
|
import { loadConfig } from '../../config/config.js';
|
|
5
5
|
import { listIntegrations } from '../../integrations/integration-store.js';
|
|
6
|
+
import { validateKnowledgeStore } from '../../knowledge/atom-store.js';
|
|
6
7
|
import { getCurrentCommit, isGitRepo } from '../../scanner/git-utils.js';
|
|
7
8
|
import { assertWorkspace, pathExists, resolveWorkspace, } from '../../storage/kgraph-paths.js';
|
|
8
9
|
import { mapPaths, mapsExist, readMaps } from '../../storage/map-store.js';
|
|
@@ -76,6 +77,22 @@ export function registerDoctorCommand(program) {
|
|
|
76
77
|
detail: missing.join(', '),
|
|
77
78
|
});
|
|
78
79
|
}
|
|
80
|
+
const knowledgeIssues = await validateKnowledgeStore(workspace, maps
|
|
81
|
+
? { fileMap: maps.fileMap, symbolMap: maps.symbolMap }
|
|
82
|
+
: undefined);
|
|
83
|
+
checks.push({
|
|
84
|
+
label: 'knowledge',
|
|
85
|
+
ok: knowledgeIssues.length === 0,
|
|
86
|
+
detail: knowledgeIssues.length === 0
|
|
87
|
+
? 'knowledge atoms, schema, and refs are valid'
|
|
88
|
+
: knowledgeIssues
|
|
89
|
+
.slice(0, 3)
|
|
90
|
+
.map((issue) => issue.message)
|
|
91
|
+
.join('; ') +
|
|
92
|
+
(knowledgeIssues.length > 3
|
|
93
|
+
? `; and ${knowledgeIssues.length - 3} more`
|
|
94
|
+
: ''),
|
|
95
|
+
});
|
|
79
96
|
const inboxCount = await countMarkdownFiles(workspace.inboxPath);
|
|
80
97
|
checks.push({
|
|
81
98
|
label: 'inbox',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { loadConfig, writeDefaultConfig } from '../../config/config.js';
|
|
2
2
|
import { normalizeIntegrationNames } from '../../integrations/integration-registry.js';
|
|
3
3
|
import { addIntegrations } from '../../integrations/integration-store.js';
|
|
4
|
+
import { ensureKnowledgeStore } from '../../knowledge/atom-store.js';
|
|
4
5
|
import { scanRepository } from '../../scanner/repo-scanner.js';
|
|
5
6
|
import { ensureWorkspace } from '../../storage/kgraph-paths.js';
|
|
6
7
|
import { readMaps, writeMaps } from '../../storage/map-store.js';
|
|
@@ -17,6 +18,7 @@ export function registerInitCommand(program) {
|
|
|
17
18
|
.option('--mode <mode>', 'Integration mode: always, smart, manual, or off', 'smart')
|
|
18
19
|
.action((options) => runCommand(async () => {
|
|
19
20
|
const workspace = await ensureWorkspace(process.cwd());
|
|
21
|
+
await ensureKnowledgeStore(workspace);
|
|
20
22
|
const wroteConfig = await writeDefaultConfig(workspace);
|
|
21
23
|
console.log(wroteConfig
|
|
22
24
|
? 'Initialized .kgraph workspace.'
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { readKnowledgeAtoms, updateKnowledgeAtom, } from '../../knowledge/atom-store.js';
|
|
2
|
+
import { assertWorkspace } from '../../storage/kgraph-paths.js';
|
|
3
|
+
import { KGraphError, runCommand } from '../errors.js';
|
|
4
|
+
export function registerKnowledgeCommand(program) {
|
|
5
|
+
const knowledge = program
|
|
6
|
+
.command('knowledge')
|
|
7
|
+
.description('Manage canonical KGraph knowledge atoms');
|
|
8
|
+
knowledge
|
|
9
|
+
.command('list')
|
|
10
|
+
.option('--type <type>', 'Filter by atom type')
|
|
11
|
+
.option('--topic <topic>', 'Filter by topic substring')
|
|
12
|
+
.option('--status <status>', 'Filter by active, stale, needs-review, or archived')
|
|
13
|
+
.option('--json', 'Print JSON output')
|
|
14
|
+
.action((options) => runCommand(async () => {
|
|
15
|
+
const workspace = await assertWorkspace(process.cwd());
|
|
16
|
+
const atoms = filterAtoms(await readKnowledgeAtoms(workspace), options);
|
|
17
|
+
if (options.json) {
|
|
18
|
+
console.log(JSON.stringify(atoms, null, 2));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
console.log('KGraph Knowledge');
|
|
22
|
+
console.log('');
|
|
23
|
+
for (const atom of atoms) {
|
|
24
|
+
console.log(`- ${atom.id} [${atom.type}, ${atom.confidence}, ${atom.status}] ${atom.topic}`);
|
|
25
|
+
console.log(` ${atom.claim}`);
|
|
26
|
+
}
|
|
27
|
+
if (atoms.length === 0)
|
|
28
|
+
console.log('- None');
|
|
29
|
+
}));
|
|
30
|
+
knowledge
|
|
31
|
+
.command('get <atomId>')
|
|
32
|
+
.option('--json', 'Print JSON output')
|
|
33
|
+
.action((atomId, options) => runCommand(async () => {
|
|
34
|
+
const workspace = await assertWorkspace(process.cwd());
|
|
35
|
+
const atom = await requireAtom(workspace, atomId);
|
|
36
|
+
if (options.json) {
|
|
37
|
+
console.log(JSON.stringify(atom, null, 2));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
console.log(`# ${atom.topic}`);
|
|
41
|
+
console.log('');
|
|
42
|
+
console.log(`ID: ${atom.id}`);
|
|
43
|
+
console.log(`Type: ${atom.type}`);
|
|
44
|
+
console.log(`Confidence: ${atom.confidence}`);
|
|
45
|
+
console.log(`Status: ${atom.status}`);
|
|
46
|
+
console.log(`Claim: ${atom.claim}`);
|
|
47
|
+
if (atom.summary)
|
|
48
|
+
console.log(`Summary: ${atom.summary}`);
|
|
49
|
+
console.log('');
|
|
50
|
+
console.log('Evidence:');
|
|
51
|
+
for (const ref of atom.evidenceRefs) {
|
|
52
|
+
console.log(`- ${JSON.stringify(ref)}`);
|
|
53
|
+
}
|
|
54
|
+
console.log('');
|
|
55
|
+
console.log('Provenance:');
|
|
56
|
+
console.log(JSON.stringify(atom.provenance, null, 2));
|
|
57
|
+
console.log('');
|
|
58
|
+
console.log('Lifecycle:');
|
|
59
|
+
console.log(JSON.stringify(atom.lifecycle, null, 2));
|
|
60
|
+
}));
|
|
61
|
+
knowledge
|
|
62
|
+
.command('archive <atomId>')
|
|
63
|
+
.option('--json', 'Print JSON output')
|
|
64
|
+
.action((atomId, options) => runCommand(async () => {
|
|
65
|
+
const workspace = await assertWorkspace(process.cwd());
|
|
66
|
+
const now = new Date().toISOString();
|
|
67
|
+
const atom = await updateKnowledgeAtom(workspace, atomId, (current) => ({
|
|
68
|
+
...current,
|
|
69
|
+
status: 'archived',
|
|
70
|
+
provenance: { ...current.provenance, updatedAt: now },
|
|
71
|
+
lifecycle: { ...current.lifecycle, archivedAt: now },
|
|
72
|
+
}));
|
|
73
|
+
console.log(options.json
|
|
74
|
+
? JSON.stringify(atom, null, 2)
|
|
75
|
+
: `Archived knowledge atom: ${atom.id}`);
|
|
76
|
+
}));
|
|
77
|
+
knowledge
|
|
78
|
+
.command('supersede <oldId> <newId>')
|
|
79
|
+
.option('--json', 'Print JSON output')
|
|
80
|
+
.action((oldId, newId, options) => runCommand(async () => {
|
|
81
|
+
const workspace = await assertWorkspace(process.cwd());
|
|
82
|
+
await requireAtom(workspace, newId);
|
|
83
|
+
const now = new Date().toISOString();
|
|
84
|
+
const oldAtom = await updateKnowledgeAtom(workspace, oldId, (current) => ({
|
|
85
|
+
...current,
|
|
86
|
+
status: 'archived',
|
|
87
|
+
provenance: { ...current.provenance, updatedAt: now },
|
|
88
|
+
lifecycle: {
|
|
89
|
+
...current.lifecycle,
|
|
90
|
+
supersededBy: newId,
|
|
91
|
+
archivedAt: now,
|
|
92
|
+
},
|
|
93
|
+
}));
|
|
94
|
+
const newAtom = await updateKnowledgeAtom(workspace, newId, (current) => ({
|
|
95
|
+
...current,
|
|
96
|
+
provenance: { ...current.provenance, updatedAt: now },
|
|
97
|
+
lifecycle: {
|
|
98
|
+
...current.lifecycle,
|
|
99
|
+
supersedes: [...new Set([...current.lifecycle.supersedes, oldId])],
|
|
100
|
+
},
|
|
101
|
+
}));
|
|
102
|
+
const result = { old: oldAtom, new: newAtom };
|
|
103
|
+
console.log(options.json
|
|
104
|
+
? JSON.stringify(result, null, 2)
|
|
105
|
+
: `Superseded ${oldId} with ${newId}`);
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
async function requireAtom(workspace, atomId) {
|
|
109
|
+
const atom = (await readKnowledgeAtoms(workspace)).find((candidate) => candidate.id === atomId);
|
|
110
|
+
if (!atom)
|
|
111
|
+
throw new KGraphError(`Knowledge atom not found: ${atomId}`);
|
|
112
|
+
return atom;
|
|
113
|
+
}
|
|
114
|
+
function filterAtoms(atoms, options) {
|
|
115
|
+
return atoms.filter((atom) => {
|
|
116
|
+
if (options.type && atom.type !== options.type)
|
|
117
|
+
return false;
|
|
118
|
+
if (options.status &&
|
|
119
|
+
atom.status !== normalizeStatus(options.status)) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
if (options.topic &&
|
|
123
|
+
!atom.topic.toLowerCase().includes(options.topic.toLowerCase())) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function normalizeStatus(value) {
|
|
130
|
+
if (value === 'active' ||
|
|
131
|
+
value === 'stale' ||
|
|
132
|
+
value === 'needs-review' ||
|
|
133
|
+
value === 'archived') {
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
136
|
+
throw new KGraphError('--status must be active, stale, needs-review, or archived.');
|
|
137
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { buildContextPack } from '../../context/context-pack.js';
|
|
2
|
+
import { queryContext } from '../../context/context-query.js';
|
|
3
|
+
import { loadConfig } from '../../config/config.js';
|
|
4
|
+
import { assertWorkspace } from '../../storage/kgraph-paths.js';
|
|
5
|
+
import { mapsExist, readMaps } from '../../storage/map-store.js';
|
|
6
|
+
import { KGraphError, runCommand } from '../errors.js';
|
|
7
|
+
export function registerPackCommand(program) {
|
|
8
|
+
program
|
|
9
|
+
.command('pack <task>')
|
|
10
|
+
.description('Build a budget-aware KGraph context pack for a task')
|
|
11
|
+
.option('--budget <tokens>', 'Maximum estimated tokens to include', '8000')
|
|
12
|
+
.option('--json', 'Print JSON output')
|
|
13
|
+
.action((task, options) => runCommand(async () => {
|
|
14
|
+
if (!task.trim())
|
|
15
|
+
throw new KGraphError('Task cannot be empty.');
|
|
16
|
+
const budget = Number.parseInt(options.budget ?? '8000', 10);
|
|
17
|
+
if (!Number.isFinite(budget) || budget < 1) {
|
|
18
|
+
throw new KGraphError('--budget must be a positive integer.');
|
|
19
|
+
}
|
|
20
|
+
const workspace = await assertWorkspace(process.cwd());
|
|
21
|
+
if (!(await mapsExist(workspace))) {
|
|
22
|
+
throw new KGraphError('KGraph maps are missing. Run `kgraph scan` first.');
|
|
23
|
+
}
|
|
24
|
+
const [config, maps] = await Promise.all([
|
|
25
|
+
loadConfig(workspace),
|
|
26
|
+
readMaps(workspace),
|
|
27
|
+
]);
|
|
28
|
+
const response = await queryContext(workspace, config, maps, task);
|
|
29
|
+
const pack = buildContextPack(response, budget);
|
|
30
|
+
if (options.json) {
|
|
31
|
+
console.log(JSON.stringify(pack, null, 2));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
console.log(`# KGraph Context Pack`);
|
|
35
|
+
console.log('');
|
|
36
|
+
console.log(`Task: ${pack.task}`);
|
|
37
|
+
console.log(`Budget: ${pack.budget}`);
|
|
38
|
+
console.log(`Used: ${pack.usedTokens}`);
|
|
39
|
+
console.log('');
|
|
40
|
+
for (const item of pack.items) {
|
|
41
|
+
console.log(`- [${item.kind}] ${item.title} (~${item.tokenEstimate} tokens)`);
|
|
42
|
+
console.log(` because ${item.reasons.slice(0, 3).join('; ')}`);
|
|
43
|
+
}
|
|
44
|
+
if (pack.omitted.length > 0) {
|
|
45
|
+
console.log('');
|
|
46
|
+
console.log(`Omitted: ${pack.omitted.length} item(s) over budget`);
|
|
47
|
+
}
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { refreshKnowledgeAtomStatuses } from '../../knowledge/atom-store.js';
|
|
2
|
+
import { readMaps } from '../../storage/map-store.js';
|
|
3
|
+
import { assertWorkspace } from '../../storage/kgraph-paths.js';
|
|
4
|
+
import { runCommand } from '../errors.js';
|
|
5
|
+
export function registerStaleCommand(program) {
|
|
6
|
+
program
|
|
7
|
+
.command('stale')
|
|
8
|
+
.description('Show knowledge atoms invalidated by changed or missing refs')
|
|
9
|
+
.option('--json', 'Print JSON output')
|
|
10
|
+
.action((options) => runCommand(async () => {
|
|
11
|
+
const workspace = await assertWorkspace(process.cwd());
|
|
12
|
+
const maps = await readMaps(workspace);
|
|
13
|
+
const result = await refreshKnowledgeAtomStatuses(workspace, {
|
|
14
|
+
fileMap: maps.fileMap,
|
|
15
|
+
symbolMap: maps.symbolMap,
|
|
16
|
+
});
|
|
17
|
+
const atoms = result.atoms.filter((atom) => atom.status === 'stale' || atom.status === 'needs-review');
|
|
18
|
+
if (options.json) {
|
|
19
|
+
console.log(JSON.stringify({ updated: result.updated, atoms }, null, 2));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
console.log('KGraph Stale Knowledge');
|
|
23
|
+
console.log('');
|
|
24
|
+
for (const atom of atoms) {
|
|
25
|
+
console.log(`- ${atom.id} [${atom.type}, ${atom.confidence}, ${atom.status}] ${atom.topic}`);
|
|
26
|
+
for (const reason of atom.lifecycle.invalidatedBy ?? []) {
|
|
27
|
+
console.log(` - ${reason}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (atoms.length === 0)
|
|
31
|
+
console.log('- None');
|
|
32
|
+
}));
|
|
33
|
+
}
|
package/dist/cli/help.js
CHANGED
|
@@ -32,6 +32,10 @@ export function renderRootHelp(useColor = supportsColor()) {
|
|
|
32
32
|
command('session end --agent codex --conclude', 'End tracking and store a durable session summary'),
|
|
33
33
|
command('conclude "auth refresh gotcha"', 'Store typed engineering cognition'),
|
|
34
34
|
command('compact', 'Merge duplicate cognition and archive stale noise'),
|
|
35
|
+
command('knowledge list', 'Inspect canonical knowledge atoms'),
|
|
36
|
+
command('pack "auth task" --budget 8000', 'Build a budget-aware context pack'),
|
|
37
|
+
command('stale', 'Show atoms invalidated by changed or missing refs'),
|
|
38
|
+
command('blame <atom-id>', 'Show atom provenance and evidence'),
|
|
35
39
|
command('context "auth token refresh"', 'Optional: return context without scanning or updating'),
|
|
36
40
|
command('impact "Button"', 'Show imports, callers, calls, cognition, and risk'),
|
|
37
41
|
command('update', 'Optional: process only .kgraph/inbox Markdown cognition notes'),
|
|
@@ -94,6 +98,8 @@ export function renderWorkflowBanner(stats, useColor = supportsColor()) {
|
|
|
94
98
|
command('kgraph "auth token refresh"', 'Return compact context for a topic'),
|
|
95
99
|
command('kgraph doctor', 'Check workspace health'),
|
|
96
100
|
command('kgraph doctor --quality', 'Check cognition quality'),
|
|
101
|
+
command('kgraph knowledge list', 'Inspect knowledge atoms'),
|
|
102
|
+
command('kgraph pack "auth task"', 'Build budget-aware context'),
|
|
97
103
|
command('kgraph session', 'Check session token waste'),
|
|
98
104
|
command('kgraph --help', 'Show all commands'),
|
|
99
105
|
].join('\n');
|
package/dist/cli/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Command } from 'commander';
|
|
|
3
3
|
import { realpathSync } from 'node:fs';
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { registerBlameCommand } from './commands/blame.js';
|
|
6
7
|
import { registerCompactCommand } from './commands/compact.js';
|
|
7
8
|
import { registerConcludeCommand } from './commands/conclude.js';
|
|
8
9
|
import { registerContextCommand } from './commands/context.js';
|
|
@@ -11,9 +12,12 @@ import { registerHistoryCommand } from './commands/history.js';
|
|
|
11
12
|
import { registerImpactCommand } from './commands/impact.js';
|
|
12
13
|
import { registerInitCommand } from './commands/init.js';
|
|
13
14
|
import { registerIntegrateCommand } from './commands/integrate.js';
|
|
15
|
+
import { registerKnowledgeCommand } from './commands/knowledge.js';
|
|
16
|
+
import { registerPackCommand } from './commands/pack.js';
|
|
14
17
|
import { registerRepairCommand } from './commands/repair.js';
|
|
15
18
|
import { registerScanCommand } from './commands/scan.js';
|
|
16
19
|
import { registerSessionCommand } from './commands/session.js';
|
|
20
|
+
import { registerStaleCommand } from './commands/stale.js';
|
|
17
21
|
import { registerUninstallCommand } from './commands/uninstall.js';
|
|
18
22
|
import { registerUpdateCommand } from './commands/update.js';
|
|
19
23
|
import { registerVisualizeCommand } from './commands/visualize.js';
|
|
@@ -46,6 +50,10 @@ export function createProgram() {
|
|
|
46
50
|
registerCompactCommand(program);
|
|
47
51
|
registerUpdateCommand(program);
|
|
48
52
|
registerContextCommand(program);
|
|
53
|
+
registerPackCommand(program);
|
|
54
|
+
registerKnowledgeCommand(program);
|
|
55
|
+
registerStaleCommand(program);
|
|
56
|
+
registerBlameCommand(program);
|
|
49
57
|
registerImpactCommand(program);
|
|
50
58
|
registerIntegrateCommand(program);
|
|
51
59
|
registerVisualizeCommand(program);
|
|
@@ -2,6 +2,7 @@ import { readFile } from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { archiveInboxNote, listInboxNotes, readCognitionNotes, slugify, writeCognitionNote, writeDomainRecord, } from '../storage/cognition-store.js';
|
|
4
4
|
import { parseMarkdownNote } from './markdown-note-parser.js';
|
|
5
|
+
import { createKnowledgeAtom } from '../knowledge/atom-store.js';
|
|
5
6
|
export async function updateCognition(workspace, currentMaps, dryRun = false) {
|
|
6
7
|
const inboxNotes = await listInboxNotes(workspace);
|
|
7
8
|
const processed = [];
|
|
@@ -38,6 +39,19 @@ export async function updateCognition(workspace, currentMaps, dryRun = false) {
|
|
|
38
39
|
await archiveInboxNote(workspace, inboxPath, timestamp);
|
|
39
40
|
await writeCognitionNote(workspace, note);
|
|
40
41
|
await writeDomainRecord(workspace, toDomainRecord(note, currentMaps));
|
|
42
|
+
await createKnowledgeAtom(workspace, {
|
|
43
|
+
type: note.kind,
|
|
44
|
+
topic: note.title,
|
|
45
|
+
claim: note.summary ?? note.title,
|
|
46
|
+
summary: note.summary,
|
|
47
|
+
confidence: note.confidence,
|
|
48
|
+
files: note.relatedFiles,
|
|
49
|
+
symbols: note.relatedSymbols,
|
|
50
|
+
domains: note.domain ? [note.domain] : [],
|
|
51
|
+
sourceCommand: 'update',
|
|
52
|
+
createdAt: note.createdAt,
|
|
53
|
+
idSeed: note.id,
|
|
54
|
+
});
|
|
41
55
|
}
|
|
42
56
|
}
|
|
43
57
|
catch (error) {
|