haansi 0.1.52 → 0.1.53

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 +102 -4
  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.52",
98
+ version: "0.1.53",
99
99
  description: "Haansi CLI - Session collector and MCP server for Claude Code & OpenAI Codex",
100
100
  bin: {
101
101
  haansi: "./dist/haansi.js"
@@ -19000,6 +19000,14 @@ var init_exclusions = __esm({
19000
19000
  "join-key",
19001
19001
  "A canonical object id (github:<repo>#<n>), never text."
19002
19002
  ],
19003
+ revert_evidence: [
19004
+ "not-personal",
19005
+ 'Revert signal kinds with ledger-written details ("Revert #12", "branch revert-12-\u2026"); no PR text.'
19006
+ ],
19007
+ possible_revert: [
19008
+ "not-personal",
19009
+ "A candidate revert's canonical id, time and ledger-written signals; no PR text."
19010
+ ],
19003
19011
  survival_14d: [
19004
19012
  "operational",
19005
19013
  "Closed CHECK vocabulary (held, failed, pending)."
@@ -19022,6 +19030,10 @@ var init_exclusions = __esm({
19022
19030
  ]
19023
19031
  }),
19024
19032
  ...exchangeExclusions(INTEL, "workstream_attempts", {
19033
+ evidence: [
19034
+ "not-personal",
19035
+ "CI check names, commit ids, PR numbers and GitHub links a verdict rests on; no PR text."
19036
+ ],
19025
19037
  process_id: [
19026
19038
  "join-key",
19027
19039
  "The workstream's process_registry.process_id, joined by equality."
@@ -19112,6 +19124,10 @@ var init_exclusions = __esm({
19112
19124
  "operational",
19113
19125
  "Closed CHECK vocabulary (held, reversed, revisited)."
19114
19126
  ],
19127
+ outcome_evidence: [
19128
+ "not-personal",
19129
+ "PR keys (owner/repo#n), commit ids and timestamps the outcome rests on; no text."
19130
+ ],
19115
19131
  change_keys: [
19116
19132
  "join-key",
19117
19133
  "owner/repo#n of the workstream's PRs, as in workstream_attempts."
@@ -19150,6 +19166,50 @@ var init_exclusions = __esm({
19150
19166
  "Counts by Actions job and step name, from CI config."
19151
19167
  ]
19152
19168
  }),
19169
+ ...exchangeExclusions(INTEL, "repository_checks", {
19170
+ repository: [
19171
+ "join-key",
19172
+ "owner/repo of the org's CI, as in change_outcomes."
19173
+ ],
19174
+ check_key: [
19175
+ "join-key",
19176
+ "Normalized CI workflow and job name, matched against captured jobs."
19177
+ ],
19178
+ workflow: ["not-personal", "A CI workflow's name, e.g. CI."],
19179
+ job: ["not-personal", "A CI job's name, e.g. Unit tests."],
19180
+ kind: [
19181
+ "operational",
19182
+ "Closed CHECK vocabulary (test, typecheck, build, lint, format, deploy, other)."
19183
+ ]
19184
+ }),
19185
+ ...exchangeExclusions(INTEL, "revert_labels", {
19186
+ repository: [
19187
+ "join-key",
19188
+ "owner/repo of the reverted PR, as in change_outcomes."
19189
+ ],
19190
+ reverted_by: [
19191
+ "join-key",
19192
+ "Canonical id of the reverting PR or commit (github:owner/repo#n, github:commit:<sha>)."
19193
+ ],
19194
+ label: [
19195
+ "operational",
19196
+ "Closed CHECK vocabulary (confirmed, rejected, cleared)."
19197
+ ]
19198
+ }),
19199
+ ...exchangeExclusions(INTEL, "repository_replay_settings", {
19200
+ repository: [
19201
+ "join-key",
19202
+ "owner/repo, as in replay_tasks and repository_checks."
19203
+ ],
19204
+ setup_command: [
19205
+ "not-personal",
19206
+ "A shell command an org admin typed for its CI (e.g. npm ci); run by the customer's own CI."
19207
+ ],
19208
+ test_command: [
19209
+ "not-personal",
19210
+ "A shell command an org admin typed for its CI (e.g. npm run test); run by the customer's own CI."
19211
+ ]
19212
+ }),
19153
19213
  ...exchangeExclusions(INTEL, "replay_results", {
19154
19214
  process_id: [
19155
19215
  "join-key",
@@ -85057,7 +85117,8 @@ __export(replay_exports, {
85057
85117
  runCommand: () => runCommand,
85058
85118
  runReplays: () => runReplays,
85059
85119
  safeTestFile: () => safeTestFile,
85060
- skipReason: () => skipReason
85120
+ skipReason: () => skipReason,
85121
+ taskCommands: () => taskCommands
85061
85122
  });
85062
85123
  function parseReplayArgs(argv) {
85063
85124
  const options = {
@@ -85065,6 +85126,7 @@ function parseReplayArgs(argv) {
85065
85126
  agentCmd: "",
85066
85127
  testCmd: "",
85067
85128
  setupCmd: null,
85129
+ repoCommands: false,
85068
85130
  attempts: 3,
85069
85131
  arms: [...ARMS],
85070
85132
  limit: null,
@@ -85092,6 +85154,7 @@ function parseReplayArgs(argv) {
85092
85154
  else if (a === "--model") options.model = next();
85093
85155
  else if (a === "--run-ref") options.runRef = next();
85094
85156
  else if (a === "--dry-run") options.dryRun = true;
85157
+ else if (a === "--repo-commands") options.repoCommands = true;
85095
85158
  else if (a === "--arms")
85096
85159
  options.arms = next().split(",").map((s) => s.trim()).filter(Boolean);
85097
85160
  else if (!sub && !a.startsWith("-")) sub = a;
@@ -85100,7 +85163,10 @@ function parseReplayArgs(argv) {
85100
85163
  if (!/^[0-9a-f-]{36}$/i.test(options.familyId))
85101
85164
  errors.push("--family <id> is required (the family's id).");
85102
85165
  if (!options.agentCmd) errors.push("--agent-cmd is required.");
85103
- if (!options.testCmd) errors.push("--test-cmd is required.");
85166
+ if (!options.testCmd && !options.repoCommands)
85167
+ errors.push(
85168
+ "--test-cmd is required (or --repo-commands, to use the repository's from Haansi)."
85169
+ );
85104
85170
  if (!Number.isInteger(options.attempts) || options.attempts < 1 || options.attempts > 20)
85105
85171
  errors.push("--attempts must be 1 to 20.");
85106
85172
  if (options.limit !== null && (!Number.isInteger(options.limit) || options.limit < 1))
@@ -85124,6 +85190,16 @@ function repositoryFromRemote(remote) {
85124
85190
  function safeTestFile(path2) {
85125
85191
  return path2.length > 0 && !path2.startsWith("/") && !path2.startsWith("-") && !path2.split("/").includes("..") && !/[\u0000-\u001f]/.test(path2);
85126
85192
  }
85193
+ function taskCommands(options, task) {
85194
+ const repo = options.repoCommands ? task.repoCommands : null;
85195
+ const setupCmd = options.setupCmd ?? repo?.setupCommand ?? null;
85196
+ const testCmd = options.testCmd || repo?.testCommand || null;
85197
+ return {
85198
+ setupCmd,
85199
+ testCmd,
85200
+ fromHaansi: Boolean(repo) && (!options.setupCmd && setupCmd !== null || !options.testCmd && testCmd !== null)
85201
+ };
85202
+ }
85127
85203
  function skipReason(task, repository) {
85128
85204
  if (!repository || task.repository.toLowerCase() !== repository)
85129
85205
  return `in ${task.repository}, not this repository`;
@@ -85294,6 +85370,24 @@ async function runReplays(options, deps) {
85294
85370
  const chosen = options.limit ? runnable.slice(0, options.limit) : runnable;
85295
85371
  const results = [];
85296
85372
  for (const task of chosen) {
85373
+ const commands = taskCommands(options, task);
85374
+ if (!commands.testCmd) {
85375
+ skipped += 1;
85376
+ deps.log(
85377
+ `skip ${task.name ?? task.processId}: no test command (pass --test-cmd, or set one for ${task.repository} in Haansi)`
85378
+ );
85379
+ continue;
85380
+ }
85381
+ if (commands.fromHaansi) {
85382
+ deps.log(
85383
+ `\u2026 ${task.name ?? task.processId}: using ${task.repository}'s replay commands from Haansi (setup: ${commands.setupCmd ?? "none"}; test: ${commands.testCmd})`
85384
+ );
85385
+ }
85386
+ const taskOptions = {
85387
+ ...options,
85388
+ setupCmd: commands.setupCmd,
85389
+ testCmd: commands.testCmd
85390
+ };
85297
85391
  if (!await ensureCommit(deps, task.baseSha) || !await ensureCommit(deps, task.targetSha)) {
85298
85392
  skipped += 1;
85299
85393
  deps.log(
@@ -85303,7 +85397,7 @@ async function runReplays(options, deps) {
85303
85397
  }
85304
85398
  for (const arm of arms) {
85305
85399
  try {
85306
- const result = await replayArm(deps, options, task, arm, playbook);
85400
+ const result = await replayArm(deps, taskOptions, task, arm, playbook);
85307
85401
  results.push(result);
85308
85402
  deps.log(
85309
85403
  `${result.passed ? "pass" : "fail"} ${arm.padEnd(8)} ${task.name ?? task.processId} (${result.attempts}/${result.maxAttempts} attempts)`
@@ -85428,6 +85522,10 @@ var init_replay = __esm({
85428
85522
  [--setup-cmd "<cmd>"] [--attempts 3] [--arms baseline,haansi] [--limit n]
85429
85523
  [--cutoff <date>] [--timeout-min 30]
85430
85524
  [--agent-name <name>] [--model <name>] [--run-ref <url>] [--dry-run]
85525
+ [--repo-commands]
85526
+
85527
+ --repo-commands uses the setup and test commands an org admin set for the
85528
+ repository in Haansi (Settings \u2192 Data sources) for any not given here.
85431
85529
 
85432
85530
  Run from a clone of the repository. Example (GitHub Actions):
85433
85531
  haansi replay run --family "$FAMILY_ID" --setup-cmd 'npm ci' \\
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haansi",
3
- "version": "0.1.52",
3
+ "version": "0.1.53",
4
4
  "description": "Haansi CLI - Session collector and MCP server for Claude Code & OpenAI Codex",
5
5
  "bin": {
6
6
  "haansi": "./dist/haansi.js"