@femtomc/mu-agent 26.2.115 → 26.2.117
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.
- package/dist/extensions/ui.d.ts.map +1 -1
- package/dist/extensions/ui.js +92 -12
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/extensions/ui.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/extensions/ui.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,+BAA+B,CAAC;AA89CpF,wBAAgB,WAAW,CAAC,EAAE,EAAE,YAAY,QA6N3C;AAED,eAAe,WAAW,CAAC"}
|
package/dist/extensions/ui.js
CHANGED
|
@@ -20,6 +20,8 @@ const UI_PICKER_TWO_PANE_LEFT_MIN = 24;
|
|
|
20
20
|
const UI_PICKER_TWO_PANE_RIGHT_MIN = 32;
|
|
21
21
|
const UI_PICKER_TWO_PANE_SEPARATOR_WIDTH = 3;
|
|
22
22
|
const UI_PICKER_INTERACTION_HINT = "↑/↓ move · tab switch pane · enter select/submit · esc cancel · click rows";
|
|
23
|
+
const UI_ASYNC_WIDGET_DOCS_MAX = 4;
|
|
24
|
+
const UI_ASYNC_WIDGET_SNAPSHOT_MAX = 96;
|
|
23
25
|
const UI_ENABLE_MOUSE_TRACKING = "\x1b[?1000h\x1b[?1006h";
|
|
24
26
|
const UI_DISABLE_MOUSE_TRACKING = "\x1b[?1000l\x1b[?1006l";
|
|
25
27
|
const UI_INTERACT_OVERLAY_OPTIONS = {
|
|
@@ -106,7 +108,7 @@ function retainPendingPromptsForActiveDocs(state) {
|
|
|
106
108
|
return false;
|
|
107
109
|
}
|
|
108
110
|
if (pending.kind === "review") {
|
|
109
|
-
return
|
|
111
|
+
return isReviewStatusProfileStatusVariant(doc);
|
|
110
112
|
}
|
|
111
113
|
const actions = runnableActions(doc);
|
|
112
114
|
if (actions.length === 0) {
|
|
@@ -160,7 +162,9 @@ function armAutoPromptForUiDocs(state, changedUiIds) {
|
|
|
160
162
|
enqueuePendingPrompt(state, { kind: "action", uiId: doc.ui_id, actionId });
|
|
161
163
|
state.promptedRevisionKeys.add(docRevisionKey(doc));
|
|
162
164
|
}
|
|
163
|
-
const statusCandidates = unpromptedDocs
|
|
165
|
+
const statusCandidates = unpromptedDocs
|
|
166
|
+
.filter((doc) => isReviewStatusProfileStatusVariant(doc))
|
|
167
|
+
.sort(byMostRecentRevision);
|
|
164
168
|
if (statusCandidates.length > 0) {
|
|
165
169
|
const doc = statusCandidates[0];
|
|
166
170
|
enqueuePendingPrompt(state, { kind: "review", uiId: doc.ui_id });
|
|
@@ -221,9 +225,39 @@ function statusProfileVariant(doc) {
|
|
|
221
225
|
const rawVariant = typeof profile?.variant === "string" ? profile.variant.trim().toLowerCase() : "";
|
|
222
226
|
return rawVariant.length > 0 ? rawVariant : "status";
|
|
223
227
|
}
|
|
228
|
+
const UI_STATUS_PROFILE_ASYNC_DEFAULT_IDS = new Set([
|
|
229
|
+
"planning",
|
|
230
|
+
"subagents",
|
|
231
|
+
"control-flow",
|
|
232
|
+
"model-routing",
|
|
233
|
+
]);
|
|
224
234
|
function isStatusProfileStatusVariant(doc) {
|
|
225
235
|
return statusProfileId(doc) !== null && statusProfileVariant(doc) === "status";
|
|
226
236
|
}
|
|
237
|
+
function statusProfileDelivery(doc) {
|
|
238
|
+
if (!isStatusProfileStatusVariant(doc)) {
|
|
239
|
+
return "review";
|
|
240
|
+
}
|
|
241
|
+
const profile = statusProfileMetadata(doc);
|
|
242
|
+
const rawDelivery = typeof profile?.delivery === "string" ? profile.delivery.trim().toLowerCase() : "";
|
|
243
|
+
if (rawDelivery === "async") {
|
|
244
|
+
return "async";
|
|
245
|
+
}
|
|
246
|
+
if (rawDelivery === "review") {
|
|
247
|
+
return "review";
|
|
248
|
+
}
|
|
249
|
+
const profileId = statusProfileId(doc)?.trim().toLowerCase();
|
|
250
|
+
if (profileId && UI_STATUS_PROFILE_ASYNC_DEFAULT_IDS.has(profileId)) {
|
|
251
|
+
return "async";
|
|
252
|
+
}
|
|
253
|
+
return "review";
|
|
254
|
+
}
|
|
255
|
+
function isAsyncStatusProfileStatusVariant(doc) {
|
|
256
|
+
return isStatusProfileStatusVariant(doc) && statusProfileDelivery(doc) === "async";
|
|
257
|
+
}
|
|
258
|
+
function isReviewStatusProfileStatusVariant(doc) {
|
|
259
|
+
return isStatusProfileStatusVariant(doc) && statusProfileDelivery(doc) === "review";
|
|
260
|
+
}
|
|
227
261
|
function statusProfileSnapshot(doc, format) {
|
|
228
262
|
if (!isStatusProfileStatusVariant(doc)) {
|
|
229
263
|
return null;
|
|
@@ -865,7 +899,9 @@ class UiActionPickerComponent {
|
|
|
865
899
|
const selectedDoc = this.#currentEntry().doc;
|
|
866
900
|
const selectedActions = this.#currentActions();
|
|
867
901
|
const renderLines = [];
|
|
868
|
-
const
|
|
902
|
+
const panelBg = (text) => this.#theme.bg("customMessageBg", text);
|
|
903
|
+
const borderCell = (tone, text) => panelBg(this.#theme.fg(tone, text));
|
|
904
|
+
const innerPadSegment = horizontalPadding > 0 ? panelBg(" ".repeat(horizontalPadding)) : "";
|
|
869
905
|
const contentRowText = (line, bg) => {
|
|
870
906
|
const core = this.#theme.bg(bg, fitStyledLine(line, contentWidth));
|
|
871
907
|
return `${innerPadSegment}${core}${innerPadSegment}`;
|
|
@@ -956,16 +992,16 @@ class UiActionPickerComponent {
|
|
|
956
992
|
const titleWidth = Math.min(innerWidth, visibleWidth(title));
|
|
957
993
|
const leftRule = "─".repeat(Math.max(0, Math.floor((innerWidth - titleWidth) / 2)));
|
|
958
994
|
const rightRule = "─".repeat(Math.max(0, innerWidth - titleWidth - leftRule.length));
|
|
959
|
-
frame.push(`${leftPad}${this.#theme.fg("borderAccent", `╭${leftRule}`)}${this.#theme.fg("accent", title)}${this.#theme.fg("borderAccent", `${rightRule}╮`)}`);
|
|
995
|
+
frame.push(`${leftPad}${panelBg(`${this.#theme.fg("borderAccent", `╭${leftRule}`)}${this.#theme.fg("accent", title)}${this.#theme.fg("borderAccent", `${rightRule}╮`)}`)}`);
|
|
960
996
|
this.#mouseTargets = [];
|
|
961
|
-
const blankInnerRow = `${leftPad}${
|
|
997
|
+
const blankInnerRow = `${leftPad}${borderCell("border", "│")}${panelBg(" ".repeat(innerWidth))}${borderCell("border", "│")}`;
|
|
962
998
|
for (let row = 0; row < verticalPadding; row += 1) {
|
|
963
999
|
frame.push(blankInnerRow);
|
|
964
1000
|
}
|
|
965
1001
|
const contentStartRow = frame.length + 1;
|
|
966
1002
|
for (let idx = 0; idx < renderLines.length; idx += 1) {
|
|
967
1003
|
const line = renderLines[idx];
|
|
968
|
-
frame.push(`${leftPad}${
|
|
1004
|
+
frame.push(`${leftPad}${borderCell("border", "│")}${line.text}${borderCell("border", "│")}`);
|
|
969
1005
|
const row = contentStartRow + idx;
|
|
970
1006
|
if (line.docTarget) {
|
|
971
1007
|
this.#mouseTargets.push({
|
|
@@ -989,7 +1025,7 @@ class UiActionPickerComponent {
|
|
|
989
1025
|
for (let row = 0; row < verticalPadding; row += 1) {
|
|
990
1026
|
frame.push(blankInnerRow);
|
|
991
1027
|
}
|
|
992
|
-
frame.push(`${leftPad}${
|
|
1028
|
+
frame.push(`${leftPad}${borderCell("borderAccent", `╰${"─".repeat(innerWidth)}╯`)}`);
|
|
993
1029
|
for (let row = 0; row < bottomMarginRows; row += 1) {
|
|
994
1030
|
frame.push("");
|
|
995
1031
|
}
|
|
@@ -1135,6 +1171,40 @@ function buildToolResult(opts) {
|
|
|
1135
1171
|
};
|
|
1136
1172
|
return result;
|
|
1137
1173
|
}
|
|
1174
|
+
function asyncStatusWidgetLines(ctx, docs) {
|
|
1175
|
+
if (!ctx.hasUI) {
|
|
1176
|
+
return null;
|
|
1177
|
+
}
|
|
1178
|
+
const asyncDocs = docs
|
|
1179
|
+
.filter((doc) => isAsyncStatusProfileStatusVariant(doc))
|
|
1180
|
+
.sort((left, right) => {
|
|
1181
|
+
if (left.updated_at_ms !== right.updated_at_ms) {
|
|
1182
|
+
return right.updated_at_ms - left.updated_at_ms;
|
|
1183
|
+
}
|
|
1184
|
+
return left.ui_id.localeCompare(right.ui_id);
|
|
1185
|
+
});
|
|
1186
|
+
if (asyncDocs.length === 0) {
|
|
1187
|
+
return null;
|
|
1188
|
+
}
|
|
1189
|
+
const visible = asyncDocs.slice(0, UI_ASYNC_WIDGET_DOCS_MAX);
|
|
1190
|
+
const lines = [
|
|
1191
|
+
ctx.ui.theme.fg("dim", `ui async status · ${asyncDocs.length} ${pluralize(asyncDocs.length, "doc")}`),
|
|
1192
|
+
];
|
|
1193
|
+
for (const doc of visible) {
|
|
1194
|
+
const profileId = statusProfileId(doc) ?? doc.ui_id;
|
|
1195
|
+
const snapshot = statusProfileSnapshot(doc, "compact") ?? doc.summary ?? `${doc.title} (${doc.revision.version})`;
|
|
1196
|
+
lines.push([
|
|
1197
|
+
ctx.ui.theme.fg("muted", " •"),
|
|
1198
|
+
ctx.ui.theme.fg("text", short(profileId, 24)),
|
|
1199
|
+
ctx.ui.theme.fg("muted", "·"),
|
|
1200
|
+
ctx.ui.theme.fg("dim", short(snapshot, UI_ASYNC_WIDGET_SNAPSHOT_MAX)),
|
|
1201
|
+
].join(" "));
|
|
1202
|
+
}
|
|
1203
|
+
if (asyncDocs.length > visible.length) {
|
|
1204
|
+
lines.push(ctx.ui.theme.fg("muted", ` ... (+${asyncDocs.length - visible.length} more)`));
|
|
1205
|
+
}
|
|
1206
|
+
return lines;
|
|
1207
|
+
}
|
|
1138
1208
|
function refreshUi(ctx) {
|
|
1139
1209
|
const key = sessionKey(ctx);
|
|
1140
1210
|
const state = ensureState(key);
|
|
@@ -1149,22 +1219,32 @@ function refreshUi(ctx) {
|
|
|
1149
1219
|
return;
|
|
1150
1220
|
}
|
|
1151
1221
|
const awaiting = awaitingDocs(state, docs);
|
|
1222
|
+
const asyncStatusDocs = docs.filter((doc) => isAsyncStatusProfileStatusVariant(doc));
|
|
1152
1223
|
const labels = docs.map((doc) => doc.ui_id).join(", ");
|
|
1153
1224
|
const readiness = state.interactionDepth > 0
|
|
1154
1225
|
? ctx.ui.theme.fg("accent", "prompting")
|
|
1155
1226
|
: awaiting.length > 0
|
|
1156
1227
|
? ctx.ui.theme.fg("accent", `awaiting ${awaiting.length}`)
|
|
1157
1228
|
: ctx.ui.theme.fg("dim", "ready");
|
|
1158
|
-
|
|
1229
|
+
const statusParts = [
|
|
1159
1230
|
ctx.ui.theme.fg("dim", "ui"),
|
|
1160
1231
|
ctx.ui.theme.fg("muted", "·"),
|
|
1161
1232
|
ctx.ui.theme.fg("accent", `${docs.length}`),
|
|
1162
1233
|
ctx.ui.theme.fg("muted", "·"),
|
|
1163
1234
|
readiness,
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1235
|
+
];
|
|
1236
|
+
if (asyncStatusDocs.length > 0) {
|
|
1237
|
+
statusParts.push(ctx.ui.theme.fg("muted", "·"), ctx.ui.theme.fg("dim", `async ${asyncStatusDocs.length}`));
|
|
1238
|
+
}
|
|
1239
|
+
statusParts.push(ctx.ui.theme.fg("muted", "·"), ctx.ui.theme.fg("text", labels));
|
|
1240
|
+
ctx.ui.setStatus("mu-ui", statusParts.join(" "));
|
|
1241
|
+
const widgetLines = asyncStatusWidgetLines(ctx, docs);
|
|
1242
|
+
if (widgetLines && widgetLines.length > 0) {
|
|
1243
|
+
ctx.ui.setWidget("mu-ui", widgetLines, { placement: "belowEditor" });
|
|
1244
|
+
}
|
|
1245
|
+
else {
|
|
1246
|
+
ctx.ui.setWidget("mu-ui", undefined);
|
|
1247
|
+
}
|
|
1168
1248
|
}
|
|
1169
1249
|
export function uiExtension(pi) {
|
|
1170
1250
|
const commandUsage = "/mu ui status|snapshot [compact|multiline]|interact [ui_id [action_id]]";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@femtomc/mu-agent",
|
|
3
|
-
"version": "26.2.
|
|
3
|
+
"version": "26.2.117",
|
|
4
4
|
"description": "Shared operator runtime for mu assistant sessions and serve extensions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mu",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"themes/**"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@femtomc/mu-core": "26.2.
|
|
27
|
+
"@femtomc/mu-core": "26.2.117",
|
|
28
28
|
"@mariozechner/pi-agent-core": "^0.54.2",
|
|
29
29
|
"@mariozechner/pi-ai": "^0.54.2",
|
|
30
30
|
"@mariozechner/pi-coding-agent": "^0.54.2",
|