hunter-harness 0.2.3 → 0.2.5

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/bin.js +68 -19
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/bin.ts
4
+ import { realpathSync } from "node:fs";
4
5
  import { pathToFileURL } from "node:url";
5
6
  import { createInterface } from "node:readline/promises";
6
7
  import { Command, CommanderError } from "commander";
@@ -3008,7 +3009,7 @@ function isBenignHighEntropyLookalike(value) {
3008
3009
  return false;
3009
3010
  }
3010
3011
  function highEntropyCandidates(content) {
3011
- const matches = content.matchAll(/\b[A-Za-z0-9_+.=\-]{24,}\b/g);
3012
+ const matches = content.matchAll(/\b[A-Za-z0-9_+.=-]{24,}\b/g);
3012
3013
  return [...matches].map((match) => ({
3013
3014
  value: match[0],
3014
3015
  offset: match.index,
@@ -5006,7 +5007,7 @@ async function runRecoveryMenuIfApplicable(options, dependencies) {
5006
5007
  }
5007
5008
 
5008
5009
  // src/workflow-data/resolve.ts
5009
- import { cp, mkdir as mkdir4, readdir as readdir7, readFile as readFile14, stat as stat5 } from "node:fs/promises";
5010
+ import { cp, mkdir as mkdir4, readdir as readdir7, readFile as readFile14, rm as rm8, stat as stat5 } from "node:fs/promises";
5010
5011
  import { dirname as dirname4, join as join16, relative as relative2 } from "node:path";
5011
5012
  import { fileURLToPath } from "node:url";
5012
5013
  var WorkflowDataResolutionError = class extends Error {
@@ -5103,6 +5104,48 @@ async function siblingWorkflowPackage(cwd) {
5103
5104
  }
5104
5105
  return null;
5105
5106
  }
5107
+ async function readCachedNpmPackageVersion(cacheRoot) {
5108
+ const manifestPath = join16(cacheRoot, "package.json");
5109
+ if (!await pathExists3(manifestPath)) return null;
5110
+ try {
5111
+ const pkg = JSON.parse(await readFile14(manifestPath, "utf8"));
5112
+ return typeof pkg.version === "string" && pkg.version.length > 0 ? pkg.version : null;
5113
+ } catch {
5114
+ return null;
5115
+ }
5116
+ }
5117
+ async function latestWorkflowCacheIsStale(cacheRoot, packageName, resolveManifest) {
5118
+ const cachedVersion = await readCachedNpmPackageVersion(cacheRoot);
5119
+ if (cachedVersion === null) return true;
5120
+ try {
5121
+ const manifest = resolveManifest ?? (async (spec) => {
5122
+ const pacote = await import("pacote");
5123
+ const result = await pacote.default.manifest(spec);
5124
+ return { version: String(result.version) };
5125
+ });
5126
+ const remote = await manifest(packageName);
5127
+ return remote.version !== cachedVersion;
5128
+ } catch {
5129
+ return false;
5130
+ }
5131
+ }
5132
+ async function materializeWorkflowPackageCache(cacheRoot, packageSpec, extract) {
5133
+ await mkdir4(cacheRoot, { recursive: true });
5134
+ const staging = join16(cacheRoot, ".extract");
5135
+ await rm8(staging, { recursive: true, force: true });
5136
+ await mkdir4(staging, { recursive: true });
5137
+ await extract(packageSpec, staging);
5138
+ const packageDir = await pathExists3(join16(staging, "harness", "manifests")) ? staging : join16(staging, "package");
5139
+ if (!await pathExists3(join16(packageDir, "harness", "manifests"))) {
5140
+ throw new WorkflowDataResolutionError(
5141
+ "\u5DE5\u4F5C\u6D41\u6570\u636E\u5305\u5185\u5BB9\u65E0\u6548\uFF1A\u7F3A\u5C11 harness/manifests",
5142
+ "WORKFLOW_DATA_INVALID",
5143
+ 7
5144
+ );
5145
+ }
5146
+ await cp(packageDir, cacheRoot, { recursive: true });
5147
+ await verifyWorkflowPackageIntegrity(cacheRoot);
5148
+ }
5106
5149
  async function resolveWorkflowResourcesRoot(options, argv = []) {
5107
5150
  if (options.override !== void 0) return options.override;
5108
5151
  const envRoot = options.env.HUNTER_HARNESS_RESOURCES_ROOT?.trim();
@@ -5124,28 +5167,25 @@ async function resolveWorkflowResourcesRoot(options, argv = []) {
5124
5167
  const cacheKey = packageSpec.replace("/", "+");
5125
5168
  const cacheRoot = join16(options.cwd, ".harness", "cache", "workflow-packages", cacheKey);
5126
5169
  if (await pathExists3(join16(cacheRoot, "harness", "manifests"))) {
5127
- await verifyWorkflowPackageIntegrity(cacheRoot);
5128
- return cacheRoot;
5170
+ if (version === "latest") {
5171
+ const stale = await latestWorkflowCacheIsStale(cacheRoot, packageName, options.pacoteManifest);
5172
+ if (stale) {
5173
+ await rm8(cacheRoot, { recursive: true, force: true });
5174
+ } else {
5175
+ await verifyWorkflowPackageIntegrity(cacheRoot);
5176
+ return cacheRoot;
5177
+ }
5178
+ } else {
5179
+ await verifyWorkflowPackageIntegrity(cacheRoot);
5180
+ return cacheRoot;
5181
+ }
5129
5182
  }
5130
5183
  try {
5131
- await mkdir4(cacheRoot, { recursive: true });
5132
5184
  const extract = options.pacoteExtract ?? (async (spec, destination) => {
5133
5185
  const pacote = await import("pacote");
5134
5186
  await pacote.default.extract(spec, destination);
5135
5187
  });
5136
- const staging = join16(cacheRoot, ".extract");
5137
- await mkdir4(staging, { recursive: true });
5138
- await extract(packageSpec, staging);
5139
- const packageDir = await pathExists3(join16(staging, "harness", "manifests")) ? staging : join16(staging, "package");
5140
- if (!await pathExists3(join16(packageDir, "harness", "manifests"))) {
5141
- throw new WorkflowDataResolutionError(
5142
- "\u5DE5\u4F5C\u6D41\u6570\u636E\u5305\u5185\u5BB9\u65E0\u6548\uFF1A\u7F3A\u5C11 harness/manifests",
5143
- "WORKFLOW_DATA_INVALID",
5144
- 7
5145
- );
5146
- }
5147
- await cp(packageDir, cacheRoot, { recursive: true });
5148
- await verifyWorkflowPackageIntegrity(cacheRoot);
5188
+ await materializeWorkflowPackageCache(cacheRoot, packageSpec, extract);
5149
5189
  return cacheRoot;
5150
5190
  } catch (error) {
5151
5191
  if (error instanceof WorkflowDataResolutionError) throw error;
@@ -5262,9 +5302,18 @@ async function runCli(argv, overrides = {}) {
5262
5302
  throw error;
5263
5303
  }
5264
5304
  }
5265
- if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL(process.argv[1]).href) {
5305
+ function isDirectCliEntrypoint(entry = process.argv[1], metaUrl = import.meta.url) {
5306
+ if (entry === void 0) return false;
5307
+ try {
5308
+ return metaUrl === pathToFileURL(realpathSync(entry)).href;
5309
+ } catch {
5310
+ return metaUrl === pathToFileURL(entry).href;
5311
+ }
5312
+ }
5313
+ if (isDirectCliEntrypoint()) {
5266
5314
  process.exitCode = await runCli(process.argv.slice(2));
5267
5315
  }
5268
5316
  export {
5317
+ isDirectCliEntrypoint,
5269
5318
  runCli
5270
5319
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hunter-harness",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Local-first, server-governed agent harness",
5
5
  "license": "MIT",
6
6
  "type": "module",