trip-optimizer 0.1.0 → 0.1.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/README.md +3 -1
- package/dist/cli.js +33 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# trip-optimizer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
If you love travel like I do, you know the pain: before every trip you're deep in Google, TripAdvisor, 小红书, 携程, reading strangers' tips, comparing restaurants, checking transit schedules. You easily spend days, sometimes weeks, on research. Travel is supposed to be leisure and relaxation, not a second job.
|
|
4
|
+
|
|
5
|
+
**trip-optimizer** autonomously optimizes travel plans using Andrej Kaparthy's autoresearch pattern — an AI-powered CLI that researches, scores, and iteratively improves your itinerary.
|
|
4
6
|
|
|
5
7
|
支持 **English** 和 **中文(简体中文)** -- 在初始化时选择语言,整个体验随之适配:提示语、生成的行程、研究搜索、评分系统全部使用您选择的语言。
|
|
6
8
|
|
package/dist/cli.js
CHANGED
|
@@ -634,22 +634,6 @@ async function initCommand(name) {
|
|
|
634
634
|
${t("init.title")}: ${name}
|
|
635
635
|
`));
|
|
636
636
|
const profile = loadProfile();
|
|
637
|
-
const useVertex = !!(process.env.CLAUDE_CODE_USE_VERTEX === "1" || process.env.GOOGLE_CLOUD_PROJECT);
|
|
638
|
-
if (!config.api_key && !useVertex) {
|
|
639
|
-
console.log(chalk.yellow(` ${t("init.first_time")}
|
|
640
|
-
`));
|
|
641
|
-
const apiKey = await input({
|
|
642
|
-
message: t("init.api_key"),
|
|
643
|
-
validate: (v) => v.length > 0 || t("init.api_key_required")
|
|
644
|
-
});
|
|
645
|
-
config.api_key = apiKey;
|
|
646
|
-
saveConfig(config);
|
|
647
|
-
console.log(chalk.green(` ${t("init.api_key_saved")}
|
|
648
|
-
`));
|
|
649
|
-
} else if (useVertex && !config.api_key) {
|
|
650
|
-
console.log(chalk.cyan(` ${t("init.vertex_detected")}
|
|
651
|
-
`));
|
|
652
|
-
}
|
|
653
637
|
if (config.model_override) {
|
|
654
638
|
const mo = config.model_override;
|
|
655
639
|
const maskedKey = mo.api_key.length > 8 ? mo.api_key.slice(0, 4) + "..." + mo.api_key.slice(-4) : "****";
|
|
@@ -716,6 +700,21 @@ async function initCommand(name) {
|
|
|
716
700
|
console.log(chalk.green(`
|
|
717
701
|
${t("init.model_saved")}`));
|
|
718
702
|
console.log(chalk.yellow(` ${t("init.model_note")}
|
|
703
|
+
`));
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
const useVertex = !!(process.env.CLAUDE_CODE_USE_VERTEX === "1" || process.env.GOOGLE_CLOUD_PROJECT);
|
|
707
|
+
if (!config.model_override && !useVertex) {
|
|
708
|
+
if (!config.api_key) {
|
|
709
|
+
const apiKey = await input({
|
|
710
|
+
message: t("init.api_key"),
|
|
711
|
+
validate: (v) => v.length > 0 || "Required"
|
|
712
|
+
});
|
|
713
|
+
config.api_key = apiKey;
|
|
714
|
+
saveConfig(config);
|
|
715
|
+
} else {
|
|
716
|
+
const maskedKey = config.api_key.length > 8 ? config.api_key.slice(0, 4) + "..." + config.api_key.slice(-4) : "****";
|
|
717
|
+
console.log(chalk.cyan(` Anthropic API key: ${maskedKey}
|
|
719
718
|
`));
|
|
720
719
|
}
|
|
721
720
|
}
|
|
@@ -1701,13 +1700,13 @@ function readResults(resultsPath) {
|
|
|
1701
1700
|
return lines.slice(1).map((line) => {
|
|
1702
1701
|
const parts = line.split(" ");
|
|
1703
1702
|
return {
|
|
1704
|
-
iteration: parseInt(parts[0], 10),
|
|
1705
|
-
commit: parts[1],
|
|
1706
|
-
score_before: parseFloat(parts[2]),
|
|
1707
|
-
score_after: parseFloat(parts[3]),
|
|
1708
|
-
delta: parseFloat(parts[4]),
|
|
1709
|
-
status: parts[5],
|
|
1710
|
-
mutation_type: parts[6],
|
|
1703
|
+
iteration: parseInt(parts[0], 10) || 0,
|
|
1704
|
+
commit: parts[1] || "",
|
|
1705
|
+
score_before: parseFloat(parts[2]) || 0,
|
|
1706
|
+
score_after: parseFloat(parts[3]) || 0,
|
|
1707
|
+
delta: parseFloat(parts[4]) || 0,
|
|
1708
|
+
status: parts[5] || "discard",
|
|
1709
|
+
mutation_type: parts[6] || "unknown",
|
|
1711
1710
|
description: parts[7] || ""
|
|
1712
1711
|
};
|
|
1713
1712
|
});
|
|
@@ -1939,8 +1938,11 @@ function statusCommand() {
|
|
|
1939
1938
|
console.log(chalk7.bold("\n Last 5 mutations:"));
|
|
1940
1939
|
for (const r of last5) {
|
|
1941
1940
|
const icon = r.status === "keep" ? chalk7.green("\u2713") : chalk7.red("\u2717");
|
|
1942
|
-
const
|
|
1943
|
-
|
|
1941
|
+
const d = isNaN(r.delta) ? 0 : r.delta;
|
|
1942
|
+
const delta = d >= 0 ? `+${d.toFixed(2)}` : d.toFixed(2);
|
|
1943
|
+
const mtype = (r.mutation_type || "unknown").padEnd(10);
|
|
1944
|
+
const desc = (r.description || "").substring(0, 50);
|
|
1945
|
+
console.log(` ${icon} ${mtype} ${desc} ${delta}`);
|
|
1944
1946
|
}
|
|
1945
1947
|
const dbPath = path8.join(cwd, "activities_db.json");
|
|
1946
1948
|
if (fs9.existsSync(dbPath)) {
|
|
@@ -2263,7 +2265,7 @@ function renderDashboard() {
|
|
|
2263
2265
|
return;
|
|
2264
2266
|
}
|
|
2265
2267
|
const lastBest = getLastBestScore(resultsPath);
|
|
2266
|
-
const score = lastBest?.score ?? 0;
|
|
2268
|
+
const score = isNaN(lastBest?.score ?? 0) ? 0 : lastBest?.score ?? 0;
|
|
2267
2269
|
console.log(` Score: ${progressBar(score, 100)} ${chalk10.bold(score.toFixed(2))}/100`);
|
|
2268
2270
|
const scorePath = path10.join(cwd, "score.json");
|
|
2269
2271
|
if (fs12.existsSync(scorePath)) {
|
|
@@ -2298,8 +2300,11 @@ function renderDashboard() {
|
|
|
2298
2300
|
console.log(chalk10.bold("\n Recent Mutations:"));
|
|
2299
2301
|
for (const r of last5) {
|
|
2300
2302
|
const icon = r.status === "keep" ? chalk10.green("\u2713") : chalk10.red("\u2717");
|
|
2301
|
-
const
|
|
2302
|
-
|
|
2303
|
+
const d = isNaN(r.delta) ? 0 : r.delta;
|
|
2304
|
+
const delta = d >= 0 ? chalk10.green(`+${d.toFixed(2)}`) : chalk10.red(d.toFixed(2));
|
|
2305
|
+
const mtype = (r.mutation_type || "unknown").padEnd(10);
|
|
2306
|
+
const desc = (r.description || "").substring(0, 45).padEnd(45);
|
|
2307
|
+
console.log(` ${icon} #${String(r.iteration || 0).padStart(3)} ${mtype} ${desc} ${delta}`);
|
|
2303
2308
|
}
|
|
2304
2309
|
const totalIterations = results[results.length - 1].iteration;
|
|
2305
2310
|
const keeps = results.filter((r) => r.status === "keep").length;
|