@integrity-labs/agt-cli 0.28.571 → 0.28.573

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.
@@ -46,7 +46,7 @@ import {
46
46
  resolveConnectivityProbe,
47
47
  worseConnectivityOutcome,
48
48
  wrapScheduledTaskPrompt
49
- } from "./chunk-72K46XUZ.js";
49
+ } from "./chunk-5Z6RJ3RX.js";
50
50
  import {
51
51
  parsePsRows
52
52
  } from "./chunk-XWVM4KPK.js";
@@ -5646,7 +5646,7 @@ function exchangeFailureKind(err) {
5646
5646
  }
5647
5647
 
5648
5648
  // src/lib/api-client.ts
5649
- var agtCliVersion = true ? "0.28.571" : "dev";
5649
+ var agtCliVersion = true ? "0.28.573" : "dev";
5650
5650
  var lastConfigHash = null;
5651
5651
  function setConfigHash(hash) {
5652
5652
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -9011,4 +9011,4 @@ export {
9011
9011
  managerInstallSystemUnitCommand,
9012
9012
  managerUninstallSystemUnitCommand
9013
9013
  };
9014
- //# sourceMappingURL=chunk-KXUYJUGI.js.map
9014
+ //# sourceMappingURL=chunk-GW2JI7NO.js.map
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
100
100
  return { ok: true };
101
101
  } catch {
102
102
  }
103
- const { resolveClaudeBinary } = await import("./persistent-session-74MH2XTM.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-6UGFGI6J.js");
104
104
  const claudeBin = resolveClaudeBinary();
105
105
  const pairEnv = {
106
106
  ...process.env,
@@ -373,4 +373,4 @@ export {
373
373
  startClaudePair,
374
374
  submitClaudePairCode
375
375
  };
376
- //# sourceMappingURL=claude-pair-runtime-XTRJNDP2.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-T4ZR7AJU.js.map
@@ -53,7 +53,7 @@ import {
53
53
  safeWriteJsonAtomic,
54
54
  setConfigHash,
55
55
  tripClass
56
- } from "../chunk-KXUYJUGI.js";
56
+ } from "../chunk-GW2JI7NO.js";
57
57
  import {
58
58
  getProjectDir as getProjectDir2,
59
59
  getReadyTasks,
@@ -182,7 +182,7 @@ import {
182
182
  toOpencodeModel,
183
183
  transcriptActivityAgeSeconds,
184
184
  writeEgressAllowlist
185
- } from "../chunk-72K46XUZ.js";
185
+ } from "../chunk-5Z6RJ3RX.js";
186
186
  import {
187
187
  reapOrphanChannelMcps
188
188
  } from "../chunk-XWVM4KPK.js";
@@ -620,9 +620,18 @@ function isSlackBehaviourRestrictive(subset) {
620
620
  // src/lib/onboarding-drive.ts
621
621
  import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, rmSync, writeFileSync as writeFileSync2 } from "fs";
622
622
  import { dirname as dirname2 } from "path";
623
- var ONBOARDING_REINJECT_INTERVAL_MS = 5 * 6e4;
623
+ var ONBOARDING_REINJECT_INTERVAL_MS = 45 * 6e4;
624
624
  var ONBOARDING_MAX_NUDGES = 3;
