@indigoai-us/hq-cli 5.327.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
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
+
5
10
  ## [5.327.0] — 2026-10-02
6
11
  - Reduce hook-time startup imports for repo-run-registry and isolate hook-helper handlers from sibling modules.
7
12
  - Keep package-root Sentry diagnostics off the fast-route import path unless root diagnostics are needed.
@@ -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() {
@@ -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"];
@@ -11,6 +11,10 @@ export function shouldConfigureNodeNetworkCompatibility(argv) {
11
11
  const fastCore = parseFastCore(argv);
12
12
  if (fastCore)
13
13
  return fastCore.entry.requiresNodeNetworkCompatibility === true;
14
+ // The MCP shim only forwards over the local hqd socket; it does not make
15
+ // outbound network requests and does not need the network-family patch.
16
+ if (argv.length === 4 && argv[2] === "mcp" && argv[3] === "serve")
17
+ return false;
14
18
  // The lightweight secrets route still makes vault API requests.
15
19
  if (parseSecretsEnvFastRequest(argv))
16
20
  return true;
@@ -111,14 +111,20 @@ function identityLookupTimeoutMs() {
111
111
  * exits on Linux CI. Reading once + re-wrapping fully drains the stream.
112
112
  */
113
113
  async function peekPlanLimitStatus(response, options = {}) {
114
+ let bufferedBody;
114
115
  try {
115
116
  if (!response.ok)
116
117
  return response;
118
+ // Fetch forbids bodies on these statuses. Leave the original response
119
+ // untouched instead of consuming it and trying to reconstruct it later.
120
+ if ([101, 103, 204, 205, 304].includes(response.status))
121
+ return response;
117
122
  const ct = response.headers.get('content-type') ?? '';
118
123
  if (!ct.includes('application/json') && !ct.includes('+json')) {
119
124
  return response;
120
125
  }
121
126
  const buf = await response.arrayBuffer();
127
+ bufferedBody = buf;
122
128
  try {
123
129
  const text = new TextDecoder().decode(buf);
124
130
  try {
@@ -141,7 +147,16 @@ async function peekPlanLimitStatus(response, options = {}) {
141
147
  }
142
148
  catch (err) {
143
149
  // Only secret-load callers need the body-read error for offline fallback.
144
- // Other endpoints retain the pre-existing best-effort peek behavior.
150
+ // Other endpoints retain the best-effort peek behavior only while the
151
+ // original body is still readable.
152
+ if (bufferedBody !== undefined) {
153
+ // Retry with safe metadata: statusText can itself make Response
154
+ // construction throw after the original stream has already been drained.
155
+ return new Response(bufferedBody, {
156
+ status: response.status,
157
+ headers: response.headers,
158
+ });
159
+ }
145
160
  if (options.throwOnBodyReadError)
146
161
  throw err;
147
162
  return response;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indigoai-us/hq-cli",
3
- "version": "5.327.0",
3
+ "version": "5.328.0",
4
4
  "description": "HQ by Indigo management CLI — modules and cloud sync",
5
5
  "main": "dist/index.js",
6
6
  "bin": {