@ccview/core 0.1.0
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/analyzer/claude-md.d.ts +2 -0
- package/dist/analyzer/claude-md.d.ts.map +1 -0
- package/dist/analyzer/claude-md.js +3 -0
- package/dist/analyzer/claude-md.js.map +1 -0
- package/dist/analyzer/cost-calculator.d.ts +3 -0
- package/dist/analyzer/cost-calculator.d.ts.map +1 -0
- package/dist/analyzer/cost-calculator.js +8 -0
- package/dist/analyzer/cost-calculator.js.map +1 -0
- package/dist/analyzer/insights.d.ts +2 -0
- package/dist/analyzer/insights.d.ts.map +1 -0
- package/dist/analyzer/insights.js +3 -0
- package/dist/analyzer/insights.js.map +1 -0
- package/dist/analyzer/waste-detector.d.ts +2 -0
- package/dist/analyzer/waste-detector.d.ts.map +1 -0
- package/dist/analyzer/waste-detector.js +3 -0
- package/dist/analyzer/waste-detector.js.map +1 -0
- package/dist/db/index.d.ts +8 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +28 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/queries.d.ts +62 -0
- package/dist/db/queries.d.ts.map +1 -0
- package/dist/db/queries.js +404 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.d.ts +4 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +148 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/sync.d.ts +4 -0
- package/dist/db/sync.d.ts.map +1 -0
- package/dist/db/sync.js +63 -0
- package/dist/db/sync.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/file-impact.d.ts +5 -0
- package/dist/parser/file-impact.d.ts.map +1 -0
- package/dist/parser/file-impact.js +102 -0
- package/dist/parser/file-impact.js.map +1 -0
- package/dist/parser/index.d.ts +7 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +6 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/log-scanner.d.ts +24 -0
- package/dist/parser/log-scanner.d.ts.map +1 -0
- package/dist/parser/log-scanner.js +115 -0
- package/dist/parser/log-scanner.js.map +1 -0
- package/dist/parser/session-parser.d.ts +3 -0
- package/dist/parser/session-parser.d.ts.map +1 -0
- package/dist/parser/session-parser.js +131 -0
- package/dist/parser/session-parser.js.map +1 -0
- package/dist/parser/step-parser.d.ts +12 -0
- package/dist/parser/step-parser.d.ts.map +1 -0
- package/dist/parser/step-parser.js +242 -0
- package/dist/parser/step-parser.js.map +1 -0
- package/dist/parser/token-estimator.d.ts +11 -0
- package/dist/parser/token-estimator.d.ts.map +1 -0
- package/dist/parser/token-estimator.js +19 -0
- package/dist/parser/token-estimator.js.map +1 -0
- package/dist/types.d.ts +90 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
export const SCHEMA_SQL = `
|
|
2
|
+
CREATE TABLE IF NOT EXISTS _migrations (
|
|
3
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
4
|
+
version INTEGER NOT NULL UNIQUE,
|
|
5
|
+
name TEXT NOT NULL,
|
|
6
|
+
applied_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
10
|
+
id TEXT PRIMARY KEY,
|
|
11
|
+
project_path TEXT,
|
|
12
|
+
project_name TEXT,
|
|
13
|
+
started_at DATETIME NOT NULL,
|
|
14
|
+
ended_at DATETIME,
|
|
15
|
+
duration_seconds INTEGER,
|
|
16
|
+
total_tokens_in INTEGER DEFAULT 0,
|
|
17
|
+
total_tokens_out INTEGER DEFAULT 0,
|
|
18
|
+
total_cost_usd REAL DEFAULT 0,
|
|
19
|
+
total_steps INTEGER DEFAULT 0,
|
|
20
|
+
tool_call_count INTEGER DEFAULT 0,
|
|
21
|
+
error_count INTEGER DEFAULT 0,
|
|
22
|
+
retry_count INTEGER DEFAULT 0,
|
|
23
|
+
model TEXT,
|
|
24
|
+
summary TEXT,
|
|
25
|
+
raw_log_path TEXT,
|
|
26
|
+
log_hash TEXT,
|
|
27
|
+
indexed_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
28
|
+
UNIQUE(raw_log_path)
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_name);
|
|
32
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_date ON sessions(started_at DESC);
|
|
33
|
+
|
|
34
|
+
CREATE TABLE IF NOT EXISTS steps (
|
|
35
|
+
id TEXT PRIMARY KEY,
|
|
36
|
+
session_id TEXT NOT NULL,
|
|
37
|
+
step_index INTEGER NOT NULL,
|
|
38
|
+
type TEXT NOT NULL,
|
|
39
|
+
subtype TEXT,
|
|
40
|
+
content TEXT,
|
|
41
|
+
content_summary TEXT,
|
|
42
|
+
tokens_in INTEGER DEFAULT 0,
|
|
43
|
+
tokens_out INTEGER DEFAULT 0,
|
|
44
|
+
duration_ms INTEGER,
|
|
45
|
+
tool_name TEXT,
|
|
46
|
+
tool_input TEXT,
|
|
47
|
+
tool_output TEXT,
|
|
48
|
+
is_error INTEGER DEFAULT 0,
|
|
49
|
+
is_retry INTEGER DEFAULT 0,
|
|
50
|
+
retry_of_step_id TEXT,
|
|
51
|
+
created_at DATETIME NOT NULL,
|
|
52
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE,
|
|
53
|
+
FOREIGN KEY (retry_of_step_id) REFERENCES steps(id)
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
CREATE INDEX IF NOT EXISTS idx_steps_session ON steps(session_id, step_index);
|
|
57
|
+
CREATE INDEX IF NOT EXISTS idx_steps_type ON steps(type);
|
|
58
|
+
|
|
59
|
+
CREATE TABLE IF NOT EXISTS file_impacts (
|
|
60
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
61
|
+
session_id TEXT NOT NULL,
|
|
62
|
+
step_id TEXT NOT NULL,
|
|
63
|
+
file_path TEXT NOT NULL,
|
|
64
|
+
action TEXT NOT NULL,
|
|
65
|
+
lines_added INTEGER DEFAULT 0,
|
|
66
|
+
lines_removed INTEGER DEFAULT 0,
|
|
67
|
+
diff_content TEXT,
|
|
68
|
+
created_at DATETIME NOT NULL,
|
|
69
|
+
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE,
|
|
70
|
+
FOREIGN KEY (step_id) REFERENCES steps(id) ON DELETE CASCADE
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
CREATE INDEX IF NOT EXISTS idx_file_impacts_session ON file_impacts(session_id);
|
|
74
|
+
CREATE INDEX IF NOT EXISTS idx_file_impacts_file ON file_impacts(file_path);
|
|
75
|
+
|
|
76
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
77
|
+
path TEXT PRIMARY KEY,
|
|
78
|
+
name TEXT NOT NULL,
|
|
79
|
+
total_sessions INTEGER DEFAULT 0,
|
|
80
|
+
total_tokens INTEGER DEFAULT 0,
|
|
81
|
+
total_cost_usd REAL DEFAULT 0,
|
|
82
|
+
first_session_at DATETIME,
|
|
83
|
+
last_session_at DATETIME,
|
|
84
|
+
claude_md_path TEXT,
|
|
85
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
CREATE TABLE IF NOT EXISTS claude_md_rules (
|
|
89
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
90
|
+
project_path TEXT NOT NULL,
|
|
91
|
+
rule_text TEXT NOT NULL,
|
|
92
|
+
rule_category TEXT,
|
|
93
|
+
times_respected INTEGER DEFAULT 0,
|
|
94
|
+
times_violated INTEGER DEFAULT 0,
|
|
95
|
+
last_checked_at DATETIME,
|
|
96
|
+
FOREIGN KEY (project_path) REFERENCES projects(path)
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
CREATE VIEW IF NOT EXISTS v_session_overview AS
|
|
100
|
+
SELECT
|
|
101
|
+
s.*,
|
|
102
|
+
p.name as project_display_name,
|
|
103
|
+
COUNT(DISTINCT fi.file_path) as unique_files_touched,
|
|
104
|
+
SUM(CASE WHEN st.is_error THEN 1 ELSE 0 END) as errors,
|
|
105
|
+
SUM(CASE WHEN st.subtype = 'bash' THEN 1 ELSE 0 END) as bash_commands,
|
|
106
|
+
SUM(CASE WHEN st.subtype = 'file_edit' THEN 1 ELSE 0 END) as file_edits
|
|
107
|
+
FROM sessions s
|
|
108
|
+
LEFT JOIN projects p ON s.project_path = p.path
|
|
109
|
+
LEFT JOIN steps st ON s.id = st.session_id
|
|
110
|
+
LEFT JOIN file_impacts fi ON s.id = fi.session_id
|
|
111
|
+
GROUP BY s.id;
|
|
112
|
+
|
|
113
|
+
CREATE VIEW IF NOT EXISTS v_file_hotspots AS
|
|
114
|
+
SELECT
|
|
115
|
+
fi.file_path,
|
|
116
|
+
s.project_name,
|
|
117
|
+
COUNT(*) as total_touches,
|
|
118
|
+
SUM(fi.lines_added) as total_lines_added,
|
|
119
|
+
SUM(fi.lines_removed) as total_lines_removed,
|
|
120
|
+
COUNT(DISTINCT fi.session_id) as sessions_involved
|
|
121
|
+
FROM file_impacts fi
|
|
122
|
+
JOIN sessions s ON fi.session_id = s.id
|
|
123
|
+
WHERE fi.action IN ('create', 'edit', 'delete')
|
|
124
|
+
GROUP BY fi.file_path, s.project_name
|
|
125
|
+
ORDER BY total_touches DESC;
|
|
126
|
+
|
|
127
|
+
CREATE VIEW IF NOT EXISTS v_daily_costs AS
|
|
128
|
+
SELECT
|
|
129
|
+
DATE(started_at) as day,
|
|
130
|
+
COUNT(*) as sessions,
|
|
131
|
+
SUM(total_tokens_in + total_tokens_out) as total_tokens,
|
|
132
|
+
SUM(total_cost_usd) as total_cost,
|
|
133
|
+
AVG(duration_seconds) as avg_session_duration
|
|
134
|
+
FROM sessions
|
|
135
|
+
GROUP BY DATE(started_at)
|
|
136
|
+
ORDER BY day DESC;
|
|
137
|
+
`;
|
|
138
|
+
const INITIAL_VERSION = 1;
|
|
139
|
+
export function initSchema(db) {
|
|
140
|
+
db.exec(SCHEMA_SQL);
|
|
141
|
+
const hasVersion = db
|
|
142
|
+
.prepare(`SELECT version FROM _migrations WHERE version = ?`)
|
|
143
|
+
.get(INITIAL_VERSION);
|
|
144
|
+
if (!hasVersion) {
|
|
145
|
+
db.prepare(`INSERT INTO _migrations (version, name) VALUES (?, ?)`).run(INITIAL_VERSION, 'initial_schema');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwIzB,CAAA;AAED,MAAM,eAAe,GAAG,CAAC,CAAA;AAEzB,MAAM,UAAU,UAAU,CAAC,EAAqB;IAC9C,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAEnB,MAAM,UAAU,GAAG,EAAE;SAClB,OAAO,CACN,mDAAmD,CACpD;SACA,GAAG,CAAC,eAAe,CAAC,CAAA;IAEvB,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,EAAE,CAAC,OAAO,CACR,uDAAuD,CACxD,CAAC,GAAG,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAA;IAC1C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/db/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAsC,MAAM,aAAa,CAAA;AAGrF,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,IAAI,CAuEN"}
|
package/dist/db/sync.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { insertSession, insertStep, insertFileImpact, upsertProject, updateSessionHash } from './queries.js';
|
|
3
|
+
export function indexSession(db, entry, logPath, hash) {
|
|
4
|
+
const sessionId = randomUUID();
|
|
5
|
+
const session = {
|
|
6
|
+
id: sessionId,
|
|
7
|
+
...entry.session,
|
|
8
|
+
};
|
|
9
|
+
const steps = entry.steps.map((s, i) => ({
|
|
10
|
+
id: randomUUID(),
|
|
11
|
+
sessionId,
|
|
12
|
+
...s,
|
|
13
|
+
}));
|
|
14
|
+
const fileImpacts = entry.fileImpacts.map((fi) => {
|
|
15
|
+
// fi.stepId from the parser is a temporary id like "step-N" where N is the index
|
|
16
|
+
const stepIndex = parseInt(fi.stepId.replace('step-', ''), 10);
|
|
17
|
+
const matchingStep = !isNaN(stepIndex) ? steps[stepIndex] : undefined;
|
|
18
|
+
return {
|
|
19
|
+
...fi,
|
|
20
|
+
id: 0, // auto-increment
|
|
21
|
+
sessionId,
|
|
22
|
+
stepId: matchingStep?.id ?? steps[0]?.id ?? sessionId,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
const txn = db.transaction(() => {
|
|
26
|
+
insertSession(db, session);
|
|
27
|
+
for (const step of steps) {
|
|
28
|
+
insertStep(db, step);
|
|
29
|
+
}
|
|
30
|
+
for (const impact of fileImpacts) {
|
|
31
|
+
insertFileImpact(db, impact);
|
|
32
|
+
}
|
|
33
|
+
updateSessionHash(db, logPath, hash);
|
|
34
|
+
// Upsert project stats
|
|
35
|
+
if (session.projectPath) {
|
|
36
|
+
const projectName = session.projectName ?? session.projectPath.split('/').pop() ?? 'unknown';
|
|
37
|
+
const stats = db.prepare(`
|
|
38
|
+
SELECT
|
|
39
|
+
COUNT(*) as total_sessions,
|
|
40
|
+
COALESCE(SUM(total_tokens_in + total_tokens_out), 0) as total_tokens,
|
|
41
|
+
COALESCE(SUM(total_cost_usd), 0) as total_cost,
|
|
42
|
+
MIN(started_at) as first_session_at,
|
|
43
|
+
MAX(started_at) as last_session_at
|
|
44
|
+
FROM sessions
|
|
45
|
+
WHERE project_path = ?
|
|
46
|
+
`).get(session.projectPath);
|
|
47
|
+
const project = {
|
|
48
|
+
path: session.projectPath,
|
|
49
|
+
name: projectName,
|
|
50
|
+
totalSessions: stats['total_sessions'] ?? 0,
|
|
51
|
+
totalTokens: stats['total_tokens'] ?? 0,
|
|
52
|
+
totalCostUsd: stats['total_cost'] ?? 0,
|
|
53
|
+
firstSessionAt: stats['first_session_at'] ? new Date(stats['first_session_at']) : null,
|
|
54
|
+
lastSessionAt: stats['last_session_at'] ? new Date(stats['last_session_at']) : null,
|
|
55
|
+
claudeMdPath: null,
|
|
56
|
+
updatedAt: new Date(),
|
|
57
|
+
};
|
|
58
|
+
upsertProject(db, project);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
txn();
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/db/sync.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,+BAA+B,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,+BAA+B,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-impact.d.ts","sourceRoot":"","sources":["../../src/parser/file-impact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAc,MAAM,aAAa,CAAA;AAE/D,KAAK,iBAAiB,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,WAAW,CAAC,CAAA;AA4C7D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,iBAAiB,EAAE,CAmFrE"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
function countLines(text) {
|
|
2
|
+
if (!text)
|
|
3
|
+
return 0;
|
|
4
|
+
return text.split('\n').length;
|
|
5
|
+
}
|
|
6
|
+
function extractPathFromBashCommand(command) {
|
|
7
|
+
const paths = [];
|
|
8
|
+
// Common patterns: cat, touch, rm, mv, cp, mkdir, echo > file
|
|
9
|
+
const redirectMatch = command.match(/>\s*(\S+)/g);
|
|
10
|
+
if (redirectMatch) {
|
|
11
|
+
for (const m of redirectMatch) {
|
|
12
|
+
const path = m.replace(/^>+\s*/, '').trim();
|
|
13
|
+
if (path && !path.startsWith('-'))
|
|
14
|
+
paths.push(path);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return paths;
|
|
18
|
+
}
|
|
19
|
+
export function extractFileImpacts(steps) {
|
|
20
|
+
const impacts = [];
|
|
21
|
+
for (const step of steps) {
|
|
22
|
+
if (step.type !== 'tool_call' || !step.toolName)
|
|
23
|
+
continue;
|
|
24
|
+
const toolName = step.toolName;
|
|
25
|
+
let input = {};
|
|
26
|
+
if (step.toolInput) {
|
|
27
|
+
try {
|
|
28
|
+
input = JSON.parse(step.toolInput);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const now = step.createdAt;
|
|
35
|
+
if (toolName === 'Edit') {
|
|
36
|
+
const inp = input;
|
|
37
|
+
const filePath = inp.file_path ?? inp.filePath;
|
|
38
|
+
if (!filePath)
|
|
39
|
+
continue;
|
|
40
|
+
const oldLines = countLines(inp.old_string);
|
|
41
|
+
const newLines = countLines(inp.new_string);
|
|
42
|
+
impacts.push({
|
|
43
|
+
stepId: step.id,
|
|
44
|
+
filePath,
|
|
45
|
+
action: 'edit',
|
|
46
|
+
linesAdded: newLines,
|
|
47
|
+
linesRemoved: oldLines,
|
|
48
|
+
diffContent: null,
|
|
49
|
+
createdAt: now,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else if (toolName === 'Write') {
|
|
53
|
+
const inp = input;
|
|
54
|
+
const filePath = inp.file_path ?? inp.filePath;
|
|
55
|
+
if (!filePath)
|
|
56
|
+
continue;
|
|
57
|
+
impacts.push({
|
|
58
|
+
stepId: step.id,
|
|
59
|
+
filePath,
|
|
60
|
+
action: 'create',
|
|
61
|
+
linesAdded: countLines(inp.content),
|
|
62
|
+
linesRemoved: 0,
|
|
63
|
+
diffContent: null,
|
|
64
|
+
createdAt: now,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else if (toolName === 'Read') {
|
|
68
|
+
const inp = input;
|
|
69
|
+
const filePath = inp.file_path ?? inp.filePath;
|
|
70
|
+
if (!filePath)
|
|
71
|
+
continue;
|
|
72
|
+
impacts.push({
|
|
73
|
+
stepId: step.id,
|
|
74
|
+
filePath,
|
|
75
|
+
action: 'read',
|
|
76
|
+
linesAdded: 0,
|
|
77
|
+
linesRemoved: 0,
|
|
78
|
+
diffContent: null,
|
|
79
|
+
createdAt: now,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
else if (toolName === 'Bash') {
|
|
83
|
+
const command = input['command'];
|
|
84
|
+
if (!command)
|
|
85
|
+
continue;
|
|
86
|
+
const paths = extractPathFromBashCommand(command);
|
|
87
|
+
for (const filePath of paths) {
|
|
88
|
+
impacts.push({
|
|
89
|
+
stepId: step.id,
|
|
90
|
+
filePath,
|
|
91
|
+
action: 'edit',
|
|
92
|
+
linesAdded: 0,
|
|
93
|
+
linesRemoved: 0,
|
|
94
|
+
diffContent: null,
|
|
95
|
+
createdAt: now,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return impacts;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=file-impact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-impact.js","sourceRoot":"","sources":["../../src/parser/file-impact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { scanClaudeDirectory, findSessionFiles, loadSessionMeta, computeFileHash } from './log-scanner.js';
|
|
2
|
+
export type { SessionFileInfo, SessionMeta } from './log-scanner.js';
|
|
3
|
+
export { parseSession } from './session-parser.js';
|
|
4
|
+
export { parseStep, extractModel, extractUsage } from './step-parser.js';
|
|
5
|
+
export { extractFileImpacts } from './file-impact.js';
|
|
6
|
+
export { estimateTokens, estimateCost } from './token-estimator.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC1G,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { scanClaudeDirectory, findSessionFiles, loadSessionMeta, computeFileHash } from './log-scanner.js';
|
|
2
|
+
export { parseSession } from './session-parser.js';
|
|
3
|
+
export { parseStep, extractModel, extractUsage } from './step-parser.js';
|
|
4
|
+
export { extractFileImpacts } from './file-impact.js';
|
|
5
|
+
export { estimateTokens, estimateCost } from './token-estimator.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAE1G,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ScanOptions, ScanResult } from '../types.js';
|
|
2
|
+
interface SessionFileInfo {
|
|
3
|
+
filePath: string;
|
|
4
|
+
hash: string;
|
|
5
|
+
projectSlug: string;
|
|
6
|
+
sessionId: string;
|
|
7
|
+
}
|
|
8
|
+
interface SessionMeta {
|
|
9
|
+
session_id: string;
|
|
10
|
+
project_path: string;
|
|
11
|
+
start_time: string;
|
|
12
|
+
duration_minutes: number;
|
|
13
|
+
input_tokens: number;
|
|
14
|
+
output_tokens: number;
|
|
15
|
+
first_prompt: string;
|
|
16
|
+
tool_counts: Record<string, number>;
|
|
17
|
+
}
|
|
18
|
+
declare function computeFileHash(filePath: string): Promise<string>;
|
|
19
|
+
declare function findSessionFiles(projectsDir: string): Promise<SessionFileInfo[]>;
|
|
20
|
+
declare function loadSessionMeta(claudePath: string, sessionId: string): Promise<SessionMeta | null>;
|
|
21
|
+
export declare function scanClaudeDirectory(options?: ScanOptions): Promise<ScanResult>;
|
|
22
|
+
export { findSessionFiles, loadSessionMeta, computeFileHash };
|
|
23
|
+
export type { SessionFileInfo, SessionMeta };
|
|
24
|
+
//# sourceMappingURL=log-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-scanner.d.ts","sourceRoot":"","sources":["../../src/parser/log-scanner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;AAKrE,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,WAAW;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAA;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACpC;AAED,iBAAe,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQhE;AAED,iBAAe,gBAAgB,CAC7B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,EAAE,CAAC,CA4C5B;AAED,iBAAe,eAAe,CAC5B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAQ7B;AAED,wBAAsB,mBAAmB,CACvC,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CAsDrB;AAED,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,CAAA;AAC7D,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,CAAA"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { readdir, stat, readFile } from 'node:fs/promises';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { createReadStream } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { homedir } from 'node:os';
|
|
6
|
+
import { parseSession } from './session-parser.js';
|
|
7
|
+
import { estimateCost } from './token-estimator.js';
|
|
8
|
+
import { DEFAULT_PRICING } from '../types.js';
|
|
9
|
+
async function computeFileHash(filePath) {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
const hash = createHash('sha256');
|
|
12
|
+
const stream = createReadStream(filePath);
|
|
13
|
+
stream.on('data', (chunk) => hash.update(chunk));
|
|
14
|
+
stream.on('end', () => resolve(hash.digest('hex')));
|
|
15
|
+
stream.on('error', reject);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
async function findSessionFiles(projectsDir) {
|
|
19
|
+
const results = [];
|
|
20
|
+
let projectDirs;
|
|
21
|
+
try {
|
|
22
|
+
projectDirs = await readdir(projectsDir);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return results;
|
|
26
|
+
}
|
|
27
|
+
for (const projectSlug of projectDirs) {
|
|
28
|
+
const projectPath = join(projectsDir, projectSlug);
|
|
29
|
+
let projectStat;
|
|
30
|
+
try {
|
|
31
|
+
projectStat = await stat(projectPath);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (!projectStat.isDirectory())
|
|
37
|
+
continue;
|
|
38
|
+
let entries;
|
|
39
|
+
try {
|
|
40
|
+
entries = await readdir(projectPath);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
if (!entry.endsWith('.jsonl'))
|
|
47
|
+
continue;
|
|
48
|
+
// Session ID is the filename without .jsonl
|
|
49
|
+
const sessionId = entry.slice(0, -6);
|
|
50
|
+
// Validate it looks like a UUID
|
|
51
|
+
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(sessionId)) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const filePath = join(projectPath, entry);
|
|
55
|
+
const hash = await computeFileHash(filePath);
|
|
56
|
+
results.push({ filePath, hash, projectSlug, sessionId });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return results;
|
|
60
|
+
}
|
|
61
|
+
async function loadSessionMeta(claudePath, sessionId) {
|
|
62
|
+
const metaPath = join(claudePath, 'usage-data', 'session-meta', `${sessionId}.json`);
|
|
63
|
+
try {
|
|
64
|
+
const content = await readFile(metaPath, 'utf-8');
|
|
65
|
+
return JSON.parse(content);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export async function scanClaudeDirectory(options = {}) {
|
|
72
|
+
const claudePath = options.claudePath ?? join(homedir(), '.claude');
|
|
73
|
+
const projectsDir = join(claudePath, 'projects');
|
|
74
|
+
const errors = [];
|
|
75
|
+
let sessionsFound = 0;
|
|
76
|
+
let newSessions = 0;
|
|
77
|
+
let skippedSessions = 0;
|
|
78
|
+
const sessionFiles = await findSessionFiles(projectsDir);
|
|
79
|
+
sessionsFound = sessionFiles.length;
|
|
80
|
+
const total = sessionFiles.length;
|
|
81
|
+
for (let i = 0; i < sessionFiles.length; i++) {
|
|
82
|
+
const file = sessionFiles[i];
|
|
83
|
+
options.onProgress?.(i + 1, total);
|
|
84
|
+
try {
|
|
85
|
+
// Try fast path first
|
|
86
|
+
const meta = await loadSessionMeta(claudePath, file.sessionId);
|
|
87
|
+
if (meta && !options.forceRescan) {
|
|
88
|
+
// Session meta exists — we could use pre-aggregated data
|
|
89
|
+
// For now we still parse the full JSONL for complete step data
|
|
90
|
+
// but this is where incremental scanning would skip unchanged files
|
|
91
|
+
}
|
|
92
|
+
const parsed = await parseSession(file.filePath);
|
|
93
|
+
// Apply cost estimation
|
|
94
|
+
if (parsed.session.model) {
|
|
95
|
+
const pricing = DEFAULT_PRICING[parsed.session.model];
|
|
96
|
+
parsed.session.totalCostUsd = estimateCost(parsed.session.totalTokensIn, parsed.session.totalTokensOut, pricing);
|
|
97
|
+
}
|
|
98
|
+
newSessions++;
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
errors.push({
|
|
102
|
+
filePath: file.filePath,
|
|
103
|
+
error: err instanceof Error ? err.message : String(err),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
sessionsFound,
|
|
109
|
+
newSessions,
|
|
110
|
+
skippedSessions,
|
|
111
|
+
errors,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export { findSessionFiles, loadSessionMeta, computeFileHash };
|
|
115
|
+
//# sourceMappingURL=log-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-scanner.js","sourceRoot":"","sources":["../../src/parser/log-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-parser.d.ts","sourceRoot":"","sources":["../../src/parser/session-parser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,aAAa,CAAA;AAYlE,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAkI5E"}
|