hillclimb 0.5.5 → 0.6.2
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 +79 -207
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -9,22 +9,6 @@ import * as p6 from "@clack/prompts";
|
|
|
9
9
|
import path7 from "path";
|
|
10
10
|
import * as p3 from "@clack/prompts";
|
|
11
11
|
|
|
12
|
-
// src/color.ts
|
|
13
|
-
var IS_TTY = Boolean(process.stdout.isTTY);
|
|
14
|
-
var NO_COLOR = process.env.FORCE_COLOR !== void 0 ? false : process.env.NO_COLOR !== void 0 || process.env.TERM === "dumb" || !IS_TTY;
|
|
15
|
-
function wrap(open, close) {
|
|
16
|
-
if (NO_COLOR) return (s) => s;
|
|
17
|
-
const o = `\x1B[${open}m`;
|
|
18
|
-
const c = `\x1B[${close}m`;
|
|
19
|
-
return (s) => `${o}${s}${c}`;
|
|
20
|
-
}
|
|
21
|
-
var bold = wrap(1, 22);
|
|
22
|
-
var dim = wrap(2, 22);
|
|
23
|
-
var red = wrap(31, 39);
|
|
24
|
-
var green = wrap(32, 39);
|
|
25
|
-
var yellow = wrap(33, 39);
|
|
26
|
-
var cyan = wrap(36, 39);
|
|
27
|
-
|
|
28
12
|
// src/config.ts
|
|
29
13
|
import fs from "fs";
|
|
30
14
|
import os from "os";
|
|
@@ -369,18 +353,18 @@ var PlatformClient = class {
|
|
|
369
353
|
let code;
|
|
370
354
|
let message = `${method} ${relative} failed: HTTP ${res.status}`;
|
|
371
355
|
try {
|
|
372
|
-
const
|
|
373
|
-
if (
|
|
356
|
+
const text2 = await res.text();
|
|
357
|
+
if (text2) {
|
|
374
358
|
try {
|
|
375
|
-
const parsed = JSON.parse(
|
|
359
|
+
const parsed = JSON.parse(text2);
|
|
376
360
|
if (parsed.error?.code) code = parsed.error.code;
|
|
377
361
|
if (parsed.error?.message) {
|
|
378
362
|
message = `${method} ${relative} failed: ${parsed.error.message}`;
|
|
379
363
|
} else {
|
|
380
|
-
message = `${method} ${relative} failed: ${
|
|
364
|
+
message = `${method} ${relative} failed: ${text2}`;
|
|
381
365
|
}
|
|
382
366
|
} catch {
|
|
383
|
-
message = `${method} ${relative} failed: ${
|
|
367
|
+
message = `${method} ${relative} failed: ${text2}`;
|
|
384
368
|
}
|
|
385
369
|
}
|
|
386
370
|
} catch {
|
|
@@ -397,17 +381,6 @@ var PlatformClient = class {
|
|
|
397
381
|
}
|
|
398
382
|
return void 0;
|
|
399
383
|
}
|
|
400
|
-
async signInWithEmail(email, password2) {
|
|
401
|
-
await this.request("POST", "/api/auth/sign-in/email", {
|
|
402
|
-
email,
|
|
403
|
-
password: password2
|
|
404
|
-
});
|
|
405
|
-
if (!this.sessionCookie) {
|
|
406
|
-
throw new PlatformError(
|
|
407
|
-
"Sign-in succeeded but no session cookie was returned"
|
|
408
|
-
);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
384
|
async getBootstrap() {
|
|
412
385
|
const data = await this.request("GET", "/api/v1/app/bootstrap");
|
|
413
386
|
if (!data?.session?.user || !data.session.session) return null;
|
|
@@ -1483,22 +1456,6 @@ var CLAUDE_DEF = TOOLS[0];
|
|
|
1483
1456
|
|
|
1484
1457
|
// src/commands/_shared.ts
|
|
1485
1458
|
import * as p from "@clack/prompts";
|
|
1486
|
-
async function requireText(label, opts = {}) {
|
|
1487
|
-
const result = opts.password ? await p.password({
|
|
1488
|
-
message: label,
|
|
1489
|
-
validate: (v) => v && v.length > 0 ? void 0 : "Required"
|
|
1490
|
-
}) : await p.text({
|
|
1491
|
-
message: label,
|
|
1492
|
-
placeholder: opts.placeholder,
|
|
1493
|
-
initialValue: opts.initialValue,
|
|
1494
|
-
validate: (v) => v && v.trim().length > 0 ? void 0 : "Required"
|
|
1495
|
-
});
|
|
1496
|
-
if (p.isCancel(result)) {
|
|
1497
|
-
p.cancel("Cancelled.");
|
|
1498
|
-
process.exit(0);
|
|
1499
|
-
}
|
|
1500
|
-
return typeof result === "string" ? result.trim() : "";
|
|
1501
|
-
}
|
|
1502
1459
|
async function withSpinner(startLabel, onSuccess, onFailureLabel, fn) {
|
|
1503
1460
|
const spinner5 = p.spinner();
|
|
1504
1461
|
spinner5.start(startLabel);
|
|
@@ -1517,6 +1474,24 @@ async function withSpinner(startLabel, onSuccess, onFailureLabel, fn) {
|
|
|
1517
1474
|
// src/commands/web-auth.ts
|
|
1518
1475
|
import { spawn } from "child_process";
|
|
1519
1476
|
import * as p2 from "@clack/prompts";
|
|
1477
|
+
|
|
1478
|
+
// src/color.ts
|
|
1479
|
+
var IS_TTY = Boolean(process.stdout.isTTY);
|
|
1480
|
+
var NO_COLOR = process.env.FORCE_COLOR !== void 0 ? false : process.env.NO_COLOR !== void 0 || process.env.TERM === "dumb" || !IS_TTY;
|
|
1481
|
+
function wrap(open, close) {
|
|
1482
|
+
if (NO_COLOR) return (s) => s;
|
|
1483
|
+
const o = `\x1B[${open}m`;
|
|
1484
|
+
const c = `\x1B[${close}m`;
|
|
1485
|
+
return (s) => `${o}${s}${c}`;
|
|
1486
|
+
}
|
|
1487
|
+
var bold = wrap(1, 22);
|
|
1488
|
+
var dim = wrap(2, 22);
|
|
1489
|
+
var red = wrap(31, 39);
|
|
1490
|
+
var green = wrap(32, 39);
|
|
1491
|
+
var yellow = wrap(33, 39);
|
|
1492
|
+
var cyan = wrap(36, 39);
|
|
1493
|
+
|
|
1494
|
+
// src/commands/web-auth.ts
|
|
1520
1495
|
function sleep(ms) {
|
|
1521
1496
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1522
1497
|
}
|
|
@@ -1531,10 +1506,6 @@ function openBrowser(url) {
|
|
|
1531
1506
|
}
|
|
1532
1507
|
}
|
|
1533
1508
|
async function webAuth(apiBaseUrl) {
|
|
1534
|
-
if (!IS_TTY) {
|
|
1535
|
-
appendLog("info", "web-auth: skipped (not a TTY)");
|
|
1536
|
-
return null;
|
|
1537
|
-
}
|
|
1538
1509
|
appendLog("info", `web-auth: started (apiBaseUrl=${apiBaseUrl})`);
|
|
1539
1510
|
const client = new PlatformClient(apiBaseUrl);
|
|
1540
1511
|
const codeResponse = await withSpinner(
|
|
@@ -1548,9 +1519,16 @@ async function webAuth(apiBaseUrl) {
|
|
|
1548
1519
|
`web-auth: code prepared (expiresIn=${codeResponse.expiresIn}s, pollInterval=${codeResponse.interval}s)`
|
|
1549
1520
|
);
|
|
1550
1521
|
const url = codeResponse.verificationUrl;
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1522
|
+
if (IS_TTY) {
|
|
1523
|
+
openBrowser(url);
|
|
1524
|
+
p2.log.info(`Opening browser to: ${cyan(url)}`);
|
|
1525
|
+
p2.log.info(dim("If the browser did not open, copy the URL above."));
|
|
1526
|
+
} else {
|
|
1527
|
+
p2.log.info(
|
|
1528
|
+
"To sign in, open this URL in a browser and approve the request:"
|
|
1529
|
+
);
|
|
1530
|
+
p2.log.info(cyan(url));
|
|
1531
|
+
}
|
|
1554
1532
|
const deadline = Date.now() + codeResponse.expiresIn * 1e3;
|
|
1555
1533
|
const interval = codeResponse.interval * 1e3;
|
|
1556
1534
|
const spinner5 = p2.spinner();
|
|
@@ -1674,66 +1652,24 @@ async function runInit(args = []) {
|
|
|
1674
1652
|
bootstrap = await tryReuseIdentity(apiBaseUrl, client, saved);
|
|
1675
1653
|
}
|
|
1676
1654
|
if (!bootstrap) {
|
|
1677
|
-
|
|
1678
|
-
if (
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
value: "web",
|
|
1684
|
-
label: "Web authentication (recommended)",
|
|
1685
|
-
hint: "opens browser"
|
|
1686
|
-
},
|
|
1687
|
-
{ value: "email", label: "Email and password" }
|
|
1688
|
-
],
|
|
1689
|
-
initialValue: "web"
|
|
1690
|
-
});
|
|
1691
|
-
if (p3.isCancel(selected)) {
|
|
1692
|
-
p3.cancel("Cancelled.");
|
|
1693
|
-
process.exit(0);
|
|
1694
|
-
}
|
|
1695
|
-
method = selected;
|
|
1655
|
+
const result = await webAuth(apiBaseUrl);
|
|
1656
|
+
if (!result) {
|
|
1657
|
+
appendLog("error", "init: web authentication failed");
|
|
1658
|
+
p3.log.error("Web authentication failed.");
|
|
1659
|
+
p3.outro("Aborted.");
|
|
1660
|
+
process.exit(1);
|
|
1696
1661
|
}
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1662
|
+
client = result.client;
|
|
1663
|
+
bootstrap = await withSpinner(
|
|
1664
|
+
"Loading account...",
|
|
1665
|
+
(b) => `Signed in as ${b.session.email}${b.session.role === "admin" ? " (admin)" : ""}.`,
|
|
1666
|
+
"Could not load account.",
|
|
1667
|
+
async () => {
|
|
1668
|
+
const data = await client.getBootstrap();
|
|
1669
|
+
if (!data) throw new Error("Bootstrap returned no session.");
|
|
1670
|
+
return data;
|
|
1705
1671
|
}
|
|
1706
|
-
|
|
1707
|
-
bootstrap = await withSpinner(
|
|
1708
|
-
"Loading account...",
|
|
1709
|
-
(b) => `Signed in as ${b.session.email}${b.session.role === "admin" ? " (admin)" : ""}.`,
|
|
1710
|
-
"Could not load account.",
|
|
1711
|
-
async () => {
|
|
1712
|
-
const data = await client.getBootstrap();
|
|
1713
|
-
if (!data) throw new Error("Bootstrap returned no session.");
|
|
1714
|
-
return data;
|
|
1715
|
-
}
|
|
1716
|
-
);
|
|
1717
|
-
} else {
|
|
1718
|
-
const email = await requireText("Email");
|
|
1719
|
-
const password2 = await requireText("Password", { password: true });
|
|
1720
|
-
await withSpinner(
|
|
1721
|
-
"Signing in...",
|
|
1722
|
-
() => "Signed in.",
|
|
1723
|
-
"Sign-in failed.",
|
|
1724
|
-
() => client.signInWithEmail(email, password2)
|
|
1725
|
-
);
|
|
1726
|
-
bootstrap = await withSpinner(
|
|
1727
|
-
"Loading account...",
|
|
1728
|
-
(b) => `Signed in as ${b.session.email}${b.session.role === "admin" ? " (admin)" : ""}.`,
|
|
1729
|
-
"Could not load account.",
|
|
1730
|
-
async () => {
|
|
1731
|
-
const data = await client.getBootstrap();
|
|
1732
|
-
if (!data) throw new Error("Bootstrap returned no session.");
|
|
1733
|
-
return data;
|
|
1734
|
-
}
|
|
1735
|
-
);
|
|
1736
|
-
}
|
|
1672
|
+
);
|
|
1737
1673
|
}
|
|
1738
1674
|
let project;
|
|
1739
1675
|
if (projectSlugFlag) {
|
|
@@ -2070,87 +2006,23 @@ async function runLogin(_args = []) {
|
|
|
2070
2006
|
println();
|
|
2071
2007
|
}
|
|
2072
2008
|
}
|
|
2073
|
-
|
|
2074
|
-
if (
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
options: [
|
|
2078
|
-
{
|
|
2079
|
-
value: "web",
|
|
2080
|
-
label: "Web authentication (recommended)",
|
|
2081
|
-
hint: "opens browser"
|
|
2082
|
-
},
|
|
2083
|
-
{ value: "email", label: "Email and password" }
|
|
2084
|
-
],
|
|
2085
|
-
initialValue: "web"
|
|
2086
|
-
});
|
|
2087
|
-
if (p4.isCancel(selected)) {
|
|
2088
|
-
p4.cancel("Cancelled.");
|
|
2089
|
-
process.exit(0);
|
|
2090
|
-
}
|
|
2091
|
-
method = selected;
|
|
2092
|
-
}
|
|
2093
|
-
appendLog("info", `login: auth method selected (${method})`);
|
|
2094
|
-
if (method === "web") {
|
|
2095
|
-
const result = await webAuth(apiBaseUrl);
|
|
2096
|
-
if (!result) {
|
|
2097
|
-
appendLog("error", "login: web authentication failed");
|
|
2098
|
-
p4.log.error("Web authentication failed.");
|
|
2099
|
-
p4.outro("Aborted.");
|
|
2100
|
-
process.exit(1);
|
|
2101
|
-
}
|
|
2102
|
-
await saveIdentity({
|
|
2103
|
-
apiBaseUrl,
|
|
2104
|
-
sessionCookie: result.sessionCookie,
|
|
2105
|
-
email: result.email,
|
|
2106
|
-
userId: result.userId,
|
|
2107
|
-
savedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2108
|
-
});
|
|
2109
|
-
appendLog("info", `login: completed via web auth (email=${result.email})`);
|
|
2110
|
-
println();
|
|
2111
|
-
row(CHECK, "Signed in", cyan(result.email));
|
|
2112
|
-
footer("Run `npx hillclimb` in a repo to wire up auto-upload.");
|
|
2113
|
-
return;
|
|
2114
|
-
}
|
|
2115
|
-
const email = await requireText("Email");
|
|
2116
|
-
const password2 = await requireText("Password", { password: true });
|
|
2117
|
-
const client = new PlatformClient(apiBaseUrl);
|
|
2118
|
-
await withSpinner(
|
|
2119
|
-
"Signing in...",
|
|
2120
|
-
() => "Signed in.",
|
|
2121
|
-
"Sign-in failed.",
|
|
2122
|
-
() => client.signInWithEmail(email, password2)
|
|
2123
|
-
);
|
|
2124
|
-
const bootstrap = await withSpinner(
|
|
2125
|
-
"Loading account...",
|
|
2126
|
-
(b) => `Signed in as ${b.session.email}.`,
|
|
2127
|
-
"Could not load account.",
|
|
2128
|
-
async () => {
|
|
2129
|
-
const data = await client.getBootstrap();
|
|
2130
|
-
if (!data) throw new Error("Bootstrap returned no session.");
|
|
2131
|
-
return data;
|
|
2132
|
-
}
|
|
2133
|
-
);
|
|
2134
|
-
const cookie = client.getSessionCookie();
|
|
2135
|
-
if (!cookie) {
|
|
2136
|
-
appendLog("error", "login: session cookie missing after sign-in");
|
|
2137
|
-
p4.log.error("Session cookie was lost during sign-in.");
|
|
2009
|
+
const result = await webAuth(apiBaseUrl);
|
|
2010
|
+
if (!result) {
|
|
2011
|
+
appendLog("error", "login: web authentication failed");
|
|
2012
|
+
p4.log.error("Web authentication failed.");
|
|
2138
2013
|
p4.outro("Aborted.");
|
|
2139
2014
|
process.exit(1);
|
|
2140
2015
|
}
|
|
2141
2016
|
await saveIdentity({
|
|
2142
2017
|
apiBaseUrl,
|
|
2143
|
-
sessionCookie:
|
|
2144
|
-
email:
|
|
2145
|
-
userId:
|
|
2018
|
+
sessionCookie: result.sessionCookie,
|
|
2019
|
+
email: result.email,
|
|
2020
|
+
userId: result.userId,
|
|
2146
2021
|
savedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2147
2022
|
});
|
|
2148
|
-
appendLog(
|
|
2149
|
-
"info",
|
|
2150
|
-
`login: completed via email/password (email=${bootstrap.session.email})`
|
|
2151
|
-
);
|
|
2023
|
+
appendLog("info", `login: completed via web auth (email=${result.email})`);
|
|
2152
2024
|
println();
|
|
2153
|
-
row(CHECK, "Signed in", cyan(
|
|
2025
|
+
row(CHECK, "Signed in", cyan(result.email));
|
|
2154
2026
|
footer("Run `npx hillclimb` in a repo to wire up auto-upload.");
|
|
2155
2027
|
}
|
|
2156
2028
|
|
|
@@ -11845,9 +11717,9 @@ function extractTextReasoningToolUses(content) {
|
|
|
11845
11717
|
} else if (content !== void 0 && content !== null) {
|
|
11846
11718
|
textParts.push(stringify(content));
|
|
11847
11719
|
}
|
|
11848
|
-
const
|
|
11720
|
+
const text2 = textParts.filter((p7) => p7 && p7.trim()).map((p7) => p7.trim()).join("\n\n");
|
|
11849
11721
|
const reasoning = reasoningParts.filter((p7) => p7 && p7.trim()).map((p7) => p7.trim()).join("\n\n");
|
|
11850
|
-
return [
|
|
11722
|
+
return [text2, reasoning || void 0, toolBlocks];
|
|
11851
11723
|
}
|
|
11852
11724
|
function buildMetrics(usage) {
|
|
11853
11725
|
if (typeof usage !== "object" || usage === null) return void 0;
|
|
@@ -11876,8 +11748,8 @@ function formatToolResult(block, toolUseResult) {
|
|
|
11876
11748
|
if (content.trim()) parts.push(content.trim());
|
|
11877
11749
|
} else if (Array.isArray(content)) {
|
|
11878
11750
|
for (const item of content) {
|
|
11879
|
-
const
|
|
11880
|
-
if (
|
|
11751
|
+
const text2 = stringify(item);
|
|
11752
|
+
if (text2.trim()) parts.push(text2.trim());
|
|
11881
11753
|
}
|
|
11882
11754
|
} else if (content !== void 0 && content !== null && content !== "") {
|
|
11883
11755
|
parts.push(stringify(content));
|
|
@@ -12005,7 +11877,7 @@ function convertClaudeToTrajectory(jsonlContent, sessionId) {
|
|
|
12005
11877
|
const eventType = event.type;
|
|
12006
11878
|
const timestamp = event.timestamp;
|
|
12007
11879
|
if (eventType === "assistant") {
|
|
12008
|
-
const [
|
|
11880
|
+
const [text2, reasoning, toolBlocks] = extractTextReasoningToolUses(
|
|
12009
11881
|
msg.content
|
|
12010
11882
|
);
|
|
12011
11883
|
const msgId = msg.id;
|
|
@@ -12029,12 +11901,12 @@ function convertClaudeToTrajectory(jsonlContent, sessionId) {
|
|
|
12029
11901
|
extra.user_type = event.userType;
|
|
12030
11902
|
extra.is_sidechain = event.isSidechain ?? false;
|
|
12031
11903
|
const modelName = msg.model || defaultModelName;
|
|
12032
|
-
if (
|
|
11904
|
+
if (text2 || reasoning || toolBlocks.length === 0) {
|
|
12033
11905
|
normalizedEvents.push({
|
|
12034
11906
|
kind: "message",
|
|
12035
11907
|
timestamp,
|
|
12036
11908
|
role: msg.role ?? "assistant",
|
|
12037
|
-
text:
|
|
11909
|
+
text: text2 || "",
|
|
12038
11910
|
reasoning: msg.role === "assistant" ? reasoning : void 0,
|
|
12039
11911
|
metrics,
|
|
12040
11912
|
extra: Object.keys(extra).length > 0 ? extra : void 0,
|
|
@@ -12074,13 +11946,13 @@ function convertClaudeToTrajectory(jsonlContent, sessionId) {
|
|
|
12074
11946
|
if (eventType === "user") {
|
|
12075
11947
|
const content = msg.content;
|
|
12076
11948
|
if (typeof content === "string") {
|
|
12077
|
-
const
|
|
12078
|
-
if (
|
|
11949
|
+
const text2 = content.trim();
|
|
11950
|
+
if (text2) {
|
|
12079
11951
|
normalizedEvents.push({
|
|
12080
11952
|
kind: "message",
|
|
12081
11953
|
timestamp,
|
|
12082
11954
|
role: "user",
|
|
12083
|
-
text:
|
|
11955
|
+
text: text2,
|
|
12084
11956
|
extra: { is_sidechain: event.isSidechain ?? false }
|
|
12085
11957
|
});
|
|
12086
11958
|
}
|
|
@@ -12142,13 +12014,13 @@ function convertClaudeToTrajectory(jsonlContent, sessionId) {
|
|
|
12142
12014
|
continue;
|
|
12143
12015
|
}
|
|
12144
12016
|
if (content !== void 0 && content !== null && content !== "") {
|
|
12145
|
-
const
|
|
12146
|
-
if (
|
|
12017
|
+
const text2 = stringify(content).trim();
|
|
12018
|
+
if (text2) {
|
|
12147
12019
|
normalizedEvents.push({
|
|
12148
12020
|
kind: "message",
|
|
12149
12021
|
timestamp,
|
|
12150
12022
|
role: "user",
|
|
12151
|
-
text:
|
|
12023
|
+
text: text2
|
|
12152
12024
|
});
|
|
12153
12025
|
}
|
|
12154
12026
|
}
|
|
@@ -12284,8 +12156,8 @@ function extractMessageText(content) {
|
|
|
12284
12156
|
const parts = [];
|
|
12285
12157
|
for (const block of content) {
|
|
12286
12158
|
if (typeof block === "object" && block !== null) {
|
|
12287
|
-
const
|
|
12288
|
-
if (typeof
|
|
12159
|
+
const text2 = block.text;
|
|
12160
|
+
if (typeof text2 === "string") parts.push(text2);
|
|
12289
12161
|
}
|
|
12290
12162
|
}
|
|
12291
12163
|
return parts.join("");
|
|
@@ -12417,12 +12289,12 @@ function convertCodexToTrajectory(jsonlContent, sessionId) {
|
|
|
12417
12289
|
}
|
|
12418
12290
|
if (payloadType === "message") {
|
|
12419
12291
|
const content = payload.content;
|
|
12420
|
-
const
|
|
12292
|
+
const text2 = Array.isArray(content) ? extractMessageText(content) : "";
|
|
12421
12293
|
normalizedEvents.push({
|
|
12422
12294
|
kind: "message",
|
|
12423
12295
|
timestamp,
|
|
12424
12296
|
role: payload.role ?? "user",
|
|
12425
|
-
text:
|
|
12297
|
+
text: text2,
|
|
12426
12298
|
reasoning: payload.role === "assistant" ? pendingReasoning : void 0
|
|
12427
12299
|
});
|
|
12428
12300
|
pendingReasoning = void 0;
|
|
@@ -12928,7 +12800,7 @@ function convertCursorToTrajectory(jsonlContent, sessionId) {
|
|
|
12928
12800
|
else if (role === "user") source = "user";
|
|
12929
12801
|
else source = "system";
|
|
12930
12802
|
const contentParts = entry.message?.content;
|
|
12931
|
-
let
|
|
12803
|
+
let text2 = "";
|
|
12932
12804
|
if (Array.isArray(contentParts)) {
|
|
12933
12805
|
const textParts = [];
|
|
12934
12806
|
for (const part of contentParts) {
|
|
@@ -12936,13 +12808,13 @@ function convertCursorToTrajectory(jsonlContent, sessionId) {
|
|
|
12936
12808
|
textParts.push(part.text);
|
|
12937
12809
|
}
|
|
12938
12810
|
}
|
|
12939
|
-
|
|
12811
|
+
text2 = textParts.join("\n\n").trim();
|
|
12940
12812
|
}
|
|
12941
|
-
if (!
|
|
12813
|
+
if (!text2) continue;
|
|
12942
12814
|
const step = {
|
|
12943
12815
|
step_id: stepId,
|
|
12944
12816
|
source,
|
|
12945
|
-
message:
|
|
12817
|
+
message: text2
|
|
12946
12818
|
};
|
|
12947
12819
|
steps.push(step);
|
|
12948
12820
|
stepId++;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hillclimb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Extract and export AI coding tool logs grouped by repo",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"node": ">=18"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@clack/prompts": "
|
|
39
|
+
"@clack/prompts": "1.0.1",
|
|
40
40
|
"archiver": "^7.0.1"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|