@indigoai-us/hq-cli 5.326.0 → 5.328.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/assets/scaffold/core/scripts/hq-dm-bind.sh +1 -1
  3. package/assets/scaffold/core/scripts/hq-job-run.sh +8 -8
  4. package/assets/scaffold/core/scripts/ontology-audience-grant.sh +1 -1
  5. package/assets/scaffold/core/scripts/ontology-candidate.sh +1 -1
  6. package/assets/scaffold/core/scripts/resolve-company.sh +1 -1
  7. package/dist/command-catalog.generated.d.ts +9 -0
  8. package/dist/command-catalog.generated.js +10 -0
  9. package/dist/commands/auth.js +3 -1
  10. package/dist/commands/core-detect-stale-review-base-fast.d.ts +2 -0
  11. package/dist/commands/core-detect-stale-review-base-fast.js +23 -0
  12. package/dist/commands/core-register-project-native.js +1 -1
  13. package/dist/commands/core-repo-run-registry-fast.d.ts +2 -0
  14. package/dist/commands/core-repo-run-registry-fast.js +35 -0
  15. package/dist/commands/core-rrr-worktree-scope-fix-fast-flag.d.ts +7 -0
  16. package/dist/commands/core-rrr-worktree-scope-fix-fast-flag.js +25 -0
  17. package/dist/commands/core-session-journal-native.js +1 -1
  18. package/dist/commands/core-share-suggestion-state-fast.d.ts +2 -0
  19. package/dist/commands/core-share-suggestion-state-fast.js +25 -0
  20. package/dist/commands/logout.js +2 -0
  21. package/dist/commands/mcp-serve.js +1 -1
  22. package/dist/commands/mcp-status.js +7 -0
  23. package/dist/fast-core.js +3 -6
  24. package/dist/fast-scaffold.js +5 -1
  25. package/dist/lib/daemon/mcp-endpoint.d.ts +8 -0
  26. package/dist/lib/daemon/mcp-endpoint.js +30 -0
  27. package/dist/lib/daemon/mcp-oauth.d.ts +24 -0
  28. package/dist/lib/daemon/mcp-oauth.js +298 -0
  29. package/dist/lib/daemon/ops/mcp.d.ts +0 -1
  30. package/dist/lib/daemon/ops/mcp.js +31 -31
  31. package/dist/lib/process-flag-company-context-fast.d.ts +4 -0
  32. package/dist/lib/process-flag-company-context-fast.js +20 -0
  33. package/dist/lib/process-flag-company-context-light.d.ts +9 -0
  34. package/dist/lib/process-flag-company-context-light.js +81 -0
  35. package/dist/lib/process-flag-company-context.d.ts +2 -4
  36. package/dist/lib/process-flag-company-context.js +2 -46
  37. package/dist/node-network-compat-fast.js +4 -0
  38. package/dist/utils/hq-roots-core.d.ts +130 -0
  39. package/dist/utils/hq-roots-core.js +354 -0
  40. package/dist/utils/hq-roots.d.ts +2 -129
  41. package/dist/utils/hq-roots.js +2 -353
  42. package/dist/utils/package-root-diagnostics.d.ts +5 -36
  43. package/dist/utils/package-root-diagnostics.js +4 -83
  44. package/dist/utils/package-root-resolution-error.d.ts +32 -0
  45. package/dist/utils/package-root-resolution-error.js +79 -0
  46. package/dist/utils/vault-api.js +16 -1
  47. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.328.0] — 2026-10-02
6
+ - Keep successful JSON responses readable if vault API plan-limit inspection cannot reconstruct its buffered response.
7
+ - Fixed bundled scaffold checks that could misclassify matching records when `grep -q` closed a pipe under `pipefail`.
8
+ - Keep `hq mcp serve` initialization lightweight by avoiding the full flag registry and network-family compatibility setup.
9
+
10
+ ## [5.327.0] — 2026-10-02
11
+ - Reduce hook-time startup imports for repo-run-registry and isolate hook-helper handlers from sibling modules.
12
+ - Keep package-root Sentry diagnostics off the fast-route import path unless root diagnostics are needed.
13
+ - `hq mcp login` adds browser-based OAuth sign-in for hosted MCP.
14
+
5
15
  ## [5.326.0] — 2026-10-02
