@femtomc/mu-agent 26.2.55 → 26.2.56

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.
@@ -1 +1 @@
1
- {"version":3,"file":"messaging-setup.d.ts","sourceRoot":"","sources":["../../src/extensions/messaging-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,YAAY,EAA6C,MAAM,+BAA+B,CAAC;AAyiC7G,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,YAAY,QA0PvD;AAED,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"messaging-setup.d.ts","sourceRoot":"","sources":["../../src/extensions/messaging-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,YAAY,EAA6C,MAAM,+BAA+B,CAAC;AAwpC7G,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,YAAY,QAwPvD;AAED,eAAe,uBAAuB,CAAC"}
@@ -452,6 +452,62 @@ function planText(plan) {
452
452
  function planSummary(plans) {
453
453
  return plans.map((plan) => planText(plan)).join("\n\n");
454
454
  }
455
+ function isRecord(value) {
456
+ return typeof value === "object" && value !== null;
457
+ }
458
+ function isControlPlaneGenerationIdentity(value) {
459
+ if (!isRecord(value))
460
+ return false;
461
+ return typeof value.generation_id === "string" && typeof value.generation_seq === "number";
462
+ }
463
+ function isControlPlaneReloadGenerationSummary(value) {
464
+ if (!isRecord(value))
465
+ return false;
466
+ if (typeof value.attempt_id !== "string")
467
+ return false;
468
+ if (typeof value.coalesced !== "boolean")
469
+ return false;
470
+ if (value.from_generation !== null && !isControlPlaneGenerationIdentity(value.from_generation))
471
+ return false;
472
+ if (!isControlPlaneGenerationIdentity(value.to_generation))
473
+ return false;
474
+ if (value.active_generation !== null && !isControlPlaneGenerationIdentity(value.active_generation))
475
+ return false;
476
+ return value.outcome === "success" || value.outcome === "failure";
477
+ }
478
+ function parseControlPlaneReloadApiResponse(raw) {
479
+ let parsed;
480
+ try {
481
+ parsed = JSON.parse(raw);
482
+ }
483
+ catch {
484
+ return {
485
+ response: null,
486
+ error: "control-plane reload returned invalid JSON response",
487
+ };
488
+ }
489
+ if (!isRecord(parsed)) {
490
+ return {
491
+ response: null,
492
+ error: "control-plane reload returned non-object payload",
493
+ };
494
+ }
495
+ if (!isControlPlaneReloadGenerationSummary(parsed.generation)) {
496
+ return {
497
+ response: null,
498
+ error: "control-plane reload response missing generation metadata (expected generation-scoped contract)",
499
+ };
500
+ }
501
+ const parsedRecord = parsed;
502
+ const response = {
503
+ ...parsed,
504
+ telegram_generation: parsedRecord.telegram_generation ?? null,
505
+ };
506
+ return {
507
+ response,
508
+ error: null,
509
+ };
510
+ }
455
511
  async function reloadControlPlaneInProcess(reason) {
456
512
  const base = muServerUrl();
457
513
  if (!base) {
@@ -468,18 +524,27 @@ async function reloadControlPlaneInProcess(reason) {
468
524
  body: JSON.stringify({ reason }),
469
525
  });
470
526
  const raw = await response.text();
471
- let parsed = null;
472
- try {
473
- parsed = JSON.parse(raw);
527
+ const parsedResult = parseControlPlaneReloadApiResponse(raw);
528
+ const parsed = parsedResult.response;
529
+ if (parsedResult.error) {
530
+ return {
531
+ ok: false,
532
+ response: null,
533
+ error: parsedResult.error,
534
+ };
474
535
  }
475
- catch {
476
- parsed = null;
536
+ if (!parsed) {
537
+ return {
538
+ ok: false,
539
+ response: null,
540
+ error: "control-plane reload response missing payload",
541
+ };
477
542
  }
478
- if (!response.ok || !parsed?.ok) {
543
+ if (!response.ok || !parsed.ok) {
479
544
  return {
480
545
  ok: false,
481
546
  response: parsed,
482
- error: parsed?.error ?? `control-plane reload failed (${response.status})`,
547
+ error: parsed.error ?? `control-plane reload failed (${response.status})`,
483
548
  };
484
549
  }
485
550
  return {
@@ -496,6 +561,22 @@ async function reloadControlPlaneInProcess(reason) {
496
561
  };
497
562
  }
498
563
  }
564
+ function reloadOutcomeSummary(reload) {
565
+ if (!reload.ok) {
566
+ return `Control-plane reload failed: ${reload.error ?? "unknown error"}.`;
567
+ }
568
+ const response = reload.response;
569
+ if (!response) {
570
+ return "Control-plane reload failed: missing reload response payload.";
571
+ }
572
+ const adapters = response.control_plane?.adapters.join(", ") || "(none)";
573
+ const generationSummary = `${response.generation.outcome} (${response.generation.active_generation?.generation_id ?? response.generation.to_generation.generation_id})`;
574
+ const telegramRollbackTrigger = response.telegram_generation?.rollback.trigger;
575
+ const telegramNote = response.telegram_generation?.handled && telegramRollbackTrigger
576
+ ? ` rollback_trigger=${telegramRollbackTrigger}`
577
+ : "";
578
+ return `Control-plane reloaded in-process. Active adapters: ${adapters}. Generation: ${generationSummary}.${telegramNote}`;
579
+ }
499
580
  function patchForAdapterValues(adapterId, values) {
500
581
  switch (adapterId) {
501
582
  case "slack":
@@ -846,9 +927,7 @@ async function runInteractiveApply(ctx, adapterId) {
846
927
  const lines = [
847
928
  `Updated config fields: ${outcome.updated_fields.join(", ") || "(none)"}`,
848
929
  `Config path: ${outcome.config_path ?? runtime.configPath ?? "(unknown)"}`,
849
- outcome.reload.ok
850
- ? `Control-plane reloaded in-process. Active adapters: ${outcome.reload.response?.control_plane?.adapters.join(", ") || "(none)"}.`
851
- : `Control-plane reload failed: ${outcome.reload.error ?? "unknown error"}.`,
930
+ reloadOutcomeSummary(outcome.reload),
852
931
  "",
853
932
  verifyText(verify),
854
933
  ];
@@ -959,9 +1038,7 @@ export function messagingSetupExtension(pi) {
959
1038
  const lines = [
960
1039
  `Updated config fields: ${outcome.updated_fields.join(", ") || "(none)"}`,
961
1040
  `Config path: ${outcome.config_path ?? runtime.configPath ?? "(unknown)"}`,
962
- outcome.reload.ok
963
- ? `Control-plane reloaded in-process. Active adapters: ${outcome.reload.response?.control_plane?.adapters.join(", ") || "(none)"}.`
964
- : `Control-plane reload failed: ${outcome.reload.error ?? "unknown error"}.`,
1041
+ reloadOutcomeSummary(outcome.reload),
965
1042
  "",
966
1043
  verifyText(verify),
967
1044
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"server-tools.d.ts","sourceRoot":"","sources":["../../src/extensions/server-tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAgElE,MAAM,MAAM,wBAAwB,GAAG;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC,CAAC;AAoXF,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,GAAE,wBAA6B,QAQzF;AAED,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,YAAY,QAS5D;AAED,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"server-tools.d.ts","sourceRoot":"","sources":["../../src/extensions/server-tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAoFlE,MAAM,MAAM,wBAAwB,GAAG;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC,CAAC;AAuXF,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,GAAE,wBAA6B,QAQzF;AAED,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,YAAY,QAS5D;AAED,eAAe,oBAAoB,CAAC"}
@@ -21,17 +21,33 @@ function cpRoutesFromStatus(routes, adapters) {
21
21
  route: `/webhooks/${name}`,
22
22
  }));
23
23
  }
24
+ function generationSummary(generation) {
25
+ const active = generation.active_generation?.generation_id ?? "(none)";
26
+ const pending = generation.pending_reload
27
+ ? `${generation.pending_reload.attempt_id}:${generation.pending_reload.state}`
28
+ : "(none)";
29
+ const last = generation.last_reload
30
+ ? `${generation.last_reload.attempt_id}:${generation.last_reload.state}`
31
+ : "(none)";
32
+ return `generation: active=${active} pending=${pending} last=${last}`;
33
+ }
34
+ function observabilitySummary(counters) {
35
+ return `observability: reload_success=${counters.reload_success_total} reload_failure=${counters.reload_failure_total} duplicate=${counters.duplicate_signal_total} drop=${counters.drop_signal_total}`;
36
+ }
24
37
  function summarizeStatus(status) {
25
- const cp = status.control_plane ?? { active: false, adapters: [], routes: [] };
38
+ const cp = status.control_plane;
26
39
  const routes = cpRoutesFromStatus(cp.routes, cp.adapters);
27
40
  const routeText = routes.length > 0 ? routes.map((entry) => `${entry.name}:${entry.route}`).join(", ") : "(none)";
28
- return [
41
+ const lines = [
29
42
  `repo: ${status.repo_root}`,
30
43
  `issues: open=${status.open_count} ready=${status.ready_count}`,
31
44
  `control_plane: ${cp.active ? "active" : "inactive"}`,
32
45
  `adapters: ${cp.adapters.length > 0 ? cp.adapters.join(", ") : "(none)"}`,
33
46
  `routes: ${routeText}`,
34
- ].join("\n");
47
+ generationSummary(cp.generation),
48
+ observabilitySummary(cp.observability.counters),
49
+ ];
50
+ return lines.join("\n");
35
51
  }
36
52
  function sliceWithLimit(items, limitRaw, fallback = 50) {
37
53
  const limit = clampInt(limitRaw, fallback, 1, 200);
@@ -68,7 +84,7 @@ function registerServerTools(pi, opts) {
68
84
  ctx.ui.setStatus("mu-server", ctx.ui.theme.fg("dim", `μ server ${url}`));
69
85
  try {
70
86
  const status = await fetchMuStatus(4_000);
71
- ctx.ui.setStatus("mu-status", ctx.ui.theme.fg("dim", `open ${status.open_count} · ready ${status.ready_count} · cp ${status.control_plane?.active ? "on" : "off"}`));
87
+ ctx.ui.setStatus("mu-status", ctx.ui.theme.fg("dim", `open ${status.open_count} · ready ${status.ready_count} · cp ${status.control_plane.active ? "on" : "off"}`));
72
88
  }
73
89
  catch {
74
90
  ctx.ui.setStatus("mu-status", ctx.ui.theme.fg("warning", "μ status unavailable"));
@@ -96,19 +112,19 @@ function registerServerTools(pi, opts) {
96
112
  parameters: ControlPlaneParams,
97
113
  async execute(_toolCallId, params) {
98
114
  const status = await fetchMuStatus();
99
- const cp = status.control_plane ?? {
100
- active: false,
101
- adapters: [],
102
- routes: [],
103
- };
115
+ const cp = status.control_plane;
104
116
  const routes = cpRoutesFromStatus(cp.routes, cp.adapters);
117
+ const generation = cp.generation;
118
+ const observability = cp.observability.counters;
105
119
  switch (params.action) {
106
120
  case "status":
107
121
  return textResult(toJsonText({
108
122
  active: cp.active,
109
123
  adapters: cp.adapters,
110
124
  routes,
111
- }), { control_plane: cp, routes });
125
+ generation,
126
+ observability,
127
+ }), { control_plane: cp, routes, generation, observability });
112
128
  case "adapters":
113
129
  return textResult(toJsonText(cp.adapters), { adapters: cp.adapters });
114
130
  case "routes":
@@ -377,16 +393,14 @@ function registerServerTools(pi, opts) {
377
393
  handler: async (_args, ctx) => {
378
394
  try {
379
395
  const status = await fetchMuStatus();
380
- const cp = status.control_plane ?? {
381
- active: false,
382
- adapters: [],
383
- routes: [],
384
- };
396
+ const cp = status.control_plane;
385
397
  const routes = cpRoutesFromStatus(cp.routes, cp.adapters);
386
398
  const lines = [
387
399
  `control_plane: ${cp.active ? "active" : "inactive"}`,
388
400
  `adapters: ${cp.adapters.length > 0 ? cp.adapters.join(", ") : "(none)"}`,
389
401
  `routes: ${routes.length > 0 ? routes.map((entry) => `${entry.name}:${entry.route}`).join(", ") : "(none)"}`,
402
+ generationSummary(cp.generation),
403
+ observabilitySummary(cp.observability.counters),
390
404
  ];
391
405
  ctx.ui.notify(lines.join("\n"), "info");
392
406
  }
@@ -2,15 +2,48 @@ export type MuControlPlaneRoute = {
2
2
  name: string;
3
3
  route: string;
4
4
  };
5
+ export type MuGenerationIdentity = {
6
+ generation_id: string;
7
+ generation_seq: number;
8
+ };
9
+ export type MuGenerationReloadAttempt = {
10
+ attempt_id: string;
11
+ reason: string;
12
+ state: "planned" | "swapped" | "completed" | "failed";
13
+ requested_at_ms: number;
14
+ swapped_at_ms: number | null;
15
+ finished_at_ms: number | null;
16
+ from_generation: MuGenerationIdentity | null;
17
+ to_generation: MuGenerationIdentity;
18
+ };
19
+ export type MuGenerationSupervisorSnapshot = {
20
+ supervisor_id: string;
21
+ active_generation: MuGenerationIdentity | null;
22
+ pending_reload: MuGenerationReloadAttempt | null;
23
+ last_reload: MuGenerationReloadAttempt | null;
24
+ };
25
+ export type MuGenerationObservabilityCounters = {
26
+ reload_success_total: number;
27
+ reload_failure_total: number;
28
+ reload_drain_duration_ms_total: number;
29
+ reload_drain_duration_samples_total: number;
30
+ duplicate_signal_total: number;
31
+ drop_signal_total: number;
32
+ };
33
+ export type MuControlPlaneStatus = {
34
+ active: boolean;
35
+ adapters: string[];
36
+ routes?: MuControlPlaneRoute[];
37
+ generation: MuGenerationSupervisorSnapshot;
38
+ observability: {
39
+ counters: MuGenerationObservabilityCounters;
40
+ };
41
+ };
5
42
  export type MuStatusResponse = {
6
43
  repo_root: string;
7
44
  open_count: number;
8
45
  ready_count: number;
9
- control_plane?: {
10
- active: boolean;
11
- adapters: string[];
12
- routes?: MuControlPlaneRoute[];
13
- };
46
+ control_plane: MuControlPlaneStatus;
14
47
  };
15
48
  export declare function muServerUrl(): string | null;
16
49
  export declare function clampInt(value: number | undefined, fallback: number, min: number, max: number): number;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/extensions/shared.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE;QACf,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,MAAM,CAAC,EAAE,mBAAmB,EAAE,CAAC;KAC/B,CAAC;CACF,CAAC;AAEF,wBAAgB,WAAW,IAAI,MAAM,GAAG,IAAI,CAG3C;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKtG;AAED,wBAAsB,WAAW,CAAC,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAChE,OAAO,CAAC,CAAC,CAAC,CA4BZ;AAED,wBAAsB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAEjF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;;;;;;EAK7E;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEjD"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/extensions/shared.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtD,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC7C,aAAa,EAAE,oBAAoB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC/C,cAAc,EAAE,yBAAyB,GAAG,IAAI,CAAC;IACjD,WAAW,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAAG;IAC/C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,8BAA8B,EAAE,MAAM,CAAC;IACvC,mCAAmC,EAAE,MAAM,CAAC;IAC5C,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC/B,UAAU,EAAE,8BAA8B,CAAC;IAC3C,aAAa,EAAE;QACd,QAAQ,EAAE,iCAAiC,CAAC;KAC5C,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,oBAAoB,CAAC;CACpC,CAAC;AAEF,wBAAgB,WAAW,IAAI,MAAM,GAAG,IAAI,CAG3C;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKtG;AAED,wBAAsB,WAAW,CAAC,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAChE,OAAO,CAAC,CAAC,CAAC,CA4BZ;AAiCD,wBAAsB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAGjF;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;;;;;;EAK7E;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEjD"}
@@ -39,8 +39,30 @@ export async function fetchMuJson(path, opts = {}) {
39
39
  clearTimeout(timeout);
40
40
  }
41
41
  }
42
+ function ensureGenerationScopedStatus(status) {
43
+ const controlPlane = status.control_plane;
44
+ if (!controlPlane || typeof controlPlane !== "object") {
45
+ throw new Error("mu server /api/status missing control_plane payload (expected generation-scoped contract)");
46
+ }
47
+ const controlPlaneRecord = controlPlane;
48
+ if (!("generation" in controlPlaneRecord) || !controlPlaneRecord.generation) {
49
+ throw new Error("mu server /api/status missing control_plane.generation (expected generation-scoped contract)");
50
+ }
51
+ if (!("observability" in controlPlaneRecord) || !controlPlaneRecord.observability) {
52
+ throw new Error("mu server /api/status missing control_plane.observability (expected generation-scoped contract)");
53
+ }
54
+ const observability = controlPlaneRecord.observability;
55
+ if (typeof observability !== "object" ||
56
+ observability == null ||
57
+ !("counters" in observability) ||
58
+ !observability.counters) {
59
+ throw new Error("mu server /api/status missing control_plane.observability.counters (expected generation-scoped contract)");
60
+ }
61
+ return status;
62
+ }
42
63
  export async function fetchMuStatus(timeoutMs) {
43
- return await fetchMuJson("/api/status", { timeoutMs });
64
+ const status = await fetchMuJson("/api/status", { timeoutMs });
65
+ return ensureGenerationScopedStatus(status);
44
66
  }
45
67
  export function textResult(text, details = {}) {
46
68
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@femtomc/mu-agent",
3
- "version": "26.2.55",
3
+ "version": "26.2.56",
4
4
  "description": "Shared agent runtime for mu chat, orchestration roles, and serve extensions.",
5
5
  "keywords": [
6
6
  "mu",