@integrity-labs/agt-cli 0.28.676 → 0.28.677

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 (24) hide show
  1. package/dist/bin/agt.js +5 -5
  2. package/dist/{chunk-7Y54PSMR.js → chunk-F6CUSDJ6.js} +2 -2
  3. package/dist/{chunk-AJNES24H.js → chunk-GYYEUNTD.js} +26 -1
  4. package/dist/chunk-GYYEUNTD.js.map +1 -0
  5. package/dist/{chunk-S6TPCOGW.js → chunk-HTLUHAKN.js} +4 -4
  6. package/dist/{claude-pair-runtime-VAU7UXE4.js → claude-pair-runtime-MY5LMJVT.js} +2 -2
  7. package/dist/lib/manager-worker.js +13 -13
  8. package/dist/mcp/augmented-admin.js +34 -1
  9. package/dist/mcp/direct-chat-channel.js +25 -0
  10. package/dist/mcp/index.js +25 -0
  11. package/dist/mcp/origami.js +25 -0
  12. package/dist/mcp/slack-channel.js +25 -0
  13. package/dist/mcp/telegram-channel.js +25 -0
  14. package/dist/{persistent-session-F7JEOWHQ.js → persistent-session-TMOTEVV6.js} +3 -3
  15. package/dist/{responsiveness-probe-7465YNMN.js → responsiveness-probe-ZHE7S6G4.js} +3 -3
  16. package/dist/{session-auth-dead-GBC5QPH3.js → session-auth-dead-JCKENEY5.js} +2 -2
  17. package/package.json +1 -1
  18. package/dist/chunk-AJNES24H.js.map +0 -1
  19. /package/dist/{chunk-7Y54PSMR.js.map → chunk-F6CUSDJ6.js.map} +0 -0
  20. /package/dist/{chunk-S6TPCOGW.js.map → chunk-HTLUHAKN.js.map} +0 -0
  21. /package/dist/{claude-pair-runtime-VAU7UXE4.js.map → claude-pair-runtime-MY5LMJVT.js.map} +0 -0
  22. /package/dist/{persistent-session-F7JEOWHQ.js.map → persistent-session-TMOTEVV6.js.map} +0 -0
  23. /package/dist/{responsiveness-probe-7465YNMN.js.map → responsiveness-probe-ZHE7S6G4.js.map} +0 -0
  24. /package/dist/{session-auth-dead-GBC5QPH3.js.map → session-auth-dead-JCKENEY5.js.map} +0 -0
@@ -12,7 +12,7 @@ import {
12
12
  parseEnvFileEntries,
13
13
  parseEnvIntegrations,
14
14
  shellQuote
15
- } from "./chunk-7Y54PSMR.js";
15
+ } from "./chunk-F6CUSDJ6.js";
16
16
  import {
17
17
  BIND_FAILURE_QUARANTINE_THRESHOLD,
18
18
  INTEGRATIONS_SECTION_END,
@@ -59,7 +59,7 @@ import {
59
59
  resolveConnectivityProbe,
60
60
  worseConnectivityOutcome,
61
61
  wrapScheduledTaskPrompt
62
- } from "./chunk-AJNES24H.js";
62
+ } from "./chunk-GYYEUNTD.js";
63
63
  import {
64
64
  parsePsRows
65
65
  } from "./chunk-XWVM4KPK.js";
@@ -6292,7 +6292,7 @@ function exchangeFailureKind(err) {
6292
6292
  }
6293
6293
 
6294
6294
  // src/lib/api-client.ts
6295
- var agtCliVersion = true ? "0.28.676" : "dev";
6295
+ var agtCliVersion = true ? "0.28.677" : "dev";
6296
6296
  var lastConfigHash = null;
6297
6297
  function setConfigHash(hash) {
6298
6298
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -10033,4 +10033,4 @@ export {
10033
10033
  managerInstallSystemUnitCommand,
10034
10034
  managerUninstallSystemUnitCommand
10035
10035
  };
10036
- //# sourceMappingURL=chunk-S6TPCOGW.js.map
10036
+ //# sourceMappingURL=chunk-HTLUHAKN.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-F7JEOWHQ.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-TMOTEVV6.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-VAU7UXE4.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-MY5LMJVT.js.map
@@ -54,7 +54,7 @@ import {
54
54
  safeWriteJsonAtomic,
55
55
  setConfigHash,
56
56
  tripClass
57
- } from "../chunk-S6TPCOGW.js";
57
+ } from "../chunk-HTLUHAKN.js";
58
58
  import {
59
59
  getProjectDir as getProjectDir2,
60
60
  getReadyTasks,
@@ -112,7 +112,7 @@ import {
112
112
  takeZombieDetection,
113
113
  toOpencodeModel,
114
114
  writeEgressAllowlist
115
- } from "../chunk-7Y54PSMR.js";
115
+ } from "../chunk-F6CUSDJ6.js";
116
116
  import {
117
117
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
118
118
  AnchorSessionClient,
@@ -193,7 +193,7 @@ import {
193
193
  subagentActivityAgeSeconds,
194
194
  sumTranscriptUsageInWindow,
195
195
  transcriptActivityAgeSeconds
196
- } from "../chunk-AJNES24H.js";
196
+ } from "../chunk-GYYEUNTD.js";
197
197
  import {
198
198
  reapOrphanChannelMcps
199
199
  } from "../chunk-XWVM4KPK.js";