6
16
  - Company-scoped daemon tools now reject an explicit company that conflicts with the active session or repository binding.
7
17
  - Added a flag-gated `hq mcp serve` command and global install hook for the Anywhere runtime.
@@ -329,7 +329,7 @@ mention_line() {
329
329
  cmd_bind() {
330
330
  local ch="${1:-}"; [ -n "$ch" ] || die "bind needs a channel name (see: hq channels)"
331
331
  ch="${ch#\#}"
332
- hq channels 2>/dev/null | grep -q -- "hq dm $ch " || die "no channel named '$ch' (see: hq channels)"
332
+ hq channels 2>/dev/null | grep -- "hq dm $ch " >/dev/null || die "no channel named '$ch' (see: hq channels)"
333
333
  bash "$SESSION_SH" set dm_channel "$ch" >/dev/null
334
334
  local sk; sk="$(latest_sk "$ch")"
335
335
  printf '%s\n' "$sk" > "$(cursor_file)"
@@ -323,24 +323,24 @@ classify_failure() {
323
323
  local lower
324
324
  lower="$(printf '%s' "$tail_txt" | tr '[:upper:]' '[:lower:]')"
325
325
 
326
- if printf '%s' "$lower" | grep -Eq \
327
- 'not logged in|please log in|authentication (failed|required)|unauthorized|401|invalid.*(token|credential)|credentials? (missing|expired|invalid)|device.?code|login required'; then
326
+ if printf '%s' "$lower" | grep -E \
327
+ 'not logged in|please log in|authentication (failed|required)|unauthorized|401|invalid.*(token|credential)|credentials? (missing|expired|invalid)|device.?code|login required' >/dev/null; then
328
328
  printf 'auth'
329
329
  return
330
330
  fi
331
- if printf '%s' "$lower" | grep -Eq \
332
- 'secret.*(not found|missing|denied|not visible|not shared)|hq secrets.*(fail|error|denied)|missing vault|access denied.*secret'; then
331
+ if printf '%s' "$lower" | grep -E \
332
+ 'secret.*(not found|missing|denied|not visible|not shared)|hq secrets.*(fail|error|denied)|missing vault|access denied.*secret' >/dev/null; then
333
333
  printf 'secrets'
334
334
  return
335
335
  fi
336
336
  # Avoid matching job metadata like timeout_seconds=N in the log header.
337
- if printf '%s' "$lower" | grep -Eq \
338
- '(^|[^_])timed out|command timed out|deadline exceeded|killed by timeout|exit[=:][[:space:]]*124\b'; then
337
+ if printf '%s' "$lower" | grep -E \
338
+ '(^|[^_])timed out|command timed out|deadline exceeded|killed by timeout|exit[=:][[:space:]]*124\b' >/dev/null; then
339
339
  printf 'timeout'
340
340
  return
341
341
  fi
342
- if printf '%s' "$lower" | grep -Eq \
343
- 'connection (refused|reset|timed out)|network is unreachable|temporary failure|econnreset|enotfound|no space left|i/o error|transport error|dns (fail|error)|http[/ ]*(502|503|504)|statusingesterror|api unreachable'; then
342
+ if printf '%s' "$lower" | grep -E \
343
+ 'connection (refused|reset|timed out)|network is unreachable|temporary failure|econnreset|enotfound|no space left|i/o error|transport error|dns (fail|error)|http[/ ]*(502|503|504)|statusingesterror|api unreachable' >/dev/null; then
344
344
  printf 'infra'
345
345
  return
346
346
  fi
@@ -67,7 +67,7 @@ for aud in "$C"/signals/@*/_audience.yaml; do
67
67
  # attendees), so they are already company identities; emails must be members.
68
68
  case "$who" in
69
69
  prs_*|agt_*) ;;
70
- *) if ! printf '%s\n' "$members" | grep -qxF "$who"; then echo "skip $who (not a member of $co)" >&2; skipped=$((skipped+1)); continue; fi ;;
70
+ *) if ! grep -qxF "$who" <<<"$members"; then echo "skip $who (not a member of $co)" >&2; skipped=$((skipped+1)); continue; fi ;;
71
71
  esac
