coolhand-cli 0.3.1 → 0.5.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/README.md +125 -1
- package/dist/api/last-sync.d.ts +16 -0
- package/dist/api/last-sync.d.ts.map +1 -0
- package/dist/api/last-sync.js +73 -0
- package/dist/api/last-sync.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +85 -58
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze-claude-sessions.d.ts +3 -0
- package/dist/commands/analyze-claude-sessions.d.ts.map +1 -0
- package/dist/commands/analyze-claude-sessions.js +169 -0
- package/dist/commands/analyze-claude-sessions.js.map +1 -0
- package/dist/commands/capture-sessions.d.ts +3 -0
- package/dist/commands/capture-sessions.d.ts.map +1 -0
- package/dist/commands/capture-sessions.js +79 -0
- package/dist/commands/capture-sessions.js.map +1 -0
- package/dist/commands/claude.d.ts +14 -0
- package/dist/commands/claude.d.ts.map +1 -0
- package/dist/commands/claude.js +84 -0
- package/dist/commands/claude.js.map +1 -0
- package/dist/commands/wildcard.d.ts +13 -0
- package/dist/commands/wildcard.d.ts.map +1 -0
- package/dist/commands/wildcard.js +72 -0
- package/dist/commands/wildcard.js.map +1 -0
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/log-request.d.ts +15 -0
- package/dist/log-request.d.ts.map +1 -0
- package/dist/log-request.js +51 -0
- package/dist/log-request.js.map +1 -0
- package/dist/sessions/capture-state.d.ts +37 -0
- package/dist/sessions/capture-state.d.ts.map +1 -0
- package/dist/sessions/capture-state.js +129 -0
- package/dist/sessions/capture-state.js.map +1 -0
- package/dist/sessions/claude-scanner.d.ts +57 -0
- package/dist/sessions/claude-scanner.d.ts.map +1 -0
- package/dist/sessions/claude-scanner.js +176 -0
- package/dist/sessions/claude-scanner.js.map +1 -0
- package/dist/types.d.ts +16 -12
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/package.json +11 -4
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { randomBytes } from 'crypto';
|
|
4
|
+
import { configDir } from '../config.js';
|
|
5
|
+
import { CliError } from '../errors.js';
|
|
6
|
+
const STATE_VERSION = 2;
|
|
7
|
+
const STATE_FILENAME = 'capture-state.json';
|
|
8
|
+
const DIR_MODE = 0o700;
|
|
9
|
+
const FILE_MODE = 0o600;
|
|
10
|
+
export function captureStatePath() {
|
|
11
|
+
return path.join(configDir(), STATE_FILENAME);
|
|
12
|
+
}
|
|
13
|
+
function emptyState() {
|
|
14
|
+
return { version: STATE_VERSION, submitted: {} };
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Sentinel stored for sessions migrated from v1 (where only a boolean "submitted?" was tracked).
|
|
18
|
+
* `run()` treats this as "already submitted, turn count unknown" — it records the actual count
|
|
19
|
+
* without re-submitting, so subsequent runs can detect growth correctly.
|
|
20
|
+
*/
|
|
21
|
+
export const V1_MIGRATION_SENTINEL = -1;
|
|
22
|
+
/** Read a turn count defensively (hand-edited files may hold garbage). */
|
|
23
|
+
function toTurnCount(value) {
|
|
24
|
+
// Allow the migration sentinel (-1) through; reject everything else outside [0, ∞).
|
|
25
|
+
if (value === V1_MIGRATION_SENTINEL) {
|
|
26
|
+
return V1_MIGRATION_SENTINEL;
|
|
27
|
+
}
|
|
28
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Normalize the on-disk `submitted` map into the v2 shape, migrating v1 as we go.
|
|
32
|
+
*
|
|
33
|
+
* v1 stored `clientId -> sessionId[]` (a yes/no list). v2 stores
|
|
34
|
+
* `clientId -> { sessionId: { turnsSubmitted } }`. Migrating a v1 entry sets `turnsSubmitted`
|
|
35
|
+
* to `V1_MIGRATION_SENTINEL` (-1). On the first v2 run, `run()` treats the sentinel as unchanged —
|
|
36
|
+
* it records the actual current turn count without re-submitting, so previously-submitted sessions
|
|
37
|
+
* are not duplicated on the server.
|
|
38
|
+
*/
|
|
39
|
+
function normalizeSubmitted(raw) {
|
|
40
|
+
if (!raw || typeof raw !== 'object') {
|
|
41
|
+
return {};
|
|
42
|
+
}
|
|
43
|
+
const out = {};
|
|
44
|
+
for (const [clientId, value] of Object.entries(raw)) {
|
|
45
|
+
const sessions = {};
|
|
46
|
+
if (Array.isArray(value)) {
|
|
47
|
+
// v1: a plain list of session ids. Use the migration sentinel so run() can learn the real
|
|
48
|
+
// turn count on the next scan without re-submitting sessions the server already holds.
|
|
49
|
+
for (const sessionId of value) {
|
|
50
|
+
if (typeof sessionId === 'string') {
|
|
51
|
+
sessions[sessionId] = { turnsSubmitted: V1_MIGRATION_SENTINEL };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (value && typeof value === 'object') {
|
|
56
|
+
// v2: a map of session id → { turnsSubmitted }.
|
|
57
|
+
for (const [sessionId, entry] of Object.entries(value)) {
|
|
58
|
+
const turns = entry?.turnsSubmitted;
|
|
59
|
+
sessions[sessionId] = { turnsSubmitted: toTurnCount(turns) };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
out[clientId] = sessions;
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
export async function loadCaptureState() {
|
|
67
|
+
const filePath = captureStatePath();
|
|
68
|
+
let raw;
|
|
69
|
+
try {
|
|
70
|
+
raw = await fs.readFile(filePath, 'utf8');
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
if (err.code === 'ENOENT') {
|
|
74
|
+
return emptyState();
|
|
75
|
+
}
|
|
76
|
+
throw new CliError('CONFIG_READ_FAILED', `Failed to read ${filePath}: ${err.message}`);
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const parsed = JSON.parse(raw);
|
|
80
|
+
return {
|
|
81
|
+
version: STATE_VERSION,
|
|
82
|
+
lastSyncAt: typeof parsed.lastSyncAt === 'string' ? parsed.lastSyncAt : undefined,
|
|
83
|
+
submitted: normalizeSubmitted(parsed.submitted),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
throw new CliError('CONFIG_READ_FAILED', `Capture state at ${filePath} is not valid JSON: ${err.message}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** Turns already submitted for this session/client, or 0 if it has never been submitted. */
|
|
91
|
+
export function getTurnsSubmitted(state, clientId, sessionId) {
|
|
92
|
+
return state.submitted[clientId]?.[sessionId]?.turnsSubmitted ?? 0;
|
|
93
|
+
}
|
|
94
|
+
/** Record that `turns` turns of this session have now been submitted for this client. */
|
|
95
|
+
export function recordSubmission(state, clientId, sessionId, turns) {
|
|
96
|
+
const sessions = state.submitted[clientId] ?? (state.submitted[clientId] = {});
|
|
97
|
+
sessions[sessionId] = { turnsSubmitted: turns };
|
|
98
|
+
}
|
|
99
|
+
async function ensureDir(dir) {
|
|
100
|
+
await fs.mkdir(dir, { recursive: true, mode: DIR_MODE });
|
|
101
|
+
try {
|
|
102
|
+
await fs.chmod(dir, DIR_MODE);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// POSIX-only — Windows rejects chmod with this mode; ignore.
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export async function saveCaptureState(state) {
|
|
109
|
+
const filePath = captureStatePath();
|
|
110
|
+
const dir = path.dirname(filePath);
|
|
111
|
+
await ensureDir(dir);
|
|
112
|
+
const tmpPath = path.join(dir, `.${path.basename(filePath)}.${randomBytes(6).toString('hex')}.tmp`);
|
|
113
|
+
const data = `${JSON.stringify(state, null, 2)}\n`;
|
|
114
|
+
try {
|
|
115
|
+
await fs.writeFile(tmpPath, data, { mode: FILE_MODE });
|
|
116
|
+
await fs.rename(tmpPath, filePath);
|
|
117
|
+
try {
|
|
118
|
+
await fs.chmod(filePath, FILE_MODE);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// ignore on Windows
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
await fs.rm(tmpPath, { force: true }).catch(() => undefined);
|
|
126
|
+
throw new CliError('CONFIG_WRITE_FAILED', `Failed to write ${filePath}: ${err.message}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=capture-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-state.js","sourceRoot":"","sources":["../../src/sessions/capture-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** One message in the reconstructed conversation. */
|
|
2
|
+
export interface ConversationMessage {
|
|
3
|
+
role: string;
|
|
4
|
+
content: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* An Anthropic-shaped envelope for ONE whole Claude Code session (a conversation). The server's
|
|
8
|
+
* `claude_code` ingestor recognises it by the synthetic `claudecode://session/<sessionId>` url,
|
|
9
|
+
* stores the full back-and-forth (the server already treats a multi-message request as one "chat"
|
|
10
|
+
* log), and deduplicates on the session id. `request_body.messages` is the conversation;
|
|
11
|
+
* `response_body` is the final assistant turn; `response_body.usage` is the session's summed tokens.
|
|
12
|
+
*/
|
|
13
|
+
export interface CaptureEnvelope {
|
|
14
|
+
url: string;
|
|
15
|
+
method: string;
|
|
16
|
+
status_code: number;
|
|
17
|
+
request_body: {
|
|
18
|
+
model?: string;
|
|
19
|
+
messages: ConversationMessage[];
|
|
20
|
+
};
|
|
21
|
+
response_body: {
|
|
22
|
+
id: string;
|
|
23
|
+
type: string;
|
|
24
|
+
role: string;
|
|
25
|
+
model?: string;
|
|
26
|
+
content: unknown;
|
|
27
|
+
usage?: unknown;
|
|
28
|
+
};
|
|
29
|
+
/** Number of assistant turns in this session — compared against state to detect growth. */
|
|
30
|
+
turnCount: number;
|
|
31
|
+
}
|
|
32
|
+
export interface ScanResult {
|
|
33
|
+
envelopes: CaptureEnvelope[];
|
|
34
|
+
sessionCount: number;
|
|
35
|
+
}
|
|
36
|
+
export declare function defaultProjectsDir(): string;
|
|
37
|
+
/**
|
|
38
|
+
* Parse one transcript's raw text (newline-delimited JSON) into a SINGLE session envelope holding
|
|
39
|
+
* the whole conversation — one log per session, not one per turn. Returns `null` when the transcript
|
|
40
|
+
* contains no assistant turns. Pure function (no filesystem) so it is easy to unit test.
|
|
41
|
+
*/
|
|
42
|
+
export declare function parseTranscript(content: string, sessionId: string): CaptureEnvelope | null;
|
|
43
|
+
/**
|
|
44
|
+
* Find every Claude Code transcript under `projectsDir` (default `~/.claude/projects`) and build one
|
|
45
|
+
* conversation envelope per session. A missing directory simply yields zero sessions.
|
|
46
|
+
*
|
|
47
|
+
* When `sinceTime` is given, files whose last-modified time is older than it are skipped entirely
|
|
48
|
+
* (not even read) — they cannot have grown since the last sync. `sessionCount` therefore counts only
|
|
49
|
+
* the files actually examined this run, so it reflects the work done rather than the whole corpus.
|
|
50
|
+
*/
|
|
51
|
+
export declare function scanSessions(options?: {
|
|
52
|
+
projectsDir?: string;
|
|
53
|
+
sinceTime?: Date;
|
|
54
|
+
}): Promise<ScanResult>;
|
|
55
|
+
/** The session id this envelope represents — used as the local dedup key. */
|
|
56
|
+
export declare function sessionIdOf(envelope: CaptureEnvelope): string;
|
|
57
|
+
//# sourceMappingURL=claude-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-scanner.d.ts","sourceRoot":"","sources":["../../src/sessions/claude-scanner.ts"],"names":[],"mappings":"AAIA,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,mBAAmB,EAAE,CAAC;KACjC,CAAC;IACF,aAAa,EAAE;QACb,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,2FAA2F;IAC3F,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAgCD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA6F1F;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,IAAI,CAAA;CAAO,GACvD,OAAO,CAAC,UAAU,CAAC,CAoDrB;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAE7D"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import * as os from 'os';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
export function defaultProjectsDir() {
|
|
5
|
+
return path.join(os.homedir(), '.claude', 'projects');
|
|
6
|
+
}
|
|
7
|
+
/** Pull plain text out of a Claude message `content`, which is either a string or block array. */
|
|
8
|
+
function extractText(content) {
|
|
9
|
+
if (typeof content === 'string') {
|
|
10
|
+
return content;
|
|
11
|
+
}
|
|
12
|
+
if (Array.isArray(content)) {
|
|
13
|
+
return content
|
|
14
|
+
.filter((block) => Boolean(block) &&
|
|
15
|
+
typeof block === 'object' &&
|
|
16
|
+
block.type === 'text' &&
|
|
17
|
+
typeof block.text === 'string')
|
|
18
|
+
.map((block) => block.text)
|
|
19
|
+
.join('\n');
|
|
20
|
+
}
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
function toCount(value) {
|
|
24
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse one transcript's raw text (newline-delimited JSON) into a SINGLE session envelope holding
|
|
28
|
+
* the whole conversation — one log per session, not one per turn. Returns `null` when the transcript
|
|
29
|
+
* contains no assistant turns. Pure function (no filesystem) so it is easy to unit test.
|
|
30
|
+
*/
|
|
31
|
+
export function parseTranscript(content, sessionId) {
|
|
32
|
+
const messages = [];
|
|
33
|
+
const usage = { input_tokens: 0, output_tokens: 0, cache_read_input_tokens: 0 };
|
|
34
|
+
let sawUsage = false;
|
|
35
|
+
let sessionModel;
|
|
36
|
+
let lastAssistant = null;
|
|
37
|
+
let turnCount = 0;
|
|
38
|
+
for (const line of content.split('\n')) {
|
|
39
|
+
const trimmed = line.trim();
|
|
40
|
+
if (!trimmed) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
let event;
|
|
44
|
+
try {
|
|
45
|
+
event = JSON.parse(trimmed);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (!event || typeof event !== 'object') {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const message = event.message;
|
|
54
|
+
if (!message) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (event.type === 'user') {
|
|
58
|
+
// `user` events include tool results (no text) — only keep actual prompt text.
|
|
59
|
+
const text = extractText(message.content);
|
|
60
|
+
if (text) {
|
|
61
|
+
messages.push({ role: 'user', content: text });
|
|
62
|
+
}
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (event.type === 'assistant' && message.role === 'assistant') {
|
|
66
|
+
const requestId = typeof event.requestId === 'string'
|
|
67
|
+
? event.requestId
|
|
68
|
+
: typeof message.id === 'string'
|
|
69
|
+
? message.id
|
|
70
|
+
: undefined;
|
|
71
|
+
messages.push({ role: 'assistant', content: extractText(message.content) });
|
|
72
|
+
turnCount += 1;
|
|
73
|
+
const model = typeof message.model === 'string' ? message.model : undefined;
|
|
74
|
+
if (model) {
|
|
75
|
+
sessionModel = model;
|
|
76
|
+
}
|
|
77
|
+
const turnUsage = message.usage;
|
|
78
|
+
if (turnUsage && typeof turnUsage === 'object') {
|
|
79
|
+
sawUsage = true;
|
|
80
|
+
usage.input_tokens += toCount(turnUsage.input_tokens);
|
|
81
|
+
usage.output_tokens += toCount(turnUsage.output_tokens);
|
|
82
|
+
usage.cache_read_input_tokens += toCount(turnUsage.cache_read_input_tokens);
|
|
83
|
+
}
|
|
84
|
+
lastAssistant = {
|
|
85
|
+
id: requestId ?? sessionId,
|
|
86
|
+
content: Array.isArray(message.content) ? message.content : [],
|
|
87
|
+
model,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// A session with no assistant turns has nothing to log.
|
|
92
|
+
if (!lastAssistant) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
url: `claudecode://session/${sessionId}`,
|
|
97
|
+
method: 'POST',
|
|
98
|
+
status_code: 200,
|
|
99
|
+
request_body: {
|
|
100
|
+
model: sessionModel,
|
|
101
|
+
messages,
|
|
102
|
+
},
|
|
103
|
+
response_body: {
|
|
104
|
+
id: lastAssistant.id,
|
|
105
|
+
type: 'message',
|
|
106
|
+
role: 'assistant',
|
|
107
|
+
model: lastAssistant.model ?? sessionModel,
|
|
108
|
+
content: lastAssistant.content,
|
|
109
|
+
usage: sawUsage ? usage : undefined,
|
|
110
|
+
},
|
|
111
|
+
turnCount,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Find every Claude Code transcript under `projectsDir` (default `~/.claude/projects`) and build one
|
|
116
|
+
* conversation envelope per session. A missing directory simply yields zero sessions.
|
|
117
|
+
*
|
|
118
|
+
* When `sinceTime` is given, files whose last-modified time is older than it are skipped entirely
|
|
119
|
+
* (not even read) — they cannot have grown since the last sync. `sessionCount` therefore counts only
|
|
120
|
+
* the files actually examined this run, so it reflects the work done rather than the whole corpus.
|
|
121
|
+
*/
|
|
122
|
+
export async function scanSessions(options = {}) {
|
|
123
|
+
const dir = options.projectsDir ?? defaultProjectsDir();
|
|
124
|
+
const sinceMs = options.sinceTime?.getTime();
|
|
125
|
+
let names;
|
|
126
|
+
try {
|
|
127
|
+
names = await fs.readdir(dir, { recursive: true });
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
if (err.code === 'ENOENT') {
|
|
131
|
+
return { envelopes: [], sessionCount: 0 };
|
|
132
|
+
}
|
|
133
|
+
throw err;
|
|
134
|
+
}
|
|
135
|
+
const files = names.filter((name) => name.endsWith('.jsonl'));
|
|
136
|
+
const envelopes = [];
|
|
137
|
+
let sessionCount = 0;
|
|
138
|
+
for (const relativePath of files) {
|
|
139
|
+
const fullPath = path.join(dir, relativePath);
|
|
140
|
+
if (sinceMs !== undefined) {
|
|
141
|
+
let stat;
|
|
142
|
+
try {
|
|
143
|
+
stat = await fs.stat(fullPath);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Unreadable transcript — skip it rather than failing the whole scan.
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
// Skip files unchanged since the cutoff. Use `>=` so a file touched exactly at the cutoff
|
|
150
|
+
// is still examined.
|
|
151
|
+
if (stat.mtimeMs < sinceMs) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
let content;
|
|
156
|
+
try {
|
|
157
|
+
content = await fs.readFile(fullPath, 'utf8');
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Unreadable transcript — skip it rather than failing the whole scan.
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
sessionCount += 1;
|
|
164
|
+
const sessionId = path.basename(relativePath, '.jsonl');
|
|
165
|
+
const envelope = parseTranscript(content, sessionId);
|
|
166
|
+
if (envelope) {
|
|
167
|
+
envelopes.push(envelope);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return { envelopes, sessionCount };
|
|
171
|
+
}
|
|
172
|
+
/** The session id this envelope represents — used as the local dedup key. */
|
|
173
|
+
export function sessionIdOf(envelope) {
|
|
174
|
+
return envelope.url.replace(/^claudecode:\/\/session\//, '');
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=claude-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-scanner.js","sourceRoot":"","sources":["../../src/sessions/claude-scanner.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -71,31 +71,35 @@ export interface GetOptimizationOptions {
|
|
|
71
71
|
json?: boolean;
|
|
72
72
|
clientId?: string;
|
|
73
73
|
}
|
|
74
|
-
export interface AddOptimizationCommentOptions {
|
|
75
|
-
id: string;
|
|
76
|
-
comment: string;
|
|
77
|
-
json?: boolean;
|
|
78
|
-
clientId?: string;
|
|
79
|
-
}
|
|
80
74
|
export interface CloseOptimizationOptions {
|
|
81
75
|
id: string;
|
|
82
76
|
reason: string;
|
|
83
77
|
json?: boolean;
|
|
84
78
|
clientId?: string;
|
|
85
79
|
}
|
|
86
|
-
export interface
|
|
80
|
+
export interface UpdateOptimizationOptions {
|
|
81
|
+
id: string;
|
|
87
82
|
title?: string;
|
|
88
83
|
analysis?: string;
|
|
89
84
|
plan?: string;
|
|
90
85
|
json?: boolean;
|
|
91
86
|
clientId?: string;
|
|
92
87
|
}
|
|
93
|
-
export interface
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
analysis?: string;
|
|
97
|
-
plan?: string;
|
|
88
|
+
export interface AnalyzeClaudeSessionsOptions {
|
|
89
|
+
dryRun?: boolean;
|
|
90
|
+
clientId?: string;
|
|
98
91
|
json?: boolean;
|
|
92
|
+
}
|
|
93
|
+
export interface ComplaintBoxOptions {
|
|
94
|
+
complaint: string;
|
|
95
|
+
agentName: string;
|
|
96
|
+
thinking?: string;
|
|
97
|
+
logId?: number;
|
|
98
|
+
json?: boolean;
|
|
99
|
+
clientId?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface ClaudeOptions {
|
|
102
|
+
args: string[];
|
|
99
103
|
clientId?: string;
|
|
100
104
|
}
|
|
101
105
|
export declare const DEFAULT_BASE_URL = "https://coolhandlabs.com";
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,CAAC;IACX,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAyHA,MAAM,CAAC,MAAM,gBAAgB,GAAG,0BAA0B,CAAC;AAC3D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* Auto-generated from package.json — do not edit manually.
|
|
3
3
|
* Run `npm run sync-version` or `npm run build` to regenerate.
|
|
4
4
|
*/
|
|
5
|
-
export declare const PACKAGE_VERSION = "0.
|
|
5
|
+
export declare const PACKAGE_VERSION = "0.5.0";
|
|
6
6
|
export declare const PACKAGE_NAME = "coolhand-cli";
|
|
7
7
|
/**
|
|
8
8
|
* Full package identifier
|
|
9
9
|
*/
|
|
10
|
-
export declare const PACKAGE_IDENTIFIER = "coolhand-cli-0.
|
|
10
|
+
export declare const PACKAGE_IDENTIFIER = "coolhand-cli-0.5.0";
|
|
11
11
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Auto-generated from package.json — do not edit manually.
|
|
3
3
|
* Run `npm run sync-version` or `npm run build` to regenerate.
|
|
4
4
|
*/
|
|
5
|
-
export const PACKAGE_VERSION = '0.
|
|
5
|
+
export const PACKAGE_VERSION = '0.5.0';
|
|
6
6
|
export const PACKAGE_NAME = 'coolhand-cli';
|
|
7
7
|
/**
|
|
8
8
|
* Full package identifier
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coolhand-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "CLI for authenticating with Coolhand and retrieving API tokens from a local dev environment",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -58,7 +58,15 @@
|
|
|
58
58
|
"clean": "rm -rf dist coverage",
|
|
59
59
|
"smoke": "node dist/bin.js --version"
|
|
60
60
|
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"coolhand-node": "^0.8.0",
|
|
63
|
+
"coolhand-proxy": "^0.0.1"
|
|
64
|
+
},
|
|
65
|
+
"overrides": {
|
|
66
|
+
"js-yaml": "^4.2.0"
|
|
67
|
+
},
|
|
61
68
|
"devDependencies": {
|
|
69
|
+
"@eslint/js": "^9.36.0",
|
|
62
70
|
"@types/jest": "^30.0.0",
|
|
63
71
|
"@types/node": "^20.0.0",
|
|
64
72
|
"@typescript-eslint/eslint-plugin": "^8.45.0",
|
|
@@ -67,9 +75,8 @@
|
|
|
67
75
|
"eslint-plugin-jest": "^29.0.1",
|
|
68
76
|
"globals": "^16.4.0",
|
|
69
77
|
"jest": "^30.2.0",
|
|
70
|
-
"ts-jest": "^29.4.
|
|
78
|
+
"ts-jest": "^29.4.11",
|
|
71
79
|
"ts-node": "^10.9.0",
|
|
72
|
-
"typescript": "^5.0.0"
|
|
73
|
-
"@eslint/js": "^9.36.0"
|
|
80
|
+
"typescript": "^5.0.0"
|
|
74
81
|
}
|
|
75
82
|
}
|