@indigoai-us/hq-cli 5.290.0 → 5.292.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 (83) hide show
  1. package/CHANGELOG.md +66 -3
  2. package/assets/scaffold/core/scripts/handoff-finalize.sh +18 -0
  3. package/assets/scaffold/core/scripts/handoff-post.sh +71 -6
  4. package/assets/scaffold/core/scripts/hook-lib.sh +345 -50
  5. package/assets/scaffold/core/scripts/hq-delegate-bundle.sh +307 -0
  6. package/assets/scaffold/core/scripts/hq-delegate-grant.sh +226 -0
  7. package/assets/scaffold/core/scripts/hq-delegate-publish.sh +91 -0
  8. package/assets/scaffold/core/scripts/hq-delegate-send.sh +259 -0
  9. package/assets/scaffold/core/scripts/hq-delegate-verify.sh +213 -0
  10. package/assets/scaffold/core/scripts/hq-job-notify.sh +389 -0
  11. package/assets/scaffold/core/scripts/hq-job-probe.sh +835 -0
  12. package/assets/scaffold/core/scripts/hq-job-remediate.sh +359 -0
  13. package/assets/scaffold/core/scripts/hq-job-run.sh +1025 -0
  14. package/assets/scaffold/core/scripts/hq-session.sh +182 -21
  15. package/assets/scaffold/core/scripts/jobs-schedule-parse.sh +310 -0
  16. package/assets/scaffold/core/scripts/jobs-validate.sh +451 -0
  17. package/assets/scaffold/core/scripts/lib/session-id.sh +3 -2
  18. package/assets/scaffold/core/scripts/lib/work-mesh-enqueue.sh +2 -1
  19. package/assets/scaffold/core/scripts/outpost-jobs-reconcile.sh +830 -0
  20. package/dist/command-catalog.generated.d.ts +165 -1
  21. package/dist/command-catalog.generated.js +205 -1
  22. package/dist/commands/cloud.d.ts +26 -14
  23. package/dist/commands/cloud.js +207 -56
  24. package/dist/commands/core-delegate-w1b.d.ts +8 -0
  25. package/dist/commands/core-delegate-w1b.js +1049 -0
  26. package/dist/commands/core-delegate.d.ts +28 -0
  27. package/dist/commands/core-delegate.js +15 -13
  28. package/dist/commands/core-handoff.js +152 -23
  29. package/dist/commands/core-jobs-native.d.ts +23 -0
  30. package/dist/commands/core-jobs-native.js +1331 -0
  31. package/dist/commands/core-native-jobs-flag.d.ts +4 -0
  32. package/dist/commands/core-native-jobs-flag.js +7 -0
  33. package/dist/commands/core-ontology.d.ts +22 -4
  34. package/dist/commands/core-ontology.js +90 -8
  35. package/dist/commands/core-policy.js +24 -5
  36. package/dist/commands/core.js +17 -0
  37. package/dist/commands/integrations-core.js +7 -0
  38. package/dist/commands/lanes.js +111 -35
  39. package/dist/commands/members.js +5 -0
  40. package/dist/commands/mesh.js +46 -25
  41. package/dist/commands/personal-targeted-push-flag.d.ts +4 -0
  42. package/dist/commands/personal-targeted-push-flag.js +7 -0
  43. package/dist/commands/personal-targeted-push-paths.d.ts +3 -0
  44. package/dist/commands/personal-targeted-push-paths.js +67 -0
  45. package/dist/commands/secrets.js +9 -0
  46. package/dist/commands/skill.d.ts +3 -0
  47. package/dist/commands/skill.js +28 -0
  48. package/dist/fast-core.js +1 -0
  49. package/dist/lib/billing/free-month.d.ts +18 -0
  50. package/dist/lib/billing/free-month.js +31 -0
  51. package/dist/lib/billing/plan-limit-refusals.d.ts +69 -0
  52. package/dist/lib/billing/plan-limit-refusals.js +187 -0
  53. package/dist/lib/billing/plan-lock.d.ts +2 -6
  54. package/dist/lib/billing/plan-lock.js +5 -16
  55. package/dist/lib/checkpoint-ontology/drop-aliases.d.ts +41 -0
  56. package/dist/lib/checkpoint-ontology/drop-aliases.js +76 -0
  57. package/dist/lib/checkpoint-ontology/entity-file.d.ts +6 -3
  58. package/dist/lib/checkpoint-ontology/entity-file.js +12 -6
  59. package/dist/lib/checkpoint-ontology/merge-copies.d.ts +27 -8
  60. package/dist/lib/checkpoint-ontology/merge-copies.js +64 -97
  61. package/dist/lib/core-utils/secret-patterns.d.ts +3 -1
  62. package/dist/lib/core-utils/secret-patterns.js +3 -2
  63. package/dist/lib/daemon/flag.d.ts +2 -0
  64. package/dist/lib/daemon/flag.js +2 -0
  65. package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
  66. package/dist/lib/flag-registry-worker-source.generated.js +1 -1
  67. package/dist/lib/lanes/autopilot.d.ts +69 -0
  68. package/dist/lib/lanes/autopilot.js +418 -0
  69. package/dist/lib/lanes/mesh-events.js +2 -0
  70. package/dist/lib/lanes/store.js +11 -6
  71. package/dist/lib/mesh/api.js +4 -0
  72. package/dist/lib/mesh/live/daemon/state.d.ts +7 -1
  73. package/dist/lib/mesh/live/daemon/state.js +34 -2
  74. package/dist/main.js +23 -12
  75. package/dist/utils/plan-gate-error.d.ts +24 -0
  76. package/dist/utils/plan-gate-error.js +219 -9
  77. package/dist/utils/scaffold-sibling-references.js +4 -4
  78. package/dist/utils/self-update.d.ts +6 -0
  79. package/dist/utils/self-update.js +28 -6
  80. package/dist/utils/staged-install.d.ts +34 -0
  81. package/dist/utils/staged-install.js +296 -0
  82. package/package.json +2 -2
  83. package/scripts/mesh-daemon-if-stale.mjs +4 -0
