lensmcp 1.17.2 → 1.17.4

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.
@@ -49720,6 +49720,16 @@ var AgentChecksSchema = external_exports.object({
49720
49720
  visual: external_exports.enum(["passed", "failed", "warning", "unknown"]).optional(),
49721
49721
  memory: external_exports.enum(["passed", "failed", "warning", "unknown"]).optional()
49722
49722
  });
49723
+ var AgentServerModeSchema = external_exports.enum(["embedded", "shared"]);
49724
+ var AgentServerInfoSchema = external_exports.object({
49725
+ mode: AgentServerModeSchema,
49726
+ /** The server process. Stable across agent sessions in `shared` mode. */
49727
+ pid: external_exports.number(),
49728
+ /** ISO timestamp this server process started — how stale its bundle may be. */
49729
+ startedAt: external_exports.string(),
49730
+ /** The loopback URL clients reach it on. Only in `shared` mode. */
49731
+ url: external_exports.string().optional()
49732
+ });
49723
49733
  var AgentCurrentStatusSchema = ResourceEnvelopeSchema.extend({
49724
49734
  sessionId: external_exports.string(),
49725
49735
  status: AgentStatusKindSchema,
@@ -49728,7 +49738,12 @@ var AgentCurrentStatusSchema = ResourceEnvelopeSchema.extend({
49728
49738
  blocking: external_exports.array(AgentBlockingItemSchema),
49729
49739
  warnings: external_exports.array(AgentBlockingItemSchema).default([]),
49730
49740
  suggestedReads: external_exports.array(external_exports.string()),
49731
- checks: AgentChecksSchema.optional()
49741
+ checks: AgentChecksSchema.optional(),
49742
+ /**
49743
+ * Optional so a bare context (no server env) still validates — and so a
49744
+ * pre-shim recorded status keeps parsing.
49745
+ */
49746
+ server: AgentServerInfoSchema.optional()
49732
49747
  });
49733
49748
  var AgentStorageStatsSchema = external_exports.object({
49734
49749
  eventsResident: external_exports.number().int().nonnegative(),
@@ -16316,6 +16316,16 @@ var AgentChecksSchema = external_exports.object({
16316
16316
  visual: external_exports.enum(["passed", "failed", "warning", "unknown"]).optional(),
16317
16317
  memory: external_exports.enum(["passed", "failed", "warning", "unknown"]).optional()
16318
16318
  });
16319
+ var AgentServerModeSchema = external_exports.enum(["embedded", "shared"]);
16320
+ var AgentServerInfoSchema = external_exports.object({
16321
+ mode: AgentServerModeSchema,
16322
+ /** The server process. Stable across agent sessions in `shared` mode. */
16323
+ pid: external_exports.number(),
16324
+ /** ISO timestamp this server process started — how stale its bundle may be. */
16325
+ startedAt: external_exports.string(),
16326
+ /** The loopback URL clients reach it on. Only in `shared` mode. */
16327
+ url: external_exports.string().optional()
16328
+ });
16319
16329
  var AgentCurrentStatusSchema = ResourceEnvelopeSchema.extend({
16320
16330
  sessionId: external_exports.string(),
16321
16331
  status: AgentStatusKindSchema,
@@ -16324,7 +16334,12 @@ var AgentCurrentStatusSchema = ResourceEnvelopeSchema.extend({
16324
16334
  blocking: external_exports.array(AgentBlockingItemSchema),
16325
16335
  warnings: external_exports.array(AgentBlockingItemSchema).default([]),
16326
16336
  suggestedReads: external_exports.array(external_exports.string()),
16327
- checks: AgentChecksSchema.optional()
16337
+ checks: AgentChecksSchema.optional(),
16338
+ /**
16339
+ * Optional so a bare context (no server env) still validates — and so a
16340
+ * pre-shim recorded status keeps parsing.
16341
+ */
16342
+ server: AgentServerInfoSchema.optional()
16328
16343
  });
16329
16344
  var AgentStorageStatsSchema = external_exports.object({
16330
16345
  eventsResident: external_exports.number().int().nonnegative(),
@@ -17031,6 +17046,16 @@ function deriveVerdict(signals) {
17031
17046
  }
17032
17047
  return { status, blocking, warnings, suggestedReads, checks: toChecks(signals) };
17033
17048
  }
17049
+ function readServerInfo(env = process.env) {
17050
+ const shared = env["LENSMCP_TRANSPORT"] === "http" || env["LENSMCP_TRANSPORT"] === "socket";
17051
+ const port = env["LENSMCP_PORT"];
17052
+ return {
17053
+ mode: shared ? "shared" : "embedded",
17054
+ pid: process.pid,
17055
+ startedAt: new Date(Date.now() - Math.round(process.uptime() * 1e3)).toISOString(),
17056
+ ...shared && port ? { url: `http://127.0.0.1:${port}/mcp` } : {}
17057
+ };
17058
+ }
17034
17059
  async function aggregateStatus(args) {
17035
17060
  const signals = await readSignals(args.resources);
17036
17061
  const verdict = deriveVerdict(signals);
@@ -17039,6 +17064,7 @@ async function aggregateStatus(args) {
17039
17064
  revision: args.revision,
17040
17065
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
17041
17066
  sessionId: args.sessionId,
17067
+ server: readServerInfo(),
17042
17068
  status: verdict.status,
17043
17069
  blocking: verdict.blocking,
17044
17070
  warnings: verdict.warnings,
@@ -19569,6 +19595,18 @@ function publishCaptureRequest(dir, request) {
19569
19595
  return false;
19570
19596
  }
19571
19597
  }
19598
+ var inFlight;
19599
+ async function captureSingleFlight(requestId, start) {
19600
+ const joined = inFlight;
19601
+ if (joined) {
19602
+ return { fresh: await joined.promise, coalesced: true, requestId: joined.requestId };
19603
+ }
19604
+ const promise2 = start().finally(() => {
19605
+ inFlight = void 0;
19606
+ });
19607
+ inFlight = { promise: promise2, requestId };
19608
+ return { fresh: await promise2, coalesced: false, requestId };
19609
+ }
19572
19610
  async function waitForFreshFrame(opts) {
19573
19611
  const now = opts.now ?? (() => Date.now());
19574
19612
  const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
@@ -19611,20 +19649,31 @@ var VisualCaptureFrameTool = class VisualCaptureFrameTool2 extends ToolContext8
19611
19649
  }
19612
19650
  });
19613
19651
  const dir = captureDir();
19614
- const requested = publishCaptureRequest(dir, {
19615
- requestedAt,
19616
- cause: input.cause,
19617
- stable: input.stable,
19618
- requestId
19619
- });
19620
19652
  const runner = liveRunner(dir);
19621
- const fresh = requested && runner ? await waitForFreshFrame({ readFrameId, before }) : false;
19653
+ let requested = false;
19654
+ const flight = await captureSingleFlight(requestId, async () => {
19655
+ requested = publishCaptureRequest(dir, {
19656
+ requestedAt,
19657
+ cause: input.cause,
19658
+ stable: input.stable,
19659
+ requestId
19660
+ });
19661
+ return requested && runner ? await waitForFreshFrame({ readFrameId, before }) : false;
19662
+ });
19622
19663
  return {
19623
- requested,
19664
+ requested: flight.coalesced ? true : requested,
19624
19665
  cause: input.cause,
19625
19666
  stable: input.stable,
19626
- /** True when the returned frame was captured for THIS request. */
19627
- fresh,
19667
+ /** True when the returned frame was captured for THIS request (or the one it joined). */
19668
+ fresh: flight.fresh,
19669
+ /**
19670
+ * True when another caller's capture was already in flight and this call
19671
+ * awaited it instead of starting a second one — so `cause`/`stable` above
19672
+ * are what was ASKED for, not necessarily what drove the capture.
19673
+ */
19674
+ coalesced: flight.coalesced,
19675
+ /** The request that actually drove the capture. */
19676
+ requestId: flight.requestId,
19628
19677
  waitedMs: Date.now() - requestedAt,
19629
19678
  /** undefined when no capture runner is attached — nothing will answer. */
19630
19679
  runner: runner ? { pid: runner.pid, url: runner.url } : void 0,
package/bundled/main.js CHANGED
@@ -16326,6 +16326,16 @@ var AgentChecksSchema = external_exports.object({
16326
16326
  visual: external_exports.enum(["passed", "failed", "warning", "unknown"]).optional(),
16327
16327
  memory: external_exports.enum(["passed", "failed", "warning", "unknown"]).optional()
16328
16328
  });
16329
+ var AgentServerModeSchema = external_exports.enum(["embedded", "shared"]);
16330
+ var AgentServerInfoSchema = external_exports.object({
16331
+ mode: AgentServerModeSchema,
16332
+ /** The server process. Stable across agent sessions in `shared` mode. */
16333
+ pid: external_exports.number(),
16334
+ /** ISO timestamp this server process started — how stale its bundle may be. */
16335
+ startedAt: external_exports.string(),
16336
+ /** The loopback URL clients reach it on. Only in `shared` mode. */
16337
+ url: external_exports.string().optional()
16338
+ });
16329
16339
  var AgentCurrentStatusSchema = ResourceEnvelopeSchema.extend({
16330
16340
  sessionId: external_exports.string(),
16331
16341
  status: AgentStatusKindSchema,
@@ -16334,7 +16344,12 @@ var AgentCurrentStatusSchema = ResourceEnvelopeSchema.extend({
16334
16344
  blocking: external_exports.array(AgentBlockingItemSchema),
16335
16345
  warnings: external_exports.array(AgentBlockingItemSchema).default([]),
16336
16346
  suggestedReads: external_exports.array(external_exports.string()),
16337
- checks: AgentChecksSchema.optional()
16347
+ checks: AgentChecksSchema.optional(),
16348
+ /**
16349
+ * Optional so a bare context (no server env) still validates — and so a
16350
+ * pre-shim recorded status keeps parsing.
16351
+ */
16352
+ server: AgentServerInfoSchema.optional()
16338
16353
  });
16339
16354
  var AgentStorageStatsSchema = external_exports.object({
16340
16355
  eventsResident: external_exports.number().int().nonnegative(),
@@ -17033,6 +17048,16 @@ function deriveVerdict(signals) {
17033
17048
  }
17034
17049
  return { status, blocking, warnings, suggestedReads, checks: toChecks(signals) };
17035
17050
  }
17051
+ function readServerInfo(env = process.env) {
17052
+ const shared = env["LENSMCP_TRANSPORT"] === "http" || env["LENSMCP_TRANSPORT"] === "socket";
17053
+ const port = env["LENSMCP_PORT"];
17054
+ return {
17055
+ mode: shared ? "shared" : "embedded",
17056
+ pid: process.pid,
17057
+ startedAt: new Date(Date.now() - Math.round(process.uptime() * 1e3)).toISOString(),
17058
+ ...shared && port ? { url: `http://127.0.0.1:${port}/mcp` } : {}
17059
+ };
17060
+ }
17036
17061
  async function aggregateStatus(args) {
17037
17062
  const signals = await readSignals(args.resources);
17038
17063
  const verdict = deriveVerdict(signals);
@@ -17041,6 +17066,7 @@ async function aggregateStatus(args) {
17041
17066
  revision: args.revision,
17042
17067
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
17043
17068
  sessionId: args.sessionId,
17069
+ server: readServerInfo(),
17044
17070
  status: verdict.status,
17045
17071
  blocking: verdict.blocking,
17046
17072
  warnings: verdict.warnings,
@@ -19571,6 +19597,18 @@ function publishCaptureRequest(dir, request) {
19571
19597
  return false;
19572
19598
  }
19573
19599
  }
19600
+ var inFlight;
19601
+ async function captureSingleFlight(requestId, start) {
19602
+ const joined = inFlight;
19603
+ if (joined) {
19604
+ return { fresh: await joined.promise, coalesced: true, requestId: joined.requestId };
19605
+ }
19606
+ const promise2 = start().finally(() => {
19607
+ inFlight = void 0;
19608
+ });
19609
+ inFlight = { promise: promise2, requestId };
19610
+ return { fresh: await promise2, coalesced: false, requestId };
19611
+ }
19574
19612
  async function waitForFreshFrame(opts) {
19575
19613
  const now = opts.now ?? (() => Date.now());
19576
19614
  const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
@@ -19613,20 +19651,31 @@ var VisualCaptureFrameTool = class VisualCaptureFrameTool2 extends ToolContext8
19613
19651
  }
19614
19652
  });
19615
19653
  const dir = captureDir();
19616
- const requested = publishCaptureRequest(dir, {
19617
- requestedAt,
19618
- cause: input.cause,
19619
- stable: input.stable,
19620
- requestId
19621
- });
19622
19654
  const runner = liveRunner(dir);
19623
- const fresh = requested && runner ? await waitForFreshFrame({ readFrameId, before }) : false;
19655
+ let requested = false;
19656
+ const flight = await captureSingleFlight(requestId, async () => {
19657
+ requested = publishCaptureRequest(dir, {
19658
+ requestedAt,
19659
+ cause: input.cause,
19660
+ stable: input.stable,
19661
+ requestId
19662
+ });
19663
+ return requested && runner ? await waitForFreshFrame({ readFrameId, before }) : false;
19664
+ });
19624
19665
  return {
19625
- requested,
19666
+ requested: flight.coalesced ? true : requested,
19626
19667
  cause: input.cause,
19627
19668
  stable: input.stable,
19628
- /** True when the returned frame was captured for THIS request. */
19629
- fresh,
19669
+ /** True when the returned frame was captured for THIS request (or the one it joined). */
19670
+ fresh: flight.fresh,
19671
+ /**
19672
+ * True when another caller's capture was already in flight and this call
19673
+ * awaited it instead of starting a second one — so `cause`/`stable` above
19674
+ * are what was ASKED for, not necessarily what drove the capture.
19675
+ */
19676
+ coalesced: flight.coalesced,
19677
+ /** The request that actually drove the capture. */
19678
+ requestId: flight.requestId,
19630
19679
  waitedMs: Date.now() - requestedAt,
19631
19680
  /** undefined when no capture runner is attached — nothing will answer. */
19632
19681
  runner: runner ? { pid: runner.pid, url: runner.url } : void 0,