@indigoai-us/hq-cli 5.345.7 → 5.345.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 (50) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/commands/__fixtures__/make-tar.d.ts +2 -10
  3. package/dist/commands/__fixtures__/make-tar.js +2 -2
  4. package/dist/commands/agent-enroll.d.ts +2 -3
  5. package/dist/commands/agent-enroll.js +2 -2
  6. package/dist/commands/lanes-message.js +100 -75
  7. package/dist/commands/mcp-status.d.ts +4 -3
  8. package/dist/commands/reindex.d.ts +0 -6
  9. package/dist/commands/reindex.js +1 -1
  10. package/dist/commands/safe-extract.d.ts +2 -17
  11. package/dist/commands/safe-extract.js +2 -2
  12. package/dist/commands/search.d.ts +2 -1
  13. package/dist/lazy-commands.d.ts +0 -6
  14. package/dist/lazy-commands.js +1 -1
  15. package/dist/lib/daemon/heartbeat.d.ts +0 -4
  16. package/dist/lib/daemon/heartbeat.js +3 -3
  17. package/dist/lib/daemon/run.d.ts +1 -1
  18. package/dist/lib/daemon/run.js +11 -2
  19. package/dist/lib/daemon/supervisor.js +2 -1
  20. package/dist/lib/doctor/__testing__/fake-hq-tree.d.ts +8 -9
  21. package/dist/lib/doctor/__testing__/fake-hq-tree.js +1 -1
  22. package/dist/lib/doctor/checks/anywhere.d.ts +3 -4
  23. package/dist/lib/doctor/checks/anywhere.js +2 -2
  24. package/dist/lib/doctor/checks/runtime-probe.d.ts +0 -21
  25. package/dist/lib/doctor/checks/runtime-probe.js +4 -4
  26. package/dist/lib/doctor/checks/sync-health.d.ts +2 -3
  27. package/dist/lib/doctor/checks/sync-health.js +1 -1
  28. package/dist/lib/doctor/compat.d.ts +2 -1
  29. package/dist/lib/doctor/deep/classify.d.ts +2 -1
  30. package/dist/lib/doctor/fix/backup.d.ts +0 -8
  31. package/dist/lib/doctor/fix/backup.js +2 -2
  32. package/dist/lib/doctor/fixtures/discover.d.ts +2 -10
  33. package/dist/lib/doctor/fixtures/discover.js +1 -1
  34. package/dist/lib/install/claude-targets.d.ts +0 -4
  35. package/dist/lib/install/claude-targets.js +3 -3
  36. package/dist/lib/install/codex-targets.d.ts +0 -9
  37. package/dist/lib/install/codex-targets.js +4 -4
  38. package/dist/lib/lanes/autopilot.d.ts +2 -17
  39. package/dist/lib/lanes/autopilot.js +8 -8
  40. package/dist/lib/lanes/flag-keys.d.ts +2 -0
  41. package/dist/lib/lanes/flag-keys.js +2 -0
  42. package/dist/lib/lanes/keep-alive.d.ts +2 -0
  43. package/dist/lib/lanes/keep-alive.js +9 -0
  44. package/dist/lib/lanes/reconcile.js +44 -27
  45. package/dist/lib/lanes/tracker-report.d.ts +16 -15
  46. package/dist/lib/lanes/wait.d.ts +2 -5
  47. package/dist/lib/lanes/wait.js +3 -3
  48. package/dist/lib/mesh/live/report-summary.d.ts +0 -10
  49. package/dist/lib/mesh/live/report-summary.js +5 -5
  50. package/package.json +1 -1