package/CHANGELOG.md CHANGED
@@ -2,13 +2,54 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
- ## [5.290.0] — 2026-09-29
6
- - A failed `hq update` restores the previous working hq-cli install when it could be backed up, instead of leaving the CLI partially updated.
5
+ ## [5.292.0] — 2026-09-30
6
+ - Add native `hq core jobs reconcile` behind `core-native-jobs`, retaining the bundled shell rollback and scheduled-job helpers.
7
+ - Behind the default-off `cli.staged-self-update` flag, an npm global self-update installs the new version beside the running package, checks that it answers `--version`, then swaps it in with two renames. The running `hq` stays on disk for the whole install, so services the daemon starts during an update no longer fail with "hq: command not found" or MODULE_NOT_FOUND. pnpm, Bun, Windows and linked installs keep the in-place update.
7
8
 
8
- ## [5.288.0] — 2026-09-29
9
+ - Disable Git auto-maintenance, auto-gc, and detached gc during CM-W2b corpus
10
+ creation so fixture snapshots cannot race lock files.
9
11
 
10
12
  ### Added
11
13
 
14
+ - `hq core ontology merge-copies --listed --only <file>` (flag `checkpoint.ontology.merge-listed-pairs`, default off) merges exactly the copy -> original pairs in the file, including pairs whose names differ, such as a company listed under two names. Each pair must name two entities of one type; a copy listed twice, or listed as both a copy and an original, is skipped as `listed_conflict`. Signal and link holds apply as for other pairs.
15
+ - `hq core ontology drop-aliases --only <file>` (flag `checkpoint.ontology.drop-aliases`, default off) removes reviewed wrong aliases, given as `{ entity, alias }` pairs, from entity files. It is a dry run unless `--apply` is given, and it writes through the multi-writer outbox so sync uploads the change.
16
+
17
+ ### Fixed
18
+
19
+ - `hq core ontology merge-copies --rewrite-refs` no longer edits signal or source files, which sync cannot upload. A pair whose copy a signal or source still names is now held as `server_owned_refs`, and its copy is kept.
20
+ ### Added
21
+
22
+ - Add `hq core delegate bundle`, `grant`, `publish`, `send`, and `verify` as
23
+ native TypeScript handlers behind the default-off `core-native-delegate`
24
+ flag, with their shell companions retained as rollback assets.
25
+ - Match native handoff open-steps JSON nulls and invalid-JSON exit codes, and sync zero-change handoffs to the calling session's bound company after mirroring the thread.
26
+
27
+ ## [5.291.0] — 2026-09-29
28
+ - Add native `hq core jobs schedule-parse` and `validate` commands behind the default-off `core-native-jobs` gate, retaining their shell rollback companions.
29
+
30
+ - Offline mesh reconcile does not refresh person tokens or start interactive sign-in; valid cached tokens still validate device defaults.
31
+ - Retry daemon state replacement briefly when Windows reports transient rename contention, while keeping the previous state file intact on failure.
32
+ - When a lane has no Board story ID, `hq lanes` records the lane event without sending a story PATCH.
33
+ - `hq core policy age-report` now matches the legacy script when a missing reference has no hidden sibling under a dot directory.
34
+ - Keep bundled scaffold scripts current with staging and check their pinned source revision in CI.
35
+ - Starter plan-limit refusals now show why and how to fix them. The CLI reads
36
+ hq-pro's hard-stop 402 body (and the older shapes) and prints the server
37
+ message, the usage, the fix options, the free-month offer when one stands,
38
+ and the upgrade link, including in non-interactive runs. `hq secrets set`,
39
+ `hq secrets generate-link`, `hq members invite` and `hq integrations connect`
40
+ all use this renderer and exit non-zero.
41
+ - `hq sync push`, `hq sync push --all`, `hq sync now`, `hq sync now --all` and
42
+ `hq skill create` no longer print a success line when a plan limit refused a
43
+ file. They list the refused files the runner names, show the upgrade link and
44
+ exit non-zero. `hq sync push --json` adds `planLimitRefused` to its `complete`
45
+ event instead.
46
+
47
+ ## [5.290.0] — 2026-09-29
48
+ - Ignore stale but well-formed worker-profile queue details when another valid queue reason is stored, and remove them on the lane's next write.
49
+
50
+ ### Added
51
+
52
+ - Gate `hq sync push --personal <paths>` behind the default-off `cli.personal-targeted-push-paths` flag; explicit paths are normalized and checked against personal-vault scope and exclusions before upload.
12
53
  - `hq core ontology merge-copies --rewrite-refs` (flag `checkpoint.ontology.merge-rewrite-refs`, default off) re-points signal refs, invoice and bill links, source and knowledge links from a merged copy to its survivor and carries the copy's external ids and web domains; a pair whose files hold different values for one external id stays held (`external_id_conflict`).
