@indigoai-us/hq-cli 5.345.86 → 5.345.88

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.
@@ -142,6 +142,10 @@ async function postBatchWithRetries(poster, body, deps) {
142
142
  lastBody = res.body;
143
143
  if (res.ok)
144
144
  return { ok: true, body: res.body };
145
+ if (res.status === 0) {
146
+ // Transport down (fetch failed): do not hot-loop five more attempts.
147
+ return { ok: false, retryable: true, status: 0, body: res.body };
148
+ }
145
149
  if (res.status === 429 || res.status === 503) {
146
150
  const retryAfterMs = typeof res.retryAfterMs === "number" &&
147
151
  Number.isFinite(res.retryAfterMs) &&
@@ -279,12 +283,13 @@ export async function flushSessionEvents(inputDeps) {
279
283
  if (leaveResult.abort)
280
284
  continue;
281
285
  const remainingItems = leaveResult.items;
286
+ state = bindHeldCompanyIfResolved(sessionId, remainingItems, state, deps, now);
282
287
  if (state?.companyConfidence === "device_default" &&
283
288
  deps.authorizeDeviceDefaultTenant) {
284
289
  const allowed = await deps.authorizeDeviceDefaultTenant(state);
285
290
  // Authorization may restore a company the gate previously cleared.
286
291
  state = readSessionState(sessionId, deps.workContextRoot) ?? state;
287
- if (!allowed) {
292
+ if (allowed === false || allowed === "unavailable") {
288
293
  const heldAt = now().toISOString();
289
294
  summary.held += appendHeldLinesIfAbsent(remainingItems.map((item) => heldEnvelope(item.event, "NEEDS_COMPANY", item.heldAt ?? heldAt)), deps.workMeshRoot);
290
295
  for (const item of remainingItems)
@@ -392,6 +397,8 @@ export async function flushSessionEvents(inputDeps) {
392
397
  summary.restored += 1;
393
398
  markDisposed(item.event);
394
399
  }
400
+ if (result.status === 0)
401
+ break sessionLoop;
395
402
  if (result.status === 429 || result.status === 503)
396
403
  break;
397
404
  if (deps.signal?.aborted)
@@ -604,6 +611,72 @@ const SESSION_EVENT_HARNESSES = new Set([
604
611
  "agent-box",
605
612
  "agents-v2",
606
613
  ]);
614
+ function bindHeldCompanyIfResolved(sessionId, items, state, deps, now) {
615
+ if (state?.companyUid)
616
+ return state;
617
+ const sample = items[0]?.event;
618
+ if (!sample)
619
+ return state;
620
+ const cwd = eventText(sample, "cwd");
621
+ const hqRoot = eventText(sample, "hqRoot");
622
+ const remoteOwnerSlug = cwd
623
+ ? deriveRemoteOwnerSlug({ cwd, hqRoot }) ?? undefined
624
+ : undefined;
625
+ const repoIdentityKey = cwd ? deriveRepoIdentityKey({ cwd }) : null;
626
+ const resolution = resolveCompany({
627
+ root: deps.workContextRoot,
628
+ sessionId,
629
+ existingState: state,
630
+ env: {
631
+ ...(deps.env ?? {}),
632
+ HQ_SPAWN_COMPANY: "",
633
+ HQ_AGENT_IDENTITY_FILE: "",
634
+ },
635
+ trusted: eventText(sample, "companySlug")
636
+ ? { companySlug: eventText(sample, "companySlug") }
637
+ : undefined,
638
+ cwd,
639
+ hqRoot,
640
+ remoteOwnerSlug,
641
+ repoIdentityKey,
642
+ });
643
+ if (resolution.status !== "resolved" || !resolution.company.uid)
644
+ return state;
645
+ if (resolution.company.source === "trusted_explicit" &&
646
+ !eventText(sample, "companySlug")) {
647
+ return state;
648
+ }
649
+ const uid = resolution.company.uid;
650
+ const slug = resolution.company.slug;
651
+ const nowIso = now().toISOString();
652
+ const next = updateSessionState(sessionId, deps.workContextRoot, (current) => {
653
+ const base = current ?? state;
654
+ if (!base)
655
+ return null;
656
+ if (base.companyUid && base.companyUid !== uid)
657
+ return null;
658
+ const contextStatus = base.contextStatus === "needs_company" ||
659
+ base.contextStatus === "unresolved" ||
660
+ !base.contextStatus
661
+ ? (base.projectId
662
+ ? (base.taskId ? "bound" : "needs_task")
663
+ : "needs_project")
664
+ : base.contextStatus;
665
+ return {
666
+ ...base,
667
+ sessionId,
668
+ contractVersion: base.contractVersion ?? 1,
669
+ companyUid: uid,
670
+ ...(slug ? { companySlug: slug } : {}),
671
+ ...(resolution.company.source === "device_default"
672
+ ? { companyConfidence: "device_default" }
673
+ : {}),
674
+ contextStatus,
675
+ updatedAt: nowIso,
676
+ };
677
+ });
678
+ return next ?? readSessionState(sessionId, deps.workContextRoot) ?? state;
679
+ }
607
680
  function applySessionMetaCompanyRebind(sessionId, items, state, deps, now) {
608
681
  if (!state)
609
682
  return state;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indigoai-us/hq-cli",
3
- "version": "5.345.86",
3
+ "version": "5.345.88",
4
4
  "description": "HQ by Indigo management CLI — modules and cloud sync",
5
5
  "main": "dist/index.js",
6
6
  "bin": {