625
- function decideOnboardingDrive(step, marker, nowMs, generation = 0, reinjectIntervalMs = ONBOARDING_REINJECT_INTERVAL_MS, maxNudges = ONBOARDING_MAX_NUDGES) {
625
+ var ONBOARDING_MIN_STANDDOWN_AGE_MS = 60 * 6e4;
626
+ var ONBOARDING_MAX_INJECTS = 8;
627
+ function decideOnboardingDrive(step, marker, nowMs, generation = 0, opts = {}) {
628
+ const {
629
+ managerContactedAt = null,
630
+ reinjectIntervalMs = ONBOARDING_REINJECT_INTERVAL_MS,
631
+ maxNudges = ONBOARDING_MAX_NUDGES,
632
+ minStandDownAgeMs = ONBOARDING_MIN_STANDDOWN_AGE_MS,
633
+ maxInjects = ONBOARDING_MAX_INJECTS
634
+ } = opts;
626
635
  if (isOnboardingArea(step)) {
627
636
  const sameStep = marker?.step === step;
628
637
  const current = sameStep ? marker : null;
@@ -631,7 +640,21 @@ function decideOnboardingDrive(step, marker, nowMs, generation = 0, reinjectInte
631
640
  return {
632
641
  inject: true,
633
642
  clearMarker: false,
634
- nextMarker: { step, injectedAtMs: nowMs, nudgeCount: 1, gaveUp: false, generation },
643
+ nextMarker: {
644
+ step,
645
+ injectedAtMs: nowMs,
646
+ // ENG-8703: a restart is a fresh sequence — no asks yet, one inject,
647
+ // and the stand-down floor re-anchors to now.
648
+ nudgeCount: 0,
649
+ injectCount: 1,
650
+ firstNudgeAtMs: nowMs,
651
+ // Baseline the stamp: a contact from the PREVIOUS generation must not
652
+ // read as an ask in this one (the column is per-agent, and /onboard
653
+ // does not reset it).
654
+ lastContactSeen: managerContactedAt ?? current.lastContactSeen ?? null,
655
+ gaveUp: false,
656
+ generation
657
+ },
635
658
  reminder: false,
636
659
  standDown: false,
637
660
  // The operator just re-ran /onboard: tell the agent to ask afresh now.
@@ -646,12 +669,31 @@ function decideOnboardingDrive(step, marker, nowMs, generation = 0, reinjectInte
646
669
  if (!fresh && !stale) {
647
670
  return { inject: false, clearMarker: false, nextMarker: current, reminder: false, standDown: false, freshRestart: false };
648
671
  }
649
- const nudgeCount = fresh ? 1 : current.nudgeCount + 1;
650
- const isFinal = nudgeCount >= maxNudges;
672
+ const askedSinceLastNudge = current !== null && managerContactedAt !== null && managerContactedAt !== void 0 && managerContactedAt !== current.lastContactSeen;
673
+ const nudgeCount = fresh ? 0 : current.nudgeCount + (askedSinceLastNudge ? 1 : 0);
674
+ const injectCount = fresh ? 1 : current.injectCount + 1;
675
+ const firstNudgeAtMs = fresh ? nowMs : current.firstNudgeAtMs;
676
+ const oldEnough = nowMs - firstNudgeAtMs >= minStandDownAgeMs;
677
+ const budgetSpent = nudgeCount >= maxNudges;
678
+ const ceilingHit = injectCount >= maxInjects;
679
+ const isFinal = oldEnough && (budgetSpent || ceilingHit);
651
680
  return {
652
681
  inject: true,
653
682
  clearMarker: false,
654
- nextMarker: { step, injectedAtMs: nowMs, nudgeCount, gaveUp: isFinal, generation },
683
+ nextMarker: {
684
+ step,
685
+ injectedAtMs: nowMs,
686
+ nudgeCount,
687
+ injectCount,
688
+ firstNudgeAtMs,
689
+ // Record what we just saw, so the NEXT cycle can tell a new ask from
690
+ // this same one. On a fresh area this baselines any pre-existing stamp,
691
+ // which is what stops an ask from a previous area or a previous
692
+ // /onboard generation being counted again here.
693
+ lastContactSeen: managerContactedAt ?? current?.lastContactSeen ?? null,
694
+ gaveUp: isFinal,
695
+ generation
696
+ },
655
697
  // A middle re-fire (not fresh, not final) is a gentle "still waiting"
656
698
  // reminder; the final one is a stand-down, not a reminder.
657
699
  reminder: !fresh && !isFinal,
@@ -668,19 +710,30 @@ var AREA_DIRECTIVE = {
668
710
  reporting: "Agree how you keep your manager posted \u2014 settle on a cadence and channel, then create a recurring report scheduled task for it"
669
711
  };
670
712
  function buildOnboardingDirective(step, completed = [], opts = {}) {
671
- const { channel, reminder = false, standDown = false, freshRestart = false, code } = opts;
713
+ const {
714
+ channel,
715
+ reminder = false,
716
+ standDown = false,
717
+ freshRestart = false,
718
+ code,
719
+ everAsked = true
720
+ } = opts;
672
721
  const doneAreas = completed.filter(isOnboardingArea);
673
722
  const alreadyCovered = doneAreas.length > 0 ? `You've already covered ${doneAreas.join(", ")} \u2014 re-orient, don't re-ask about those. ` : "";
674
723
  const where = channel ? `whoever is guiding your onboarding in ${describeOnboardingChannel(channel)} (the channel onboarding was triggered from)` : "your manager over your usual channel";
724
+ const whoRef = channel ? `whoever is guiding your onboarding in ${describeOnboardingChannel(channel)}` : "your manager";
675
725
  const waitClause = `WAIT for their reply. Do NOT self-answer, and do NOT call \`onboarding_advance\` until they respond. ${AREA_DIRECTIVE[step]} only once they have. `;
676
726
  const askAndWait = `Ask ${where} this area's question and ${waitClause}`;
677
727
  const mustAskNow = `Post this area's question to ${where} as a NEW message in THIS turn. Even if you think you asked in an earlier round, do NOT "stand down" to wait unless you have just asked it now; a previous round's ask does not count. Once it is out, ${waitClause}`;
678
728
  if (standDown) {
679
729
  const resumeCmd = code ? `/onboard-${code}` : "/onboard";
680
- return `\u{1F6D1} Onboarding (${step}): your manager hasn't replied after a few nudges, so stand down on this for now. Post exactly this once to ${where}, then STOP nudging this area and do NOT call \`onboarding_advance\`: "Let me know if you'd like me to stop nudging you on this. You can resume onboarding at any time using ${resumeCmd}." After posting, leave onboarding parked; your manager can resume it whenever they're ready.`;
730
+ if (!everAsked) {
731
+ return `\u{1F6D1} Onboarding (${step}): parking this area. You never got the question out to ${where}, so there is nothing for anyone to reply to and nothing to chase. Do NOT post a stand-down message, do NOT tell anyone they failed to reply, and do NOT call \`onboarding_advance\`. Onboarding stays parked and can be resumed at any time with ${resumeCmd}. If you are able to ask the question now, ask it instead of parking.`;
732
+ }
733
+ return `\u{1F6D1} Onboarding (${step}): ${whoRef} hasn't replied after a few nudges, so stand down on this for now. Post exactly this once to ${where}, then STOP nudging this area and do NOT call \`onboarding_advance\`: "Let me know if you'd like me to stop nudging you on this. You can resume onboarding at any time using ${resumeCmd}." After posting, leave onboarding parked; they can resume it whenever they're ready.`;
681
734
  }
682
735
  if (reminder) {
683
- return `\u23F3 Onboarding (${step}): still waiting on your manager's answer for this area. If you haven't asked yet, ask now; otherwise give them a gentle nudge, but don't move on without a reply. ` + askAndWait + `Advance with \`onboarding_advance\` (ADVANCE) once this area is done.`;
736
+ return `\u23F3 Onboarding (${step}): still waiting on an answer from ${whoRef} for this area. If you haven't asked yet, ask now; otherwise give them a gentle nudge, but don't move on without a reply. ` + askAndWait + `Advance with \`onboarding_advance\` (ADVANCE) once this area is done.`;
684
737
  }
685
738
  if (freshRestart) {
686
739
  return `\u{1F504} Onboarding (${step}): your manager just re-ran \`/onboard\`, so onboarding has RESTARTED at this area. Call the \`onboarding_get\` tool now to re-read this area, then ${mustAskNow}Advance with \`onboarding_advance\` (ADVANCE) once this area is done.`;
@@ -694,12 +747,20 @@ function readOnboardingDriveMarker(path) {
694
747
  try {
695
748
  const raw = JSON.parse(readFileSync2(path, "utf8"));
696
749
  if (typeof raw.step === "string" && isOnboardingArea(raw.step) && typeof raw.injectedAtMs === "number" && Number.isFinite(raw.injectedAtMs)) {
697
- const nudgeCount = typeof raw.nudgeCount === "number" && Number.isFinite(raw.nudgeCount) && raw.nudgeCount >= 1 ? Math.floor(raw.nudgeCount) : 1;
750
+ const legacyInjects = typeof raw.nudgeCount === "number" && Number.isFinite(raw.nudgeCount) && raw.nudgeCount >= 1 ? Math.floor(raw.nudgeCount) : 1;
751
+ const hasNewCounters = typeof raw.injectCount === "number" && Number.isFinite(raw.injectCount) && raw.injectCount >= 1;
752
+ const injectCount = hasNewCounters ? Math.floor(raw.injectCount) : legacyInjects;
753
+ const nudgeCount = hasNewCounters ? typeof raw.nudgeCount === "number" && Number.isFinite(raw.nudgeCount) && raw.nudgeCount >= 0 ? Math.floor(raw.nudgeCount) : 1 : 0;
754
+ const lastContactSeen = typeof raw.lastContactSeen === "string" ? raw.lastContactSeen : null;
755
+ const firstNudgeAtMs = typeof raw.firstNudgeAtMs === "number" && Number.isFinite(raw.firstNudgeAtMs) ? raw.firstNudgeAtMs : raw.injectedAtMs;
698
756
  const generation = typeof raw.generation === "number" && Number.isFinite(raw.generation) && raw.generation >= 0 ? Math.floor(raw.generation) : 0;
699
757
  return {
700
758
  step: raw.step,
701
759
  injectedAtMs: raw.injectedAtMs,
702
760
  nudgeCount,
761
+ injectCount,
762
+ firstNudgeAtMs,
763
+ lastContactSeen,
703
764
  generation,
704
765
  gaveUp: raw.gaveUp === true
705
766
  };
@@ -11527,7 +11588,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
11527
11588
  var lastVersionCheckAt = 0;
11528
11589
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
11529
11590
  var lastResponsivenessProbeAt = 0;
11530
- var agtCliVersion = true ? "0.28.571" : "dev";
11591
+ var agtCliVersion = true ? "0.28.573" : "dev";
11531
11592
  function resolveBrewPath(execFileSync2) {
11532
11593
  try {
11533
11594
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -12834,7 +12895,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
12834
12895
  if (codeNames.length === 0) return;
12835
12896
  void (async () => {
12836
12897
  try {
12837
- const { collectDiagnostics } = await import("../persistent-session-74MH2XTM.js");
12898
+ const { collectDiagnostics } = await import("../persistent-session-6UGFGI6J.js");
12838
12899
  await api.post("/host/heartbeat", {
12839
12900
  host_id: hostId,
12840
12901
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics)
@@ -12942,7 +13003,7 @@ async function pollCycle() {
12942
13003
  }
12943
13004
  try {
12944
13005
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
12945
- const { collectDiagnostics } = await import("../persistent-session-74MH2XTM.js");
13006
+ const { collectDiagnostics } = await import("../persistent-session-6UGFGI6J.js");
12946
13007
  const diagCodeNames = [...agentState.persistentSessionAgents];
12947
13008
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics) : void 0;
12948
13009
  let tailscaleHostname;
@@ -13065,7 +13126,7 @@ async function pollCycle() {
13065
13126
  collectPanelessActivityProbes,
13066
13127
  getResponsivenessIntervalMs,
13067
13128
  occupancyQualificationClassifications
13068
- } = await import("../responsiveness-probe-5VNQQZNJ.js");
13129
+ } = await import("../responsiveness-probe-O7AVC73R.js");
13069
13130
  const probeIntervalMs = getResponsivenessIntervalMs();
13070
13131
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
13071
13132
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -13156,7 +13217,7 @@ async function pollCycle() {
13156
13217
  collectResponsivenessProbes,
13157
13218
  livePendingInboundOldestAgeSeconds,
13158
13219
  parkPendingInbound
13159
- } = await import("../responsiveness-probe-5VNQQZNJ.js");
13220
+ } = await import("../responsiveness-probe-O7AVC73R.js");
13160
13221
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
13161
13222
  const wedgeNow = /* @__PURE__ */ new Date();
13162
13223
  const liveAgents = agentState.persistentSessionAgents;
@@ -15941,7 +16002,11 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
15941
16002
  const obStep = obState.step;
15942
16003
  const markerPath = join34(homedir16(), ".augmented", agent.code_name, "onboarding-drive.json");
15943
16004
  const marker = readOnboardingDriveMarker(markerPath);
15944
- const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
16005
+ const obContactRaw = refreshData.agent.manager_last_contacted_at;
16006
+ const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
16007
+ const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0, {
16008
+ managerContactedAt: obContact
16009
+ });
15945
16010
  if (decision.clearMarker) {
15946
16011
  clearOnboardingDriveMarker(markerPath);
15947
16012
  } else if (decision.inject && isOnboardingArea(obStep) && isSessionHealthy(agent.code_name)) {
@@ -15959,7 +16024,14 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
15959
16024
  reminder: decision.reminder,
15960
16025
  standDown: decision.standDown,
15961
16026
  freshRestart: decision.freshRestart,
15962
- code: agent.code_name
16027
+ code: agent.code_name,
16028
+ // ENG-8703: never accuse a manager of not replying to a message
16029
+ // that was never sent. Read from the ask counter rather than the
16030
+ // raw column, which is per-agent and survives a /onboard restart —
16031
+ // an ask in a previous generation must not license an accusation in
16032
+ // this one. `nudgeCount > 0` means an ask was credited within THIS
16033
+ // area's sequence, by construction.
16034
+ everAsked: (decision.nextMarker?.nudgeCount ?? 0) > 0
15963
16035
  }),
15964
16036
  { task_name: "onboarding" },
15965
16037
  log
@@ -16715,7 +16787,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
16715
16787
  void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
16716
16788
  void (async () => {
16717
16789
  try {
16718
- const { collectDiagnostics } = await import("../persistent-session-74MH2XTM.js");
16790
+ const { collectDiagnostics } = await import("../persistent-session-6UGFGI6J.js");
16719
16791
  await api.post("/host/heartbeat", {
16720
16792
  host_id: hostId,
16721
16793
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics)
@@ -16766,7 +16838,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
16766
16838
  }
16767
16839
  try {
16768
16840
  const hostId = await getHostId();
16769
- const { collectDiagnostics } = await import("../persistent-session-74MH2XTM.js");
16841
+ const { collectDiagnostics } = await import("../persistent-session-6UGFGI6J.js");
16770
16842
  await api.post("/host/heartbeat", {
16771
16843
  host_id: hostId,
16772
16844
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics)
@@ -17344,7 +17416,7 @@ async function processClaudePairSessions(agents) {
17344
17416
  killPairSession,
17345
17417
  pairTmuxSession,
17346
17418
  finalizeClaudePairOnboarding
17347
- } = await import("../claude-pair-runtime-XTRJNDP2.js");
17419
+ } = await import("../claude-pair-runtime-T4ZR7AJU.js");
17348
17420
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
17349
17421
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
17350
17422
  const killed = await killPairSession(pairTmuxSession(pairId));