13
54
  - A `--only` entry can carry `resolve_external_ids: { <provider>: { primary, namespace, object_type? } }`. With `--rewrite-refs`, a conflicting provider id then keeps `primary` in `external_ids` and moves the pair's other id to the survivor's `external_refs` (`system`, `namespace`, `objectType`, `recordId`), so no id is dropped. A `primary` that matches neither id still holds the pair.
14
55
 
@@ -20,6 +61,26 @@
20
61
  - `merge-copies --rewrite-refs` no longer holds a survivor as `merge_invalid` when it gains external ids but has no `web_domains` key (or the reverse).
21
62
  - `merge-copies` treats an annotation list item whose first key is `path:` as a link to the copy, so it no longer deletes a copy such an annotation still names.
22
63
 
64
+ ## [5.289.0] — 2026-09-29
65
+ - A failed `hq update` restores the previous working hq-cli install when it could be backed up, instead of leaving the CLI partially updated.
66
+
67
+ ## [5.288.0] — 2026-09-29
68
+
69
+ ### Added
70
+
71
+ - Add lead autopilot prompts to the lanes reconcile pass behind
72
+ `lanes.lead-autopilot` (off by default) and expose
73
+ `hq lanes autopilot run --dry-run --json`. It asks registered leads to review
74
+ finished, blocked, or missing workers or fill unused grant slots, starts a
75
+ ready worker after an
76
+ unanswered fill prompt ages 15 minutes, and relies on keep-alive to resume
77
+ completed leads with open work.
78
+
79
+ ### Fixed
80
+
81
+ - Retry daemon state replacement briefly when Windows reports transient rename
82
+ contention, while keeping the previous state file intact on failure.
83
+
23
84
  ## [5.287.0] — 2026-09-29
24
85
  - Group hook-timeout events by script while preserving triage diagnostics.
25
86
  - Preserve safe slow-child script basenames in hook-timeout diagnostics.
@@ -29,6 +90,8 @@
29
90
  handoff scripts behind the default-off `core-native-handoff` flag. The
30
91
  original shell assets remain bundled as the rollback path.
31
92
  - Add default-off native `hq core handoff finalize`, `post`, and `open-steps` commands with the staging scripts retained as the rollback path.
93
+ - Add a default-off `core-native-jobs` rollout gate for native `hq core jobs
94
+ schedule-parse` and `validate` commands.
32
95
 
33
96
  ### Fixed
34
97
 
@@ -56,6 +56,8 @@ set -euo pipefail
56
56
  HQ_ROOT="${HQ_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
57
57
  cd "$HQ_ROOT"
58
58
  HQ_ROOT="$(pwd -P)"
59
+ HANDOFF_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
60
+ source "$HANDOFF_SCRIPT_DIR/lib/session-id.sh"
59
61
  HAS_GIT_CHECKOUT="false"
