agent-lookout 0.2.5 → 0.2.6

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.
@@ -3,13 +3,13 @@ import {
3
3
  statusJson,
4
4
  statusReport,
5
5
  statusText
6
- } from "./chunk-NWVEVCRT.js";
6
+ } from "./chunk-LZ62RW3N.js";
7
7
  import {
8
8
  addressesToTry,
9
9
  findSnapshot,
10
10
  readAppVersion,
11
11
  readSessions
12
- } from "./chunk-OT3EGOTY.js";
12
+ } from "./chunk-I6Q35DHC.js";
13
13
 
14
14
  // src/cli/agentLookout.ts
15
15
  import { isatty } from "node:tty";
@@ -167,7 +167,7 @@ async function runCommand(options) {
167
167
  return EXIT.notKnown;
168
168
  }
169
169
  if (parsed.kind === "start") {
170
- const { startCommand } = await import("./startCommand-J3QS26SZ.js");
170
+ const { startCommand } = await import("./startCommand-PR5JPWCT.js");
171
171
  const url = await startCommand({
172
172
  ...parsed.options,
173
173
  distDir: options.distDir ?? fileURLToPath(new URL("../../dist/", import.meta.url)),
@@ -187,7 +187,7 @@ async function runCommand(options) {
187
187
  const read = options.read ?? ((address) => readSessions(address));
188
188
  const now = options.now ?? Date.now;
189
189
  if (parsed.kind === "mcp") {
190
- const { serveMcp } = await import("./mcpServer-IFB2FEOZ.js");
190
+ const { serveMcp } = await import("./mcpServer-HJSH3WIS.js");
191
191
  await serveMcp({
192
192
  addresses: toTry,
193
193
  read,
@@ -291,6 +291,8 @@ var SESSION_STATUSES = [
291
291
  ];
292
292
  var WAITING_REASONS = ["permission", "question", "other"];
293
293
  var ANSWER_DECISIONS = ["allow", "deny"];
294
+ var EDIT_TOOLS = ["Edit", "Write", "MultiEdit", "NotebookEdit"];
295
+ var NOT_YES_OR_NO_TOOLS = ["ExitPlanMode", "AskUserQuestion"];
294
296
  var CHECKS_STATES = ["failing", "pending", "passing", "none"];
295
297
  var SOURCE_STATES = ["ok", "searching", "unavailable", "not-set-up", "error"];
296
298
  var SOURCE_STATE_LABEL = {
@@ -453,6 +455,36 @@ function oneLine(text, max = MAX_LINE_LENGTH) {
453
455
  return `${characters.slice(0, max - 1).join("").trimEnd()}\u2026`;
454
456
  }
455
457
 
458
+ // src/core/waits/answeredWaits.ts
459
+ var ANSWER_HOLDS_MS = 1e4;
460
+ function needsYou(session) {
461
+ return session.status === "needs-you" && session.answered !== true;
462
+ }
463
+ function inAnsweredWait(session, wait) {
464
+ if (session.status !== "needs-you" || session.waitingReason !== "permission") return false;
465
+ return wait.since === null || session.statusSince === null || session.statusSince === wait.since;
466
+ }
467
+ function answeredNow(answers, snapshot, now) {
468
+ const read = new Set(
469
+ snapshot.sources.filter((source) => source.state === "ok" || source.state === "not-set-up").map((source) => source.id)
470
+ );
471
+ const listed = new Map(snapshot.sessions.map((session) => [session.id, session]));
472
+ const ids = /* @__PURE__ */ new Set();
473
+ const kept = /* @__PURE__ */ new Map();
474
+ for (const [id, wait] of answers) {
475
+ if (Math.abs(now - wait.at) >= ANSWER_HOLDS_MS) continue;
476
+ if (!read.has(wait.source)) {
477
+ kept.set(id, wait);
478
+ continue;
479
+ }
480
+ const session = listed.get(id);
481
+ if (session === void 0 || !inAnsweredWait(session, wait)) continue;
482
+ ids.add(id);
483
+ kept.set(id, wait);
484
+ }
485
+ return { ids, kept };
486
+ }
487
+
456
488
  export {
457
489
  __commonJS,
458
490
  __export,
@@ -476,6 +508,8 @@ export {
476
508
  SESSION_STATUSES,
477
509
  WAITING_REASONS,
478
510
  ANSWER_DECISIONS,
511
+ EDIT_TOOLS,
512
+ NOT_YES_OR_NO_TOOLS,
479
513
  SOURCE_STATES,
480
514
  SOURCE_STATE_LABEL,
481
515
  CAPABILITIES,
@@ -505,5 +539,8 @@ export {
505
539
  cut,
506
540
  sessionName,
507
541
  waitingText,
508
- oneLine
542
+ oneLine,
543
+ needsYou,
544
+ inAnsweredWait,
545
+ answeredNow
509
546
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SESSION_STATUSES
3
- } from "./chunk-OT3EGOTY.js";
3
+ } from "./chunk-I6Q35DHC.js";
4
4
 
5
5
  // src/core/sessions/sorting.ts
6
6
  var STATUS_ORDER = SESSION_STATUSES;
@@ -4,10 +4,11 @@ import {
4
4
  agentName,
5
5
  formatDuration,
6
6
  isMachineName,
7
+ needsYou,
7
8
  pullRequestSummaryOf,
8
9
  sessionTitle,
9
10
  waitingLabel
10
- } from "./chunk-OT3EGOTY.js";
11
+ } from "./chunk-I6Q35DHC.js";
11
12
 
12
13
  // src/cli/statusReport.ts
13
14
  var NOT_KNOWN = "\u2013";
@@ -32,6 +33,10 @@ function statusReport(snapshot, now) {
32
33
  for (const session of snapshot.sessions) {
33
34
  switch (session.status) {
34
35
  case "needs-you": {
36
+ if (!needsYou(session)) {
37
+ report.working += 1;
38
+ break;
39
+ }
35
40
  report.needsYou += 1;
36
41
  const since = session.statusSince;
37
42
  const git = session.git;
@@ -133,8 +138,8 @@ function statusCount(report) {
133
138
  }
134
139
  var ESCAPED_IN_JSON = new RegExp(`[\\u007f-\\u009f\\u2028\\u2029${REORDERING_MARKS}]`, "g");
135
140
  function statusJson(report) {
136
- const { counted, needsYou, working, idle, stale, waiting } = report;
137
- const json = JSON.stringify({ counted, needsYou, working, idle, stale, waiting }, null, 2);
141
+ const { counted, needsYou: needsYou2, working, idle, stale, waiting } = report;
142
+ const json = JSON.stringify({ counted, needsYou: needsYou2, working, idle, stale, waiting }, null, 2);
138
143
  return `${json.replace(
139
144
  ESCAPED_IN_JSON,
140
145
  (character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`
@@ -2,11 +2,11 @@ import {
2
2
  machineOf,
3
3
  statusReport,
4
4
  terminalText
5
- } from "./chunk-NWVEVCRT.js";
5
+ } from "./chunk-LZ62RW3N.js";
6
6
  import {
7
7
  STATUS_ORDER,
8
8
  sortSessions
9
- } from "./chunk-Q73JDXXW.js";
9
+ } from "./chunk-JSBQMY3Q.js";
10
10
  import {
11
11
  CAPABILITIES,
12
12
  CAPABILITY_LABEL,
@@ -22,11 +22,12 @@ import {
22
22
  agentName,
23
23
  findSnapshot,
24
24
  formatDuration,
25
+ needsYou,
25
26
  pullRequestSummaryOf,
26
27
  readAppVersion,
27
28
  sessionTitle,
28
29
  surfaceLabel
29
- } from "./chunk-OT3EGOTY.js";
30
+ } from "./chunk-I6Q35DHC.js";
30
31
 
31
32
  // node_modules/@modelcontextprotocol/sdk/node_modules/ajv/dist/compile/codegen/code.js
32
33
  var require_code = __commonJS({
@@ -23490,11 +23491,13 @@ function iso(ms) {
23490
23491
  return Number.isNaN(date3.getTime()) ? null : date3.toISOString();
23491
23492
  }
23492
23493
  function listed(session, sources, now) {
23493
- const status = isOneOf(SESSION_STATUSES, session.status) ? session.status : "unknown";
23494
+ const read = isOneOf(SESSION_STATUSES, session.status) ? session.status : "unknown";
23495
+ const answered = read === "needs-you" && !needsYou(session);
23496
+ const status = answered ? "working" : read;
23494
23497
  const id = clean(session.id) ?? "";
23495
23498
  const git = isObject2(session.git) ? session.git : {};
23496
23499
  const lastWriteAt = session.lastWriteAt;
23497
- const quietForMs = status === "working" && typeof lastWriteAt === "number" && Number.isFinite(lastWriteAt) ? Math.max(0, now - lastWriteAt) : null;
23500
+ const quietForMs = read === "working" && typeof lastWriteAt === "number" && Number.isFinite(lastWriteAt) ? Math.max(0, now - lastWriteAt) : null;
23498
23501
  return {
23499
23502
  id,
23500
23503
  // A name made only of escape sequences leaves nothing, so the id stands in.
@@ -23508,14 +23511,14 @@ function listed(session, sources, now) {
23508
23511
  commit: clean(git.commit),
23509
23512
  pullRequest: pullRequestSummaryOf(git.pullRequest),
23510
23513
  app: isOneOf(SURFACES, session.surface) ? surfaceLabel(session.surface) : null,
23511
- since: iso(session.statusSince),
23514
+ since: answered ? null : iso(session.statusSince),
23512
23515
  quietFor: quietForMs === null ? null : formatDuration(quietForMs),
23513
23516
  quietForMs,
23514
23517
  stale: session.stale === true
23515
23518
  };
23516
23519
  }
23517
23520
  function listSessions(snapshot, now, status = null) {
23518
- const sessions = sortSessions(snapshot.sessions).map((session) => listed(session, snapshot.sources, now)).filter((session) => status === null || session.status === status);
23521
+ const sessions = sortSessions(snapshot.sessions).sort((a, b) => Number(needsYou(b)) - Number(needsYou(a))).map((session) => listed(session, snapshot.sources, now)).filter((session) => status === null || session.status === status);
23519
23522
  return {
23520
23523
  readAt: new Date(now).toISOString(),
23521
23524
  counted: statusReport(snapshot, now).counted,