@integrity-labs/agt-cli 0.28.74 → 0.28.76

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.
@@ -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-VKRJVW7A.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-ZUGPA5HU.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-6KND4QS7.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-75J2Q6BN.js.map
@@ -27,7 +27,7 @@ import {
27
27
  requireHost,
28
28
  safeWriteJsonAtomic,
29
29
  setConfigHash
30
- } from "../chunk-WNUAEC22.js";
30
+ } from "../chunk-5TJ25V24.js";
31
31
  import {
32
32
  getProjectDir as getProjectDir2,
33
33
  getReadyTasks,
@@ -65,7 +65,7 @@ import {
65
65
  takeWatchdogGiveUpCount,
66
66
  takeZombieDetection,
67
67
  transcriptActivityAgeSeconds
68
- } from "../chunk-AB57D3NN.js";
68
+ } from "../chunk-4NTTCTDC.js";
69
69
  import {
70
70
  FLAGS_SCHEMA_VERSION,
71
71
  FLAG_REGISTRY,
@@ -75,6 +75,7 @@ import {
75
75
  StreamEncoder,
76
76
  appendDmFooter,
77
77
  attributeTranscriptUsageByRun,
78
+ buildScheduledTaskContextBlocks,
78
79
  classifyActor,
79
80
  classifyOutput,
80
81
  coerceOnboardingState,
@@ -84,6 +85,7 @@ import {
84
85
  formatRunMarker,
85
86
  getFramework,
86
87
  isEmptyTotals,
88
+ isOnboardingArea,
87
89
  isParseError,
88
90
  isResolveError,
89
91
  isSelfCompletion,
@@ -97,7 +99,7 @@ import {
97
99
  resolveDmTarget,
98
100
  sumTranscriptUsageInWindow,
99
101
  wrapScheduledTaskPrompt
100
- } from "../chunk-PXMYLQWB.js";
102
+ } from "../chunk-GHH23BAM.js";
101
103
  import {
102
104
  parsePsRows,
103
105
  reapOrphanChannelMcps
@@ -846,7 +848,7 @@ import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, rmSync, writeFi
846
848
  import { dirname as dirname2 } from "path";
847
849
  var ONBOARDING_REINJECT_INTERVAL_MS = 20 * 6e4;
848
850
  function decideOnboardingDrive(step, marker, nowMs, reinjectIntervalMs = ONBOARDING_REINJECT_INTERVAL_MS) {
849
- if (step === "interviewing" || step === "configuring") {
851
+ if (isOnboardingArea(step)) {
850
852
  const sameStep = marker?.step === step;
851
853
  const stale = sameStep && nowMs - marker.injectedAtMs >= reinjectIntervalMs;
852
854
  if (!sameStep || stale) {
@@ -856,14 +858,19 @@ function decideOnboardingDrive(step, marker, nowMs, reinjectIntervalMs = ONBOARD
856
858
  }
857
859
  return { inject: false, clearMarker: marker !== null, nextMarker: null };
858
860
  }
861
+ var AREA_DIRECTIVE = {
862
+ framing: "Frame the work \u2014 ask your manager what matters in week one and what success looks like, then record it with memory_save",
863
+ tasks: "Set up your recurring work \u2014 propose your role default scheduled tasks, let your manager pick which to set up, then call onboarding_provision_tasks with their choices and tune the result",
864
+ integrations: "Wire up your tools \u2014 ask your manager which integrations your role uses and request access to the ones they confirm (connecting is a human OAuth step)",
865
+ reporting: "Agree how you keep your manager posted \u2014 settle on a cadence and channel, then create a recurring report scheduled task for it"
866
+ };
859
867
  function buildOnboardingDirective(step) {
860
- const phase = step === "interviewing" ? "Interview your manager over their preferred channel to gather setup context (priorities, tools/SaaS to use, reporting cadence)" : "Configure yourself \u2014 propose your role default scheduled tasks and let your manager pick which to set up (then call onboarding_provision_tasks with their choices), tune the provisioned tasks, connect integrations, and add any role-specific extras";
861
- return `\u{1F680} Onboarding (${step}): your self-onboarding is active and waiting on you. Call the \`onboarding_get\` tool now to see your current step and full instructions, then proceed. ${phase}. Advance with \`onboarding_advance\` (INTERVIEW_DONE \u2192 configuring, CONFIGURE_DONE \u2192 ready).`;
868
+ return `\u{1F680} Onboarding (${step}): your self-onboarding is active and waiting on you. Call the \`onboarding_get\` tool now to see this area's questions and full instructions, then proceed. ${AREA_DIRECTIVE[step]}. Advance with \`onboarding_advance\` (ADVANCE) once this area is done.`;
862
869
  }
863
870
  function readOnboardingDriveMarker(path) {
864
871
  try {
865
872
  const raw = JSON.parse(readFileSync2(path, "utf8"));
866
- if ((raw.step === "interviewing" || raw.step === "configuring") && typeof raw.injectedAtMs === "number" && Number.isFinite(raw.injectedAtMs)) {
873
+ if (typeof raw.step === "string" && isOnboardingArea(raw.step) && typeof raw.injectedAtMs === "number" && Number.isFinite(raw.injectedAtMs)) {
867
874
  return { step: raw.step, injectedAtMs: raw.injectedAtMs };
868
875
  }
869
876
  } catch {
@@ -3882,6 +3889,9 @@ var KANBAN_WORK_TEMPLATES = /* @__PURE__ */ new Set(["kanban-work"]);
3882
3889
  function isPlainScheduledTemplate(templateId) {
3883
3890
  return !STANDUP_TEMPLATES.has(templateId) && !TASK_UPDATE_TEMPLATES.has(templateId) && !PLAN_TEMPLATES.has(templateId) && !KANBAN_WORK_TEMPLATES.has(templateId);
3884
3891
  }
3892
+ function isManagerSideEffectTemplate(templateId) {
3893
+ return STANDUP_TEMPLATES.has(templateId) || TASK_UPDATE_TEMPLATES.has(templateId);
3894
+ }
3885
3895
  function isKanbanHybridEnabled() {
3886
3896
  return true;
3887
3897
  }
@@ -4824,7 +4834,7 @@ async function deliverScheduledTaskOutput(agentCodeName, agentId, rawTarget, bod
4824
4834
  }
4825
4835
 
4826
4836
  // src/lib/manager/scheduler/kanban-route.ts
4827
- async function deliverScheduledCardResult(codeName, agentId, cardId) {
4837
+ async function deliverScheduledCardResult(codeName, agentId, cardId, completedBy = "self") {
4828
4838
  if (!claimScheduledCardDelivery(cardId)) {
4829
4839
  return completedScheduledCards.has(cardId) ? "terminal" : "in_flight";
4830
4840
  }
@@ -4856,8 +4866,11 @@ async function deliverScheduledCardResult(codeName, agentId, cardId) {
4856
4866
  markScheduledCardDeliveryComplete(cardId);
4857
4867
  return "terminal";
4858
4868
  }
4859
- if (!isPlainScheduledTemplate(task.templateId)) {
4860
- log(`[scheduled-kanban] delivery: card ${cardId} template '${task.templateId}' on '${codeName}' is not a plain scheduled template \u2014 skipping manager delivery`);
4869
+ const isPlain = isPlainScheduledTemplate(task.templateId);
4870
+ const isPlanFamily = PLAN_TEMPLATES.has(task.templateId);
4871
+ const isManagerSideEffect = isManagerSideEffectTemplate(task.templateId);
4872
+ if (!isPlain && !isPlanFamily && !(isManagerSideEffect && completedBy === "self")) {
4873
+ log(`[scheduled-kanban] delivery: card ${cardId} template '${task.templateId}' on '${codeName}' (completedBy=${completedBy}) has no eligible manager side effect \u2014 skipping manager delivery`);
4861
4874
  markScheduledCardDeliveryComplete(cardId);
4862
4875
  return "terminal";
4863
4876
  }
@@ -4890,7 +4903,8 @@ async function deliverScheduledCardResult(codeName, agentId, cardId) {
4890
4903
  mode: task.deliveryMode,
4891
4904
  channel: task.deliveryChannel,
4892
4905
  to: task.deliveryTo,
4893
- taskId: task.taskId
4906
+ taskId: task.taskId,
4907
+ skipBoardSideEffects: true
4894
4908
  });
4895
4909
  if (!outcome.ok) {
4896
4910
  releaseScheduledCardDelivery(cardId);
@@ -4909,7 +4923,7 @@ async function reconcileScheduledRuns(codeName, agentId, board) {
4909
4923
  const card = byId.get(cardId);
4910
4924
  if (!card) continue;
4911
4925
  if (card.status === "done") {
4912
- const result = await deliverScheduledCardResult(codeName, agentId, cardId);
4926
+ const result = await deliverScheduledCardResult(codeName, agentId, cardId, "self");
4913
4927
  if (result === "retry" || result === "in_flight") continue;
4914
4928
  m.delete(cardId);
4915
4929
  void finishRun(runId, "completed", { outcomeMessage: "scheduled-task card done" });
@@ -4926,7 +4940,15 @@ var SCHEDULED_CARD_DELIVERY_CONTRACT = `
4926
4940
  [delivery contract \u2014 system]
4927
4941
  The result you write on this card IS the message that will be delivered to the user. Delivery happens automatically from the card \u2014 never send, post, or message it yourself.
4928
4942
  If \u2014 and ONLY if \u2014 the task above contains explicit opt-out wording the user typed ("DO NOT notify me unless \u2026", "only if X", "stay silent unless \u2026") and that condition is NOT met this run, call kanban_done with suppress_delivery: true \u2014 your result is still recorded on the card but will NOT be messaged to the user. That is how you honor the user's do-not-notify instruction; a "nothing urgent" / "all quiet" result WITHOUT the flag would still be DELIVERED as a message. (Legacy fallback: writing exactly ${SUPPRESS_SENTINEL} alone as the result also suppresses.) If the task asks for a digest/report WITHOUT opt-out wording, a zero-item report is a valid deliverable \u2014 deliver it.`;
4943
+ var SCHEDULED_CARD_PLAN_INSTRUCTION = `
4944
+
4945
+ ---
4946
+ [planning task \u2014 system]
4947
+ This is a board-PLANNING task. Review your current board with kanban_list, then create each item of today's plan as its OWN card using kanban_add (status: todo, with a sensible priority and estimate). Do NOT just write the plan as text \u2014 the cards you create with kanban_add ARE the deliverable; nothing parses a plan out of this card's result. When done, write a brief summary of the plan you created as this card's result and mark it done.`;
4929
4948
  async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt) {
4949
+ const priorRuns = await fetchPriorScheduledRuns(agentId, task.taskId);
4950
+ const contextBlocks = buildScheduledTaskContextBlocks({ priorRuns, timezone: task.timezone });
4951
+ const cardDescription = contextBlocks + (PLAN_TEMPLATES.has(task.templateId) ? prompt + SCHEDULED_CARD_PLAN_INSTRUCTION : prompt + SCHEDULED_CARD_DELIVERY_CONTRACT);
4930
4952
  const { run_id, kanban_item_id } = await startRun({
4931
4953
  agent_id: agentId,
4932
4954
  source_type: "scheduled_task",
@@ -4934,7 +4956,7 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt) {
4934
4956
  metadata: { template_id: task.templateId, name: task.name, via: "kanban-inject" },
4935
4957
  materialize_kanban: {
4936
4958
  title: task.name,
4937
- description: prompt + SCHEDULED_CARD_DELIVERY_CONTRACT,
4959
+ description: cardDescription,
4938
4960
  priority: 2,
4939
4961
  initial_status: "todo",
4940
4962
  ...deriveScheduledTaskNotify(task)
@@ -4995,6 +5017,7 @@ async function fireScheduledTaskViaKanban(codeName, agentId, task, prompt) {
4995
5017
  return routed;
4996
5018
  }
4997
5019
  async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput, delivery) {
5020
+ const skipBoardSideEffects = delivery?.skipBoardSideEffects === true;
4998
5021
  try {
4999
5022
  const classification = classifyOutput(rawOutput);
5000
5023
  if (classification.action === "suppress") {
@@ -5031,7 +5054,7 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
5031
5054
  current_tasks: output.slice(0, 2e3)
5032
5055
  });
5033
5056
  log(`[claude-scheduler] Task update posted for '${codeName}'`);
5034
- } else if (PLAN_TEMPLATES.has(templateId)) {
5057
+ } else if (PLAN_TEMPLATES.has(templateId) && !skipBoardSideEffects) {
5035
5058
  const planItems = parsePlanItems(output);
5036
5059
  if (planItems.length > 0) {
5037
5060
  await api.post("/host/kanban", {
@@ -5040,7 +5063,7 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
5040
5063
  });
5041
5064
  log(`[claude-scheduler] Plan items posted for '${codeName}' (${planItems.length} items)`);
5042
5065
  }
5043
- } else if (KANBAN_WORK_TEMPLATES.has(templateId)) {
5066
+ } else if (KANBAN_WORK_TEMPLATES.has(templateId) && !skipBoardSideEffects) {
5044
5067
  const kanbanUpdates = parseKanbanUpdates(output);
5045
5068
  if (kanbanUpdates.length > 0) {
5046
5069
  await api.post("/host/kanban", {
@@ -5127,7 +5150,7 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
5127
5150
  }
5128
5151
  inFlightClaudeTasks.add(task.taskId);
5129
5152
  claudeTaskConcurrency.set(codeName, (claudeTaskConcurrency.get(codeName) ?? 0) + 1);
5130
- if (isScheduledViaKanbanEnabled() && isPlainScheduledTemplate(task.templateId)) {
5153
+ if (isScheduledViaKanbanEnabled() && (isPlainScheduledTemplate(task.templateId) || isManagerSideEffectTemplate(task.templateId) || PLAN_TEMPLATES.has(task.templateId))) {
5131
5154
  await fireScheduledTaskViaKanban(codeName, agent.agent_id, task, prompt);
5132
5155
  inFlightClaudeTasks.delete(task.taskId);
5133
5156
  claudeTaskConcurrency.set(codeName, Math.max(0, (claudeTaskConcurrency.get(codeName) ?? 1) - 1));
@@ -6775,7 +6798,7 @@ var cachedMaintenanceWindow = null;
6775
6798
  var lastVersionCheckAt = 0;
6776
6799
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
6777
6800
  var lastResponsivenessProbeAt = 0;
6778
- var agtCliVersion = true ? "0.28.74" : "dev";
6801
+ var agtCliVersion = true ? "0.28.76" : "dev";
6779
6802
  function resolveBrewPath(execFileSync4) {
6780
6803
  try {
6781
6804
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -7883,7 +7906,7 @@ async function pollCycle() {
7883
7906
  }
7884
7907
  try {
7885
7908
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
7886
- const { collectDiagnostics } = await import("../persistent-session-VKRJVW7A.js");
7909
+ const { collectDiagnostics } = await import("../persistent-session-ZUGPA5HU.js");
7887
7910
  const diagCodeNames = [...agentState.persistentSessionAgents];
7888
7911
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
7889
7912
  let tailscaleHostname;
@@ -7984,7 +8007,7 @@ async function pollCycle() {
7984
8007
  const {
7985
8008
  collectResponsivenessProbes,
7986
8009
  getResponsivenessIntervalMs
7987
- } = await import("../responsiveness-probe-2VTHIPLG.js");
8010
+ } = await import("../responsiveness-probe-KDMBLW5W.js");
7988
8011
  const probeIntervalMs = getResponsivenessIntervalMs();
7989
8012
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
7990
8013
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -8016,7 +8039,7 @@ async function pollCycle() {
8016
8039
  collectResponsivenessProbes,
8017
8040
  livePendingInboundOldestAgeSeconds,
8018
8041
  parkPendingInbound
8019
- } = await import("../responsiveness-probe-2VTHIPLG.js");
8042
+ } = await import("../responsiveness-probe-KDMBLW5W.js");
8020
8043
  const { getProjectDir: wedgeProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
8021
8044
  const wedgeNow = /* @__PURE__ */ new Date();
8022
8045
  const liveAgents = agentState.persistentSessionAgents;
@@ -10279,7 +10302,7 @@ In progress for ${age} minutes \u2014 auto-failed`).catch(() => {
10279
10302
  const decision = decideOnboardingDrive(obStep, marker, Date.now());
10280
10303
  if (decision.clearMarker) {
10281
10304
  clearOnboardingDriveMarker(markerPath);
10282
- } else if (decision.inject && (obStep === "interviewing" || obStep === "configuring") && isSessionHealthy(agent.code_name)) {
10305
+ } else if (decision.inject && isOnboardingArea(obStep) && isSessionHealthy(agent.code_name)) {
10283
10306
  const delivered = await injectMessage(
10284
10307
  agent.code_name,
10285
10308
  "system",
@@ -10926,7 +10949,7 @@ function ensureRealtimeKanbanStarted(agentStates) {
10926
10949
  `[realtime] Kanban completion forwarded for '${codeName}': item=${event.item_id} status=${event.status} actor=${event.last_actor_id ?? "unknown"}`
10927
10950
  );
10928
10951
  if (event.status === "done" && (isScheduledViaKanbanEnabled() || isKanbanHybridEnabled()) && classifyActor(event.last_actor_id, event.agent_id) === "user" && isScheduledCardTracked(event.item_id)) {
10929
- void deliverScheduledCardResult(codeName, event.agent_id, event.item_id);
10952
+ void deliverScheduledCardResult(codeName, event.agent_id, event.item_id, "user");
10930
10953
  }
10931
10954
  },
10932
10955
  log
@@ -11479,7 +11502,7 @@ async function processClaudePairSessions(agents) {
11479
11502
  killPairSession,
11480
11503
  pairTmuxSession,
11481
11504
  finalizeClaudePairOnboarding
11482
- } = await import("../claude-pair-runtime-6KND4QS7.js");
11505
+ } = await import("../claude-pair-runtime-75J2Q6BN.js");
11483
11506
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
11484
11507
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
11485
11508
  const killed = await killPairSession(pairTmuxSession(pairId));