harness-evolver 3.0.3 → 3.0.4

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.
Files changed (2) hide show
  1. package/bin/install.js +64 -25
  2. package/package.json +1 -1
package/bin/install.js CHANGED
@@ -216,45 +216,84 @@ function installPythonDeps() {
216
216
  }
217
217
 
218
218
  async function configureLangSmith(rl) {
219
- console.log(`\n ${YELLOW}LangSmith Configuration${RESET} ${DIM}(required for v3)${RESET}\n`);
219
+ console.log(`\n ${BOLD}${GREEN}LangSmith Configuration${RESET} ${DIM}(required)${RESET}\n`);
220
220
 
221
- // Check if already configured
222
221
  const langsmithCredsDir = process.platform === "darwin"
223
222
  ? path.join(HOME, "Library", "Application Support", "langsmith-cli")
224
223
  : path.join(HOME, ".config", "langsmith-cli");
225
224
  const langsmithCredsFile = path.join(langsmithCredsDir, "credentials");
225
+ const hasLangsmithCli = checkCommand("langsmith-cli --version");
226
+
227
+ // --- Step 1: API Key ---
228
+ let hasKey = false;
226
229
 
227
- // Check env var
228
230
  if (process.env.LANGSMITH_API_KEY) {
229
231
  console.log(` ${GREEN}✓${RESET} LANGSMITH_API_KEY found in environment`);
230
- return;
232
+ hasKey = true;
233
+ } else if (fs.existsSync(langsmithCredsFile)) {
234
+ try {
235
+ const content = fs.readFileSync(langsmithCredsFile, "utf8");
236
+ if (content.includes("LANGSMITH_API_KEY=lsv2_")) {
237
+ console.log(` ${GREEN}✓${RESET} API key found in credentials file`);
238
+ hasKey = true;
239
+ }
240
+ } catch {}
231
241
  }
232
242
 
233
- // Check credentials file
234
- if (fs.existsSync(langsmithCredsFile)) {
235
- console.log(` ${GREEN}✓${RESET} LangSmith credentials found at ${DIM}${langsmithCredsFile}${RESET}`);
236
- return;
243
+ if (!hasKey) {
244
+ console.log(` ${BOLD}LangSmith API Key${RESET} — get yours at ${DIM}https://smith.langchain.com/settings${RESET}`);
245
+ console.log(` ${DIM}LangSmith is required. The evolver won't work without it.${RESET}\n`);
246
+
247
+ // Keep asking until they provide a key or explicitly skip
248
+ let attempts = 0;
249
+ while (!hasKey && attempts < 3) {
250
+ const apiKey = await ask(rl, ` ${YELLOW}Paste your LangSmith API key (lsv2_pt_...):${RESET} `);
251
+ const key = apiKey.trim();
252
+
253
+ if (key && key.startsWith("lsv2_")) {
254
+ try {
255
+ fs.mkdirSync(langsmithCredsDir, { recursive: true });
256
+ fs.writeFileSync(langsmithCredsFile, `LANGSMITH_API_KEY=${key}\n`);
257
+ console.log(` ${GREEN}✓${RESET} API key saved`);
258
+ hasKey = true;
259
+ } catch {
260
+ console.log(` ${RED}Failed to save.${RESET} Add to your shell: export LANGSMITH_API_KEY=${key}`);
261
+ hasKey = true; // they have the key, just couldn't save
262
+ }
263
+ } else if (key) {
264
+ console.log(` ${YELLOW}Invalid — LangSmith keys start with lsv2_${RESET}`);
265
+ attempts++;
266
+ } else {
267
+ // Empty input — skip
268
+ console.log(`\n ${RED}WARNING:${RESET} No API key configured.`);
269
+ console.log(` ${BOLD}/evolver:setup will not work${RESET} until you set LANGSMITH_API_KEY.`);
270
+ console.log(` Run: ${DIM}export LANGSMITH_API_KEY=lsv2_pt_your_key${RESET}\n`);
271
+ break;
272
+ }
273
+ }
237
274
  }
238
275
 
239
- // Ask for API key
240
- console.log(` ${BOLD}LangSmith API Key${RESET} — get yours at ${DIM}https://smith.langchain.com/settings${RESET}`);
241
- console.log(` ${DIM}LangSmith is required for v3 (datasets, experiments, evaluators).${RESET}\n`);
242
- const apiKey = await ask(rl, ` ${YELLOW}Paste your LangSmith API key:${RESET} `);
243
- const key = apiKey.trim();
276
+ // --- Step 2: langsmith-cli ---
277
+ if (hasLangsmithCli) {
278
+ console.log(` ${GREEN}✓${RESET} langsmith-cli installed`);
279
+ } else {
280
+ console.log(`\n ${BOLD}langsmith-cli${RESET} optional but useful for debugging traces`);
281
+ console.log(` ${DIM}Quick project listing, trace inspection, run stats from terminal.${RESET}`);
282
+ const lsCliAnswer = await ask(rl, `\n ${YELLOW}Install langsmith-cli? [Y/n]:${RESET} `);
283
+ if (lsCliAnswer.trim().toLowerCase() !== "n") {
284
+ console.log(`\n Installing langsmith-cli...`);
285
+ try {
286
+ execSync("uv tool install langsmith-cli 2>/dev/null || pip install langsmith-cli 2>/dev/null || pip3 install langsmith-cli", { stdio: "pipe", timeout: 60000 });
287
+ console.log(` ${GREEN}✓${RESET} langsmith-cli installed`);
244
288
 
245
- if (key && key.startsWith("lsv2_")) {
246
- try {
247
- fs.mkdirSync(langsmithCredsDir, { recursive: true });
248
- fs.writeFileSync(langsmithCredsFile, `LANGSMITH_API_KEY=${key}\n`);
249
- console.log(` ${GREEN}✓${RESET} API key saved to ${DIM}${langsmithCredsFile}${RESET}`);
250
- } catch {
251
- console.log(` ${RED}Failed to save.${RESET} Add to your shell: export LANGSMITH_API_KEY=${key}`);
289
+ // If we have a key, auto-authenticate
290
+ if (hasKey && fs.existsSync(langsmithCredsFile)) {
291
+ console.log(` ${GREEN}✓${RESET} langsmith-cli auto-authenticated (credentials file exists)`);
292
+ }
293
+ } catch {
294
+ console.log(` ${YELLOW}!${RESET} Could not install. Try manually: ${DIM}uv tool install langsmith-cli${RESET}`);
295
+ }
252
296
  }
253
- } else if (key) {
254
- console.log(` ${YELLOW}Doesn't look like a LangSmith key (should start with lsv2_).${RESET}`);
255
- console.log(` Add to your shell: ${BOLD}export LANGSMITH_API_KEY=your_key${RESET}`);
256
- } else {
257
- console.log(` ${YELLOW}Skipped.${RESET} You must set LANGSMITH_API_KEY before using /evolver:setup`);
258
297
  }
259
298
  }
260
299
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harness-evolver",
3
- "version": "3.0.3",
3
+ "version": "3.0.4",
4
4
  "description": "LangSmith-native autonomous agent optimization for Claude Code",
5
5
  "author": "Raphael Valdetaro",
6
6
  "license": "MIT",