@femtomc/mu-agent 26.2.103 → 26.2.104

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.
Binary file
@@ -1 +1 @@
1
- {"version":3,"file":"branding.d.ts","sourceRoot":"","sources":["../../src/extensions/branding.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,+BAA+B,CAAC;AAwEpF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY,QAoOjD;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"branding.d.ts","sourceRoot":"","sources":["../../src/extensions/branding.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,+BAA+B,CAAC;AAsGpF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY,QAuPjD;AAED,eAAe,iBAAiB,CAAC"}
@@ -6,7 +6,10 @@
6
6
  * - Terminal title and working message branding
7
7
  * - Lightweight periodic status refresh (open/ready/control-plane)
8
8
  */
9
+ import { readFileSync } from "node:fs";
9
10
  import { basename } from "node:path";
11
+ import { fileURLToPath } from "node:url";
12
+ import { Image as TuiImage, detectCapabilities } from "@mariozechner/pi-tui";
10
13
  import { MU_DEFAULT_THEME_NAME, MU_VERSION } from "../ui_defaults.js";
11
14
  import { registerMuSubcommand } from "./mu-command-dispatcher.js";
12
15
  import { fetchMuStatus, muServerUrl } from "./shared.js";
@@ -17,6 +20,24 @@ const EMPTY_SNAPSHOT = {
17
20
  adapters: [],
18
21
  error: null,
19
22
  };
23
+ const TUI_LOGO_MIME_TYPE = "image/png";
24
+ const TUI_LOGO_FILENAME = "mu-tui-logo.png";
25
+ const TUI_LOGO_MAX_WIDTH_CELLS = 16;
26
+ function resolveTuiLogoPath() {
27
+ return fileURLToPath(new URL("../../assets/mu-tui-logo.png", import.meta.url));
28
+ }
29
+ function readTuiLogoBase64() {
30
+ try {
31
+ return readFileSync(resolveTuiLogoPath()).toString("base64");
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ }
37
+ const TUI_LOGO_BASE64 = readTuiLogoBase64();
38
+ function canRenderTuiLogoImage() {
39
+ return TUI_LOGO_BASE64 !== null && detectCapabilities().images !== null;
40
+ }
20
41
  const ANSI_RE = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
21
42
  function visibleWidth(text) {
22
43
  return text.replace(ANSI_RE, "").length;
@@ -38,6 +59,12 @@ function centerLine(text, width) {
38
59
  const pad = Math.floor((width - vw) / 2);
39
60
  return " ".repeat(pad) + text;
40
61
  }
62
+ function centerLogoLines(lines, width) {
63
+ const targetLogoWidth = Math.max(1, Math.min(TUI_LOGO_MAX_WIDTH_CELLS, width - 2));
64
+ const pad = Math.max(0, Math.floor((width - targetLogoWidth) / 2));
65
+ const prefix = " ".repeat(pad);
66
+ return lines.map((line) => (line.length > 0 ? `${prefix}${line}` : line));
67
+ }
41
68
  function routesFromStatus(adapters, routes) {
42
69
  if (routes && routes.length > 0)
43
70
  return routes;
@@ -85,24 +112,35 @@ export function brandingExtension(pi) {
85
112
  ctx.ui.setTitle(`mu · ${repoName}`);
86
113
  ctx.ui.setWorkingMessage("working…");
87
114
  ctx.ui.setWidget("mu-quick-actions", undefined);
88
- ctx.ui.setHeader((_tui, theme) => ({
89
- render(width) {
90
- const cpPart = snapshot.error
91
- ? ""
92
- : snapshot.controlPlaneActive
93
- ? ` ${theme.fg("muted", "·")} ${theme.fg("success", `cp:${snapshot.adapters.join(",") || "on"}`)}`
94
- : "";
95
- const line = [
96
- theme.fg("accent", theme.bold("μ")),
97
- theme.fg("muted", "·"),
98
- theme.fg("dim", `v${MU_VERSION}`),
99
- theme.fg("muted", "·"),
100
- theme.fg("dim", repoName),
101
- ].join(" ") + cpPart;
102
- return [centerLine(line, width)];
103
- },
104
- invalidate() { },
105
- }));
115
+ ctx.ui.setHeader((_tui, theme) => {
116
+ const logoComponent = canRenderTuiLogoImage()
117
+ ? new TuiImage(TUI_LOGO_BASE64, TUI_LOGO_MIME_TYPE, { fallbackColor: (text) => theme.fg("dim", text) }, { maxWidthCells: TUI_LOGO_MAX_WIDTH_CELLS, filename: TUI_LOGO_FILENAME })
118
+ : null;
119
+ return {
120
+ render(width) {
121
+ const cpPart = snapshot.error
122
+ ? ""
123
+ : snapshot.controlPlaneActive
124
+ ? ` ${theme.fg("muted", "·")} ${theme.fg("success", `cp:${snapshot.adapters.join(",") || "on"}`)}`
125
+ : "";
126
+ const line = [
127
+ theme.fg("accent", theme.bold("μ")),
128
+ theme.fg("muted", "·"),
129
+ theme.fg("dim", `v${MU_VERSION}`),
130
+ theme.fg("muted", "·"),
131
+ theme.fg("dim", repoName),
132
+ ].join(" ") + cpPart;
133
+ if (!logoComponent) {
134
+ return [centerLine(line, width)];
135
+ }
136
+ const logoLines = centerLogoLines(logoComponent.render(width), width);
137
+ return [...logoLines, centerLine(line, width)];
138
+ },
139
+ invalidate() {
140
+ logoComponent?.invalidate();
141
+ },
142
+ };
143
+ });
106
144
  ctx.ui.setFooter((tui, theme, footerData) => {
107
145
  const requestRender = () => tui.requestRender();
108
146
  const unsubscribeBranch = footerData.onBranchChange(requestRender);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@femtomc/mu-agent",
3
- "version": "26.2.103",
3
+ "version": "26.2.104",
4
4
  "description": "Shared operator runtime for mu assistant sessions and serve extensions.",
5
5
  "keywords": [
6
6
  "mu",
@@ -20,14 +20,16 @@
20
20
  },
21
21
  "files": [
22
22
  "dist/**",
23
+ "assets/**",
23
24
  "prompts/**",
24
25
  "themes/**"
25
26
  ],
26
27
  "dependencies": {
27
- "@femtomc/mu-core": "26.2.103",
28
+ "@femtomc/mu-core": "26.2.104",
28
29
  "@mariozechner/pi-agent-core": "^0.54.2",
29
30
  "@mariozechner/pi-ai": "^0.54.2",
30
31
  "@mariozechner/pi-coding-agent": "^0.54.2",
32
+ "@mariozechner/pi-tui": "^0.54.2",
31
33
  "zod": "^4.1.9"
32
34
  }
33
35
  }