skill-distill 1.0.0 → 1.0.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/cli.js +100 -66
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +100 -66
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -149,9 +149,8 @@ declare class ClaudeSessionLoader extends SessionLoader {
|
|
|
149
149
|
getDefaultBasePath(): string;
|
|
150
150
|
listSessions(): Promise<SessionInfo[]>;
|
|
151
151
|
getSession(id: string): Promise<Session>;
|
|
152
|
-
private
|
|
152
|
+
private readTranscriptFile;
|
|
153
153
|
private transformSession;
|
|
154
|
-
private transformMessage;
|
|
155
154
|
private extractSummary;
|
|
156
155
|
}
|
|
157
156
|
|
package/dist/index.js
CHANGED
|
@@ -95,94 +95,128 @@ var ClaudeSessionLoader = class extends SessionLoader {
|
|
|
95
95
|
super(options);
|
|
96
96
|
}
|
|
97
97
|
getDefaultBasePath() {
|
|
98
|
-
return join2(homedir2(), ".claude", "
|
|
98
|
+
return join2(homedir2(), ".claude", "transcripts");
|
|
99
99
|
}
|
|
100
100
|
async listSessions() {
|
|
101
101
|
const sessions = [];
|
|
102
102
|
try {
|
|
103
|
-
const
|
|
104
|
-
for (const
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
summary: this.extractSummary(sessionData.messages)
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
} catch {
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
103
|
+
const files = await fs2.readdir(this.basePath);
|
|
104
|
+
for (const file of files) {
|
|
105
|
+
if (!file.endsWith(".jsonl") || !file.startsWith("ses_")) continue;
|
|
106
|
+
const filePath = join2(this.basePath, file);
|
|
107
|
+
const stat = await fs2.stat(filePath);
|
|
108
|
+
const sessionId = file.replace(".jsonl", "");
|
|
109
|
+
const entries = await this.readTranscriptFile(filePath);
|
|
110
|
+
if (entries.length === 0) continue;
|
|
111
|
+
const userMessages = entries.filter((e) => e.type === "user");
|
|
112
|
+
const firstEntry = entries[0];
|
|
113
|
+
const lastEntry = entries[entries.length - 1];
|
|
114
|
+
sessions.push({
|
|
115
|
+
id: sessionId,
|
|
116
|
+
projectPath: "",
|
|
117
|
+
startTime: firstEntry.timestamp,
|
|
118
|
+
endTime: lastEntry.timestamp,
|
|
119
|
+
messageCount: userMessages.length,
|
|
120
|
+
summary: this.extractSummary(entries)
|
|
121
|
+
});
|
|
129
122
|
}
|
|
130
123
|
} catch (error) {
|
|
131
124
|
throw new Error(`Failed to list sessions: ${error}`);
|
|
132
125
|
}
|
|
133
|
-
return sessions
|
|
126
|
+
return sessions.sort(
|
|
127
|
+
(a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime()
|
|
128
|
+
);
|
|
134
129
|
}
|
|
135
130
|
async getSession(id) {
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
131
|
+
const filePath = join2(this.basePath, `${id}.jsonl`);
|
|
132
|
+
try {
|
|
133
|
+
await fs2.access(filePath);
|
|
134
|
+
} catch {
|
|
139
135
|
throw new Error(`Session not found: ${id}`);
|
|
140
136
|
}
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
throw new Error(`Failed to read session: ${id}`);
|
|
137
|
+
const entries = await this.readTranscriptFile(filePath);
|
|
138
|
+
if (entries.length === 0) {
|
|
139
|
+
throw new Error(`Empty session: ${id}`);
|
|
145
140
|
}
|
|
146
|
-
return this.transformSession(
|
|
141
|
+
return this.transformSession(id, entries);
|
|
147
142
|
}
|
|
148
|
-
async
|
|
143
|
+
async readTranscriptFile(path) {
|
|
149
144
|
try {
|
|
150
145
|
const content = await fs2.readFile(path, "utf-8");
|
|
151
|
-
|
|
146
|
+
const lines = content.trim().split("\n").filter(Boolean);
|
|
147
|
+
return lines.map((line) => JSON.parse(line));
|
|
152
148
|
} catch {
|
|
153
|
-
return
|
|
149
|
+
return [];
|
|
154
150
|
}
|
|
155
151
|
}
|
|
156
|
-
transformSession(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
152
|
+
transformSession(id, entries) {
|
|
153
|
+
const messages = [];
|
|
154
|
+
let currentAssistantContent = "";
|
|
155
|
+
let currentToolCalls = [];
|
|
156
|
+
let currentToolResults = [];
|
|
157
|
+
let lastTimestamp = "";
|
|
158
|
+
for (const entry of entries) {
|
|
159
|
+
if (entry.type === "user") {
|
|
160
|
+
if (currentAssistantContent || currentToolCalls?.length) {
|
|
161
|
+
messages.push({
|
|
162
|
+
role: "assistant",
|
|
163
|
+
content: currentAssistantContent,
|
|
164
|
+
timestamp: lastTimestamp,
|
|
165
|
+
toolCalls: currentToolCalls.length > 0 ? currentToolCalls : void 0,
|
|
166
|
+
toolResults: currentToolResults.length > 0 ? currentToolResults : void 0
|
|
167
|
+
});
|
|
168
|
+
currentAssistantContent = "";
|
|
169
|
+
currentToolCalls = [];
|
|
170
|
+
currentToolResults = [];
|
|
171
|
+
}
|
|
172
|
+
messages.push({
|
|
173
|
+
role: "user",
|
|
174
|
+
content: entry.content ?? "",
|
|
175
|
+
timestamp: entry.timestamp
|
|
176
|
+
});
|
|
177
|
+
} else if (entry.type === "assistant") {
|
|
178
|
+
currentAssistantContent += (entry.content ?? "") + "\n";
|
|
179
|
+
lastTimestamp = entry.timestamp;
|
|
180
|
+
} else if (entry.type === "tool_use") {
|
|
181
|
+
currentToolCalls.push({
|
|
182
|
+
name: entry.tool_name ?? "unknown",
|
|
183
|
+
input: entry.tool_input ?? {}
|
|
184
|
+
});
|
|
185
|
+
lastTimestamp = entry.timestamp;
|
|
186
|
+
} else if (entry.type === "tool_result") {
|
|
187
|
+
currentToolResults.push({
|
|
188
|
+
name: entry.tool_name ?? "unknown",
|
|
189
|
+
output: entry.tool_output?.preview ?? "",
|
|
190
|
+
success: true
|
|
191
|
+
});
|
|
192
|
+
lastTimestamp = entry.timestamp;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (currentAssistantContent || currentToolCalls?.length) {
|
|
196
|
+
messages.push({
|
|
197
|
+
role: "assistant",
|
|
198
|
+
content: currentAssistantContent.trim(),
|
|
199
|
+
timestamp: lastTimestamp,
|
|
200
|
+
toolCalls: currentToolCalls.length > 0 ? currentToolCalls : void 0,
|
|
201
|
+
toolResults: currentToolResults.length > 0 ? currentToolResults : void 0
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
const firstEntry = entries[0];
|
|
205
|
+
const lastEntry = entries[entries.length - 1];
|
|
166
206
|
return {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
input: t.input
|
|
173
|
-
})),
|
|
174
|
-
toolResults: msg.toolResultBlocks?.map((t) => ({
|
|
175
|
-
name: t.toolUseId,
|
|
176
|
-
output: t.content,
|
|
177
|
-
success: !t.isError
|
|
178
|
-
}))
|
|
207
|
+
id,
|
|
208
|
+
projectPath: "",
|
|
209
|
+
startTime: firstEntry.timestamp,
|
|
210
|
+
endTime: lastEntry.timestamp,
|
|
211
|
+
messages
|
|
179
212
|
};
|
|
180
213
|
}
|
|
181
|
-
extractSummary(
|
|
182
|
-
const
|
|
183
|
-
if (!
|
|
184
|
-
const content =
|
|
185
|
-
|
|
214
|
+
extractSummary(entries) {
|
|
215
|
+
const firstUserEntry = entries.find((e) => e.type === "user");
|
|
216
|
+
if (!firstUserEntry?.content) return "";
|
|
217
|
+
const content = firstUserEntry.content;
|
|
218
|
+
const firstLine = content.split("\n")[0];
|
|
219
|
+
return firstLine.length > 80 ? firstLine.slice(0, 80) + "..." : firstLine;
|
|
186
220
|
}
|
|
187
221
|
};
|
|
188
222
|
|