60
62
  COMMON_GIT_DIR=""
61
63
  GIT_PROBE_OUTPUT=""
@@ -252,6 +254,22 @@ MIRROR_COMPANIES_JSON=$(printf '%s\n' "${SAFE_STAGE_PATHS[@]:-}" | jq -R -s -c '
252
254
  | unique
253
255
  ' 2>/dev/null || printf '[]')
254
256
 
257
+ bound_session_company() {
258
+ local session_id metadata company
259
+ session_id="$(session_id_resolve "$HQ_ROOT")"
260
+ [[ -n "$session_id" ]] || return 0
261
+ metadata="$HQ_ROOT/workspace/sessions/$session_id/meta.yaml"
262
+ [[ -r "$metadata" ]] || return 0
263
+ company="$(awk '$1 == "company_slug:" { sub(/^[^:]+:[[:space:]]*/, ""); gsub(/^"|"$/, ""); print; exit }' "$metadata" 2>/dev/null || true)"
264
+ [[ "$company" =~ ^[a-z][a-z0-9_-]*$ ]] || return 0
265
+ printf '%s' "$company"
266
+ }
267
+
268
+ BOUND_SESSION_COMPANY="$(bound_session_company)"
269
+ if [[ -n "$BOUND_SESSION_COMPANY" && -d "companies/$BOUND_SESSION_COMPANY" ]]; then
270
+ MIRROR_COMPANIES_JSON="$(jq -c --arg company "$BOUND_SESSION_COMPANY" '. + [$company] | unique' <<< "$MIRROR_COMPANIES_JSON")"
271
+ fi
272
+
255
273
  # -------- bg git reap (if launched by caller) --------
256
274
  GIT_BG_ERRORS=""
257
275
  if [[ -f /tmp/handoff-git-bg.pid ]]; then
@@ -18,6 +18,8 @@ set -euo pipefail
18
18
 
19
19
  HQ_ROOT="${HQ_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
20
20
  cd "$HQ_ROOT"
21
+ HANDOFF_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
+ source "$HANDOFF_SCRIPT_DIR/lib/session-id.sh"
21
23
 
22
24
  THREAD_PATH="${1:-}"
23
25
  LEARNINGS_FILE="${2:-}"
@@ -105,18 +107,83 @@ fi
105
107
 
106
108
  # --- 3b. Push company handoff mirrors promptly (best effort) ---
107
109
  # Session snapshots are intentionally gitignored, so a completed mirror needs
108
- # the sync client to make the handoff available to a second device. Trust only
109
- # the finalizer's lowercase company-slug metadata before constructing a path.
110
+ # the sync client to make the handoff available to a second device. Keep
111
+ # finalizer company metadata and add the company bound to this session when no
112
+ # changed path identified one; never use a device-wide active-company value.
113
+ bound_session_company() {
114
+ local session_id metadata company
115
+ session_id="$(session_id_resolve "$HQ_ROOT")"
116
+ [[ -n "$session_id" ]] || return 0
117
+ metadata="$HQ_ROOT/workspace/sessions/$session_id/meta.yaml"
118
+ [[ -r "$metadata" ]] || return 0
119
+ company="$(awk '$1 == "company_slug:" { sub(/^[^:]+:[[:space:]]*/, ""); gsub(/^"|"$/, ""); print; exit }' "$metadata" 2>/dev/null || true)"
120
+ [[ "$company" =~ ^[a-z][a-z0-9_-]*$ ]] || return 0
121
+ printf '%s' "$company"
122
+ }
123
+
110
124
  if [[ -n "$THREAD_PATH" && -f "$THREAD_PATH" ]] && command -v hq >/dev/null 2>&1; then
125
+ if [[ "$THREAD_PATH" == /* ]]; then
126
+ THREAD_FILE="$THREAD_PATH"
127
+ else
128
+ THREAD_FILE="$HQ_ROOT/$THREAD_PATH"
129
+ fi
130
+ SYNC_COMPANIES_JSON="$(jq -c '
131
+ (.metadata.company // [])
132
+ | (if type == "array" then . else [.] end)
133
+ | map(select(type == "string" and test("^[a-z][a-z0-9_-]*$")))
134
+ | unique
135
+ ' "$THREAD_FILE" 2>/dev/null || printf '[]')"
136
+ BOUND_COMPANY="$(bound_session_company)"
137
+ if [[ -n "$BOUND_COMPANY" ]]; then
138
+ UPDATED_SYNC_COMPANIES_JSON="$(jq -c --arg company "$BOUND_COMPANY" '. + [$company] | unique' <<< "$SYNC_COMPANIES_JSON")"
139
+ if [[ "$SYNC_COMPANIES_JSON" != "$UPDATED_SYNC_COMPANIES_JSON" ]]; then
140
+ SYNC_COMPANIES_JSON="$UPDATED_SYNC_COMPANIES_JSON"
141
+ THREAD_TMP="$(mktemp "$HQ_ROOT/workspace/threads/.handoff-post-XXXXXX")"
142
+ if jq -c --argjson companies "$SYNC_COMPANIES_JSON" \
143
+ '.metadata = (.metadata // {}) | .metadata.company = $companies' \
144
+ "$THREAD_FILE" > "$THREAD_TMP" && mv "$THREAD_TMP" "$THREAD_FILE"; then
145
+ :
146
+ else
147
+ rm -f "$THREAD_TMP"
148
+ log "workspace-sync: skipped (could not add bound company to handoff thread)"
149
+ SYNC_COMPANIES_JSON='[]'
150
+ fi
151
+ else
152
+ SYNC_COMPANIES_JSON="$UPDATED_SYNC_COMPANIES_JSON"
153
+ fi
154
+ fi
155
+ THREAD_ID="$(jq -r '.thread_id // empty' "$THREAD_FILE" 2>/dev/null || true)"
156
+ THREAD_MIRRORABLE="false"
157
+ case "$THREAD_FILE" in
158
+ "$HQ_ROOT"/workspace/threads/T-*.json)
159
+ if [[ "$THREAD_ID" =~ ^T-[A-Za-z0-9._-]+$ ]]; then THREAD_MIRRORABLE="true"; fi
160
+ ;;
161
+ esac
162
+ if [[ "$THREAD_MIRRORABLE" == "true" && "$SYNC_COMPANIES_JSON" != '[]' ]]; then
163
+ MIRROR_HOOK="$HQ_ROOT/.claude/hooks/mirror-thread-to-company.sh"
164
+ if [[ -f "$MIRROR_HOOK" ]]; then
165
+ jq -n --arg file_path "$THREAD_FILE" \
166
+ '{tool_name:"Write",tool_input:{file_path:$file_path}}' | \
167
+ bash "$MIRROR_HOOK" >>"$LOG_MAIN" 2>&1 || \
168
+ log "workspace-sync: mirror hook failed for handoff thread"
169
+ else
170
+ log "workspace-sync: mirror hook unavailable for handoff thread"
171
+ fi
172
+ fi
111
173
  while IFS= read -r company; do
112
174
  [[ "$company" =~ ^[a-z][a-z0-9_-]*$ ]] || continue
113
175
  [[ -d "$HQ_ROOT/companies/$company/workspace" ]] || continue
176
+ if [[ "$THREAD_MIRRORABLE" != "true" || \
177
+ ! -f "$HQ_ROOT/companies/$company/workspace/sessions/$THREAD_ID.json" ]]; then
178
+ log "workspace-sync: skipped (thread mirror missing for $company)"
179
+ continue
180
+ fi
114
181
  if hq sync push --company "$company" "companies/$company/workspace" >>"$LOG_MAIN" 2>&1; then
115
182
  log "workspace-sync: pushed companies/$company/workspace"
116
183
  else
117
184
  log "workspace-sync: failed companies/$company/workspace"
118
185
  fi
119
- done < <(jq -r '.metadata.company // empty | if type == "array" then .[] else . end' "$THREAD_PATH" 2>/dev/null || true)
186
+ done < <(jq -r '.[]' <<< "$SYNC_COMPANIES_JSON")
120
187
  elif [[ -n "$THREAD_PATH" && -f "$THREAD_PATH" ]]; then
121
188
  log "workspace-sync: skipped (hq CLI unavailable)"
122
189
  fi
@@ -150,9 +217,7 @@ fi
150
217
  WM_END_HOOK="$HQ_ROOT/core/hooks/SessionEnd/35-work-mesh-session-end.sh"
151
218
  if [[ -f "$WM_END_HOOK" ]]; then
152
219
  sid=""
153
- if [[ -f "$HQ_ROOT/workspace/sessions/.current" ]]; then
154
- sid="$(tr -d '[:space:]' <"$HQ_ROOT/workspace/sessions/.current" 2>/dev/null || true)"
155
- fi
220
+ sid="$(session_id_resolve "$HQ_ROOT")"
156
221
  if [[ -n "$sid" ]]; then
157
222
  payload=$(printf '{"session_id":"%s"}' "$sid")
158
223
  else