pi-open-tui 0.2.9 → 0.2.11
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/README.md +105 -99
- package/extensions/open-tui/config.ts +141 -129
- package/extensions/open-tui/editor.ts +100 -100
- package/extensions/open-tui/footer.ts +67 -20
- package/extensions/open-tui/git.ts +5 -2
- package/extensions/open-tui/icons.ts +4 -1
- package/extensions/open-tui/index.ts +286 -273
- package/extensions/open-tui/settings-command.ts +361 -289
- package/extensions/open-tui/state.ts +90 -90
- package/extensions/open-tui/utils.ts +38 -6
- package/package.json +66 -66
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CustomEditor,
|
|
3
|
-
type ExtensionAPI,
|
|
4
|
-
type ExtensionContext,
|
|
5
|
-
type KeybindingsManager,
|
|
6
|
-
} from "@earendil-works/pi-coding-agent";
|
|
7
|
-
import type { EditorTheme, TUI } from "@earendil-works/pi-tui";
|
|
8
|
-
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
9
|
-
import { findBottomBorderIndex, isEditorBorderLine, stripAnsi } from "./utils.ts";
|
|
10
|
-
|
|
11
|
-
function fillLine(content: string, width: number): string {
|
|
12
|
-
const truncated = truncateToWidth(content, Math.max(0, width), "");
|
|
13
|
-
const pad = " ".repeat(Math.max(0, width - visibleWidth(truncated)));
|
|
14
|
-
return `${truncated}${pad}`;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function roundedBorder(
|
|
18
|
-
width: number,
|
|
19
|
-
kind: "top" | "bottom",
|
|
20
|
-
paint: (s: string) => string,
|
|
21
|
-
sourceLine?: string,
|
|
22
|
-
): string {
|
|
23
|
-
if (width < 2) return paint(truncateToWidth(kind === "top" ? "╭╮" : "╰╯", width, ""));
|
|
24
|
-
const corners = kind === "top" ? (["╭", "╮"] as const) : (["╰", "╯"] as const);
|
|
25
|
-
|
|
26
|
-
if (sourceLine) {
|
|
27
|
-
const plain = stripAnsi(sourceLine);
|
|
28
|
-
const scrollMatch = plain.match(/([↑↓]\s+\d+\s+more)/);
|
|
29
|
-
if (scrollMatch) {
|
|
30
|
-
const label = `─── ${scrollMatch[1]} `;
|
|
31
|
-
const fill = Math.max(0, width - 2 - visibleWidth(label));
|
|
32
|
-
return paint(`${corners[0]}${label}${"─".repeat(fill)}${corners[1]}`);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return paint(`${corners[0]}${"─".repeat(Math.max(0, width - 2))}${corners[1]}`);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export class OpenTuiEditor extends CustomEditor {
|
|
40
|
-
private readonly getRail: () => string;
|
|
41
|
-
private readonly getBorder: (s: string) => string;
|
|
42
|
-
|
|
43
|
-
constructor(
|
|
44
|
-
tui: TUI,
|
|
45
|
-
editorTheme: EditorTheme,
|
|
46
|
-
keybindings: KeybindingsManager,
|
|
47
|
-
) {
|
|
48
|
-
super(tui, editorTheme, keybindings, { paddingX: 0 });
|
|
49
|
-
// ponytail: route the frame through this.borderColor so Pi can recolor it
|
|
50
|
-
// via updateEditorBorderColor() — bash mode ("! " prefix → green) and
|
|
51
|
-
// thinking-level borders both flow through this one property.
|
|
52
|
-
this.getRail = () => this.borderColor("│");
|
|
53
|
-
this.getBorder = (s: string) => this.borderColor(s);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
override setPaddingX(_padding: number): void {
|
|
57
|
-
// The custom rail owns the horizontal inset and keeps one stable text gap.
|
|
58
|
-
super.setPaddingX(0);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
render(width: number): string[] {
|
|
62
|
-
if (width < 4) return super.render(width);
|
|
63
|
-
|
|
64
|
-
const rail = this.getRail();
|
|
65
|
-
const borderPaint = this.getBorder;
|
|
66
|
-
// ponytail: 1-char rail + 1-char gap on each side = 4 chars of chrome.
|
|
67
|
-
const innerWidth = Math.max(0, width - 4);
|
|
68
|
-
const baseLines = super.render(innerWidth);
|
|
69
|
-
const bottomIdx = findBottomBorderIndex(baseLines);
|
|
70
|
-
|
|
71
|
-
const result: string[] = [];
|
|
72
|
-
result.push(roundedBorder(width, "top", borderPaint, baseLines[0]));
|
|
73
|
-
|
|
74
|
-
for (let i = 1; i < bottomIdx; i++) {
|
|
75
|
-
const line = baseLines[i] ?? "";
|
|
76
|
-
if (isEditorBorderLine(line)) {
|
|
77
|
-
result.push(`${rail} ${fillLine("", innerWidth)} ${rail}`);
|
|
78
|
-
} else {
|
|
79
|
-
result.push(`${rail} ${fillLine(line, innerWidth)} ${rail}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
result.push(roundedBorder(width, "bottom", borderPaint, baseLines[bottomIdx]));
|
|
84
|
-
|
|
85
|
-
for (let i = bottomIdx + 1; i < baseLines.length; i++) {
|
|
86
|
-
result.push(baseLines[i]!);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return result.map((line) => truncateToWidth(line, width, ""));
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function installEditor(_pi: ExtensionAPI, ctx: ExtensionContext): () => void {
|
|
94
|
-
ctx.ui.setEditorComponent((tui, editorTheme, keybindings) =>
|
|
95
|
-
new OpenTuiEditor(tui, editorTheme, keybindings),
|
|
96
|
-
);
|
|
97
|
-
return () => {
|
|
98
|
-
ctx.ui.setEditorComponent(undefined);
|
|
99
|
-
};
|
|
100
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
CustomEditor,
|
|
3
|
+
type ExtensionAPI,
|
|
4
|
+
type ExtensionContext,
|
|
5
|
+
type KeybindingsManager,
|
|
6
|
+
} from "@earendil-works/pi-coding-agent";
|
|
7
|
+
import type { EditorTheme, TUI } from "@earendil-works/pi-tui";
|
|
8
|
+
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
9
|
+
import { findBottomBorderIndex, isEditorBorderLine, stripAnsi } from "./utils.ts";
|
|
10
|
+
|
|
11
|
+
function fillLine(content: string, width: number): string {
|
|
12
|
+
const truncated = truncateToWidth(content, Math.max(0, width), "");
|
|
13
|
+
const pad = " ".repeat(Math.max(0, width - visibleWidth(truncated)));
|
|
14
|
+
return `${truncated}${pad}`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function roundedBorder(
|
|
18
|
+
width: number,
|
|
19
|
+
kind: "top" | "bottom",
|
|
20
|
+
paint: (s: string) => string,
|
|
21
|
+
sourceLine?: string,
|
|
22
|
+
): string {
|
|
23
|
+
if (width < 2) return paint(truncateToWidth(kind === "top" ? "╭╮" : "╰╯", width, ""));
|
|
24
|
+
const corners = kind === "top" ? (["╭", "╮"] as const) : (["╰", "╯"] as const);
|
|
25
|
+
|
|
26
|
+
if (sourceLine) {
|
|
27
|
+
const plain = stripAnsi(sourceLine);
|
|
28
|
+
const scrollMatch = plain.match(/([↑↓]\s+\d+\s+more)/);
|
|
29
|
+
if (scrollMatch) {
|
|
30
|
+
const label = `─── ${scrollMatch[1]} `;
|
|
31
|
+
const fill = Math.max(0, width - 2 - visibleWidth(label));
|
|
32
|
+
return paint(`${corners[0]}${label}${"─".repeat(fill)}${corners[1]}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return paint(`${corners[0]}${"─".repeat(Math.max(0, width - 2))}${corners[1]}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class OpenTuiEditor extends CustomEditor {
|
|
40
|
+
private readonly getRail: () => string;
|
|
41
|
+
private readonly getBorder: (s: string) => string;
|
|
42
|
+
|
|
43
|
+
constructor(
|
|
44
|
+
tui: TUI,
|
|
45
|
+
editorTheme: EditorTheme,
|
|
46
|
+
keybindings: KeybindingsManager,
|
|
47
|
+
) {
|
|
48
|
+
super(tui, editorTheme, keybindings, { paddingX: 0 });
|
|
49
|
+
// ponytail: route the frame through this.borderColor so Pi can recolor it
|
|
50
|
+
// via updateEditorBorderColor() — bash mode ("! " prefix → green) and
|
|
51
|
+
// thinking-level borders both flow through this one property.
|
|
52
|
+
this.getRail = () => this.borderColor("│");
|
|
53
|
+
this.getBorder = (s: string) => this.borderColor(s);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
override setPaddingX(_padding: number): void {
|
|
57
|
+
// The custom rail owns the horizontal inset and keeps one stable text gap.
|
|
58
|
+
super.setPaddingX(0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
render(width: number): string[] {
|
|
62
|
+
if (width < 4) return super.render(width);
|
|
63
|
+
|
|
64
|
+
const rail = this.getRail();
|
|
65
|
+
const borderPaint = this.getBorder;
|
|
66
|
+
// ponytail: 1-char rail + 1-char gap on each side = 4 chars of chrome.
|
|
67
|
+
const innerWidth = Math.max(0, width - 4);
|
|
68
|
+
const baseLines = super.render(innerWidth);
|
|
69
|
+
const bottomIdx = findBottomBorderIndex(baseLines);
|
|
70
|
+
|
|
71
|
+
const result: string[] = [];
|
|
72
|
+
result.push(roundedBorder(width, "top", borderPaint, baseLines[0]));
|
|
73
|
+
|
|
74
|
+
for (let i = 1; i < bottomIdx; i++) {
|
|
75
|
+
const line = baseLines[i] ?? "";
|
|
76
|
+
if (isEditorBorderLine(line)) {
|
|
77
|
+
result.push(`${rail} ${fillLine("", innerWidth)} ${rail}`);
|
|
78
|
+
} else {
|
|
79
|
+
result.push(`${rail} ${fillLine(line, innerWidth)} ${rail}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
result.push(roundedBorder(width, "bottom", borderPaint, baseLines[bottomIdx]));
|
|
84
|
+
|
|
85
|
+
for (let i = bottomIdx + 1; i < baseLines.length; i++) {
|
|
86
|
+
result.push(baseLines[i]!);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return result.map((line) => truncateToWidth(line, width, ""));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function installEditor(_pi: ExtensionAPI, ctx: ExtensionContext): () => void {
|
|
94
|
+
ctx.ui.setEditorComponent((tui, editorTheme, keybindings) =>
|
|
95
|
+
new OpenTuiEditor(tui, editorTheme, keybindings),
|
|
96
|
+
);
|
|
97
|
+
return () => {
|
|
98
|
+
ctx.ui.setEditorComponent(undefined);
|
|
99
|
+
};
|
|
100
|
+
}
|
|
@@ -7,6 +7,7 @@ import type { GitStatus } from "./git.ts";
|
|
|
7
7
|
import type { RuntimeInfo } from "./runtime.ts";
|
|
8
8
|
import {
|
|
9
9
|
alignRight,
|
|
10
|
+
basenamePath,
|
|
10
11
|
cacheHitColor,
|
|
11
12
|
effortColor,
|
|
12
13
|
fitSegmentsByPriority,
|
|
@@ -17,7 +18,9 @@ import {
|
|
|
17
18
|
providerColor,
|
|
18
19
|
sanitizeStatus,
|
|
19
20
|
stressColor,
|
|
21
|
+
truncateBranch,
|
|
20
22
|
truncatePath,
|
|
23
|
+
type PrioritizedSegment,
|
|
21
24
|
} from "./utils.ts";
|
|
22
25
|
import type { FooterState, ModelMeta, UsageTotals } from "./state.ts";
|
|
23
26
|
import { getUsageTotals } from "./state.ts";
|
|
@@ -36,6 +39,15 @@ function renderBar(theme: Theme, pct: number, barWidth: number, ascii: boolean):
|
|
|
36
39
|
);
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
/** Compact context form: icon + percentage, no bar or token counts. */
|
|
43
|
+
function renderContextCompact(theme: Theme, ctx: ExtensionContext, glyphs: IconGlyphs): string {
|
|
44
|
+
const contextUsage = ctx.getContextUsage();
|
|
45
|
+
const contextWindow = contextUsage?.contextWindow ?? ctx.model?.contextWindow ?? 0;
|
|
46
|
+
if (contextWindow <= 0) return "";
|
|
47
|
+
const contextPct = contextUsage?.percent ?? 0;
|
|
48
|
+
return `${theme.fg(stressColor(contextPct), glyphs.context)} ${theme.fg(stressColor(contextPct), `${contextPct.toFixed(1)}%`)}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
39
51
|
function renderGitSegment(
|
|
40
52
|
theme: Theme,
|
|
41
53
|
git: GitStatus,
|
|
@@ -47,7 +59,7 @@ function renderGitSegment(
|
|
|
47
59
|
if (segments.gitBranch) {
|
|
48
60
|
if (git.branch) {
|
|
49
61
|
parts.push(theme.fg("mdLink", glyphs.git));
|
|
50
|
-
parts.push(theme.fg("mdLink",
|
|
62
|
+
parts.push(theme.fg("mdLink", truncateBranch(git.branch, maxBranchLen)));
|
|
51
63
|
} else if (git.commit?.detached) {
|
|
52
64
|
parts.push(theme.fg("warning", glyphs.git));
|
|
53
65
|
parts.push(theme.fg("warning", "HEAD"));
|
|
@@ -131,6 +143,8 @@ function renderContextBar(
|
|
|
131
143
|
const pctText = theme.fg(stressColor(contextPct), `${contextPct.toFixed(1)}%`);
|
|
132
144
|
const ctxText = `${theme.fg("text", fmtTokens(contextTokens))}${theme.fg("dim", "/")}${theme.fg("text", fmtTokens(contextWindow))}`;
|
|
133
145
|
const contextIcon = theme.fg(stressColor(contextPct), glyphs.context);
|
|
146
|
+
// Cap the bar at `width - reserved` (with a floor of 4) so the full form
|
|
147
|
+
// never forces the left segments out before compact/drop logic kicks in.
|
|
134
148
|
const reserved = visibleWidth(contextIcon) + visibleWidth(pctText) + visibleWidth(ctxText) + 5 + 2;
|
|
135
149
|
const barWidth = Math.max(4, Math.min(12, width - reserved));
|
|
136
150
|
return `${contextIcon} ${renderBar(theme, contextPct, barWidth, resolveIconMode(iconMode) === "ascii")} ${pctText} ${theme.fg("dim", "·")} ${ctxText}`;
|
|
@@ -213,32 +227,63 @@ export function installFooter(
|
|
|
213
227
|
|
|
214
228
|
const totals = getUsageTotals(ctx);
|
|
215
229
|
|
|
216
|
-
const leftParts:
|
|
230
|
+
const leftParts: PrioritizedSegment[] = [];
|
|
217
231
|
if (segments.cwd) {
|
|
218
232
|
const maxCwd = Math.min(30, Math.max(10, Math.floor(width * 0.4)));
|
|
233
|
+
const cwd = formatCwd(ctx.sessionManager.getCwd());
|
|
234
|
+
const cwdPrefix = `${theme.fg("mdLink", glyphs.cwd)} `;
|
|
235
|
+
const accent = (text: string) => theme.fg("accent", text);
|
|
219
236
|
leftParts.push({
|
|
220
|
-
text: `${
|
|
237
|
+
text: `${cwdPrefix}${accent(truncatePath(cwd, maxCwd))}`,
|
|
238
|
+
compactText: `${cwdPrefix}${accent(truncatePath(basenamePath(cwd), maxCwd))}`,
|
|
221
239
|
priority: 0,
|
|
240
|
+
truncate: (_text, maxWidth, ellipsis) => {
|
|
241
|
+
const pathWidth = maxWidth - visibleWidth(cwdPrefix);
|
|
242
|
+
if (pathWidth <= visibleWidth(ellipsis)) {
|
|
243
|
+
return truncateToWidth(`${cwdPrefix}${accent(basenamePath(cwd))}`, maxWidth, ellipsis);
|
|
244
|
+
}
|
|
245
|
+
return `${cwdPrefix}${accent(truncatePath(basenamePath(cwd), pathWidth))}`;
|
|
246
|
+
},
|
|
222
247
|
});
|
|
223
248
|
}
|
|
249
|
+
if (segments.sessionName) {
|
|
250
|
+
const sessionName = ctx.sessionManager.getSessionName();
|
|
251
|
+
if (sessionName) {
|
|
252
|
+
leftParts.push({
|
|
253
|
+
text: `${theme.fg("dim", glyphs.session)} ${theme.fg("text", truncateToWidth(sessionName, 24, theme.fg("dim", "...")))}`,
|
|
254
|
+
priority: 2,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
224
258
|
const gitSeg = renderGitSegment(theme, state.git, glyphs, segments);
|
|
225
259
|
if (gitSeg) leftParts.push({ text: gitSeg, priority: 3 });
|
|
226
260
|
if (segments.runtime) {
|
|
227
261
|
const runtimeSeg = renderRuntimeSegment(theme, state.runtime, config.icons.mode);
|
|
228
|
-
if (runtimeSeg) leftParts.push({ text: runtimeSeg, priority:
|
|
262
|
+
if (runtimeSeg) leftParts.push({ text: runtimeSeg, priority: 4 });
|
|
229
263
|
}
|
|
230
264
|
const timerSeg = renderTimerSegment(theme, state, glyphs);
|
|
231
|
-
if (timerSeg) leftParts.push({ text: timerSeg, priority:
|
|
265
|
+
if (timerSeg) leftParts.push({ text: timerSeg, priority: 1 });
|
|
232
266
|
|
|
233
|
-
|
|
267
|
+
// The context bar competes with the left segments for the same row:
|
|
268
|
+
// full bar first, then the compact icon+pct form, then dropped.
|
|
269
|
+
let contextText = "";
|
|
270
|
+
let contextCompact: string | undefined;
|
|
234
271
|
if (segments.context) {
|
|
235
|
-
|
|
272
|
+
contextText = renderContextBar(theme, ctx, width, glyphs, config.icons.mode);
|
|
273
|
+
const compact = renderContextCompact(theme, ctx, glyphs);
|
|
274
|
+
if (compact && visibleWidth(compact) < visibleWidth(contextText)) {
|
|
275
|
+
contextCompact = compact;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const allParts: PrioritizedSegment[] = [...leftParts];
|
|
279
|
+
if (contextText) {
|
|
280
|
+
// ponytail: priority 4 = sheds with runtime, before git/timer/cwd.
|
|
281
|
+
allParts.push({ text: contextText, compactText: contextCompact, priority: 4 });
|
|
236
282
|
}
|
|
237
283
|
|
|
238
|
-
const
|
|
239
|
-
const
|
|
240
|
-
const
|
|
241
|
-
const line1 = alignRight(fittedLeft.join(" "), rightBlock, width, theme);
|
|
284
|
+
const fitted = fitSegmentsByPriority(allParts, width, theme.fg("dim", "..."));
|
|
285
|
+
const fittedContext = contextText ? fitted.pop() ?? "" : "";
|
|
286
|
+
const line1 = alignRight(fitted.join(" "), fittedContext, width, theme);
|
|
242
287
|
|
|
243
288
|
const modelParts: string[] = [];
|
|
244
289
|
modelParts.push(theme.fg("mdLink", glyphs.model));
|
|
@@ -262,15 +307,17 @@ export function installFooter(
|
|
|
262
307
|
|
|
263
308
|
const mainLines = [line1, line2]
|
|
264
309
|
.map((line) => truncateToWidth(line, width, theme.fg("dim", "...")));
|
|
265
|
-
return
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
310
|
+
return segments.extensionStatuses
|
|
311
|
+
? [
|
|
312
|
+
...mainLines,
|
|
313
|
+
...renderExtensionStatusLines(
|
|
314
|
+
theme,
|
|
315
|
+
footerData.getExtensionStatuses(),
|
|
316
|
+
glyphs,
|
|
317
|
+
width,
|
|
318
|
+
),
|
|
319
|
+
]
|
|
320
|
+
: mainLines;
|
|
274
321
|
},
|
|
275
322
|
};
|
|
276
323
|
});
|
|
@@ -57,7 +57,7 @@ async function gitExec(args: string[], cwd: string): Promise<string | null> {
|
|
|
57
57
|
|
|
58
58
|
export async function readGitStatus(
|
|
59
59
|
cwd: string,
|
|
60
|
-
options: { readCommit?: boolean; readTag?: boolean } = {},
|
|
60
|
+
options: { readCommit?: boolean; readTag?: boolean; readCounts?: boolean } = {},
|
|
61
61
|
): Promise<GitStatus> {
|
|
62
62
|
if (!existsSync(join(cwd, ".git"))) {
|
|
63
63
|
return emptyGitStatus();
|
|
@@ -102,6 +102,9 @@ export async function readGitStatus(
|
|
|
102
102
|
continue;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
// ponytail: skip file-entry counting when only branch/commit display is on;
|
|
106
|
+
// the first `git status` call itself can't be split, but the stash fallback below can.
|
|
107
|
+
if (options.readCounts === false) continue;
|
|
105
108
|
if (line.length < 3) continue;
|
|
106
109
|
const x = line[0]!;
|
|
107
110
|
const y = line[1]!;
|
|
@@ -116,7 +119,7 @@ export async function readGitStatus(
|
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
|
|
119
|
-
if (stashSupported && status.stashed === 0 && !stdout.includes("# stash")) {
|
|
122
|
+
if (options.readCounts !== false && stashSupported && status.stashed === 0 && !stdout.includes("# stash")) {
|
|
120
123
|
const stashOut = await gitExec(["stash", "list", "--count"], cwd);
|
|
121
124
|
if (stashOut !== null) {
|
|
122
125
|
const count = parseInt(stashOut.trim(), 10);
|
|
@@ -2,6 +2,7 @@ export type IconMode = "auto" | "nerd" | "ascii";
|
|
|
2
2
|
|
|
3
3
|
export interface IconGlyphs {
|
|
4
4
|
cwd: string;
|
|
5
|
+
session: string;
|
|
5
6
|
git: string;
|
|
6
7
|
working: string;
|
|
7
8
|
done: string;
|
|
@@ -30,6 +31,7 @@ export interface IconGlyphs {
|
|
|
30
31
|
|
|
31
32
|
const NERD_GLYPHS: IconGlyphs = {
|
|
32
33
|
cwd: "",
|
|
34
|
+
session: "",
|
|
33
35
|
git: "",
|
|
34
36
|
working: "",
|
|
35
37
|
done: "",
|
|
@@ -62,10 +64,11 @@ const NERD_GLYPHS: IconGlyphs = {
|
|
|
62
64
|
// avoid collisions with the git-status set {= S ! A ? r x ^ v}.
|
|
63
65
|
const ASCII_GLYPHS: IconGlyphs = {
|
|
64
66
|
cwd: "@",
|
|
67
|
+
session: "s",
|
|
65
68
|
git: "*",
|
|
66
69
|
working: "o",
|
|
67
70
|
done: "+",
|
|
68
|
-
context: "
|
|
71
|
+
context: "#",
|
|
69
72
|
model: "M",
|
|
70
73
|
thinking: "~",
|
|
71
74
|
input: "↑",
|