72
72
  for p in $prefixes; do grant "$p" "$who"; done
73
73
  done
@@ -79,7 +79,7 @@ id="$(printf '%s\n%s\n%s\n%s' "$kind" "$type" "$key" "$norm_body" | sha)"
79
79
 
80
80
  dir="$root/companies/$co/$store/_candidates/$(date -u +%Y-%m-%d)"
81
81
  # Idempotent across days: the same candidate already written (pending or done) is a no-op.
82
- if find "$root/companies/$co/$store/_candidates" -name "$id.md" 2>/dev/null | grep -q .; then
82
+ if [ -n "$(find "$root/companies/$co/$store/_candidates" -name "$id.md" -print -quit 2>/dev/null)" ]; then
83
83
  echo "exists $id"; exit 0
84
84
  fi
85
85
  mkdir -p "$dir"
@@ -65,7 +65,7 @@ SLUGS="$(
65
65
  [ -n "$SLUGS" ] || emit "" "none"
66
66
 
67
67
  is_known_slug() {
68
- printf '%s\n' "$SLUGS" | grep -Fxq "$1"
68
+ printf '%s\n' "$SLUGS" | grep -Fx -- "$1" >/dev/null
69
69
  }
70
70
 
71
71
  prompt_slug() {
@@ -3728,6 +3728,15 @@ export declare const COMMAND_CATALOG: readonly [{
3728
3728
  readonly arguments: readonly [];
3729
3729
  readonly options: readonly [];
3730
3730
  readonly subcommands: readonly [];
3731
+ }, {
3732
+ readonly name: "login";
3733
+ readonly description: "Sign in to the hosted HQ MCP connector with browser OAuth";
3734
+ readonly aliases: readonly [];
3735
+ readonly hidden: false;
3736
+ readonly usage: "[options]";
3737
+ readonly arguments: readonly [];
3738
+ readonly options: readonly [];
3739
+ readonly subcommands: readonly [];
3731
3740
  }, {
3732
3741
  readonly name: "status";
3733
3742
  readonly description: "Show installed MCP packs/servers and their health in BOTH Claude and Codex (PARTIAL/DRIFT flagged; secrets redacted)";
@@ -4811,6 +4811,16 @@ export const COMMAND_CATALOG = [
4811
4811
  "options": [],
4812
4812
  "subcommands": []
4813
4813
  },
4814
+ {
4815
+ "name": "login",
4816
+ "description": "Sign in to the hosted HQ MCP connector with browser OAuth",
4817
+ "aliases": [],
4818
+ "hidden": false,
4819
+ "usage": "[options]",
4820
+ "arguments": [],
4821
+ "options": [],
4822
+ "subcommands": []
4823
+ },
4814
4824
  {
4815
4825
  "name": "status",
4816
4826
  "description": "Show installed MCP packs/servers and their health in BOTH Claude and Codex (PARTIAL/DRIFT flagged; secrets redacted)",
@@ -264,7 +264,9 @@ export function registerAuthCommands(program) {
264
264
  authCmd
265
265
  .command("logout")
266
266
  .description("Clear the cached HQ Cognito session")
267
- .action(() => {
267
+ .action(async () => {
268
+ const { clearMcpOAuthCaches } = await import("../lib/daemon/mcp-oauth.js");
269
+ clearMcpOAuthCaches();
268
270
  const existing = loadCachedTokens();
269
271
  if (!existing) {
270
272
  console.log(chalk.yellow("No cached HQ session"));
@@ -0,0 +1,2 @@
1
+ export declare function runDetectStaleReviewBaseFast(args: readonly string[], _stdin: string, _cwd: string, hqRoot: string | undefined): Promise<number>;
2
+ //# sourceMappingURL=core-detect-stale-review-base-fast.d.ts.map
@@ -0,0 +1,23 @@
1
+ /** Fast-route adapter isolated from the other hook-helper command modules. */
2
+ import { resolveBundledAsset } from "../utils/hq-roots-core.js";
3
+ import { runDetectStaleReviewBase, DETECT_STALE_REVIEW_BASE_ASSET } from "./core-detect-stale-review-base-native.js";
4
+ function writeResult(result) {
5
+ if (result.stdout)
6
+ process.stdout.write(result.stdout);
7
+ if (result.stderr)
8
+ process.stderr.write(result.stderr);
9
+ return result.code;
10
+ }
11
+ export async function runDetectStaleReviewBaseFast(args, _stdin, _cwd, hqRoot) {
12
+ let root = hqRoot;
13
+ if (!root) {
14
+ const { resolveLiveRoot } = await import("../utils/hq-roots-core.js");
15
+ root = resolveLiveRoot();
16
+ }
17
+ return writeResult(runDetectStaleReviewBase(args, {
18
+ cwd: root,
19
+ env: { ...process.env, HQ_ROOT: root },
20
+ scriptPath: resolveBundledAsset(DETECT_STALE_REVIEW_BASE_ASSET),
21
+ }));
22
+ }
23
+ //# sourceMappingURL=core-detect-stale-review-base-fast.js.map
@@ -4,7 +4,7 @@ import * as os from "node:os";
4
4
  import * as path from "node:path";
5
5
  import { spawnSync } from "node:child_process";
6
6
  import { serializeJqJson } from "../lib/core-utils/jq-json-serializer.js";
7
- import { resolveBundledAsset } from "../utils/hq-roots.js";
7
+ import { resolveBundledAsset } from "../utils/hq-roots-core.js";
8
8
  export const REGISTER_PROJECT_ASSET = "core/scripts/register-project.sh";
9
9
  const USAGE = "usage: register-project.sh <company> <project> | --audit <company> | --backfill <company> --only-active [--yes] | --retry-pending <company>";
10
10
  const MIN_HQ_CLI = "5.139.0";
@@ -0,0 +1,2 @@
1
+ export declare function runRepoRunRegistryFast(args: readonly string[], _stdin: string, _cwd: string, hqRoot: string | undefined, _commandName: string, _hqRootArg?: string, worktreeScopeFixEnabled?: boolean): Promise<number>;
2
+ //# sourceMappingURL=core-repo-run-registry-fast.d.ts.map
@@ -0,0 +1,35 @@
1
+ /** Fast-route adapter isolated from the other hook-helper command modules. */
2
+ import { runBundledScript } from "../utils/run-bundled-script.js";
3
+ import { runRepoRunRegistry, REPO_RUN_REGISTRY_ASSET } from "./core-repo-run-registry-native.js";
4
+ function writeResult(result) {
5
+ if (result.stdout)
6
+ process.stdout.write(result.stdout);
7
+ if (result.stderr)
8
+ process.stderr.write(result.stderr);
9
+ return result.code;
10
+ }
11
+ async function liveRoot(hqRoot) {
12
+ if (hqRoot)
13
+ return hqRoot;
14
+ const { resolveLiveRoot } = await import("../utils/hq-roots-core.js");
15
+ return resolveLiveRoot();
16
+ }
17
+ export async function runRepoRunRegistryFast(args, _stdin, _cwd, hqRoot, _commandName, _hqRootArg, worktreeScopeFixEnabled = false) {
18
+ const root = await liveRoot(hqRoot);
19
+ return writeResult(runRepoRunRegistry(args, {
20
+ root,
21
+ cwd: root,
22
+ env: process.env,
23
+ worktreeScopeFixEnabled,
24
+ runShellFallback: (fallbackArgs) => {
25
+ const { code } = runBundledScript({
26
+ asset: REPO_RUN_REGISTRY_ASSET,
27
+ args: [...fallbackArgs],
28
+ cwd: root,
29
+ hqRoot: root,
30
+ });
31
+ return { code, stdout: "", stderr: "" };
32
+ },
33
+ }));
34
+ }
35
+ //# sourceMappingURL=core-repo-run-registry-fast.js.map
@@ -0,0 +1,7 @@
1
+ /** Light company-scoped reader for the repo-run-registry worktree-scope flag. */
2
+ /**
3
+ * Resolve the same default-off, company-scoped flag without loading the full
4
+ * flag registry and work-context graph on the ordinary UID-scoped path.
5
+ */
6
+ export declare function coreRrrWorktreeScopeFixFastFlagEnabled(env?: NodeJS.ProcessEnv): Promise<boolean>;
7
+ //# sourceMappingURL=core-rrr-worktree-scope-fix-fast-flag.d.ts.map
@@ -0,0 +1,25 @@
1
+ /** Light company-scoped reader for the repo-run-registry worktree-scope flag. */
2
+ import { readLocalOverride } from "@indigoai-us/hq-flags-client";
3
+ import { readFlagSnapshotFile } from "../lib/flag-snapshot-file.js";
4
+ import { resolveFastProcessFlagCompanyContext } from "../lib/process-flag-company-context-fast.js";
5
+ /**
6
+ * Resolve the same default-off, company-scoped flag without loading the full
7
+ * flag registry and work-context graph on the ordinary UID-scoped path.
8
+ */
9
+ export async function coreRrrWorktreeScopeFixFastFlagEnabled(env = process.env) {
10
+ const flagKey = "core-rrr-worktree-scope-fix";
11
+ const override = readLocalOverride(flagKey, env);
12
+ if (override !== null)
13
+ return override;
14
+ try {
15
+ const context = await resolveFastProcessFlagCompanyContext(env);
16
+ if (!context.companyUid)
17
+ return false;
18
+ return readFlagSnapshotFile(context.companyUid, { env })?.flags[flagKey] === true;
19
+ }
20
+ catch {
21
+ // Keep the fast gate's established fail-closed default for unavailable scope or cache data.
22
+ return false;
23
+ }
24
+ }
25
+ //# sourceMappingURL=core-rrr-worktree-scope-fix-fast-flag.js.map
@@ -1,7 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { resolveSessionHelperRuntime } from "./core-session-helper-runtime.js";
4
- import { resolveBundledAsset } from "../utils/hq-roots.js";
4
+ import { resolveBundledAsset } from "../utils/hq-roots-core.js";
5
5
  const USAGE = `session-journal.sh: usage:
6
6
  session-journal.sh write "<title>" [--files f1,f2,...] [--body-file PATH] [--session KEY]
7
7
  session-journal.sh list [--date YYYY-MM-DD]
@@ -0,0 +1,2 @@
1
+ export declare function runShareSuggestionStateFast(args: readonly string[], stdin: string, _cwd: string, hqRoot: string | undefined): Promise<number>;
2
+ //# sourceMappingURL=core-share-suggestion-state-fast.d.ts.map
@@ -0,0 +1,25 @@
1
+ /** Fast-route adapter isolated from the other hook-helper command modules. */
2
+ import { runShareSuggestionState } from "./core-share-suggestion-state-native.js";
3
+ function writeResult(result) {
4
+ if (result.stdout)
5
+ process.stdout.write(result.stdout);
6
+ if (result.stderr)
7
+ process.stderr.write(result.stderr);
8
+ return result.code;
9
+ }
10
+ async function liveRoot(hqRoot) {
11
+ if (hqRoot)
12
+ return hqRoot;
13
+ const { resolveLiveRoot } = await import("../utils/hq-roots-core.js");
14
+ return resolveLiveRoot();
15
+ }
16
+ export async function runShareSuggestionStateFast(args, stdin, _cwd, hqRoot) {
17
+ const root = await liveRoot(hqRoot);
18
+ return writeResult(runShareSuggestionState(args, stdin, {
19
+ root,
20
+ cwd: root,
21
+ env: process.env,
22
+ stdinIsTty: process.stdin.isTTY,
23
+ }));
24
+ }
25
+ //# sourceMappingURL=core-share-suggestion-state-fast.js.map
@@ -9,6 +9,8 @@ export function registerLogoutCommand(program) {
9
9
  .description('Log out and clear cached credentials')
10
10
  .action(async () => {
11
11
  try {
12
+ const { clearMcpOAuthCaches } = await import('../lib/daemon/mcp-oauth.js');
13
+ clearMcpOAuthCaches();
12
14
  const existing = loadCachedTokens();
13
15
  if (!existing) {
14
16
  console.log(chalk.yellow('No cached HQ session'));
@@ -15,7 +15,7 @@ import * as fs from "node:fs";
15
15
  import * as os from "node:os";
16
16
  import * as path from "node:path";
17
17
  import { CLI_VERSION } from "../cli-version.js";
18
- import { HQ_ANYWHERE_RUNTIME_FLAG } from "./anywhere-runtime-flag.js";
18
+ import { HQ_ANYWHERE_RUNTIME_FLAG } from "../lib/anywhere-runtime-flag-key.js";
19
19
  import { anywhereRuntimeEnabledFromSnapshot } from "../lib/anywhere-runtime-fast-flag.js";
20
20
  import { createLineSplitter, HqdClientError, hqdRequest, hqdSocketPath } from "../lib/daemon/protocol.js";
21
21
  export const MCP_PROTOCOL_VERSIONS = ["2025-06-18", "2025-03-26", "2024-11-05"];
@@ -396,6 +396,13 @@ export function registerMcpCommand(program) {
396
396
  const { runMcpServe } = await import('./mcp-serve.js');
397
397
  await runMcpServe();
398
398
  });
399
+ mcp
400
+ .command('login')
401
+ .description('Sign in to the hosted HQ MCP connector with browser OAuth')
402
+ .action(async () => {
403
+ const { loginHostedMcp } = await import('../lib/daemon/mcp-oauth.js');
404
+ await loginHostedMcp();
405
+ });
399
406
  mcp
400
407
  .command('status')
401
408
  .alias('list')
package/dist/fast-core.js CHANGED
@@ -39,11 +39,8 @@ export async function runFastCore(argv, parsed = parseFastCore(argv)) {
39
39
  const useShell = entry.kind === "native" && Boolean(entry.familyFlagKey) && !familyEnabled;
40
40
  let worktreeScopeFixEnabled;
41
41
  if (entry.name === "repo-run-registry") {
42
- const [{ CORE_RRR_WORKTREE_SCOPE_FIX_FLAG }, { fastFlagEnabled }] = await Promise.all([
43
- import("./commands/core-rrr-worktree-scope-fix-flag.js"),
44
- import("./native-fast-route.js"),
45
- ]);
46
- worktreeScopeFixEnabled = await fastFlagEnabled(CORE_RRR_WORKTREE_SCOPE_FIX_FLAG, process.env, { numericEnvironmentOverride: false });
42
+ const { coreRrrWorktreeScopeFixFastFlagEnabled } = await import("./commands/core-rrr-worktree-scope-fix-fast-flag.js");
43
+ worktreeScopeFixEnabled = await coreRrrWorktreeScopeFixFastFlagEnabled(process.env);
47
44
  }
48
45
  const shouldInjectRoot = useShell
49
46
  ? entry.shellHqRoot === "live" || (entry.shellHqRoot === "reconcile-default" &&
@@ -57,7 +54,7 @@ export async function runFastCore(argv, parsed = parseFastCore(argv)) {
57
54
  // its expected-user-error formatting remains authoritative.
58
55
  let hqRoot;
59
56
  if (shouldInjectRoot) {
60
- const { resolveLiveRoot } = await import("./utils/hq-roots.js");
57
+ const { resolveLiveRoot } = await import("./utils/hq-roots-core.js");
61
58
  try {
62
59
  hqRoot = resolveLiveRoot(parsed.hqRootArg ? { hqRoot: parsed.hqRootArg } : {});
63
60
  }
@@ -175,7 +175,11 @@ export const FAST_SCAFFOLD_SCRIPTS = [
175
175
  ...["share-suggestion-state", "repo-run-registry", "detect-stale-review-base"].map((name) => ({
176
176
  name,
177
177
  kind: "native",
178
- modulePath: "./commands/core-hook-state-helpers-native.js",
178
+ modulePath: name === "share-suggestion-state"
179
+ ? "./commands/core-share-suggestion-state-fast.js"
180
+ : name === "repo-run-registry"
181
+ ? "./commands/core-repo-run-registry-fast.js"
182
+ : "./commands/core-detect-stale-review-base-fast.js",
179
183
  exportName: name === "share-suggestion-state"
180
184
  ? "runShareSuggestionStateFast"
181
185
  : name === "repo-run-registry"
@@ -0,0 +1,8 @@
1
+ export declare class McpEndpointError extends Error {
2
+ readonly code = "hq_mcp_config_error";
3
+ }
4
+ /** Derive the hosted MCP sibling from the same hq-pro URL used by hq-cli. */
5
+ export declare function resolveHqMcpEndpoint(env?: NodeJS.ProcessEnv): URL;
6
+ /** OAuth endpoints share the origin with the Streamable HTTP MCP endpoint. */
7
+ export declare function resolveHqMcpOAuthOrigin(env?: NodeJS.ProcessEnv): URL;
8
+ //# sourceMappingURL=mcp-endpoint.d.ts.map
@@ -0,0 +1,30 @@
1
+ import { DEFAULT_VAULT_API_URL } from "../../utils/cognito-session.js";
2
+ export class McpEndpointError extends Error {
3
+ code = "hq_mcp_config_error";
4
+ }
5
+ /** Derive the hosted MCP sibling from the same hq-pro URL used by hq-cli. */
6
+ export function resolveHqMcpEndpoint(env = process.env) {
7
+ const apiUrl = env.HQ_VAULT_API_URL?.trim() || DEFAULT_VAULT_API_URL;
8
+ let api;
9
+ try {
10
+ api = new URL(apiUrl);
11
+ }
12
+ catch {
13
+ throw new McpEndpointError("HQ's configured API URL is invalid; check HQ_VAULT_API_URL.");
14
+ }
15
+ if (api.protocol !== "https:" || !api.hostname.startsWith("hqapi.")) {
16
+ throw new McpEndpointError("Hosted hq-mcp requires an HTTPS hqapi host in HQ_VAULT_API_URL.");
17
+ }
18
+ api.hostname = `hq-mcp.${api.hostname.slice("hqapi.".length)}`;
19
+ api.pathname = "/mcp";
20
+ api.search = "";
21
+ api.hash = "";
22
+ return api;
23
+ }
24
+ /** OAuth endpoints share the origin with the Streamable HTTP MCP endpoint. */
25
+ export function resolveHqMcpOAuthOrigin(env = process.env) {
26
+ const endpoint = resolveHqMcpEndpoint(env);
27
+ endpoint.pathname = "/";
28
+ return endpoint;
29
+ }
30
+ //# sourceMappingURL=mcp-endpoint.js.map
@@ -0,0 +1,24 @@
1
+ export declare class McpOAuthError extends Error {
2
+ readonly code = "hq_mcp_auth_required";
3
+ constructor(message: string);
4
+ }
5
+ export interface McpOAuthOptions {
6
+ env?: NodeJS.ProcessEnv;
7
+ home?: string;
8
+ oauthOrigin?: URL;
9
+ fetchImpl?: typeof fetch;
10
+ openBrowser?: (url: string) => Promise<unknown>;
11
+ writeOutput?: (message: string) => void;
12
+ isEnabled?: () => boolean;
13
+ isMachine?: () => boolean;
14
+ now?: () => number;
15
+ callbackTimeoutMs?: number;
16
+ }
17
+ export declare function mcpOAuthCacheFile(options?: McpOAuthOptions): string;
18
+ /** Perform hosted DCR + PKCE login and cache only the hq-mcp audience tokens. */
19
+ export declare function loginHostedMcp(options?: McpOAuthOptions): Promise<void>;
20
+ /** Load or refresh a person's hosted MCP token without printing token material. */
21
+ export declare function getMcpAudienceToken(options?: McpOAuthOptions): Promise<string>;
22
+ /** Remove all per-origin hosted MCP OAuth caches during either HQ logout flow. */
23
+ export declare function clearMcpOAuthCaches(options?: Pick<McpOAuthOptions, "env" | "home">): void;
24
+ //# sourceMappingURL=mcp-oauth.d.ts.map