@gethmy/agent 1.32.0 → 1.33.0

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 CHANGED
@@ -841,6 +841,31 @@ function findRemovedConfigKeys(rawConfig) {
841
841
  }
842
842
  return found;
843
843
  }
844
+ function sandboxConfigIssues(args) {
845
+ const out = [];
846
+ if (args.image && !/^[A-Za-z0-9]/.test(args.image)) {
847
+ out.push(`${args.imagePath}: must start with a letter or digit (got "${args.image}") — a leading "-" is read by docker as a flag, not an image`);
848
+ }
849
+ if (args.timeoutPath !== undefined) {
850
+ const ms = args.timeoutMs;
851
+ if (typeof ms !== "number" || !Number.isInteger(ms) || ms < 1) {
852
+ out.push(`${args.timeoutPath}: must be an integer >= 1 (got ${ms})`);
853
+ }
854
+ }
855
+ return out;
856
+ }
857
+ function validateVerificationConfig(config) {
858
+ const v = config.verification;
859
+ const issues = sandboxConfigIssues({
860
+ image: v.sandboxImage,
861
+ imagePath: "verification.sandboxImage"
862
+ });
863
+ if (issues.length > 0) {
864
+ throw new ConfigValidationError(`Invalid verification config:
865
+ - ${issues.join(`
866
+ - `)}`, issues);
867
+ }
868
+ }
844
869
  function validateAutoMergeConfig(config) {
845
870
  const autoMerge = config.review.autoMerge;
846
871
  const issues = [];
@@ -869,18 +894,18 @@ function validateAutoMergeConfig(config) {
869
894
  if (!autoMerge.reReviewOnBranchChange) {
870
895
  issues.push("review.autoMerge.ciRepair.patch.enabled: needs review.autoMerge.reReviewOnBranchChange — without it a machine-authored repair could merge with nothing having reviewed its diff");
871
896
  }
872
- if (patch.sandboxImage && !/^[A-Za-z0-9]/.test(patch.sandboxImage)) {
873
- issues.push(`review.autoMerge.ciRepair.patch.sandboxImage: must start with a letter or digit (got "${patch.sandboxImage}") — a leading "-" is read by docker as a flag, not an image`);
874
- }
897
+ issues.push(...sandboxConfigIssues({
898
+ image: patch.sandboxImage,
899
+ timeoutMs: patch.sandboxTimeoutMs,
900
+ imagePath: "review.autoMerge.ciRepair.patch.sandboxImage",
901
+ timeoutPath: "review.autoMerge.ciRepair.patch.sandboxTimeoutMs"
902
+ }));
875
903
  if (!Number.isInteger(patch.maxTurns) || patch.maxTurns < 1) {
876
904
  issues.push(`review.autoMerge.ciRepair.patch.maxTurns: must be an integer >= 1 (got ${patch.maxTurns})`);
877
905
  }
878
906
  if (!(patch.maxBudgetUsd > 0)) {
879
907
  issues.push(`review.autoMerge.ciRepair.patch.maxBudgetUsd: must be greater than 0 (got ${patch.maxBudgetUsd})`);
880
908
  }
881
- if (!Number.isInteger(patch.sandboxTimeoutMs) || patch.sandboxTimeoutMs < 1) {
882
- issues.push(`review.autoMerge.ciRepair.patch.sandboxTimeoutMs: must be an integer >= 1 (got ${patch.sandboxTimeoutMs})`);
883
- }
884
909
  }
885
910
  const independent = autoMerge.independentReview;
886
911
  if (typeof independent?.enabled !== "boolean") {
@@ -2750,6 +2775,7 @@ var init_types2 = __esm(() => {
2750
2775
  devServerBasePort: 4200,
2751
2776
  timeout: 120000,
2752
2777
  testTimeout: 600000,
2778
+ sandboxImage: "",
2753
2779
  failColumn: "To Do"
2754
2780
  },
2755
2781
  review: {
@@ -5233,7 +5259,8 @@ import {
5233
5259
  reportFindings,
5234
5260
  runFormatFix,
5235
5261
  runVerification,
5236
- teardownWorktree
5262
+ teardownWorktree,
5263
+ verificationSandbox
5237
5264
  } from "@gethmy/harness";
5238
5265
  function formatTokenCount(tokens) {
5239
5266
  if (tokens >= 1e6)
@@ -5275,7 +5302,7 @@ async function runCompletion(client, card, branchName, worktreePath, config, wor
5275
5302
  revertWarnings: []
5276
5303
  };
5277
5304
  if (config.verification.enabled && config.verification.lint) {
5278
- runFormatFix(worktreePath, config.verification.timeout, workerId);
5305
+ await runFormatFix(worktreePath, config.verification.timeout, workerId, verificationSandbox(config));
5279
5306
  }
5280
5307
  commitUncommittedChanges(worktreePath, card);
5281
5308
  const hasCommits = checkHasCommits(worktreePath, config.worktree.baseBranch, runBaselineSha);
@@ -9674,6 +9701,7 @@ import {
9674
9701
  spawnInGroup as spawnInGroup4,
9675
9702
  teardownWorktree as teardownWorktree2,
9676
9703
  terminateGroup as terminateGroup3,
9704
+ verificationSandbox as verificationSandbox2,
9677
9705
  WorktreeBaseError
9678
9706
  } from "@gethmy/harness";
9679
9707
  function sdkDraftLogLine(ev) {
@@ -10998,7 +11026,8 @@ ${prompt}`;
10998
11026
  build: {
10999
11027
  worktreePath,
11000
11028
  buildTimeout: this.config.verification.timeout,
11001
- lintTimeout: this.config.verification.timeout
11029
+ lintTimeout: this.config.verification.timeout,
11030
+ sandbox: verificationSandbox2(this.config)
11002
11031
  },
11003
11032
  artifact: {
11004
11033
  worktreePath,
@@ -14581,6 +14610,7 @@ async function main() {
14581
14610
  validateBudgetConfig(config.agent);
14582
14611
  validateSweepConfig(config.agent);
14583
14612
  validateRankingConfig(config.agent);
14613
+ validateVerificationConfig(config.agent);
14584
14614
  } catch (err) {
14585
14615
  if (err instanceof ConfigValidationError) {
14586
14616
  banner.fail();
package/dist/index.js CHANGED
@@ -840,6 +840,31 @@ function findRemovedConfigKeys(rawConfig) {
840
840
  }
841
841
  return found;
842
842
  }
843
+ function sandboxConfigIssues(args) {
844
+ const out = [];
845
+ if (args.image && !/^[A-Za-z0-9]/.test(args.image)) {
846
+ out.push(`${args.imagePath}: must start with a letter or digit (got "${args.image}") — a leading "-" is read by docker as a flag, not an image`);
847
+ }
848
+ if (args.timeoutPath !== undefined) {
849
+ const ms = args.timeoutMs;
850
+ if (typeof ms !== "number" || !Number.isInteger(ms) || ms < 1) {
851
+ out.push(`${args.timeoutPath}: must be an integer >= 1 (got ${ms})`);
852
+ }
853
+ }
854
+ return out;
855
+ }
856
+ function validateVerificationConfig(config) {
857
+ const v = config.verification;
858
+ const issues = sandboxConfigIssues({
859
+ image: v.sandboxImage,
860
+ imagePath: "verification.sandboxImage"
861
+ });
862
+ if (issues.length > 0) {
863
+ throw new ConfigValidationError(`Invalid verification config:
864
+ - ${issues.join(`
865
+ - `)}`, issues);
866
+ }
867
+ }
843
868
  function validateAutoMergeConfig(config) {
844
869
  const autoMerge = config.review.autoMerge;
845
870
  const issues = [];
@@ -868,18 +893,18 @@ function validateAutoMergeConfig(config) {
868
893
  if (!autoMerge.reReviewOnBranchChange) {
869
894
  issues.push("review.autoMerge.ciRepair.patch.enabled: needs review.autoMerge.reReviewOnBranchChange — without it a machine-authored repair could merge with nothing having reviewed its diff");
870
895
  }
871
- if (patch.sandboxImage && !/^[A-Za-z0-9]/.test(patch.sandboxImage)) {
872
- issues.push(`review.autoMerge.ciRepair.patch.sandboxImage: must start with a letter or digit (got "${patch.sandboxImage}") — a leading "-" is read by docker as a flag, not an image`);
873
- }
896
+ issues.push(...sandboxConfigIssues({
897
+ image: patch.sandboxImage,
898
+ timeoutMs: patch.sandboxTimeoutMs,
899
+ imagePath: "review.autoMerge.ciRepair.patch.sandboxImage",
900
+ timeoutPath: "review.autoMerge.ciRepair.patch.sandboxTimeoutMs"
901
+ }));
874
902
  if (!Number.isInteger(patch.maxTurns) || patch.maxTurns < 1) {
875
903
  issues.push(`review.autoMerge.ciRepair.patch.maxTurns: must be an integer >= 1 (got ${patch.maxTurns})`);
876
904
  }
877
905
  if (!(patch.maxBudgetUsd > 0)) {
878
906
  issues.push(`review.autoMerge.ciRepair.patch.maxBudgetUsd: must be greater than 0 (got ${patch.maxBudgetUsd})`);
879
907
  }
880
- if (!Number.isInteger(patch.sandboxTimeoutMs) || patch.sandboxTimeoutMs < 1) {
881
- issues.push(`review.autoMerge.ciRepair.patch.sandboxTimeoutMs: must be an integer >= 1 (got ${patch.sandboxTimeoutMs})`);
882
- }
883
908
  }
884
909
  const independent = autoMerge.independentReview;
885
910
  if (typeof independent?.enabled !== "boolean") {
@@ -2749,6 +2774,7 @@ var init_types2 = __esm(() => {
2749
2774
  devServerBasePort: 4200,
2750
2775
  timeout: 120000,
2751
2776
  testTimeout: 600000,
2777
+ sandboxImage: "",
2752
2778
  failColumn: "To Do"
2753
2779
  },
2754
2780
  review: {
@@ -5232,7 +5258,8 @@ import {
5232
5258
  reportFindings,
5233
5259
  runFormatFix,
5234
5260
  runVerification,
5235
- teardownWorktree
5261
+ teardownWorktree,
5262
+ verificationSandbox
5236
5263
  } from "@gethmy/harness";
5237
5264
  function formatTokenCount(tokens) {
5238
5265
  if (tokens >= 1e6)
@@ -5274,7 +5301,7 @@ async function runCompletion(client, card, branchName, worktreePath, config, wor
5274
5301
  revertWarnings: []
5275
5302
  };
5276
5303
  if (config.verification.enabled && config.verification.lint) {
5277
- runFormatFix(worktreePath, config.verification.timeout, workerId);
5304
+ await runFormatFix(worktreePath, config.verification.timeout, workerId, verificationSandbox(config));
5278
5305
  }
5279
5306
  commitUncommittedChanges(worktreePath, card);
5280
5307
  const hasCommits = checkHasCommits(worktreePath, config.worktree.baseBranch, runBaselineSha);
@@ -9673,6 +9700,7 @@ import {
9673
9700
  spawnInGroup as spawnInGroup4,
9674
9701
  teardownWorktree as teardownWorktree2,
9675
9702
  terminateGroup as terminateGroup3,
9703
+ verificationSandbox as verificationSandbox2,
9676
9704
  WorktreeBaseError
9677
9705
  } from "@gethmy/harness";
9678
9706
  function sdkDraftLogLine(ev) {
@@ -10997,7 +11025,8 @@ ${prompt}`;
10997
11025
  build: {
10998
11026
  worktreePath,
10999
11027
  buildTimeout: this.config.verification.timeout,
11000
- lintTimeout: this.config.verification.timeout
11028
+ lintTimeout: this.config.verification.timeout,
11029
+ sandbox: verificationSandbox2(this.config)
11001
11030
  },
11002
11031
  artifact: {
11003
11032
  worktreePath,
@@ -14580,6 +14609,7 @@ async function main() {
14580
14609
  validateBudgetConfig(config.agent);
14581
14610
  validateSweepConfig(config.agent);
14582
14611
  validateRankingConfig(config.agent);
14612
+ validateVerificationConfig(config.agent);
14583
14613
  } catch (err) {
14584
14614
  if (err instanceof ConfigValidationError) {
14585
14615
  banner.fail();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gethmy/agent",
3
- "version": "1.32.0",
3
+ "version": "1.33.0",
4
4
  "description": "Push-based agent daemon for Harmony — picks up assigned cards, builds them in isolated git worktrees, and opens PRs. It runs where you put it.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@anthropic-ai/claude-agent-sdk": "^0.3.178",
48
- "@gethmy/harness": "1.5.0",
48
+ "@gethmy/harness": "1.6.0",
49
49
  "@gethmy/mcp": "3.2.0",
50
50
  "@supabase/supabase-js": "2.95.3"
51
51
  },