hunter-harness 0.2.7 → 0.2.9

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 +65 -9
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -4,6 +4,7 @@
4
4
  import { realpathSync } from "node:fs";
5
5
  import { pathToFileURL } from "node:url";
6
6
  import { createInterface } from "node:readline/promises";
7
+ import { Writable } from "node:stream";
7
8
  import { Command, CommanderError } from "commander";
8
9
 
9
10
  // ../contracts/dist/ai-config.js
@@ -882,6 +883,8 @@ var semanticDocumentKindSchema = z12.enum([
882
883
  var semanticEdgeKindSchema = z12.enum([
883
884
  "references_path",
884
885
  "supersedes",
886
+ "conflicts_with",
887
+ "shared_scope",
885
888
  "related_archive",
886
889
  "tag_cooccurrence"
887
890
  ]);
@@ -3379,6 +3382,17 @@ async function ensureCredentialsGitignore(projectRoot) {
3379
3382
  }
3380
3383
  }
3381
3384
  const existing = new Set(content.split("\n").map((line) => line.trim()));
3385
+ const harnessDirectoryIgnored = [
3386
+ ".harness",
3387
+ ".harness/",
3388
+ "/.harness",
3389
+ "/.harness/",
3390
+ ".harness/**",
3391
+ "/.harness/**"
3392
+ ].some((line) => existing.has(line));
3393
+ if (harnessDirectoryIgnored) {
3394
+ return;
3395
+ }
3382
3396
  const missing = CREDENTIALS_GITIGNORE_LINES.filter((line) => !existing.has(line));
3383
3397
  if (missing.length === 0) {
3384
3398
  return;
@@ -3392,11 +3406,21 @@ function resolvePushAuth(input) {
3392
3406
  const localToken = input.local?.token?.trim();
3393
3407
  const token = envToken && envToken.length > 0 ? envToken : localToken && localToken.length > 0 ? localToken : void 0;
3394
3408
  const serverUrl = input.serverUrlFlag ?? input.local?.server_url ?? input.projectUrl ?? void 0;
3409
+ const missing = [];
3395
3410
  if (serverUrl === void 0 || serverUrl === null || serverUrl.trim() === "") {
3396
- return { code: "SERVER_URL_REQUIRED" };
3411
+ missing.push("url");
3397
3412
  }
3398
3413
  if (token === void 0) {
3399
- return { code: "TOKEN_INVALID" };
3414
+ missing.push("token");
3415
+ }
3416
+ if (missing.length > 0) {
3417
+ return {
3418
+ code: missing.includes("url") ? "SERVER_URL_REQUIRED" : "TOKEN_INVALID",
3419
+ missing
3420
+ };
3421
+ }
3422
+ if (serverUrl === void 0 || token === void 0) {
3423
+ throw new Error("push auth resolution invariant failed");
3400
3424
  }
3401
3425
  return { serverUrl, token };
3402
3426
  }
@@ -3734,9 +3758,6 @@ async function pushProject(options) {
3734
3758
  if (options.dryRun) {
3735
3759
  return { preview, proposalId: null, projectId: project.project.project_id };
3736
3760
  }
3737
- if (options.confirmProposal !== void 0 && !await options.confirmProposal(preview)) {
3738
- return { preview, proposalId: null, projectId: project.project.project_id, cancelled: true };
3739
- }
3740
3761
  const localCredentials = await readLocalCredentials(root);
3741
3762
  const auth = resolvePushAuth({
3742
3763
  ...options.serverUrl === void 0 ? {} : { serverUrlFlag: options.serverUrl },
@@ -3748,10 +3769,10 @@ async function pushProject(options) {
3748
3769
  });
3749
3770
  if ("code" in auth) {
3750
3771
  if (auth.code === "SERVER_URL_REQUIRED") {
3751
- throw new PushWorkflowError("server_url is required; use --server-url, project.yaml server.url, or " + CREDENTIALS_HINT, 3, "SERVER_URL_REQUIRED");
3772
+ throw new PushWorkflowError("server_url is required; use --server-url, project.yaml server.url, or " + CREDENTIALS_HINT, 3, "SERVER_URL_REQUIRED", { missing_credentials: auth.missing });
3752
3773
  }
3753
3774
  const tokenEnv2 = options.tokenEnv ?? project.server.token_env;
3754
- throw new PushWorkflowError("API token is unset; set " + tokenEnv2 + " or " + CREDENTIALS_HINT, 8, "TOKEN_INVALID");
3775
+ throw new PushWorkflowError("API token is unset; set " + tokenEnv2 + " or " + CREDENTIALS_HINT, 8, "TOKEN_INVALID", { missing_credentials: auth.missing });
3755
3776
  }
3756
3777
  const serverUrl = auth.serverUrl;
3757
3778
  const token = auth.token;
@@ -3768,6 +3789,9 @@ async function pushProject(options) {
3768
3789
  if (parsedServerUrl.protocol !== "https:") {
3769
3790
  throw new PushWorkflowError("server_url must use HTTPS", 3, "SERVER_URL_INVALID");
3770
3791
  }
3792
+ if (options.confirmProposal !== void 0 && !await options.confirmProposal(preview)) {
3793
+ return { preview, proposalId: null, projectId: project.project.project_id, cancelled: true };
3794
+ }
3771
3795
  const workflowPath = join10(root, ".harness", "state", "local", "push-workflow.json");
3772
3796
  const priorWorkflow = await readOptionalJson(workflowPath);
3773
3797
  const provisionalRequestId = priorWorkflow?.local_project_key === project.project.local_project_key ? priorWorkflow.request_id : uuidV7();
@@ -5089,7 +5113,9 @@ function errorPayload(error) {
5089
5113
  }
5090
5114
  async function promptForCredentials(dependencies, missing) {
5091
5115
  const serverUrl = missing === "token" ? void 0 : (await dependencies.prompt("\u670D\u52A1\u7AEF URL (https://...): ")).trim();
5092
- const token = missing === "url" ? void 0 : (await dependencies.prompt("API Token: ")).trim();
5116
+ const token = missing === "url" ? void 0 : (await (dependencies.promptSecret ?? dependencies.prompt)(
5117
+ "API Token\uFF08\u8F93\u5165\u5C06\u9690\u85CF\uFF09: "
5118
+ )).trim();
5093
5119
  if ((missing === "url" || missing === "both") && (serverUrl === void 0 || serverUrl === "")) {
5094
5120
  return null;
5095
5121
  }
@@ -5198,7 +5224,8 @@ async function runPush(options, dependencies) {
5198
5224
  return 0;
5199
5225
  } catch (error) {
5200
5226
  if (attempt === 0 && options.nonInteractive !== true && options.dryRun !== true && error instanceof PushWorkflowError && (error.code === "SERVER_URL_REQUIRED" || error.code === "TOKEN_INVALID")) {
5201
- const missing = error.code === "SERVER_URL_REQUIRED" ? "url" : error.code === "TOKEN_INVALID" ? "token" : "both";
5227
+ const missingCredentials = error.details?.missing_credentials;
5228
+ const missing = missingCredentials?.includes("url") === true && missingCredentials.includes("token") ? "both" : missingCredentials?.includes("url") === true || error.code === "SERVER_URL_REQUIRED" ? "url" : "token";
5202
5229
  dependencies.stderr(
5203
5230
  error.message + "\n\u53EF\u5728\u4E0B\u65B9\u5F55\u5165\u5E76\u5199\u5165 .harness/credentials.local.yaml\u3002\n"
5204
5231
  );
@@ -5668,6 +5695,33 @@ async function readWorkflowFamilyManifest(resourcesRoot) {
5668
5695
  }
5669
5696
 
5670
5697
  // src/bin.ts
5698
+ async function promptSecret(question, input = process.stdin, output = process.stdout) {
5699
+ if (input.isTTY !== true || output.isTTY !== true) {
5700
+ const terminal2 = createInterface({ input, output });
5701
+ try {
5702
+ return await terminal2.question(question);
5703
+ } finally {
5704
+ terminal2.close();
5705
+ }
5706
+ }
5707
+ output.write(question);
5708
+ const mutedOutput = new Writable({
5709
+ write(_chunk, _encoding, callback) {
5710
+ callback();
5711
+ }
5712
+ });
5713
+ const terminal = createInterface({
5714
+ input,
5715
+ output: mutedOutput,
5716
+ terminal: true
5717
+ });
5718
+ try {
5719
+ return await terminal.question("");
5720
+ } finally {
5721
+ terminal.close();
5722
+ output.write("\n");
5723
+ }
5724
+ }
5671
5725
  function defaultDependencies(overrides) {
5672
5726
  return {
5673
5727
  cwd: overrides.cwd ?? process.cwd(),
@@ -5682,6 +5736,7 @@ function defaultDependencies(overrides) {
5682
5736
  terminal.close();
5683
5737
  }
5684
5738
  }),
5739
+ promptSecret: overrides.promptSecret ?? overrides.prompt ?? promptSecret,
5685
5740
  fetch: overrides.fetch ?? globalThis.fetch,
5686
5741
  env: overrides.env ?? process.env
5687
5742
  };
@@ -5765,5 +5820,6 @@ if (isDirectCliEntrypoint()) {
5765
5820
  }
5766
5821
  export {
5767
5822
  isDirectCliEntrypoint,
5823
+ promptSecret,
5768
5824
  runCli
5769
5825
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hunter-harness",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Local-first, server-governed agent harness",
5
5
  "license": "MIT",
6
6
  "type": "module",