@codehourra/llm-iwiki 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +514 -0
- package/package.json +7 -8
- package/src/ai-yaml.ts +0 -82
- package/src/cli.ts +0 -485
- package/src/collectors/claude-code.ts +0 -120
- package/src/collectors/codebuddy.ts +0 -164
- package/src/collectors/codex.ts +0 -130
- package/src/collectors/cursor.ts +0 -178
- package/src/collectors/gemini.ts +0 -141
- package/src/collectors/index.ts +0 -20
- package/src/collectors/types.ts +0 -22
- package/src/collectors/util.ts +0 -58
- package/src/compaction.ts +0 -63
- package/src/config.ts +0 -57
- package/src/db.ts +0 -152
- package/src/experiences.ts +0 -235
- package/src/index.ts +0 -10
- package/src/obsidian.ts +0 -345
- package/src/paths.ts +0 -23
- package/src/projects.ts +0 -192
- package/src/sessions.ts +0 -119
- package/src/skills.ts +0 -168
- package/src/summarize.ts +0 -122
- package/src/sync.ts +0 -207
- package/src/types.ts +0 -26
package/src/sync.ts
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import type { LlmIwikiDatabase } from './db'
|
|
2
|
-
import { resolveProjectByPath } from './projects'
|
|
3
|
-
import { COLLECTORS, type Collector, type RawSession } from './collectors'
|
|
4
|
-
|
|
5
|
-
export interface SourceSyncReport {
|
|
6
|
-
source: string
|
|
7
|
-
new: number
|
|
8
|
-
changed: number
|
|
9
|
-
unchanged: number
|
|
10
|
-
sourceMissing: number
|
|
11
|
-
total: number
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface SyncReport {
|
|
15
|
-
bySource: SourceSyncReport[]
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface SyncOptions {
|
|
19
|
-
homeDir: string
|
|
20
|
-
projectFilter?: string | null
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function hash(value: string): string {
|
|
24
|
-
return Bun.hash(value).toString(16)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function sessionPrimaryId(sourceId: string, session: RawSession): string {
|
|
28
|
-
return `ses_${hash(`${sourceId}\u0000${session.sourceSessionId}\u0000${session.rawPath}`)}`
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function messageContentHash(role: string, content: string): string {
|
|
32
|
-
return hash(`${role}\u0000${content}`)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function sessionContentHash(messageHashes: string[]): string {
|
|
36
|
-
return hash(`${messageHashes.length}\u0000${messageHashes.join('\u0000')}`)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function upsertSource(db: LlmIwikiDatabase, collector: Collector, now: string): void {
|
|
40
|
-
db.query(`
|
|
41
|
-
INSERT INTO sources (id, name, enabled, scan_paths, config_json, last_sync_at)
|
|
42
|
-
VALUES ($id, $name, 1, NULL, NULL, $now)
|
|
43
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
44
|
-
name = excluded.name,
|
|
45
|
-
last_sync_at = excluded.last_sync_at
|
|
46
|
-
`).run({ $id: collector.id, $name: collector.name, $now: now })
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function resolveProjectId(db: LlmIwikiDatabase, rawProjectPath: string | null): string | null {
|
|
50
|
-
if (!rawProjectPath) return null
|
|
51
|
-
try {
|
|
52
|
-
return resolveProjectByPath(db, rawProjectPath).id
|
|
53
|
-
} catch {
|
|
54
|
-
return null
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function writeSession(
|
|
59
|
-
db: LlmIwikiDatabase,
|
|
60
|
-
collector: Collector,
|
|
61
|
-
session: RawSession,
|
|
62
|
-
now: string,
|
|
63
|
-
report: SourceSyncReport,
|
|
64
|
-
): string {
|
|
65
|
-
const id = sessionPrimaryId(collector.id, session)
|
|
66
|
-
const messageHashes = session.messages.map((message) => messageContentHash(message.role, message.content))
|
|
67
|
-
const contentHash = sessionContentHash(messageHashes)
|
|
68
|
-
const projectId = resolveProjectId(db, session.rawProjectPath)
|
|
69
|
-
|
|
70
|
-
const existing = db
|
|
71
|
-
.query<{ content_hash: string; first_seen_at: string }, [string]>(
|
|
72
|
-
'SELECT content_hash, first_seen_at FROM sessions WHERE id = ?',
|
|
73
|
-
)
|
|
74
|
-
.get(id)
|
|
75
|
-
|
|
76
|
-
if (existing && existing.content_hash === contentHash) {
|
|
77
|
-
db.query('UPDATE sessions SET project_id = $projectId, status = $status, last_seen_at = $now WHERE id = $id').run({
|
|
78
|
-
$projectId: projectId,
|
|
79
|
-
$status: 'unchanged',
|
|
80
|
-
$now: now,
|
|
81
|
-
$id: id,
|
|
82
|
-
})
|
|
83
|
-
report.unchanged += 1
|
|
84
|
-
return id
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const status = existing ? 'changed' : 'new'
|
|
88
|
-
const firstSeenAt = existing?.first_seen_at ?? now
|
|
89
|
-
|
|
90
|
-
db.query(`
|
|
91
|
-
INSERT INTO sessions (
|
|
92
|
-
id, source_id, source_session_id, project_id, checkout_id, raw_project_path, raw_path,
|
|
93
|
-
title, message_count, content_hash, status, created_at, updated_at, first_seen_at, last_seen_at
|
|
94
|
-
) VALUES (
|
|
95
|
-
$id, $sourceId, $sourceSessionId, $projectId, NULL, $rawProjectPath, $rawPath,
|
|
96
|
-
$title, $messageCount, $contentHash, $status, $createdAt, $updatedAt, $firstSeenAt, $now
|
|
97
|
-
)
|
|
98
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
99
|
-
project_id = excluded.project_id,
|
|
100
|
-
raw_project_path = excluded.raw_project_path,
|
|
101
|
-
title = excluded.title,
|
|
102
|
-
message_count = excluded.message_count,
|
|
103
|
-
content_hash = excluded.content_hash,
|
|
104
|
-
status = excluded.status,
|
|
105
|
-
created_at = excluded.created_at,
|
|
106
|
-
updated_at = excluded.updated_at,
|
|
107
|
-
last_seen_at = excluded.last_seen_at
|
|
108
|
-
`).run({
|
|
109
|
-
$id: id,
|
|
110
|
-
$sourceId: collector.id,
|
|
111
|
-
$sourceSessionId: session.sourceSessionId,
|
|
112
|
-
$projectId: projectId,
|
|
113
|
-
$rawProjectPath: session.rawProjectPath,
|
|
114
|
-
$rawPath: session.rawPath,
|
|
115
|
-
$title: session.title,
|
|
116
|
-
$messageCount: session.messages.length,
|
|
117
|
-
$contentHash: contentHash,
|
|
118
|
-
$status: status,
|
|
119
|
-
$createdAt: session.createdAt,
|
|
120
|
-
$updatedAt: session.updatedAt,
|
|
121
|
-
$firstSeenAt: firstSeenAt,
|
|
122
|
-
$now: now,
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
db.query('DELETE FROM messages WHERE session_id = ?').run(id)
|
|
126
|
-
session.messages.forEach((message, index) => {
|
|
127
|
-
db.query(`
|
|
128
|
-
INSERT INTO messages (id, session_id, role, content, timestamp, seq_order, content_hash)
|
|
129
|
-
VALUES ($id, $sessionId, $role, $content, $timestamp, $seqOrder, $contentHash)
|
|
130
|
-
`).run({
|
|
131
|
-
$id: `msg_${id}_${index}`,
|
|
132
|
-
$sessionId: id,
|
|
133
|
-
$role: message.role,
|
|
134
|
-
$content: message.content,
|
|
135
|
-
$timestamp: message.timestamp,
|
|
136
|
-
$seqOrder: index,
|
|
137
|
-
$contentHash: messageHashes[index]!,
|
|
138
|
-
})
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
if (status === 'new') report.new += 1
|
|
142
|
-
else report.changed += 1
|
|
143
|
-
return id
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function markMissingSessions(
|
|
147
|
-
db: LlmIwikiDatabase,
|
|
148
|
-
sourceId: string,
|
|
149
|
-
seenIds: Set<string>,
|
|
150
|
-
now: string,
|
|
151
|
-
report: SourceSyncReport,
|
|
152
|
-
): void {
|
|
153
|
-
const rows = db
|
|
154
|
-
.query<{ id: string }, [string]>(
|
|
155
|
-
"SELECT id FROM sessions WHERE source_id = ? AND status != 'source_missing'",
|
|
156
|
-
)
|
|
157
|
-
.all(sourceId)
|
|
158
|
-
|
|
159
|
-
for (const row of rows) {
|
|
160
|
-
if (seenIds.has(row.id)) continue
|
|
161
|
-
db.query('UPDATE sessions SET status = $status, last_seen_at = $now WHERE id = $id').run({
|
|
162
|
-
$status: 'source_missing',
|
|
163
|
-
$now: now,
|
|
164
|
-
$id: row.id,
|
|
165
|
-
})
|
|
166
|
-
report.sourceMissing += 1
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export function runSync(db: LlmIwikiDatabase, options: SyncOptions): SyncReport {
|
|
171
|
-
const now = new Date().toISOString()
|
|
172
|
-
const bySource: SourceSyncReport[] = []
|
|
173
|
-
|
|
174
|
-
for (const collector of COLLECTORS) {
|
|
175
|
-
if (!collector.detect(options.homeDir)) continue
|
|
176
|
-
|
|
177
|
-
upsertSource(db, collector, now)
|
|
178
|
-
const report: SourceSyncReport = {
|
|
179
|
-
source: collector.id,
|
|
180
|
-
new: 0,
|
|
181
|
-
changed: 0,
|
|
182
|
-
unchanged: 0,
|
|
183
|
-
sourceMissing: 0,
|
|
184
|
-
total: 0,
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const sessions = collector.collect(options.homeDir)
|
|
188
|
-
const seenIds = new Set<string>()
|
|
189
|
-
|
|
190
|
-
const writeAll = db.transaction(() => {
|
|
191
|
-
for (const session of sessions) {
|
|
192
|
-
if (options.projectFilter && session.rawProjectPath !== options.projectFilter) continue
|
|
193
|
-
const id = writeSession(db, collector, session, now, report)
|
|
194
|
-
seenIds.add(id)
|
|
195
|
-
report.total += 1
|
|
196
|
-
}
|
|
197
|
-
if (!options.projectFilter) {
|
|
198
|
-
markMissingSessions(db, collector.id, seenIds, now, report)
|
|
199
|
-
}
|
|
200
|
-
})
|
|
201
|
-
writeAll()
|
|
202
|
-
|
|
203
|
-
bySource.push(report)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return { bySource }
|
|
207
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export type SummaryValue = 'none' | 'low' | 'medium' | 'high'
|
|
2
|
-
export type Confidence = 'low' | 'medium' | 'high'
|
|
3
|
-
|
|
4
|
-
export interface ParsedSummariesYaml {
|
|
5
|
-
projectId: string
|
|
6
|
-
summaries: Array<{
|
|
7
|
-
sessionId: string
|
|
8
|
-
title: string
|
|
9
|
-
value: SummaryValue
|
|
10
|
-
summaryMarkdown: string
|
|
11
|
-
metadata: Record<string, unknown>
|
|
12
|
-
}>
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface ParsedExperiencesYaml {
|
|
16
|
-
projectId: string
|
|
17
|
-
experiences: Array<{
|
|
18
|
-
title: string
|
|
19
|
-
slug: string | null
|
|
20
|
-
summary: string
|
|
21
|
-
bodyMarkdown: string
|
|
22
|
-
sourceSessions: string[]
|
|
23
|
-
confidence: Confidence | null
|
|
24
|
-
metadata: Record<string, unknown>
|
|
25
|
-
}>
|
|
26
|
-
}
|