@@ -22,12 +22,12 @@ import { ANSWERED_QUESTIONS_FILE, armLaneWatcher, envelopeRepairMode, isPidRecor
22
22
  import { appendCappedHistory, lanesStoreRoot, parseLaneRecord, parseQuestionRecord, readLane, readQuestion, listQuestionIds, updateLane, updateQuestion, } from "./store.js";
23
23
  import { applyThrottleDecision, decideAdmission, defaultThrottleDeps, emptyThrottleState, evaluateThrottle, isCpuCheckEnabled, readAvailableMemMb, readThrottleState, resolveCpuBusyFraction, sampleCpuBusyObservation, recordCpuBusyObservation, throttleStatePath, writeThrottleState, } from "./throttle.js";
24
24
  import { readLanesRegistryFlag, readLanesRegistryFlagFailOff } from "./registry-flag.js";
25
- import { LANE_HIRE_GRANT_FINISHED_LANES_FLAG, LANE_LEAD_ADMISSION_PRIORITY_FLAG } from "./flag-keys.js";
25
+ import { LANE_HIRE_GRANT_FINISHED_LANES_FLAG, LANE_KEEP_ALIVE_DUE_WAKE_PRECISE_FLAG, LANE_LEAD_ADMISSION_PRIORITY_FLAG, } from "./flag-keys.js";
26
26
  import { checkLaneDiskSpace, configuredCodexRolloutHomes, laneDiskAccount, retainCodexRollouts } from "./disk-guard.js";
27
27
  import { laneCompanyUidSource, resolveLaneCompany } from "./lane-company.js";
28
28
  import { appendDropboxMessage } from "./dropbox.js";
29
29
  import { DEFAULT_RUNAWAY_SEARCH_GUARD_CONFIG, listHostProcesses, runRunawayToolGuard, RUNAWAY_TOOL_GUARD_FLAG, } from "./runaway-tool-guard.js";
30
- import { LEAD_LANE_KEEP_ALIVE_FLAG, LEAD_LANE_KEEP_ALIVE_RESUME_BLOCKED_FLAG, LEAD_LANE_KEEP_ALIVE_IMMEDIATE_FIRST_RESUME_FLAG, LEAD_LANE_KEEP_ALIVE_FIRST_RESUME_SETTLE_MS, LEAD_LANE_KEEP_ALIVE_NEXT_CHECK_MAX_DELAY_MS, LEAD_LANE_KEEP_ALIVE_BLOCKED_GRACE_MS, LEAD_LANE_KEEP_ALIVE_BLOCKED_RESUME_TEXT, queueLaneTerminalResume, LEAD_LANE_KEEP_ALIVE_INTERRUPTED_RESUME_TEXT, LEAD_LANE_KEEP_ALIVE_MAX_RESUMES, LEAD_LANE_KEEP_ALIVE_RESUME_TEXT, LANE_SUPERSESSION_LINEAGE_AWARE_FLAG, doneKeepAliveVerdict, hasPendingKeepAliveWork, keepAliveNextCheckAtMs, keepAliveExclusion, loadRetiredLaneIds, leadLaneKeepAliveBackoffMs, undeliveredAnsweredQuestions, } from "./keep-alive.js";
30
+ import { LEAD_LANE_KEEP_ALIVE_FLAG, LEAD_LANE_KEEP_ALIVE_RESUME_BLOCKED_FLAG, LEAD_LANE_KEEP_ALIVE_IMMEDIATE_FIRST_RESUME_FLAG, LEAD_LANE_KEEP_ALIVE_FIRST_RESUME_SETTLE_MS, LEAD_LANE_KEEP_ALIVE_BLOCKED_GRACE_MS, LEAD_LANE_KEEP_ALIVE_BLOCKED_RESUME_TEXT, queueLaneTerminalResume, LEAD_LANE_KEEP_ALIVE_INTERRUPTED_RESUME_TEXT, LEAD_LANE_KEEP_ALIVE_MAX_RESUMES, LEAD_LANE_KEEP_ALIVE_RESUME_TEXT, LANE_SUPERSESSION_LINEAGE_AWARE_FLAG, doneKeepAliveVerdict, dueKeepAliveNextCheckMs, hasPendingKeepAliveWork, keepAliveNextCheckAtMs, keepAliveExclusion, loadRetiredLaneIds, leadLaneKeepAliveBackoffMs, undeliveredAnsweredQuestions, } from "./keep-alive.js";
31
31
  import { providerSupportsSessionResume } from "./delivery.js";
32
32
  import { isIsoDateTime } from "./types.js";
33
33
  import { applyDefaultQuotaHold, clearAccountQuotaAfterSuccessfulTurnBestEffort, loadQuotaState, readQuotaSignal, recordAccountQuota, } from "./quota.js";
@@ -1236,6 +1236,7 @@ export async function runPassBody(hqRoot, deps) {
1236
1236
  const keepAliveFlagByCompany = new Map();
1237
1237
  const blockedResumeFlagByCompany = new Map();
1238
1238
  const immediateFirstResumeFlagByCompany = new Map();
1239
+ const preciseDueWakeFlagByCompany = new Map();
1239
1240
  const supersessionLineageAwareByCompany = new Map();
1240
1241
  await Promise.all([...keepAliveFlagCompanies.entries()].map(async ([key, company]) => {
1241
1242
  const options = {
@@ -1246,17 +1247,19 @@ export async function runPassBody(hqRoot, deps) {
1246
1247
  lane.keep_alive === true &&
1247
1248
  laneRunsHere(lane, startDeps.host) &&
1248
1249
  keepAliveCompanyKey(resolveLaneCompany(hqRoot, lane).company) === key);
1249
- const [keepAliveEnabled, lineageAware, blockedResumeEnabled, immediateFirstResumeEnabled] = await Promise.all([
1250
+ const [keepAliveEnabled, lineageAware, blockedResumeEnabled, immediateFirstResumeEnabled, preciseDueWakeEnabled] = await Promise.all([
1250
1251
  readRegistryFlag(LEAD_LANE_KEEP_ALIVE_FLAG, options),
1251
1252
  readRegistryFlag(LANE_SUPERSESSION_LINEAGE_AWARE_FLAG, options),
1252
1253
  hasBlockedKeepAliveLane
1253
1254
  ? readRegistryFlag(LEAD_LANE_KEEP_ALIVE_RESUME_BLOCKED_FLAG, options)
1254
1255
  : Promise.resolve(false),
1255
1256
  readRegistryFlag(LEAD_LANE_KEEP_ALIVE_IMMEDIATE_FIRST_RESUME_FLAG, options),
1257
+ readRegistryFlag(LANE_KEEP_ALIVE_DUE_WAKE_PRECISE_FLAG, options),
1256
1258
  ]);
1257
1259
  keepAliveFlagByCompany.set(key, keepAliveEnabled);
1258
1260
  blockedResumeFlagByCompany.set(key, blockedResumeEnabled);
1259
1261
  immediateFirstResumeFlagByCompany.set(key, immediateFirstResumeEnabled);
1262
+ preciseDueWakeFlagByCompany.set(key, preciseDueWakeEnabled);
1260
1263
  supersessionLineageAwareByCompany.set(key, lineageAware);
1261
1264
  }));
1262
1265
  const admissionThrottleDeps = startDeps.throttleDeps ?? defaultThrottleDeps(startDeps.env ?? process.env);
@@ -1278,7 +1281,7 @@ export async function runPassBody(hqRoot, deps) {
1278
1281
  const freshLanes = loadLaneRecords(hqRoot, summary);
1279
1282
  const freshQuestions = loadQuestionRecords(hqRoot, summary);
1280
1283
  await closeInterruptedDoneStoryWorkers(hqRoot, freshLanes, freshQuestions, summary, admissionDeps, now, storyCloseEnabledByCompany);
1281
- const dueKeepAlivesAdmitted = await resumeKeepAlive(hqRoot, freshLanes, freshQuestions, summary, admissionDeps, now, keepAliveFlagByCompany, supersessionLineageAwareByCompany, blockedResumeFlagByCompany, immediateFirstResumeFlagByCompany, deps.terminalKeepAliveCandidate, async (laneIds) => {
1284
+ const dueKeepAlivesAdmitted = await resumeKeepAlive(hqRoot, freshLanes, freshQuestions, summary, admissionDeps, now, keepAliveFlagByCompany, supersessionLineageAwareByCompany, blockedResumeFlagByCompany, immediateFirstResumeFlagByCompany, preciseDueWakeFlagByCompany, deps.terminalKeepAliveCandidate, async (laneIds) => {
1282
1285
  dueKeepAliveLaneIds = new Set(laneIds);
1283
1286
  await admitQueued(hqRoot, loadLaneRecords(hqRoot, summary), summary, admissionDeps, now, laneIds);
1284
1287
  });
@@ -2513,7 +2516,7 @@ function appendBlockedKeepAliveHistory(hqRoot, lane, terminalAt, at, reason, dep
2513
2516
  }),
2514
2517
  }), false);
2515
2518
  }
2516
- async function resumeKeepAlive(hqRoot, lanes, questions, summary, deps, now, flagByCompany, supersessionLineageAwareByCompany, blockedResumeFlagByCompany, immediateFirstResumeFlagByCompany, terminalKeepAliveCandidate, admitDueCandidates) {
2519
+ async function resumeKeepAlive(hqRoot, lanes, questions, summary, deps, now, flagByCompany, supersessionLineageAwareByCompany, blockedResumeFlagByCompany, immediateFirstResumeFlagByCompany, preciseDueWakeFlagByCompany, terminalKeepAliveCandidate, admitDueCandidates) {
2517
2520
  const nowMs = now.getTime();
2518
2521
  const nowIso = now.toISOString();
2519
2522
  const config = loadLanesConfig(hqRoot);
@@ -2546,10 +2549,14 @@ async function resumeKeepAlive(hqRoot, lanes, questions, summary, deps, now, fla
2546
2549
  continue;
2547
2550
  const anchorMs = Date.parse(lane.last_envelope?.at ?? lane.updated_at);
2548
2551
  const nextCheckMs = Date.parse(envelope.next_check_at ?? "");
2549
- if (!Number.isFinite(anchorMs) || !Number.isFinite(nextCheckMs))
2552
+ if (!Number.isFinite(anchorMs))
2550
2553
  continue;
2551
- const cappedNextCheckMs = Math.min(nextCheckMs, anchorMs + LEAD_LANE_KEEP_ALIVE_NEXT_CHECK_MAX_DELAY_MS);
2552
- if (cappedNextCheckMs <= nowMs &&
2554
+ const companyKey = keepAliveCompanyKey(resolveLaneCompany(hqRoot, lane).company);
2555
+ const preciseDueWakeEnabled = preciseDueWakeFlagByCompany.get(companyKey) === true;
2556
+ // This set only accelerates lanes with an explicit due next-check. Retry
2557
+ // backoff is decided once in the resume path and queuedDueCandidateIds.
2558
+ const dueNextCheckMs = dueKeepAliveNextCheckMs(nextCheckMs, nowMs, anchorMs, preciseDueWakeEnabled);
2559
+ if (dueNextCheckMs !== undefined &&
2553
2560
  doneKeepAliveVerdict(lane, envelope, false, { nowMs, nextCheckAnchorMs: anchorMs }) === "eligible")
2554
2561
  dueCandidateIds.add(lane.lane_id);
2555
2562
  }
@@ -2939,23 +2946,13 @@ async function resumeKeepAlive(hqRoot, lanes, questions, summary, deps, now, fla
2939
2946
  const storedNextMs = resetByHuman
2940
2947
  ? Number.NaN
2941
2948
  : Date.parse(current.keep_alive_next_eligible_at ?? "");
2942
- const nextEligibleMs = Number.isFinite(storedNextMs)
2949
+ let nextEligibleMs = Number.isFinite(storedNextMs)
2943
2950
  ? Math.max(attemptEligibleMs, storedNextMs)
2944
2951
  : attemptEligibleMs;
2945
- if (nowMs < nextEligibleMs) {
2946
- let skipLane = current;
2947
- if (resetByHuman && hasKeepAliveProgress(current)) {
2948
- const clearedProgress = casLaneIf(hqRoot, current.lane_id, (latestLane) => latestLane.version === current.version &&
2949
- latestLane.state === current.state &&
2950
- latestLane.keep_alive === true &&
2951
- latestLane.keep_alive_opted_in_at === current.keep_alive_opted_in_at, (latestLane) => clearedKeepAliveProgress(latestLane), deps.dryRun);
2952
- skipLane = clearedProgress.record;
2953
- }
2954
- recordKeepAliveSkipEvent(hqRoot, skipLane, "backoff", skipLane.version, summary, deps, new Date(nextEligibleMs).toISOString());
2955
- continue;
2956
- }
2957
- const nextEligibleAt = new Date(nowMs + leadLaneKeepAliveBackoffMs(immediateFirstResumeEnabled ? attempt : attempt + 1)).toISOString();
2958
2952
  let resumeReason = "backoff";
2953
+ let dueNextCheckMs;
2954
+ const preciseDueWakeEnabled = initialState === "done" &&
2955
+ preciseDueWakeFlagByCompany.get(keepAliveCompanyKey(companyForLane(current))) === true;
2959
2956
  if (initialState === "done") {
2960
2957
  if (hasPendingKeepAliveWork(hqRoot, current, questions)) {
2961
2958
  resumeReason = "pending_work";
@@ -2965,13 +2962,30 @@ async function resumeKeepAlive(hqRoot, lanes, questions, summary, deps, now, fla
2965
2962
  const nextCheckMs = Date.parse(finalEnvelope?.next_check_at ?? "");
2966
2963
  const anchorMs = Date.parse(current.last_envelope?.at ?? current.updated_at);
2967
2964
  if (Number.isFinite(nextCheckMs) && Number.isFinite(anchorMs)) {
2968
- const cappedNextCheckMs = Math.min(nextCheckMs, anchorMs + LEAD_LANE_KEEP_ALIVE_NEXT_CHECK_MAX_DELAY_MS);
2969
- if (cappedNextCheckMs > nextEligibleMs && cappedNextCheckMs <= nowMs) {
2965
+ const eligibleNextCheckMs = dueKeepAliveNextCheckMs(nextCheckMs, nowMs, anchorMs, preciseDueWakeEnabled);
2966
+ if (eligibleNextCheckMs !== undefined &&
2967
+ (preciseDueWakeEnabled || eligibleNextCheckMs > nextEligibleMs)) {
2970
2968
  resumeReason = "next_check_at_due";
2969
+ dueNextCheckMs = eligibleNextCheckMs;
2970
+ if (preciseDueWakeEnabled)
2971
+ nextEligibleMs = Math.min(nextEligibleMs, eligibleNextCheckMs);
2971
2972
  }
2972
2973
  }
2973
2974
  }
2974
2975
  }
2976
+ if (nowMs < nextEligibleMs) {
2977
+ let skipLane = current;
2978
+ if (resetByHuman && hasKeepAliveProgress(current)) {
2979
+ const clearedProgress = casLaneIf(hqRoot, current.lane_id, (latestLane) => latestLane.version === current.version &&
2980
+ latestLane.state === current.state &&
2981
+ latestLane.keep_alive === true &&
2982
+ latestLane.keep_alive_opted_in_at === current.keep_alive_opted_in_at, (latestLane) => clearedKeepAliveProgress(latestLane), deps.dryRun);
2983
+ skipLane = clearedProgress.record;
2984
+ }
2985
+ recordKeepAliveSkipEvent(hqRoot, skipLane, "backoff", skipLane.version, summary, deps, new Date(nextEligibleMs).toISOString());
2986
+ continue;
2987
+ }
2988
+ const nextEligibleAt = new Date(nowMs + leadLaneKeepAliveBackoffMs(immediateFirstResumeEnabled ? attempt : attempt + 1)).toISOString();
2975
2989
  const queuedCount = loadLaneRecords(hqRoot, summary).filter((queuedLane) => queuedLane.state === "queued" &&
2976
2990
  queuedLane.provider === current.provider &&
2977
2991
  laneRunsHere(queuedLane, deps.host) &&
@@ -3233,7 +3247,8 @@ async function resumeKeepAlive(hqRoot, lanes, questions, summary, deps, now, fla
3233
3247
  }
3234
3248
  if (!queued.changed)
3235
3249
  continue;
3236
- if (resumeReason === "next_check_at_due")
3250
+ if (resumeReason === "next_check_at_due" ||
3251
+ (preciseDueWakeEnabled && initialState === "done" && nowMs >= nextEligibleMs && dueNextCheckMs === undefined))
3237
3252
  queuedDueCandidateIds.add(current.lane_id);
3238
3253
  summary.resumed.push({
3239
3254
  id: current.lane_id,
@@ -3478,11 +3493,13 @@ async function runTerminalKeepAliveCandidatePass(hqRoot, lanes, summary, deps, n
3478
3493
  let keepAliveEnabled;
3479
3494
  let lineageAware;
3480
3495
  let immediateFirstResumeEnabled;
3496
+ let preciseDueWakeEnabled;
3481
3497
  try {
3482
- [keepAliveEnabled, lineageAware, immediateFirstResumeEnabled] = await Promise.all([
3498
+ [keepAliveEnabled, lineageAware, immediateFirstResumeEnabled, preciseDueWakeEnabled] = await Promise.all([
3483
3499
  readFlag(LEAD_LANE_KEEP_ALIVE_FLAG, options),
3484
3500
  readFlag(LANE_SUPERSESSION_LINEAGE_AWARE_FLAG, options),
3485
3501
  readFlag(LEAD_LANE_KEEP_ALIVE_IMMEDIATE_FIRST_RESUME_FLAG, options),
3502
+ readFlag(LANE_KEEP_ALIVE_DUE_WAKE_PRECISE_FLAG, options),
3486
3503
  ]);
3487
3504
  }
3488
3505
  catch (err) {
@@ -3497,7 +3514,7 @@ async function runTerminalKeepAliveCandidatePass(hqRoot, lanes, summary, deps, n
3497
3514
  const current = freshLanes.find((row) => row.lane_id === candidate.laneId);
3498
3515
  if (!current || current.version !== candidate.version || current.state !== "done")
3499
3516
  return;
3500
- await resumeKeepAlive(hqRoot, freshLanes, freshQuestions, summary, deps, now, new Map([[keepAliveCompanyKey(company), true]]), new Map([[keepAliveCompanyKey(company), lineageAware]]), new Map(), new Map([[keepAliveCompanyKey(company), immediateFirstResumeEnabled]]), candidate);
3517
+ await resumeKeepAlive(hqRoot, freshLanes, freshQuestions, summary, deps, now, new Map([[keepAliveCompanyKey(company), true]]), new Map([[keepAliveCompanyKey(company), lineageAware]]), new Map(), new Map([[keepAliveCompanyKey(company), immediateFirstResumeEnabled]]), new Map([[keepAliveCompanyKey(company), preciseDueWakeEnabled]]), candidate);
3501
3518
  await admitQueued(hqRoot, loadLaneRecords(hqRoot, summary), summary, deps, now, new Set([candidate.laneId]));
3502
3519
  });
3503
3520
  return summary;
@@ -3,12 +3,12 @@ import type { QuestionRecord } from "./types.js";
3
3
  import type { TrackerRecord } from "./tracker-store.js";
4
4
  export type ReportStoryStatus = "queued" | "in_progress" | "review" | "done" | "dropped";
5
5
  export type ReportAudience = "owner" | "operator" | "lane";
6
- export type ApprovalState = "proposal" | "approved";
6
+ type ApprovalState = "proposal" | "approved";
7
7
  export interface TrackerReportRecord extends TrackerRecord {
8
8
  /** Absolute path of the validated on-disk record; used only in errors. */
9
9
  source_path: string;
10
10
  }
11
- export interface TrackerReportStory {
11
+ interface TrackerReportStory {
12
12
  id: string;
13
13
  title: string;
14
14
  status: ReportStoryStatus;
@@ -24,18 +24,18 @@ export interface TrackerReportIssue {
24
24
  record_id?: string;
25
25
  question_id?: string;
26
26
  }
27
- export interface TrackerReportPullRequest {
27
+ interface TrackerReportPullRequest {
28
28
  number: string;
29
29
  title: string;
30
30
  merged_at: string;
31
31
  source_path: string;
32
32
  }
33
- export interface TrackerReportRelease {
33
+ interface TrackerReportRelease {
34
34
  version: string;
35
35
  released_at: string;
36
36
  source_path: string;
37
37
  }
38
- export interface TrackerReportQuestion {
38
+ interface TrackerReportQuestion {
39
39
  record: QuestionRecord;
40
40
  /** Loaded through the existing company-checked question body reader. */
41
41
  body: QuestionBody;
@@ -63,22 +63,22 @@ export interface TrackerReportInput {
63
63
  since_source: "explicit" | "previous_report" | "first_run";
64
64
  teams: readonly TrackerReportTeamInput[];
65
65
  }
66
- export interface ReportTimedStory {
66
+ interface ReportTimedStory {
67
67
  id: string;
68
68
  title: string;
69
69
  at: string;
70
70
  references: string[];
71
71
  }
72
- export interface ReportPullRequest {
72
+ interface ReportPullRequest {
73
73
  number: string;
74
74
  title: string;
75
75
  merged_at: string;
76
76
  }
77
- export interface ReportRelease {
77
+ interface ReportRelease {
78
78
  version: string;
79
79
  released_at: string;
80
80
  }
81
- export interface ReportKpiValue {
81
+ interface ReportKpiValue {
82
82
  kpi_id: string;
83
83
  name: string;
84
84
  at: string;
@@ -86,7 +86,7 @@ export interface ReportKpiValue {
86
86
  unit: string;
87
87
  source: string;
88
88
  }
89
- export interface ReportQuestion {
89
+ interface ReportQuestion {
90
90
  question_id: string;
91
91
  question: string;
92
92
  asked_at: string;
@@ -99,7 +99,7 @@ export interface ReportQuestion {
99
99
  answered_by: string;
100
100
  };
101
101
  }
102
- export interface ReportBlocker {
102
+ interface ReportBlocker {
103
103
  id: string;
104
104
  story_id: string;
105
105
  what: string;
@@ -107,7 +107,7 @@ export interface ReportBlocker {
107
107
  next_step: string;
108
108
  opened_at: string;
109
109
  }
110
- export interface ReportDirective {
110
+ interface ReportDirective {
111
111
  id: string;
112
112
  text: string;
113
113
  date: string;
@@ -117,7 +117,7 @@ export interface ReportDirective {
117
117
  at: string;
118
118
  }>;
119
119
  }
120
- export interface TrackerOwnerTeamReport {
120
+ interface TrackerOwnerTeamReport {
121
121
  team: string;
122
122
  project_id: string;
123
123
  errors: TrackerReportIssue[];
@@ -142,7 +142,7 @@ export interface TrackerOwnerReport {
142
142
  since_source: TrackerReportInput["since_source"];
143
143
  teams: TrackerOwnerTeamReport[];
144
144
  }
145
- export interface TrackerTeamKpi {
145
+ interface TrackerTeamKpi {
146
146
  id: string;
147
147
  name: string;
148
148
  definition: string;
@@ -162,7 +162,7 @@ export interface TrackerTeamKpi {
162
162
  }>;
163
163
  trend: "improving" | "regressing" | "flat" | "insufficient_data";
164
164
  }
165
- export interface TrackerTeamOkr {
165
+ interface TrackerTeamOkr {
166
166
  id: string;
167
167
  objective: string;
168
168
  period: string;
@@ -200,4 +200,5 @@ export declare function buildTrackerTeamPage(team: TrackerReportTeamInput, compa
200
200
  export declare function renderTrackerOwnerReportText(report: TrackerOwnerReport): string;
201
201
  /** Human-readable team page, with proposal status visible beside each objective and KPI. */
202
202
  export declare function renderTrackerTeamPageText(page: TrackerTeamPage): string;
203
+ export {};
203
204
  //# sourceMappingURL=tracker-report.d.ts.map
@@ -1,11 +1,7 @@
1
1
  import type { LaneRecord, QuestionRecord } from "./types.js";
2
- export declare const LANE_WAIT_POLL_INTERVAL_MS = 2000;
3
- export declare const LANE_WAIT_MAX_LANES = 64;
4
2
  export declare const LANE_WAIT_TIMEOUT_EXIT_CODE = 4;
5
3
  export declare const LANE_WAIT_INVALID_INPUT_EXIT_CODE = 2;
6
- export declare const LANE_WAIT_CHANGE_TYPES: readonly ["envelope", "question", "state"];
7
- export type LaneWaitChangeType = (typeof LANE_WAIT_CHANGE_TYPES)[number];
8
- export type LaneWaitChange = {
4
+ type LaneWaitChange = {
9
5
  type: "envelope";
10
6
  ref: string;
11
7
  decision: "done" | "ask" | "blocked";
@@ -36,4 +32,5 @@ export interface LaneWaitDeps {
36
32
  * lock. Question records are scanned in one pass when question changes matter.
37
33
  */
38
34
  export declare function runLaneWait(hqRoot: string, laneIds: readonly string[], changeTypes: readonly string[], timeoutMs: number, deps?: LaneWaitDeps): Promise<LaneWaitResult | null>;
35
+ export {};
39
36
  //# sourceMappingURL=wait.d.ts.map
@@ -1,10 +1,10 @@
1
1
  import { listQuestionIds, readLane, readQuestion } from "./store.js";
2
2
  import { LanesError } from "./errors.js";
3
- export const LANE_WAIT_POLL_INTERVAL_MS = 2_000;
4
- export const LANE_WAIT_MAX_LANES = 64;
3
+ const LANE_WAIT_POLL_INTERVAL_MS = 2_000;
4
+ const LANE_WAIT_MAX_LANES = 64;
5
5
  export const LANE_WAIT_TIMEOUT_EXIT_CODE = 4;
6
6
  export const LANE_WAIT_INVALID_INPUT_EXIT_CODE = 2;
7
- export const LANE_WAIT_CHANGE_TYPES = ["envelope", "question", "state"];
7
+ const LANE_WAIT_CHANGE_TYPES = ["envelope", "question", "state"];
8
8
  function defaultSleep(ms) {
9
9
  return new Promise((resolve) => setTimeout(resolve, ms));
10
10
  }
@@ -4,9 +4,6 @@
4
4
  * Built locally at the quiet trigger / SessionEnd flush. Never includes file
5
5
  * contents. Tokens, secret-looking strings, and secrets-file paths are redacted.
6
6
  */
7
- export declare const REPORT_SUMMARY_MAX_CHARS = 140;
8
- export declare const REPORT_SUMMARY_SCHEMA_MAX = 280;
9
- export declare const REPORT_TRANSCRIPT_TAIL_BYTES: number;
10
7
  export interface SessionEndReportFields {
11
8
  summary?: string;
12
9
  repo?: string;
@@ -26,19 +23,12 @@ export interface BuildSessionEndReportFieldsInput {
26
23
  export declare function redactReportSummary(text: string): string;
27
24
  export declare function firstSentence(text: string, max?: number): string;
28
25
  export declare function extractLastAssistantText(jsonl: string): string | undefined;
29
- export declare function readTranscriptTail(transcriptPath: string, maxBytes?: number): string | undefined;
30
26
  export declare function collectGitContext(cwd: string, git?: (cwd: string, args: string[]) => string | undefined): {
31
27
  repo?: string;
32
28
  gitBranch?: string;
33
29
  };
34
30
  export declare function extractPrUrls(text: string, max?: number): string[];
35
31
  export declare function claudeTranscriptPathFor(sessionId: string, cwd: string, home?: string): string;
36
- export declare function resolveTranscriptPath(input: {
37
- transcriptPath?: string;
38
- sessionId?: string;
39
- cwd?: string;
40
- home?: string;
41
- }): string | undefined;
42
32
  export declare function buildSessionEndReportFields(input: BuildSessionEndReportFieldsInput): SessionEndReportFields;
43
33
  /** Merge report fields onto a session_end event object (no-op for other kinds). */
44
34
  export declare function enrichSessionEndEvent(event: Record<string, unknown>, extra?: Pick<BuildSessionEndReportFieldsInput, "transcriptPath" | "home" | "git" | "readTranscript">): Record<string, unknown>;
@@ -9,9 +9,9 @@ import * as fs from "node:fs";
9
9
  import * as os from "node:os";
10
10
  import * as path from "node:path";
11
11
  import { SECRET_RE, SECRETS_PATH_RE } from "../../lanes/text-scan.js";
12
- export const REPORT_SUMMARY_MAX_CHARS = 140;
13
- export const REPORT_SUMMARY_SCHEMA_MAX = 280;
14
- export const REPORT_TRANSCRIPT_TAIL_BYTES = 256 * 1024;
12
+ const REPORT_SUMMARY_MAX_CHARS = 140;
13
+ const REPORT_SUMMARY_SCHEMA_MAX = 280;
14
+ const REPORT_TRANSCRIPT_TAIL_BYTES = 256 * 1024;
15
15
  const PR_URL_RE = /https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/pull\/\d+/g;
16
16
  export function redactReportSummary(text) {
17
17
  let out = text.replace(SECRET_RE, "[redacted]");
@@ -101,7 +101,7 @@ export function extractLastAssistantText(jsonl) {
101
101
  }
102
102
  return last;
103
103
  }
104
- export function readTranscriptTail(transcriptPath, maxBytes = REPORT_TRANSCRIPT_TAIL_BYTES) {
104
+ function readTranscriptTail(transcriptPath, maxBytes = REPORT_TRANSCRIPT_TAIL_BYTES) {
105
105
  try {
106
106
  const st = fs.statSync(transcriptPath);
107
107
  if (!st.isFile() || st.size <= 0)
@@ -171,7 +171,7 @@ export function claudeTranscriptPathFor(sessionId, cwd, home = os.homedir()) {
171
171
  const encoded = cwd.startsWith("/") ? cwd.replace(/\//g, "-") : `-${cwd.replace(/\//g, "-")}`;
172
172
  return path.join(home, ".claude", "projects", encoded, `${sessionId}.jsonl`);
173
173
  }
174
- export function resolveTranscriptPath(input) {
174
+ function resolveTranscriptPath(input) {
175
175
  const explicit = input.transcriptPath?.trim();
176
176
  if (explicit)
177
177
  return explicit;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indigoai-us/hq-cli",
3
- "version": "5.345.7",
3
+ "version": "5.345.9",
4
4
  "description": "HQ by Indigo management CLI — modules and cloud sync",
5
5
  "main": "dist/index.js",
6
6
  "bin": {