haansi 0.1.50 → 0.1.52

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/dist/haansi.js +43 -8
  2. package/package.json +1 -1
package/dist/haansi.js CHANGED
@@ -95,7 +95,7 @@ var require_package = __commonJS({
95
95
  "package.json"(exports2, module2) {
96
96
  module2.exports = {
97
97
  name: "haansi",
98
- version: "0.1.50",
98
+ version: "0.1.52",
99
99
  description: "Haansi CLI - Session collector and MCP server for Claude Code & OpenAI Codex",
100
100
  bin: {
101
101
  haansi: "./dist/haansi.js"
@@ -85064,6 +85064,7 @@ function parseReplayArgs(argv) {
85064
85064
  familyId: "",
85065
85065
  agentCmd: "",
85066
85066
  testCmd: "",
85067
+ setupCmd: null,
85067
85068
  attempts: 3,
85068
85069
  arms: [...ARMS],
85069
85070
  limit: null,
@@ -85082,6 +85083,7 @@ function parseReplayArgs(argv) {
85082
85083
  if (a === "--family") options.familyId = next();
85083
85084
  else if (a === "--agent-cmd") options.agentCmd = next();
85084
85085
  else if (a === "--test-cmd") options.testCmd = next();
85086
+ else if (a === "--setup-cmd") options.setupCmd = next() || null;
85085
85087
  else if (a === "--attempts") options.attempts = Number(next());
85086
85088
  else if (a === "--limit") options.limit = Number(next());
85087
85089
  else if (a === "--cutoff") options.cutoff = next();
@@ -85173,6 +85175,25 @@ async function replayArm(deps, options, task, arm, playbook) {
85173
85175
  );
85174
85176
  if (add.code !== 0) throw new Error(`could not check out ${task.baseSha}`);
85175
85177
  try {
85178
+ const label = `${task.name ?? task.processId} [${arm}]`;
85179
+ const since = (from) => `${Math.round((deps.now() - from) / 1e3)}s`;
85180
+ deps.log(`\u2026 ${label}: checked out ${task.baseSha.slice(0, 9)}`);
85181
+ if (options.setupCmd) {
85182
+ const at = deps.now();
85183
+ deps.log(`\u2026 ${label}: setting up`);
85184
+ const setup = await deps.shell(
85185
+ options.setupCmd,
85186
+ dir,
85187
+ {},
85188
+ options.timeoutMs
85189
+ );
85190
+ if (setup.code !== 0) {
85191
+ throw new Error(
85192
+ `setup failed after ${since(at)}: ${setup.output.trim().split("\n").slice(-3).join(" | ")}`
85193
+ );
85194
+ }
85195
+ deps.log(`\u2026 ${label}: set up in ${since(at)}`);
85196
+ }
85176
85197
  const promptFile = (0, import_node_path9.join)(dir, ".haansi-replay", "prompt.md");
85177
85198
  if (arm === "haansi" && playbook)
85178
85199
  deps.writeFile(
@@ -85183,6 +85204,10 @@ async function replayArm(deps, options, task, arm, playbook) {
85183
85204
  for (let attempt = 1; attempt <= options.attempts; attempt++) {
85184
85205
  const prompt2 = replayPrompt(task, arm, feedback);
85185
85206
  deps.writeFile(promptFile, prompt2);
85207
+ const agentAt = deps.now();
85208
+ deps.log(
85209
+ `\u2026 ${label}: attempt ${attempt}/${options.attempts}, running the agent`
85210
+ );
85186
85211
  await deps.shell(
85187
85212
  options.agentCmd,
85188
85213
  dir,
@@ -85196,12 +85221,21 @@ async function replayArm(deps, options, task, arm, playbook) {
85196
85221
  );
85197
85222
  if (checkout.code !== 0)
85198
85223
  throw new Error("could not check out the fix's tests");
85224
+ const testAt = deps.now();
85225
+ deps.log(`\u2026 ${label}: agent done in ${since(agentAt)}, grading`);
85199
85226
  const test = await deps.shell(
85200
85227
  options.testCmd,
85201
85228
  dir,
85202
85229
  { HAANSI_REPLAY_TEST_FILES: files.join(" ") },
85203
85230
  options.timeoutMs
85204
85231
  );
85232
+ deps.log(
85233
+ `\u2026 ${label}: tests ${test.code === 0 ? "passed" : "failed"} in ${since(testAt)}`
85234
+ );
85235
+ if (test.code !== 0) {
85236
+ for (const line of test.output.trim().split("\n").slice(-FAILURE_LINES))
85237
+ deps.log(` ${line}`);
85238
+ }
85205
85239
  if (test.code === 0) {
85206
85240
  return {
85207
85241
  processId: task.processId,
@@ -85334,17 +85368,17 @@ async function replay(argv) {
85334
85368
  try {
85335
85369
  const { results, skipped, recorded } = await runReplays(options, {
85336
85370
  getTasks: async (familyId, cutoff) => (await apiGet3(
85337
- `/memory/processes/families/${familyId}/replay-tasks${cutoff ? `?cutoff=${encodeURIComponent(cutoff)}` : ""}`,
85371
+ `/memory/replays/families/${familyId}/tasks${cutoff ? `?cutoff=${encodeURIComponent(cutoff)}` : ""}`,
85338
85372
  token,
85339
85373
  apiUrl2
85340
85374
  )).replay,
85341
85375
  getPlaybook: async (familyId) => (await apiGet3(
85342
- `/memory/skills/families/${familyId}/playbook`,
85376
+ `/memory/replays/families/${familyId}/playbook`,
85343
85377
  token,
85344
85378
  apiUrl2
85345
- ).catch(() => ({ data: { playbook: null } }))).data.playbook,
85379
+ )).playbook,
85346
85380
  report: async (familyId, body) => await apiPost2(
85347
- `/memory/processes/families/${familyId}/replay-results`,
85381
+ `/memory/replays/families/${familyId}/results`,
85348
85382
  body,
85349
85383
  token,
85350
85384
  apiUrl2
@@ -85376,7 +85410,7 @@ Baseline: ${passed("baseline")}/${ran("baseline")} passed \xB7 With Haansi: ${pa
85376
85410
  (0, import_node_fs10.rmSync)(work, { recursive: true, force: true });
85377
85411
  }
85378
85412
  }
85379
- var import_node_child_process4, import_node_fs10, import_node_os9, import_node_path9, SHA, ARMS, FEEDBACK_CHARS, USAGE;
85413
+ var import_node_child_process4, import_node_fs10, import_node_os9, import_node_path9, SHA, ARMS, FEEDBACK_CHARS, FAILURE_LINES, USAGE;
85380
85414
  var init_replay = __esm({
85381
85415
  "src/commands/replay.ts"() {
85382
85416
  "use strict";
@@ -85389,13 +85423,14 @@ var init_replay = __esm({
85389
85423
  SHA = /^[0-9a-f]{7,40}$/i;
85390
85424
  ARMS = ["baseline", "haansi"];
85391
85425
  FEEDBACK_CHARS = 6e3;
85426
+ FAILURE_LINES = 8;
85392
85427
  USAGE = `Usage: haansi replay run --family <id> --agent-cmd "<cmd>" --test-cmd "<cmd>"
85393
- [--attempts 3] [--arms baseline,haansi] [--limit n]
85428
+ [--setup-cmd "<cmd>"] [--attempts 3] [--arms baseline,haansi] [--limit n]
85394
85429
  [--cutoff <date>] [--timeout-min 30]
85395
85430
  [--agent-name <name>] [--model <name>] [--run-ref <url>] [--dry-run]
85396
85431
 
85397
85432
  Run from a clone of the repository. Example (GitHub Actions):
85398
- haansi replay run --family "$FAMILY_ID" \\
85433
+ haansi replay run --family "$FAMILY_ID" --setup-cmd 'npm ci' \\
85399
85434
  --agent-cmd 'claude -p "$HAANSI_REPLAY_PROMPT" --permission-mode acceptEdits' \\
85400
85435
  --test-cmd 'npx vitest run $HAANSI_REPLAY_TEST_FILES' \\
85401
85436
  --agent-name claude-code --model claude-sonnet-5-5`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haansi",
3
- "version": "0.1.50",
3
+ "version": "0.1.52",
4
4
  "description": "Haansi CLI - Session collector and MCP server for Claude Code & OpenAI Codex",
5
5
  "bin": {
6
6
  "haansi": "./dist/haansi.js"