@kentwynn/kgraph 0.2.22 → 0.2.24
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 +35 -11
- package/dist/cli/commands/knowledge.js +15 -1
- package/dist/cli/help.js +3 -2
- package/dist/cli/init-summary.d.ts +1 -1
- package/dist/cli/init-summary.js +28 -8
- package/dist/cognition/cognition-quality.js +14 -8
- package/dist/cognition/compact.js +2 -29
- package/dist/cognition/conclusion.js +1 -1
- package/dist/cognition/domain-records.d.ts +4 -0
- package/dist/cognition/domain-records.js +32 -0
- package/dist/config/config.js +45 -0
- package/dist/knowledge/atom-store.js +1 -1
- package/dist/scanner/broad-symbol-extractor.d.ts +3 -0
- package/dist/scanner/broad-symbol-extractor.js +292 -0
- package/dist/scanner/extraction-context.d.ts +23 -0
- package/dist/scanner/extraction-context.js +77 -0
- package/dist/scanner/file-classifier.js +15 -2
- package/dist/scanner/git-utils.d.ts +5 -0
- package/dist/scanner/git-utils.js +33 -1
- package/dist/scanner/php-symbol-extractor.d.ts +2 -0
- package/dist/scanner/php-symbol-extractor.js +79 -0
- package/dist/scanner/repo-scanner.js +65 -4
- package/dist/scanner/ruby-symbol-extractor.d.ts +2 -0
- package/dist/scanner/ruby-symbol-extractor.js +75 -0
- package/dist/scanner/shell-symbol-extractor.d.ts +2 -0
- package/dist/scanner/shell-symbol-extractor.js +78 -0
- package/dist/scanner/sql-symbol-extractor.d.ts +2 -0
- package/dist/scanner/sql-symbol-extractor.js +166 -0
- package/dist/scanner/tree-sitter-parser.d.ts +1 -2
- package/dist/scanner/tree-sitter-parser.js +14 -0
- package/package.json +12 -1
package/README.md
CHANGED
|
@@ -41,22 +41,33 @@ The CLI presents this as **Atom Core**: lightweight local atoms plus determinist
|
|
|
41
41
|
|
|
42
42
|
## The Workflow
|
|
43
43
|
|
|
44
|
-
Use KGraph
|
|
44
|
+
Use KGraph with one setup command and one normal daily command:
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
# Required once per repository
|
|
48
|
-
kgraph
|
|
47
|
+
# Required once per repository.
|
|
48
|
+
# Creates .kgraph/, runs the first scan, and detects likely AI tools.
|
|
49
|
+
kgraph init
|
|
49
50
|
|
|
50
|
-
# Normal daily command
|
|
51
|
+
# Normal daily command.
|
|
52
|
+
# Refreshes maps, processes pending capture notes, and returns focused context.
|
|
51
53
|
kgraph "auth token refresh"
|
|
52
54
|
```
|
|
53
55
|
|
|
54
|
-
|
|
56
|
+
AI tool integrations are optional. During `kgraph init`, KGraph detects likely local tools such as Codex, Copilot, Claude Code, and Gemini, then prompts or prints a suggested `kgraph integrate add ...` command. You can accept the recommendation, choose custom integrations, skip the step, or configure them later.
|
|
57
|
+
|
|
58
|
+
If you already know exactly which integrations you want, you can pass them during init:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
kgraph init --integrations codex,copilot,cursor,claude-code,gemini,windsurf,cline
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The daily command runs the full practical workflow:
|
|
55
65
|
|
|
56
66
|
1. Refreshes the repository scan.
|
|
57
67
|
2. Updates file, symbol, import, and relationship maps.
|
|
58
68
|
3. Processes any Markdown capture notes waiting in `.kgraph/inbox/` into knowledge atoms.
|
|
59
|
-
4.
|
|
69
|
+
4. Reports memory health and actionable next steps.
|
|
70
|
+
5. Returns compact context for the topic you asked about.
|
|
60
71
|
|
|
61
72
|
You can also run just:
|
|
62
73
|
|
|
@@ -134,10 +145,11 @@ KGraph's core functionality is free and local-first. It does not require account
|
|
|
134
145
|
From the root of a repository:
|
|
135
146
|
|
|
136
147
|
```bash
|
|
137
|
-
# 1. Create the local KGraph workspace
|
|
148
|
+
# 1. Create the local KGraph workspace and run the first scan
|
|
138
149
|
kgraph init
|
|
139
150
|
|
|
140
|
-
# 2. Optional:
|
|
151
|
+
# 2. Optional: accept detected AI tool recommendations during init,
|
|
152
|
+
# or add integrations later when you want KGraph-managed instructions
|
|
141
153
|
kgraph integrate add codex copilot cursor claude-code gemini windsurf cline
|
|
142
154
|
|
|
143
155
|
# 3. Run the normal workflow for a topic
|
|
@@ -147,7 +159,7 @@ kgraph "auth token refresh"
|
|
|
147
159
|
kgraph doctor
|
|
148
160
|
```
|
|
149
161
|
|
|
150
|
-
`kgraph init`
|
|
162
|
+
`kgraph init` scans once, prints repo language coverage, detects likely local AI tools, and recommends matching integrations. Integrations are still optional: they only write local instruction files so tools know when to run KGraph. They do not start background agents or call AI providers.
|
|
151
163
|
|
|
152
164
|
After useful AI work, assistants save durable runtime-capture notes into `.kgraph/inbox/`. These notes are not project documentation; they are KGraph input files that the next `kgraph` run processes automatically. You can also process them directly with `kgraph update`.
|
|
153
165
|
|
|
@@ -183,13 +195,13 @@ This is optional. Claude Code can use generated hook scripts for automatic captu
|
|
|
183
195
|
kgraph init
|
|
184
196
|
```
|
|
185
197
|
|
|
186
|
-
Required once per repo. Creates `.kgraph/`, writes the local config, runs the first scan, and prints suggested next actions based on
|
|
198
|
+
Required once per repo. Creates `.kgraph/`, writes the local config, initializes the knowledge store, runs the first scan, detects likely local AI tools, and prints suggested next actions based on repo languages and detected tools.
|
|
187
199
|
|
|
188
200
|
```bash
|
|
189
201
|
kgraph init --integrations codex,copilot,cursor,claude-code,gemini,windsurf,cline
|
|
190
202
|
```
|
|
191
203
|
|
|
192
|
-
Initializes KGraph and writes local instruction files for
|
|
204
|
+
Initializes KGraph and immediately writes local instruction files for the named AI tools. This is optional; plain `kgraph init` can detect likely tools and recommend or prompt for integrations instead.
|
|
193
205
|
|
|
194
206
|
```bash
|
|
195
207
|
kgraph "some topic"
|
|
@@ -356,6 +368,10 @@ Show processed capture history. Add a query to find historical work by title, su
|
|
|
356
368
|
|
|
357
369
|
KGraph integrations are local files. They do not start background agents, call AI providers, or send data anywhere.
|
|
358
370
|
|
|
371
|
+
You do not need integrations to use KGraph manually. They are useful when you want Codex, Copilot, Cursor, Claude Code, Gemini, Windsurf, or Cline to see repo-local KGraph workflow instructions automatically.
|
|
372
|
+
|
|
373
|
+
`kgraph init` detects likely local tools and recommends integrations when possible. You can also manage them explicitly:
|
|
374
|
+
|
|
359
375
|
```bash
|
|
360
376
|
kgraph integrate add codex copilot cursor claude-code gemini windsurf cline
|
|
361
377
|
kgraph integrate add copilot --mode smart
|
|
@@ -424,9 +440,17 @@ KGraph deeply scans:
|
|
|
424
440
|
- Java and Kotlin
|
|
425
441
|
- C and C++
|
|
426
442
|
- C#
|
|
443
|
+
- PHP
|
|
444
|
+
- Ruby
|
|
445
|
+
- Shell
|
|
446
|
+
- SQL
|
|
427
447
|
|
|
428
448
|
Other languages keep practical file, import, and symbol depth without full call graph analysis. Common file types still appear in the file map with generic metadata, so context queries can still point to docs, config, SQL, CSS, HTML, YAML, and similar files.
|
|
429
449
|
|
|
450
|
+
KGraph also extracts basic symbols/imports for Swift, Terraform/HCL,
|
|
451
|
+
GraphQL, Protocol Buffers, Lua, Dart, Elixir, Scala, and R. Structured file extraction covers
|
|
452
|
+
YAML, JSON, TOML, Dockerfile/Containerfile, Markdown/MDX, HTML, CSS, SCSS, Sass, Less, and XML.
|
|
453
|
+
|
|
430
454
|
## Visualization
|
|
431
455
|
|
|
432
456
|
```bash
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { readKnowledgeAtoms, updateKnowledgeAtom, } from '../../knowledge/atom-store.js';
|
|
1
|
+
import { atomToCognitionNote, readKnowledgeAtoms, updateKnowledgeAtom, } from '../../knowledge/atom-store.js';
|
|
2
|
+
import { rebuildDomainRecords } from '../../cognition/domain-records.js';
|
|
2
3
|
import { assertWorkspace } from '../../storage/kgraph-paths.js';
|
|
4
|
+
import { readMaps } from '../../storage/map-store.js';
|
|
3
5
|
import { KGraphError, runCommand } from '../errors.js';
|
|
4
6
|
export function registerKnowledgeCommand(program) {
|
|
5
7
|
const knowledge = program
|
|
@@ -70,6 +72,7 @@ export function registerKnowledgeCommand(program) {
|
|
|
70
72
|
provenance: { ...current.provenance, updatedAt: now },
|
|
71
73
|
lifecycle: { ...current.lifecycle, archivedAt: now },
|
|
72
74
|
}));
|
|
75
|
+
await rebuildActiveDomainRecords(workspace);
|
|
73
76
|
console.log(options.json
|
|
74
77
|
? JSON.stringify(atom, null, 2)
|
|
75
78
|
: `Archived knowledge atom: ${atom.id}`);
|
|
@@ -99,12 +102,23 @@ export function registerKnowledgeCommand(program) {
|
|
|
99
102
|
supersedes: [...new Set([...current.lifecycle.supersedes, oldId])],
|
|
100
103
|
},
|
|
101
104
|
}));
|
|
105
|
+
await rebuildActiveDomainRecords(workspace);
|
|
102
106
|
const result = { old: oldAtom, new: newAtom };
|
|
103
107
|
console.log(options.json
|
|
104
108
|
? JSON.stringify(result, null, 2)
|
|
105
109
|
: `Superseded ${oldId} with ${newId}`);
|
|
106
110
|
}));
|
|
107
111
|
}
|
|
112
|
+
async function rebuildActiveDomainRecords(workspace) {
|
|
113
|
+
const maps = await readMaps(workspace);
|
|
114
|
+
const activeNotes = (await readKnowledgeAtoms(workspace))
|
|
115
|
+
.filter((atom) => atom.status !== 'archived')
|
|
116
|
+
.map(atomToCognitionNote);
|
|
117
|
+
await rebuildDomainRecords(workspace, activeNotes, {
|
|
118
|
+
files: maps.fileMap.files,
|
|
119
|
+
symbols: maps.symbolMap.symbols,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
108
122
|
async function requireAtom(workspace, atomId) {
|
|
109
123
|
const atom = (await readKnowledgeAtoms(workspace)).find((candidate) => candidate.id === atomId);
|
|
110
124
|
if (!atom)
|
package/dist/cli/help.js
CHANGED
|
@@ -20,7 +20,7 @@ export function renderRootHelp(useColor = supportsColor()) {
|
|
|
20
20
|
'',
|
|
21
21
|
sectionTitle(theme, `${accent} Start`),
|
|
22
22
|
command('init', 'Required once: create .kgraph/ workspace'),
|
|
23
|
-
command('init --integrations codex,gemini', '
|
|
23
|
+
command('init --integrations codex,gemini', 'Optional: initialize and connect named AI tools'),
|
|
24
24
|
'',
|
|
25
25
|
sectionTitle(theme, `${accent} Daily workflow`),
|
|
26
26
|
command('kgraph', 'Refresh scan maps and process pending capture notes'),
|
|
@@ -68,7 +68,8 @@ export function renderRootHelp(useColor = supportsColor()) {
|
|
|
68
68
|
command('--capture-symbol <name>', 'Attach symbol evidence to root capture'),
|
|
69
69
|
'',
|
|
70
70
|
sectionTitle(theme, `${accent} Examples`),
|
|
71
|
-
' kgraph init
|
|
71
|
+
' kgraph init',
|
|
72
|
+
' kgraph integrate add codex copilot cursor claude-code gemini windsurf cline',
|
|
72
73
|
' kgraph "blog admin token usage"',
|
|
73
74
|
' kgraph "blog admin token usage" --final',
|
|
74
75
|
' kgraph "blog admin token usage" --capture "Author filter now uses display names" --capture-file www/app/blog/page.tsx',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { IntegrationConfig } from '../types/config.js';
|
|
2
2
|
import type { RepositoryFile } from '../types/maps.js';
|
|
3
3
|
import { type InitIntegrationRecommendation } from './init-recommendations.js';
|
|
4
|
-
type CoverageLevel = 'deep' | 'basic' | 'generic';
|
|
4
|
+
type CoverageLevel = 'deep' | 'basic' | 'structured' | 'generic';
|
|
5
5
|
export interface InitLanguageSummary {
|
|
6
6
|
language: string;
|
|
7
7
|
label: string;
|
package/dist/cli/init-summary.js
CHANGED
|
@@ -12,15 +12,32 @@ const LANGUAGE_PRESENTATION = {
|
|
|
12
12
|
c: { label: 'C', coverage: 'deep' },
|
|
13
13
|
cpp: { label: 'C++', coverage: 'deep' },
|
|
14
14
|
csharp: { label: 'C#', coverage: 'deep' },
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
php: { label: 'PHP', coverage: 'deep' },
|
|
16
|
+
swift: { label: 'Swift', coverage: 'basic' },
|
|
17
|
+
ruby: { label: 'Ruby', coverage: 'deep' },
|
|
18
|
+
shell: { label: 'Shell', coverage: 'deep' },
|
|
19
|
+
lua: { label: 'Lua', coverage: 'basic' },
|
|
20
|
+
dart: { label: 'Dart', coverage: 'basic' },
|
|
21
|
+
elixir: { label: 'Elixir', coverage: 'basic' },
|
|
22
|
+
scala: { label: 'Scala', coverage: 'basic' },
|
|
23
|
+
r: { label: 'R', coverage: 'basic' },
|
|
24
|
+
sql: { label: 'SQL', coverage: 'deep' },
|
|
25
|
+
terraform: { label: 'Terraform/HCL', coverage: 'basic' },
|
|
26
|
+
graphql: { label: 'GraphQL', coverage: 'basic' },
|
|
27
|
+
protobuf: { label: 'Protocol Buffers', coverage: 'basic' },
|
|
28
|
+
yaml: { label: 'YAML', coverage: 'structured' },
|
|
29
|
+
json: { label: 'JSON', coverage: 'structured' },
|
|
30
|
+
toml: { label: 'TOML', coverage: 'structured' },
|
|
31
|
+
dockerfile: { label: 'Dockerfile', coverage: 'structured' },
|
|
32
|
+
markdown: { label: 'Markdown', coverage: 'structured' },
|
|
33
|
+
html: { label: 'HTML', coverage: 'structured' },
|
|
34
|
+
css: { label: 'CSS', coverage: 'structured' },
|
|
35
|
+
scss: { label: 'SCSS', coverage: 'structured' },
|
|
36
|
+
sass: { label: 'Sass', coverage: 'structured' },
|
|
37
|
+
less: { label: 'Less', coverage: 'structured' },
|
|
38
|
+
xml: { label: 'XML', coverage: 'structured' },
|
|
22
39
|
};
|
|
23
|
-
const EXCLUDED_LANGUAGES = new Set(['unknown', '
|
|
40
|
+
const EXCLUDED_LANGUAGES = new Set(['unknown', 'restructuredtext']);
|
|
24
41
|
export function summarizeInitLanguages(files) {
|
|
25
42
|
const byLabel = new Map();
|
|
26
43
|
for (const file of files) {
|
|
@@ -103,6 +120,7 @@ function moreDetailedCoverage(left, right) {
|
|
|
103
120
|
const rank = {
|
|
104
121
|
deep: 3,
|
|
105
122
|
basic: 2,
|
|
123
|
+
structured: 2,
|
|
106
124
|
generic: 1,
|
|
107
125
|
};
|
|
108
126
|
return rank[left] >= rank[right] ? left : right;
|
|
@@ -113,6 +131,8 @@ function coverageDescription(coverage) {
|
|
|
113
131
|
return 'deep built-in extraction';
|
|
114
132
|
case 'basic':
|
|
115
133
|
return 'basic built-in extraction';
|
|
134
|
+
case 'structured':
|
|
135
|
+
return 'structured file extraction';
|
|
116
136
|
default:
|
|
117
137
|
return 'generic file coverage';
|
|
118
138
|
}
|
|
@@ -26,7 +26,7 @@ export async function analyzeCognitionQuality(workspace, maps) {
|
|
|
26
26
|
noisySymbolRefCount: changes.reduce((total, change) => total + change.removedSymbolRefs.length, 0),
|
|
27
27
|
unresolvedLocalImportCount: countUnresolvedLocalImports(maps.dependencyMap),
|
|
28
28
|
unresolvedCallCount: countUnresolvedCalls(maps.symbolMap, maps.relationshipMap),
|
|
29
|
-
duplicateTitleCount:
|
|
29
|
+
duplicateTitleCount: countDuplicateTitles(notes),
|
|
30
30
|
generatedFileScanCount: countGeneratedScannedFiles(maps.fileMap),
|
|
31
31
|
expensiveFileCount: countExpensiveFiles(maps.fileMap),
|
|
32
32
|
highConfidenceMissingEvidenceCount: countHighConfidenceMissingEvidence(activeAtoms),
|
|
@@ -148,13 +148,23 @@ export async function repairCognition(workspace, maps, dryRun = false) {
|
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
150
|
function countUnresolvedLocalImports(dependencyMap) {
|
|
151
|
-
return (dependencyMap?.dependencies.filter((dependency) => dependency.kind === 'local' &&
|
|
151
|
+
return (dependencyMap?.dependencies.filter((dependency) => dependency.kind === 'local' &&
|
|
152
|
+
!dependency.resolvedFile &&
|
|
153
|
+
isActionableUnresolvedLocalImport(dependency)).length ?? 0);
|
|
154
|
+
}
|
|
155
|
+
function isActionableUnresolvedLocalImport(dependency) {
|
|
156
|
+
if (dependency.fromFile.endsWith('/next-env.d.ts') &&
|
|
157
|
+
dependency.specifier.includes('.next/')) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
return true;
|
|
152
161
|
}
|
|
153
162
|
function countUnresolvedCalls(symbolMap, relationshipMap) {
|
|
154
163
|
const symbolIds = new Set(symbolMap.symbols.map((symbol) => symbol.id));
|
|
155
164
|
const symbolNames = new Set(symbolMap.symbols.map((symbol) => symbol.name));
|
|
156
165
|
return (relationshipMap?.relationships.filter((relationship) => relationship.relationshipType === 'calls' &&
|
|
157
166
|
relationship.targetType === 'symbol' &&
|
|
167
|
+
relationship.confidence !== 'low' &&
|
|
158
168
|
!symbolIds.has(relationship.targetId) &&
|
|
159
169
|
!symbolNames.has(relationship.targetId) &&
|
|
160
170
|
![...symbolNames].some((name) => relationship.targetId.endsWith(`#${name}`))).length ?? 0);
|
|
@@ -176,12 +186,8 @@ function countDuplicateAtomTopics(atoms) {
|
|
|
176
186
|
const seen = new Set();
|
|
177
187
|
const duplicates = new Set();
|
|
178
188
|
for (const atom of atoms) {
|
|
179
|
-
const key =
|
|
180
|
-
|
|
181
|
-
atom.topic.trim().toLowerCase(),
|
|
182
|
-
atom.claim.trim().toLowerCase(),
|
|
183
|
-
].join('\0');
|
|
184
|
-
if (!atom.topic.trim())
|
|
189
|
+
const key = atom.topic.trim().toLowerCase();
|
|
190
|
+
if (!key)
|
|
185
191
|
continue;
|
|
186
192
|
if (seen.has(key))
|
|
187
193
|
duplicates.add(key);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { mkdir, rename } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { atomToCognitionNote, refreshKnowledgeAtomStatuses, writeKnowledgeAtoms, } from '../knowledge/atom-store.js';
|
|
4
|
-
import {
|
|
4
|
+
import { rebuildDomainRecords } from './domain-records.js';
|
|
5
|
+
import { slugify, writeCognitionNote, } from '../storage/cognition-store.js';
|
|
5
6
|
import { pathExists } from '../storage/kgraph-paths.js';
|
|
6
7
|
import { readMaps } from '../storage/map-store.js';
|
|
7
8
|
import { evaluateReferenceStatus } from './cognition-updater.js';
|
|
@@ -194,34 +195,6 @@ function mergeNotes(notes, currentMaps) {
|
|
|
194
195
|
referencesStatus: evaluateReferenceStatus(relatedFiles, relatedSymbols, currentMaps),
|
|
195
196
|
};
|
|
196
197
|
}
|
|
197
|
-
async function rebuildDomainRecords(workspace, notes, currentMaps) {
|
|
198
|
-
const existingDomains = await readDomainRecords(workspace);
|
|
199
|
-
const existingByName = new Map(existingDomains.map((domain) => [domain.name, domain]));
|
|
200
|
-
const domainNames = new Set([
|
|
201
|
-
...existingDomains.map((domain) => domain.name),
|
|
202
|
-
...notes.map((note) => note.domain ?? 'general'),
|
|
203
|
-
]);
|
|
204
|
-
const fileSet = new Set(currentMaps.files.map((file) => file.path));
|
|
205
|
-
const symbolSet = new Set(currentMaps.symbols.map((symbol) => symbol.name));
|
|
206
|
-
for (const name of domainNames) {
|
|
207
|
-
const relatedNotes = notes.filter((note) => (note.domain ?? 'general') === name);
|
|
208
|
-
const existing = existingByName.get(name);
|
|
209
|
-
const next = {
|
|
210
|
-
name,
|
|
211
|
-
description: existing?.description,
|
|
212
|
-
pathHints: unique(relatedNotes.flatMap((note) => note.relatedFiles)),
|
|
213
|
-
tags: unique(relatedNotes.flatMap((note) => note.tags)),
|
|
214
|
-
files: unique(relatedNotes
|
|
215
|
-
.flatMap((note) => note.relatedFiles)
|
|
216
|
-
.filter((file) => fileSet.has(file))),
|
|
217
|
-
symbols: unique(relatedNotes
|
|
218
|
-
.flatMap((note) => note.relatedSymbols)
|
|
219
|
-
.filter((symbol) => symbolSet.has(symbol))),
|
|
220
|
-
cognitionNotes: relatedNotes.map((note) => note.id),
|
|
221
|
-
};
|
|
222
|
-
await overwriteDomainRecord(workspace, next);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
198
|
async function archiveNote(workspace, note, reason) {
|
|
226
199
|
const source = path.join(workspace.cognitionPath, `${note.id}.md`);
|
|
227
200
|
if (!(await pathExists(source)))
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { KGraphWorkspace } from '../types/config.js';
|
|
2
|
+
import type { CognitionNote } from '../types/cognition.js';
|
|
3
|
+
import type { ScanResult } from '../types/maps.js';
|
|
4
|
+
export declare function rebuildDomainRecords(workspace: KGraphWorkspace, notes: CognitionNote[], currentMaps: Pick<ScanResult, 'files' | 'symbols'>): Promise<void>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { overwriteDomainRecord, readDomainRecords, } from '../storage/cognition-store.js';
|
|
2
|
+
export async function rebuildDomainRecords(workspace, notes, currentMaps) {
|
|
3
|
+
const existingDomains = await readDomainRecords(workspace);
|
|
4
|
+
const existingByName = new Map(existingDomains.map((domain) => [domain.name, domain]));
|
|
5
|
+
const domainNames = new Set([
|
|
6
|
+
...existingDomains.map((domain) => domain.name),
|
|
7
|
+
...notes.map((note) => note.domain ?? 'general'),
|
|
8
|
+
]);
|
|
9
|
+
const fileSet = new Set(currentMaps.files.map((file) => file.path));
|
|
10
|
+
const symbolSet = new Set(currentMaps.symbols.map((symbol) => symbol.name));
|
|
11
|
+
for (const name of domainNames) {
|
|
12
|
+
const relatedNotes = notes.filter((note) => (note.domain ?? 'general') === name);
|
|
13
|
+
const existing = existingByName.get(name);
|
|
14
|
+
const next = {
|
|
15
|
+
name,
|
|
16
|
+
description: existing?.description,
|
|
17
|
+
pathHints: unique(relatedNotes.flatMap((note) => note.relatedFiles)),
|
|
18
|
+
tags: unique(relatedNotes.flatMap((note) => note.tags)),
|
|
19
|
+
files: unique(relatedNotes
|
|
20
|
+
.flatMap((note) => note.relatedFiles)
|
|
21
|
+
.filter((file) => fileSet.has(file))),
|
|
22
|
+
symbols: unique(relatedNotes
|
|
23
|
+
.flatMap((note) => note.relatedSymbols)
|
|
24
|
+
.filter((symbol) => symbolSet.has(symbol))),
|
|
25
|
+
cognitionNotes: relatedNotes.map((note) => note.id),
|
|
26
|
+
};
|
|
27
|
+
await overwriteDomainRecord(workspace, next);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function unique(items) {
|
|
31
|
+
return [...new Set(items)];
|
|
32
|
+
}
|
package/dist/config/config.js
CHANGED
|
@@ -7,6 +7,10 @@ export const DEFAULT_CONFIG = {
|
|
|
7
7
|
exclude: [
|
|
8
8
|
'.git',
|
|
9
9
|
'node_modules',
|
|
10
|
+
'venv',
|
|
11
|
+
'.venv',
|
|
12
|
+
'__pycache__',
|
|
13
|
+
'.pytest_cache',
|
|
10
14
|
'dist',
|
|
11
15
|
'build',
|
|
12
16
|
'.next',
|
|
@@ -67,6 +71,47 @@ export const DEFAULT_CONFIG = {
|
|
|
67
71
|
'.hxx',
|
|
68
72
|
// C#
|
|
69
73
|
'.cs',
|
|
74
|
+
// PHP / Swift / Ruby
|
|
75
|
+
'.php',
|
|
76
|
+
'.swift',
|
|
77
|
+
'.rb',
|
|
78
|
+
'.rake',
|
|
79
|
+
// Shell
|
|
80
|
+
'.sh',
|
|
81
|
+
'.bash',
|
|
82
|
+
'.zsh',
|
|
83
|
+
'.fish',
|
|
84
|
+
// Web / styles
|
|
85
|
+
'.html',
|
|
86
|
+
'.htm',
|
|
87
|
+
'.css',
|
|
88
|
+
'.scss',
|
|
89
|
+
'.sass',
|
|
90
|
+
'.less',
|
|
91
|
+
// Data / config / schema
|
|
92
|
+
'.json',
|
|
93
|
+
'.jsonc',
|
|
94
|
+
'.yaml',
|
|
95
|
+
'.yml',
|
|
96
|
+
'.toml',
|
|
97
|
+
'.dockerfile',
|
|
98
|
+
'.xml',
|
|
99
|
+
'.graphql',
|
|
100
|
+
'.gql',
|
|
101
|
+
'.sql',
|
|
102
|
+
'.tf',
|
|
103
|
+
'.proto',
|
|
104
|
+
// Docs
|
|
105
|
+
'.md',
|
|
106
|
+
'.mdx',
|
|
107
|
+
// Additional app languages
|
|
108
|
+
'.lua',
|
|
109
|
+
'.r',
|
|
110
|
+
'.R',
|
|
111
|
+
'.dart',
|
|
112
|
+
'.ex',
|
|
113
|
+
'.exs',
|
|
114
|
+
'.scala',
|
|
70
115
|
],
|
|
71
116
|
},
|
|
72
117
|
maxContextItems: 8,
|
|
@@ -423,7 +423,7 @@ function buildIndexes(atoms) {
|
|
|
423
423
|
const terms = {};
|
|
424
424
|
const refs = {};
|
|
425
425
|
const topics = {};
|
|
426
|
-
for (const atom of atoms) {
|
|
426
|
+
for (const atom of atoms.filter((item) => item.status !== 'archived')) {
|
|
427
427
|
for (const term of tokenize([atom.topic, atom.claim, atom.summary ?? ''].join(' '))) {
|
|
428
428
|
addIndex(terms, term, atom.id);
|
|
429
429
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { SymbolExtractionResult } from './ts-symbol-extractor.js';
|
|
2
|
+
export declare function extractBroadSymbols(sourceText: string, filePath: string, language: string): Promise<SymbolExtractionResult>;
|
|
3
|
+
export declare function supportsBroadExtraction(language: string): boolean;
|