@@ -11711,7 +11711,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
11711
11711
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
11712
11712
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
11713
11713
  async function channelInboundActivityAgeSecondsFor(codeName) {
11714
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-7465YNMN.js");
11714
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-ZHE7S6G4.js");
11715
11715
  const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
11716
11716
  if (newest === null) return null;
11717
11717
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -12359,7 +12359,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
12359
12359
  var lastVersionCheckAt = 0;
12360
12360
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12361
12361
  var lastResponsivenessProbeAt = 0;
12362
- var agtCliVersion = true ? "0.28.676" : "dev";
12362
+ var agtCliVersion = true ? "0.28.677" : "dev";
12363
12363
  function resolveBrewPath(execFileSync3) {
12364
12364
  try {
12365
12365
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -13820,7 +13820,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
13820
13820
  if (codeNames.length === 0) return;
13821
13821
  void (async () => {
13822
13822
  try {
13823
- const { collectDiagnostics } = await import("../persistent-session-F7JEOWHQ.js");
13823
+ const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
13824
13824
  await api.post("/host/heartbeat", {
13825
13825
  host_id: hostId,
13826
13826
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -13937,7 +13937,7 @@ async function pollCycleInner() {
13937
13937
  }
13938
13938
  try {
13939
13939
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
13940
- const { collectDiagnostics } = await import("../persistent-session-F7JEOWHQ.js");
13940
+ const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
13941
13941
  const diagCodeNames = [...agentState.persistentSessionAgents];
13942
13942
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor) : void 0;
13943
13943
  let tailscaleHostname;
@@ -14089,7 +14089,7 @@ async function pollCycleInner() {
14089
14089
  collectPanelessActivityProbes,
14090
14090
  getResponsivenessIntervalMs,
14091
14091
  occupancyQualificationClassifications
14092
- } = await import("../responsiveness-probe-7465YNMN.js");
14092
+ } = await import("../responsiveness-probe-ZHE7S6G4.js");
14093
14093
  const probeIntervalMs = getResponsivenessIntervalMs();
14094
14094
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
14095
14095
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -14199,7 +14199,7 @@ async function pollCycleInner() {
14199
14199
  collectResponsivenessProbes,
14200
14200
  livePendingInboundOldestAgeSeconds,
14201
14201
  parkPendingInbound
14202
- } = await import("../responsiveness-probe-7465YNMN.js");
14202
+ } = await import("../responsiveness-probe-ZHE7S6G4.js");
14203
14203
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
14204
14204
  const wedgeNow = /* @__PURE__ */ new Date();
14205
14205
  const liveAgents = agentState.persistentSessionAgents;
@@ -14355,7 +14355,7 @@ async function pollCycleInner() {
14355
14355
  }
14356
14356
  try {
14357
14357
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
14358
- const { probeSessionAuth } = await import("../session-auth-dead-GBC5QPH3.js");
14358
+ const { probeSessionAuth } = await import("../session-auth-dead-JCKENEY5.js");
14359
14359
  const observations = [];
14360
14360
  const pendingCacheCommits = [];
14361
14361
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -18115,7 +18115,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
18115
18115
  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}`));
18116
18116
  void (async () => {
18117
18117
  try {
18118
- const { collectDiagnostics } = await import("../persistent-session-F7JEOWHQ.js");
18118
+ const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
18119
18119
  await api.post("/host/heartbeat", {
18120
18120
  host_id: hostId,
18121
18121
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -18166,7 +18166,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
18166
18166
  }
18167
18167
  try {
18168
18168
  const hostId = await getHostId();
18169
- const { collectDiagnostics } = await import("../persistent-session-F7JEOWHQ.js");
18169
+ const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
18170
18170
  await api.post("/host/heartbeat", {
18171
18171
  host_id: hostId,
18172
18172
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -18798,7 +18798,7 @@ async function processClaudePairSessions(agents) {
18798
18798
  killPairSession,
18799
18799
  pairTmuxSession,
18800
18800
  finalizeClaudePairOnboarding
18801
- } = await import("../claude-pair-runtime-VAU7UXE4.js");
18801
+ } = await import("../claude-pair-runtime-MY5LMJVT.js");
18802
18802
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
18803
18803
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
18804
18804
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -21326,6 +21326,18 @@ var AdminDebugClient = class _AdminDebugClient {
21326
21326
  run_id: this.runId
21327
21327
  });
21328
21328
  }
21329
+ /** Request a HITL-gated end to a circuit-breaker pause (ENG-9343). */
21330
+ requestResumeAgent(args) {
21331
+ if (!this.agentId) {
21332
+ throw makeError(400, "AdminDebugClient.requestResumeAgent requires agentId (set AGT_AGENT_ID)");
21333
+ }
21334
+ return this.post("/admin/debug/actions/resume", {
21335
+ target_agent_id: args.target_agent_id,
21336
+ reason: args.reason,
21337
+ agent_id: this.agentId,
21338
+ run_id: this.runId
21339
+ });
21340
+ }
21329
21341
  /** Poll a remedial action's HITL decision. */
21330
21342
  getActionStatus(requestId) {
21331
21343
  return this.get(`/admin/debug/actions/${encodeURIComponent(requestId)}`);
@@ -21457,6 +21469,12 @@ var clearRestartRequestSchema = strictObject({
21457
21469
  target_agent_id: external_exports.string().min(1).max(64).describe("UUID of the customer agent whose stuck restart request to clear (from the inspect result)."),
21458
21470
  reason: external_exports.string().min(1).max(2e3).describe("Why this stuck restart request should be cleared \u2014 shown verbatim to the human approver. Be specific.")
21459
21471
  });
21472
+ var resumeAgentSchema = strictObject({
21473
+ target_agent_id: external_exports.string().min(1).max(64).describe("UUID of the customer agent whose CIRCUIT-BREAKER pause to end (from debug_search_agents status=paused)."),
21474
+ reason: external_exports.string().min(1).max(2e3).describe(
21475
+ 'Why this agent should come back now, and what you know about the condition that tripped the breaker - shown verbatim to the human approver alongside the trip reason and count. Be specific: the approver is deciding "resume DESPITE this driver", not "resume".'
21476
+ )
21477
+ });
21460
21478
  var listAlertsSchema = strictObject({
21461
21479
  severity: external_exports.string().max(16).optional().describe("Filter by severity (critical | warning | info)."),
21462
21480
  open: external_exports.boolean().optional().describe("When true, only currently-open (unclosed) alerts."),
@@ -21869,7 +21887,7 @@ server.registerTool(
21869
21887
  );
21870
21888
  server.registerTool(
21871
21889
  "debug_restart_agent",
21872
- { description: `Request a HITL-gated RESTART of a customer agent \u2014 bounce its session so the manager respawns it on the next poll (reversible; the inbound backlog replays). Use this to recover a wedged agent or to make it pick up a newly-bound integration/config change. A HUMAN must approve in Slack before anything happens, and only if writes are armed for this stage; in shadow mode the approval runs but nothing executes. Org-agnostic: keyed on the agent's host assignment, so it works cross-org without an active-org dependency. This is the same path as request_action({ action: "restart" }), exposed as a dedicated tool for discoverability. Returns { request_id, status, write_mode, notification_status }. Surface a brief, jargon-free note to the user (e.g. "I've asked an admin to approve restarting that agent"). Pass { target_agent_id, reason }.`, inputSchema: restartAgentSchema },
21890
+ { description: `Request a HITL-gated RESTART of a customer agent \u2014 bounce its session so the manager respawns it on the next poll (reversible; the inbound backlog replays). Use this to recover a wedged agent or to make it pick up a newly-bound integration/config change. NOT for a PAUSED agent: a paused agent's manager does not respawn it, so a restart against one does nothing at all - use \`debug_resume_agent\`, which is the only tool that ends a pause (ENG-9343). A HUMAN must approve in Slack before anything happens, and only if writes are armed for this stage; in shadow mode the approval runs but nothing executes. Org-agnostic: keyed on the agent's host assignment, so it works cross-org without an active-org dependency. This is the same path as request_action({ action: "restart" }), exposed as a dedicated tool for discoverability. Returns { request_id, status, write_mode, notification_status }. Surface a brief, jargon-free note to the user (e.g. "I've asked an admin to approve restarting that agent"). Pass { target_agent_id, reason }.`, inputSchema: restartAgentSchema },
21873
21891
  async (args) => {
21874
21892
  try {
21875
21893
  const result = await client.requestAction("restart", {
@@ -21882,6 +21900,21 @@ server.registerTool(
21882
21900
  }
21883
21901
  }
21884
21902
  );
21903
+ server.registerTool(
21904
+ "debug_resume_agent",
21905
+ { description: 'Request a HITL-gated END to a customer agent\'s CIRCUIT-BREAKER pause - flip it back to active so its manager respawns it, close the agent_paused alert, and clear any pending restart request. This is the ONLY tool that ends a pause; debug_restart_agent does NOT, because a paused agent\'s manager never respawns it, so a restart against a paused agent is a no-op. SCOPE: it touches ONLY pauses whose reason is `circuit_breaker`. A "manual" pause (a person clicked Pause) and an "hourly_cost_exceeded" pause (a budget guard) are refused with a 409 - do not retry those, escalate to a human. BEFORE YOU CALL IT: the approval card names the breaker\'s trip reason and count and flags when that condition still appears to hold (e.g. other agents on the same host tripping on the same driver), so write a `reason` that addresses the driver, not just the downtime - the approver is deciding "resume DESPITE day-rollover=3", not "resume". Resuming while the driver is still live just re-trips the breaker and the agent flaps instead of failing cleanly. A HUMAN must approve in Slack, and only if writes are armed for this stage (shadow mode runs the approval but executes nothing). Returns { request_id, status, write_mode, trip_driver, trip_count, precondition_verdict, precondition_signals, notification_status }; after approval, poll check_action_status (result_payload carries { resumed, alert_closed, cleared_restart_bindings } or { resumed: false, not_eligible }). Pass { target_agent_id, reason }.', inputSchema: resumeAgentSchema },
21906
+ async (args) => {
21907
+ try {
21908
+ const result = await client.requestResumeAgent({
21909
+ target_agent_id: args.target_agent_id,
21910
+ reason: args.reason
21911
+ });
21912
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
21913
+ } catch (err) {
21914
+ return { content: [{ type: "text", text: formatError2(err) }], isError: true };
21915
+ }
21916
+ }
21917
+ );
21885
21918
  server.registerTool(
21886
21919
  "request_config_update",
21887
21920
  { description: "Request a HITL-gated change to a customer agent's model config (primary/secondary/tertiary_model). A HUMAN must approve in Slack before anything happens, and only if writes are armed for this stage (shadow mode runs the approval but executes nothing). The change is reversible and applies at the agent's NEXT session launch after /host/refresh \u2014 it does not restart the agent. The new value is validated against the agent before approval is requested: Claude Code (subscription) agents take a family alias (fable/opus/opus[fast]/sonnet/haiku); routed agents take a full stored model id (e.g. openrouter/anthropic/claude-opus-4-6). Use this to fix a misconfigured model (e.g. an agent wedged on a model its auth can't access). Returns { request_id, status, write_mode, notification_status }. Pass { target_agent_id, field, new_value, reason }.", inputSchema: requestConfigUpdateSchema },
@@ -34277,6 +34277,9 @@ var DIRECTIVE_KINDS = [
34277
34277
  ];
34278
34278
  var DIRECTIVE_SET = new Set(DIRECTIVE_KINDS);
34279
34279
 
34280
+ // ../core/dist/admin-debug/resume-precondition.js
34281
+ var DEFAULT_RESUME_LOOKBACK_MS = 14 * 24 * 60 * 60 * 1e3;
34282
+
34280
34283
  // ../core/dist/admin-debug/index.js
34281
34284
  var STUCK_RESTART_THRESHOLD_SECONDS = 15 * 60;
34282
34285
 
@@ -36563,6 +36566,28 @@ var FLAG_REGISTRY = [
36563
36566
  // exactly the org whose brand should be shown.
36564
36567
  public: true
36565
36568
  },
36569
+ {
36570
+ key: "ninjafy-logo",
36571
+ description: "Which Ninjafy logo TREATMENT the console chrome renders (ENG-9365). This is a SUB-SELECTION under ninjafy-brand, not a second brand gate: it is consulted only once ninjafy-brand has already resolved ON, so with the brand off the value is inert and the half-branded state that flag's description calls unreachable stays unreachable. ninjafy-brand remains the single kill switch for the rebrand. It exists so candidate logo treatments can be put in front of a human and compared in the running console, rather than judged from a static export. lockup = mark and wordmark together, both in the brand blue \u2014 exactly what ENG-9298 shipped, so an unset flag is a no-op. two-tone = the mark in brand blue with the wordmark in the neutral text colour (the treatment of the blue-icon/black-wordmark artwork). wordmark = the word alone, no mark. Every treatment is composed from the ENG-9298 geometry \u2014 ENG-9312 pins that the lockup's blue path IS the mark subpath followed by the wordmark subpaths, byte for byte \u2014 so a new treatment is a composition, never a fresh trace, and the three drawings cannot drift apart. Surfaces are the dashboard sidebar and the top nav. The top nav shows the WORDMARK portion at every width whatever the treatment, because ENG-9342 decided that deliberately (a full lockup at the header's icon height crowds the team switcher on a phone) \u2014 so a treatment changes the word's colour there, never whether a mark appears. The admin sidebar (ENG-9323) is NOT wired to this key and always renders the mark; widening it is a separate decision. Resolved SERVER-SIDE in (dashboard)/layout.tsx via getPublicEnumFlagServer, beside ninjafy-brand and in the same single GET /flags round trip, then passed down as a required prop. That is not a style preference: the client hook starts at its default and updates after an async fetch, so a client read would paint one logo and swap it after hydration \u2014 the exact flash ENG-9227 removed from the wordmark and ENG-8858 removed from the palette. Org and team are the useful pilot grains, as for ninjafy-brand: the single consumer evaluates in the active-org cookie scope, so a host- or agent-scoped override row is accepted by the table but never reached by the console.",
36572
+ flagType: "enum",
36573
+ allowedValues: ["lockup", "two-tone", "wordmark"],
36574
+ // Declared safe value is `lockup` — what ENG-9298 shipped. This flag has no
36575
+ // "off" direction: it selects among presentations that are all live-safe, so
36576
+ // fail-safe here means "the treatment currently in production", not the
36577
+ // narrowest one. A flag-DB read error, an archived row, or a stored value
36578
+ // outside allowedValues all resolve here (evaluate.ts normalizeFlagValue),
36579
+ // which is what makes an experimental value impossible to strand.
36580
+ defaultValue: "lockup",
36581
+ // Same trap as ninjafy-brand, and it bites harder here because there are no
36582
+ // client readers of this key AT ALL — it is server-resolved by construction.
36583
+ // `public` does NOT mean "read by a browser"; it means "readable through the
36584
+ // public map". getPublicEnumFlagServer resolves against the same GET /flags
36585
+ // endpoint the browser uses, and that route filters to listPublicFlagKeys()
36586
+ // (routes/flags.ts). Drop `public` and the key is simply absent from the map,
36587
+ // so the helper falls through to its default and returns `lockup` FOREVER —
36588
+ // the dropdown appearing to do nothing, with no error raised anywhere.
36589
+ public: true
36590
+ },
36566
36591
  {
36567
36592
  key: "agent-recruit",
36568
36593
  description: "The `recruit_agent` MCP tool (ENG-8159): lets an ordinary managed agent PROPOSE a new teammate in its own org. The proposal is filed under the `agent.recruit` approval verb and routed to an org owner as a server-rendered card, so this gates the ASK \u2014 nothing is created until a human taps Approve. Deliberately distinct from augmented-support-writes, which gates the concierge's own create_agent surface: the two requesters are separately controllable because an org may well want its support concierge to propose agents without giving every agent in the fleet the same power. Ships dark.",
package/dist/mcp/index.js CHANGED
@@ -41597,6 +41597,9 @@ var DIRECTIVE_KINDS = [
41597
41597
  ];
41598
41598
  var DIRECTIVE_SET = new Set(DIRECTIVE_KINDS);
41599
41599
 
41600
+ // ../core/dist/admin-debug/resume-precondition.js
41601
+ var DEFAULT_RESUME_LOOKBACK_MS = 14 * 24 * 60 * 60 * 1e3;
41602
+
41600
41603
  // ../core/dist/admin-debug/index.js
41601
41604
  var STUCK_RESTART_THRESHOLD_SECONDS = 15 * 60;
41602
41605
 
@@ -43490,6 +43493,28 @@ var FLAG_REGISTRY = [
43490
43493
  // exactly the org whose brand should be shown.
43491
43494
  public: true
43492
43495
  },
43496
+ {
43497
+ key: "ninjafy-logo",
43498
+ description: "Which Ninjafy logo TREATMENT the console chrome renders (ENG-9365). This is a SUB-SELECTION under ninjafy-brand, not a second brand gate: it is consulted only once ninjafy-brand has already resolved ON, so with the brand off the value is inert and the half-branded state that flag's description calls unreachable stays unreachable. ninjafy-brand remains the single kill switch for the rebrand. It exists so candidate logo treatments can be put in front of a human and compared in the running console, rather than judged from a static export. lockup = mark and wordmark together, both in the brand blue \u2014 exactly what ENG-9298 shipped, so an unset flag is a no-op. two-tone = the mark in brand blue with the wordmark in the neutral text colour (the treatment of the blue-icon/black-wordmark artwork). wordmark = the word alone, no mark. Every treatment is composed from the ENG-9298 geometry \u2014 ENG-9312 pins that the lockup's blue path IS the mark subpath followed by the wordmark subpaths, byte for byte \u2014 so a new treatment is a composition, never a fresh trace, and the three drawings cannot drift apart. Surfaces are the dashboard sidebar and the top nav. The top nav shows the WORDMARK portion at every width whatever the treatment, because ENG-9342 decided that deliberately (a full lockup at the header's icon height crowds the team switcher on a phone) \u2014 so a treatment changes the word's colour there, never whether a mark appears. The admin sidebar (ENG-9323) is NOT wired to this key and always renders the mark; widening it is a separate decision. Resolved SERVER-SIDE in (dashboard)/layout.tsx via getPublicEnumFlagServer, beside ninjafy-brand and in the same single GET /flags round trip, then passed down as a required prop. That is not a style preference: the client hook starts at its default and updates after an async fetch, so a client read would paint one logo and swap it after hydration \u2014 the exact flash ENG-9227 removed from the wordmark and ENG-8858 removed from the palette. Org and team are the useful pilot grains, as for ninjafy-brand: the single consumer evaluates in the active-org cookie scope, so a host- or agent-scoped override row is accepted by the table but never reached by the console.",
43499
+ flagType: "enum",
43500
+ allowedValues: ["lockup", "two-tone", "wordmark"],
43501
+ // Declared safe value is `lockup` — what ENG-9298 shipped. This flag has no
43502
+ // "off" direction: it selects among presentations that are all live-safe, so
43503
+ // fail-safe here means "the treatment currently in production", not the
43504
+ // narrowest one. A flag-DB read error, an archived row, or a stored value
43505
+ // outside allowedValues all resolve here (evaluate.ts normalizeFlagValue),
43506
+ // which is what makes an experimental value impossible to strand.
43507
+ defaultValue: "lockup",
43508
+ // Same trap as ninjafy-brand, and it bites harder here because there are no
43509
+ // client readers of this key AT ALL — it is server-resolved by construction.
43510
+ // `public` does NOT mean "read by a browser"; it means "readable through the
43511
+ // public map". getPublicEnumFlagServer resolves against the same GET /flags
43512
+ // endpoint the browser uses, and that route filters to listPublicFlagKeys()
43513
+ // (routes/flags.ts). Drop `public` and the key is simply absent from the map,
43514
+ // so the helper falls through to its default and returns `lockup` FOREVER —
43515
+ // the dropdown appearing to do nothing, with no error raised anywhere.
43516
+ public: true
43517
+ },
43493
43518
  {
43494
43519
  key: "agent-recruit",
43495
43520
  description: "The `recruit_agent` MCP tool (ENG-8159): lets an ordinary managed agent PROPOSE a new teammate in its own org. The proposal is filed under the `agent.recruit` approval verb and routed to an org owner as a server-rendered card, so this gates the ASK \u2014 nothing is created until a human taps Approve. Deliberately distinct from augmented-support-writes, which gates the concierge's own create_agent surface: the two requesters are separately controllable because an org may well want its support concierge to propose agents without giving every agent in the fleet the same power. Ships dark.",
@@ -40429,6 +40429,9 @@ var DIRECTIVE_KINDS = [
40429
40429
  ];
40430
40430
  var DIRECTIVE_SET = new Set(DIRECTIVE_KINDS);
40431
40431
 
40432
+ // ../core/dist/admin-debug/resume-precondition.js
40433
+ var DEFAULT_RESUME_LOOKBACK_MS = 14 * 24 * 60 * 60 * 1e3;
40434
+
40432
40435
  // ../core/dist/admin-debug/index.js
40433
40436
  var STUCK_RESTART_THRESHOLD_SECONDS = 15 * 60;
40434
40437
 
@@ -42301,6 +42304,28 @@ var FLAG_REGISTRY = [
42301
42304
  // exactly the org whose brand should be shown.
42302
42305
  public: true
42303
42306
  },
42307
+ {
42308
+ key: "ninjafy-logo",
42309
+ description: "Which Ninjafy logo TREATMENT the console chrome renders (ENG-9365). This is a SUB-SELECTION under ninjafy-brand, not a second brand gate: it is consulted only once ninjafy-brand has already resolved ON, so with the brand off the value is inert and the half-branded state that flag's description calls unreachable stays unreachable. ninjafy-brand remains the single kill switch for the rebrand. It exists so candidate logo treatments can be put in front of a human and compared in the running console, rather than judged from a static export. lockup = mark and wordmark together, both in the brand blue \u2014 exactly what ENG-9298 shipped, so an unset flag is a no-op. two-tone = the mark in brand blue with the wordmark in the neutral text colour (the treatment of the blue-icon/black-wordmark artwork). wordmark = the word alone, no mark. Every treatment is composed from the ENG-9298 geometry \u2014 ENG-9312 pins that the lockup's blue path IS the mark subpath followed by the wordmark subpaths, byte for byte \u2014 so a new treatment is a composition, never a fresh trace, and the three drawings cannot drift apart. Surfaces are the dashboard sidebar and the top nav. The top nav shows the WORDMARK portion at every width whatever the treatment, because ENG-9342 decided that deliberately (a full lockup at the header's icon height crowds the team switcher on a phone) \u2014 so a treatment changes the word's colour there, never whether a mark appears. The admin sidebar (ENG-9323) is NOT wired to this key and always renders the mark; widening it is a separate decision. Resolved SERVER-SIDE in (dashboard)/layout.tsx via getPublicEnumFlagServer, beside ninjafy-brand and in the same single GET /flags round trip, then passed down as a required prop. That is not a style preference: the client hook starts at its default and updates after an async fetch, so a client read would paint one logo and swap it after hydration \u2014 the exact flash ENG-9227 removed from the wordmark and ENG-8858 removed from the palette. Org and team are the useful pilot grains, as for ninjafy-brand: the single consumer evaluates in the active-org cookie scope, so a host- or agent-scoped override row is accepted by the table but never reached by the console.",
42310
+ flagType: "enum",
42311
+ allowedValues: ["lockup", "two-tone", "wordmark"],
42312
+ // Declared safe value is `lockup` — what ENG-9298 shipped. This flag has no
42313
+ // "off" direction: it selects among presentations that are all live-safe, so
42314
+ // fail-safe here means "the treatment currently in production", not the
42315
+ // narrowest one. A flag-DB read error, an archived row, or a stored value
42316
+ // outside allowedValues all resolve here (evaluate.ts normalizeFlagValue),
42317
+ // which is what makes an experimental value impossible to strand.
42318
+ defaultValue: "lockup",
42319
+ // Same trap as ninjafy-brand, and it bites harder here because there are no
42320
+ // client readers of this key AT ALL — it is server-resolved by construction.
42321
+ // `public` does NOT mean "read by a browser"; it means "readable through the
42322
+ // public map". getPublicEnumFlagServer resolves against the same GET /flags
42323
+ // endpoint the browser uses, and that route filters to listPublicFlagKeys()
42324
+ // (routes/flags.ts). Drop `public` and the key is simply absent from the map,
42325
+ // so the helper falls through to its default and returns `lockup` FOREVER —
42326
+ // the dropdown appearing to do nothing, with no error raised anywhere.
42327
+ public: true
42328
+ },
42304
42329
  {
42305
42330
  key: "agent-recruit",
42306
42331
  description: "The `recruit_agent` MCP tool (ENG-8159): lets an ordinary managed agent PROPOSE a new teammate in its own org. The proposal is filed under the `agent.recruit` approval verb and routed to an org owner as a server-rendered card, so this gates the ASK \u2014 nothing is created until a human taps Approve. Deliberately distinct from augmented-support-writes, which gates the concierge's own create_agent surface: the two requesters are separately controllable because an org may well want its support concierge to propose agents without giving every agent in the fleet the same power. Ships dark.",
@@ -34495,6 +34495,9 @@ var DIRECTIVE_KINDS = [
34495
34495
  ];
34496
34496
  var DIRECTIVE_SET = new Set(DIRECTIVE_KINDS);
34497
34497
 
34498
+ // ../core/dist/admin-debug/resume-precondition.js
34499
+ var DEFAULT_RESUME_LOOKBACK_MS = 14 * 24 * 60 * 60 * 1e3;
34500
+
34498
34501
  // ../core/dist/admin-debug/index.js
34499
34502
  var STUCK_RESTART_THRESHOLD_SECONDS = 15 * 60;
34500
34503
 
@@ -36784,6 +36787,28 @@ var FLAG_REGISTRY = [
36784
36787
  // exactly the org whose brand should be shown.
36785
36788
  public: true
36786
36789
  },
36790
+ {
36791
+ key: "ninjafy-logo",
36792
+ description: "Which Ninjafy logo TREATMENT the console chrome renders (ENG-9365). This is a SUB-SELECTION under ninjafy-brand, not a second brand gate: it is consulted only once ninjafy-brand has already resolved ON, so with the brand off the value is inert and the half-branded state that flag's description calls unreachable stays unreachable. ninjafy-brand remains the single kill switch for the rebrand. It exists so candidate logo treatments can be put in front of a human and compared in the running console, rather than judged from a static export. lockup = mark and wordmark together, both in the brand blue \u2014 exactly what ENG-9298 shipped, so an unset flag is a no-op. two-tone = the mark in brand blue with the wordmark in the neutral text colour (the treatment of the blue-icon/black-wordmark artwork). wordmark = the word alone, no mark. Every treatment is composed from the ENG-9298 geometry \u2014 ENG-9312 pins that the lockup's blue path IS the mark subpath followed by the wordmark subpaths, byte for byte \u2014 so a new treatment is a composition, never a fresh trace, and the three drawings cannot drift apart. Surfaces are the dashboard sidebar and the top nav. The top nav shows the WORDMARK portion at every width whatever the treatment, because ENG-9342 decided that deliberately (a full lockup at the header's icon height crowds the team switcher on a phone) \u2014 so a treatment changes the word's colour there, never whether a mark appears. The admin sidebar (ENG-9323) is NOT wired to this key and always renders the mark; widening it is a separate decision. Resolved SERVER-SIDE in (dashboard)/layout.tsx via getPublicEnumFlagServer, beside ninjafy-brand and in the same single GET /flags round trip, then passed down as a required prop. That is not a style preference: the client hook starts at its default and updates after an async fetch, so a client read would paint one logo and swap it after hydration \u2014 the exact flash ENG-9227 removed from the wordmark and ENG-8858 removed from the palette. Org and team are the useful pilot grains, as for ninjafy-brand: the single consumer evaluates in the active-org cookie scope, so a host- or agent-scoped override row is accepted by the table but never reached by the console.",
36793
+ flagType: "enum",
36794
+ allowedValues: ["lockup", "two-tone", "wordmark"],
36795
+ // Declared safe value is `lockup` — what ENG-9298 shipped. This flag has no
36796
+ // "off" direction: it selects among presentations that are all live-safe, so
36797
+ // fail-safe here means "the treatment currently in production", not the
36798
+ // narrowest one. A flag-DB read error, an archived row, or a stored value
36799
+ // outside allowedValues all resolve here (evaluate.ts normalizeFlagValue),
36800
+ // which is what makes an experimental value impossible to strand.
36801
+ defaultValue: "lockup",
36802
+ // Same trap as ninjafy-brand, and it bites harder here because there are no
36803
+ // client readers of this key AT ALL — it is server-resolved by construction.
36804
+ // `public` does NOT mean "read by a browser"; it means "readable through the
36805
+ // public map". getPublicEnumFlagServer resolves against the same GET /flags
36806
+ // endpoint the browser uses, and that route filters to listPublicFlagKeys()
36807
+ // (routes/flags.ts). Drop `public` and the key is simply absent from the map,
36808
+ // so the helper falls through to its default and returns `lockup` FOREVER —
36809
+ // the dropdown appearing to do nothing, with no error raised anywhere.
36810
+ public: true
36811
+ },
36787
36812
  {
36788
36813
  key: "agent-recruit",
36789
36814
  description: "The `recruit_agent` MCP tool (ENG-8159): lets an ordinary managed agent PROPOSE a new teammate in its own org. The proposal is filed under the `agent.recruit` approval verb and routed to an org owner as a server-rendered card, so this gates the ASK \u2014 nothing is created until a human taps Approve. Deliberately distinct from augmented-support-writes, which gates the concierge's own create_agent surface: the two requesters are separately controllable because an org may well want its support concierge to propose agents without giving every agent in the fleet the same power. Ships dark.",
@@ -34639,6 +34639,9 @@ var DIRECTIVE_KINDS = [
34639
34639
  ];
34640
34640
  var DIRECTIVE_SET = new Set(DIRECTIVE_KINDS);
34641
34641
 
34642
+ // ../core/dist/admin-debug/resume-precondition.js
34643
+ var DEFAULT_RESUME_LOOKBACK_MS = 14 * 24 * 60 * 60 * 1e3;
34644
+
34642
34645
  // ../core/dist/admin-debug/index.js
34643
34646
  var STUCK_RESTART_THRESHOLD_SECONDS = 15 * 60;
34644
34647
 
@@ -36928,6 +36931,28 @@ var FLAG_REGISTRY = [
36928
36931
  // exactly the org whose brand should be shown.
36929
36932
  public: true
36930
36933
  },
36934
+ {
36935
+ key: "ninjafy-logo",
36936
+ description: "Which Ninjafy logo TREATMENT the console chrome renders (ENG-9365). This is a SUB-SELECTION under ninjafy-brand, not a second brand gate: it is consulted only once ninjafy-brand has already resolved ON, so with the brand off the value is inert and the half-branded state that flag's description calls unreachable stays unreachable. ninjafy-brand remains the single kill switch for the rebrand. It exists so candidate logo treatments can be put in front of a human and compared in the running console, rather than judged from a static export. lockup = mark and wordmark together, both in the brand blue \u2014 exactly what ENG-9298 shipped, so an unset flag is a no-op. two-tone = the mark in brand blue with the wordmark in the neutral text colour (the treatment of the blue-icon/black-wordmark artwork). wordmark = the word alone, no mark. Every treatment is composed from the ENG-9298 geometry \u2014 ENG-9312 pins that the lockup's blue path IS the mark subpath followed by the wordmark subpaths, byte for byte \u2014 so a new treatment is a composition, never a fresh trace, and the three drawings cannot drift apart. Surfaces are the dashboard sidebar and the top nav. The top nav shows the WORDMARK portion at every width whatever the treatment, because ENG-9342 decided that deliberately (a full lockup at the header's icon height crowds the team switcher on a phone) \u2014 so a treatment changes the word's colour there, never whether a mark appears. The admin sidebar (ENG-9323) is NOT wired to this key and always renders the mark; widening it is a separate decision. Resolved SERVER-SIDE in (dashboard)/layout.tsx via getPublicEnumFlagServer, beside ninjafy-brand and in the same single GET /flags round trip, then passed down as a required prop. That is not a style preference: the client hook starts at its default and updates after an async fetch, so a client read would paint one logo and swap it after hydration \u2014 the exact flash ENG-9227 removed from the wordmark and ENG-8858 removed from the palette. Org and team are the useful pilot grains, as for ninjafy-brand: the single consumer evaluates in the active-org cookie scope, so a host- or agent-scoped override row is accepted by the table but never reached by the console.",
36937
+ flagType: "enum",
36938
+ allowedValues: ["lockup", "two-tone", "wordmark"],
36939
+ // Declared safe value is `lockup` — what ENG-9298 shipped. This flag has no
36940
+ // "off" direction: it selects among presentations that are all live-safe, so
36941
+ // fail-safe here means "the treatment currently in production", not the
36942
+ // narrowest one. A flag-DB read error, an archived row, or a stored value
36943
+ // outside allowedValues all resolve here (evaluate.ts normalizeFlagValue),
36944
+ // which is what makes an experimental value impossible to strand.
36945
+ defaultValue: "lockup",
36946
+ // Same trap as ninjafy-brand, and it bites harder here because there are no
36947
+ // client readers of this key AT ALL — it is server-resolved by construction.
36948
+ // `public` does NOT mean "read by a browser"; it means "readable through the
36949
+ // public map". getPublicEnumFlagServer resolves against the same GET /flags
36950
+ // endpoint the browser uses, and that route filters to listPublicFlagKeys()
36951
+ // (routes/flags.ts). Drop `public` and the key is simply absent from the map,
36952
+ // so the helper falls through to its default and returns `lockup` FOREVER —
36953
+ // the dropdown appearing to do nothing, with no error raised anywhere.
36954
+ public: true
36955
+ },
36931
36956
  {
36932
36957
  key: "agent-recruit",
36933
36958
  description: "The `recruit_agent` MCP tool (ENG-8159): lets an ordinary managed agent PROPOSE a new teammate in its own org. The proposal is filed under the `agent.recruit` approval verb and routed to an org owner as a server-rendered card, so this gates the ASK \u2014 nothing is created until a human taps Approve. Deliberately distinct from augmented-support-writes, which gates the concierge's own create_agent surface: the two requesters are separately controllable because an org may well want its support concierge to propose agents without giving every agent in the fleet the same power. Ships dark.",
@@ -43,8 +43,8 @@ import {
43
43
  writeDirectChatSessionState,
44
44
  writeEgressAllowlist,
45
45
  writePersistentClaudeWrapper
46
- } from "./chunk-7Y54PSMR.js";
47
- import "./chunk-AJNES24H.js";
46
+ } from "./chunk-F6CUSDJ6.js";
47
+ import "./chunk-GYYEUNTD.js";
48
48
  import "./chunk-XWVM4KPK.js";
49
49
  export {
50
50
  EGRESS_BASELINE_DOMAINS,
@@ -92,4 +92,4 @@ export {
92
92
  writeEgressAllowlist,
93
93
  writePersistentClaudeWrapper
94
94
  };
95
- //# sourceMappingURL=persistent-session-F7JEOWHQ.js.map
95
+ //# sourceMappingURL=persistent-session-TMOTEVV6.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-7Y54PSMR.js";
4
- import "./chunk-AJNES24H.js";
3
+ } from "./chunk-F6CUSDJ6.js";
4
+ import "./chunk-GYYEUNTD.js";
5
5
  import "./chunk-XWVM4KPK.js";
6
6
 
7
7
  // src/lib/responsiveness-probe.ts
@@ -727,4 +727,4 @@ export {
727
727
  readAndResetSlackReplyBindingClassifications,
728
728
  readAndResetSlackReplyTargetClassifications
729
729
  };
730
- //# sourceMappingURL=responsiveness-probe-7465YNMN.js.map
730
+ //# sourceMappingURL=responsiveness-probe-ZHE7S6G4.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sessionTranscriptDir
3
- } from "./chunk-AJNES24H.js";
3
+ } from "./chunk-GYYEUNTD.js";
4
4
 
5
5
  // src/lib/session-auth-dead.ts
6
6
  import { closeSync, openSync, readSync, readdirSync, statSync } from "fs";
@@ -203,4 +203,4 @@ export {
203
203
  decideSessionAuthState,
204
204
  probeSessionAuth
205
205
  };
206
- //# sourceMappingURL=session-auth-dead-GBC5QPH3.js.map
206
+ //# sourceMappingURL=session-auth-dead-JCKENEY5.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.676",
3
+ "version": "0.28.677",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {