@gavin-hu/my-pi-agent 0.8.1 → 0.10.0
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 +35 -8
- package/README.zh-CN.md +33 -8
- package/assets/bytefly.schema.json +17 -1
- package/assets/chrome.png +0 -0
- package/assets/file-browse.png +0 -0
- package/assets/job.png +0 -0
- package/assets/plan-review.png +0 -0
- package/assets/question.png +0 -0
- package/assets/rewind.png +0 -0
- package/assets/todo.png +0 -0
- package/assets/tool-renderings.png +0 -0
- package/assets/tools/ask_user_question.png +0 -0
- package/assets/tools/bash.png +0 -0
- package/assets/tools/edit.png +0 -0
- package/assets/tools/enter_plan_mode.png +0 -0
- package/assets/tools/enter_worktree.png +0 -0
- package/assets/tools/exit_plan_mode.png +0 -0
- package/assets/tools/exit_worktree.png +0 -0
- package/assets/tools/find.png +0 -0
- package/assets/tools/goal.png +0 -0
- package/assets/tools/grep.png +0 -0
- package/assets/tools/job.png +0 -0
- package/assets/tools/list_worktrees.png +0 -0
- package/assets/tools/ls.png +0 -0
- package/assets/tools/memory.png +0 -0
- package/assets/tools/notice.png +0 -0
- package/assets/tools/open_path.png +0 -0
- package/assets/tools/prune_worktrees.png +0 -0
- package/assets/tools/read.png +0 -0
- package/assets/tools/read_doc.png +0 -0
- package/assets/tools/run_doctor.png +0 -0
- package/assets/tools/send_wechat.png +0 -0
- package/assets/tools/set_plan_steps.png +0 -0
- package/assets/tools/subagent.png +0 -0
- package/assets/tools/todo.png +0 -0
- package/assets/tools/turn-rule.png +0 -0
- package/assets/tools/user-message.png +0 -0
- package/assets/tools/watch.png +0 -0
- package/assets/tools/web_fetch.png +0 -0
- package/assets/tools/web_search.png +0 -0
- package/assets/tools/write.png +0 -0
- package/assets/tools/write_plan.png +0 -0
- package/extensions/bytefly/README.md +306 -68
- package/extensions/bytefly/block/component.ts +282 -0
- package/extensions/bytefly/block/config.ts +24 -0
- package/extensions/bytefly/block/fallback.ts +120 -0
- package/extensions/bytefly/block/register.ts +164 -0
- package/extensions/bytefly/chrome.ts +97 -0
- package/extensions/bytefly/doctor/format.ts +36 -10
- package/extensions/bytefly/doctor/tools.ts +10 -6
- package/extensions/bytefly/footer/config.ts +1 -1
- package/extensions/bytefly/footer/render/format.ts +5 -18
- package/extensions/bytefly/footer/render/layout.ts +2 -1
- package/extensions/bytefly/footer/render/segments.ts +51 -78
- package/extensions/bytefly/header/component.ts +49 -21
- package/extensions/bytefly/header/config.ts +28 -21
- package/extensions/bytefly/header/register.ts +6 -1
- package/extensions/bytefly/index.ts +32 -12
- package/extensions/bytefly/message/config.ts +15 -0
- package/extensions/bytefly/message/format.ts +42 -0
- package/extensions/bytefly/message/register.ts +15 -0
- package/extensions/bytefly/notice/component.ts +107 -0
- package/extensions/bytefly/notice/config.ts +41 -0
- package/extensions/bytefly/notice/register.ts +27 -0
- package/extensions/bytefly/pad.ts +42 -0
- package/extensions/bytefly/panel/commands.ts +69 -35
- package/extensions/bytefly/panel/format.ts +8 -8
- package/extensions/bytefly/panel/tui.ts +45 -70
- package/extensions/bytefly/separator/component.ts +2 -1
- package/extensions/bytefly/separator/config.ts +16 -8
- package/extensions/bytefly/separator/format.ts +18 -38
- package/extensions/bytefly/separator/register.ts +3 -2
- package/extensions/bytefly/separator/types.ts +0 -10
- package/extensions/bytefly/working/config.ts +20 -0
- package/extensions/bytefly/working/format.ts +25 -0
- package/extensions/bytefly/working/register.ts +88 -0
- package/extensions/document/README.md +12 -5
- package/extensions/document/paging.ts +10 -10
- package/extensions/document/render.ts +17 -16
- package/extensions/document/tool.ts +1 -1
- package/extensions/file-browse/README.md +54 -10
- package/extensions/file-browse/client.ts +110 -2
- package/extensions/file-browse/config.ts +12 -0
- package/extensions/file-browse/diff.ts +187 -0
- package/extensions/file-browse/git.ts +180 -8
- package/extensions/file-browse/html.ts +401 -25
- package/extensions/file-browse/index.ts +15 -4
- package/extensions/file-browse/markdown.ts +33 -0
- package/extensions/file-browse/router.ts +94 -2
- package/extensions/file-browse/server.ts +4 -1
- package/extensions/file-open/README.md +6 -0
- package/extensions/goal/README.md +16 -10
- package/extensions/goal/format.ts +13 -25
- package/extensions/goal/tools.ts +11 -22
- package/extensions/goal/tui.ts +12 -40
- package/extensions/job/README.md +22 -13
- package/extensions/job/format.ts +36 -13
- package/extensions/job/index.ts +26 -21
- package/extensions/job/tools.ts +15 -12
- package/extensions/job/tui.ts +148 -222
- package/extensions/job/ui.ts +24 -49
- package/extensions/memory/README.md +7 -1
- package/extensions/memory/format.ts +5 -3
- package/extensions/memory/tools.ts +4 -3
- package/extensions/memory/tui.ts +32 -36
- package/extensions/plan/README.md +86 -36
- package/extensions/plan/blocks.ts +44 -2
- package/extensions/plan/feedback.ts +20 -5
- package/extensions/plan/index.ts +1 -1
- package/extensions/plan/runtime.ts +3 -2
- package/extensions/plan/tools.ts +43 -27
- package/extensions/plan/tui.ts +21 -27
- package/extensions/plan/web-client.ts +386 -40
- package/extensions/plan/web-page.ts +138 -33
- package/extensions/plan/web-router.ts +46 -13
- package/extensions/plan/web.ts +63 -12
- package/extensions/question/README.md +14 -2
- package/extensions/question/answers.ts +25 -18
- package/extensions/question/tools.ts +22 -16
- package/extensions/question/tui.ts +132 -76
- package/extensions/rewind/README.md +3 -1
- package/extensions/rewind/format.ts +35 -2
- package/extensions/rewind/index.ts +3 -1
- package/extensions/rewind/rewind-tui.ts +66 -62
- package/extensions/rewind/snapshot-run.ts +1 -1
- package/extensions/rewind/status.ts +3 -2
- package/extensions/subagent/README.md +6 -0
- package/extensions/subagent/index.ts +1 -1
- package/extensions/subagent/render.ts +108 -66
- package/extensions/todo/README.md +20 -13
- package/extensions/todo/format.ts +47 -34
- package/extensions/todo/tools.ts +6 -4
- package/extensions/todo/tui.ts +46 -26
- package/extensions/watch/README.md +16 -8
- package/extensions/watch/format.ts +33 -13
- package/extensions/watch/index.ts +29 -24
- package/extensions/watch/tools.ts +16 -9
- package/extensions/watch/tui.ts +142 -196
- package/extensions/watch/ui.ts +24 -46
- package/extensions/web-access/README.md +16 -7
- package/extensions/web-access/fetch/tool.ts +12 -11
- package/extensions/web-access/search/tool.ts +16 -13
- package/extensions/wechat/README.md +8 -2
- package/extensions/wechat/index.ts +4 -3
- package/extensions/wechat/login-screen.ts +8 -5
- package/extensions/wechat/status-screen.ts +41 -22
- package/extensions/wechat/tools.ts +6 -5
- package/extensions/worktree/README.md +6 -0
- package/extensions/worktree/enter.ts +1 -1
- package/extensions/worktree/index.ts +1 -1
- package/extensions/worktree/runtime.ts +1 -1
- package/lib/README.md +11 -7
- package/lib/format.ts +17 -0
- package/lib/notice.ts +87 -0
- package/lib/requirements.ts +2 -2
- package/lib/{tui.ts → tui/chrome.ts} +17 -34
- package/lib/tui/columns.ts +96 -0
- package/lib/{list-cursor.ts → tui/cursor.ts} +58 -4
- package/lib/tui/gauge.ts +78 -0
- package/lib/{ui.ts → tui/glyphs.ts} +10 -11
- package/lib/tui/indent.ts +166 -0
- package/lib/tui/index.ts +27 -0
- package/lib/tui/line-pane.ts +173 -0
- package/lib/tui/rows.ts +143 -0
- package/lib/tui/rules.ts +94 -0
- package/lib/tui/status-controller.ts +107 -0
- package/lib/tui/tokens.ts +72 -0
- package/lib/web/base.ts +2 -1
- package/lib/web/components.ts +3 -1
- package/lib/web/layout.ts +5 -1
- package/package.json +7 -3
- package/themes/bytefly-dark.json +7 -8
- package/themes/bytefly-light.json +10 -11
- package/assets/bytefly-chrome.png +0 -0
package/extensions/job/format.ts
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
16
16
|
import { truncateToWidth } from "@earendil-works/pi-tui";
|
|
17
|
-
import { GLYPHS } from "../../lib/
|
|
17
|
+
import { GLYPHS, SEPARATORS } from "../../lib/tui/glyphs.ts";
|
|
18
|
+
import { paint, type TuiRole } from "../../lib/tui/tokens.ts";
|
|
18
19
|
import type { JobRecord, JobStatus } from "./types.ts";
|
|
19
20
|
|
|
20
21
|
/** Longest sanitized log line kept for display; longer lines are clipped. */
|
|
@@ -76,22 +77,43 @@ export function elapsedMs(job: JobRecord, now: number): number {
|
|
|
76
77
|
return (job.finishedAt ?? now) - job.startedAt;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
/**
|
|
80
|
-
export function
|
|
80
|
+
/** The design role a job status is drawn in. */
|
|
81
|
+
export function statusRole(status: JobStatus): TuiRole {
|
|
81
82
|
switch (status) {
|
|
82
83
|
case "exited":
|
|
83
|
-
return
|
|
84
|
+
return "ok";
|
|
84
85
|
case "failed":
|
|
85
|
-
return
|
|
86
|
+
return "bad";
|
|
86
87
|
case "killed":
|
|
87
|
-
return
|
|
88
|
+
return "meta";
|
|
88
89
|
case "unknown":
|
|
89
|
-
return
|
|
90
|
+
return "faint";
|
|
90
91
|
default:
|
|
91
|
-
return
|
|
92
|
+
return "accent";
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
|
|
96
|
+
/** Width-1 glyph for a status, from the shared vocabulary. */
|
|
97
|
+
export function statusGlyphChar(status: JobStatus): string {
|
|
98
|
+
switch (status) {
|
|
99
|
+
case "exited":
|
|
100
|
+
return GLYPHS.check;
|
|
101
|
+
case "failed":
|
|
102
|
+
return GLYPHS.jobsFailure;
|
|
103
|
+
case "killed":
|
|
104
|
+
return GLYPHS.killed;
|
|
105
|
+
case "unknown":
|
|
106
|
+
return GLYPHS.unknown;
|
|
107
|
+
default:
|
|
108
|
+
return GLYPHS.jobsRunning;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Width-1 themed glyph for a status. */
|
|
113
|
+
export function statusGlyph(status: JobStatus, theme: Theme): string {
|
|
114
|
+
return paint(theme, statusRole(status), statusGlyphChar(status));
|
|
115
|
+
}
|
|
116
|
+
|
|
95
117
|
/** Short status word for text output. */
|
|
96
118
|
function statusWord(job: JobRecord): string {
|
|
97
119
|
if (job.status === "failed" && job.exitCode !== null) return `failed (exit ${job.exitCode})`;
|
|
@@ -229,18 +251,19 @@ export function jobOutcome(job: JobRecord): string {
|
|
|
229
251
|
|
|
230
252
|
/** One-line outcome for a single job, themed for the transcript result. */
|
|
231
253
|
export function formatJobOutcomeLine(job: JobRecord, theme: Theme, now = Date.now()): string {
|
|
232
|
-
const sep = theme
|
|
233
|
-
const outcome =
|
|
254
|
+
const sep = paint(theme, "faint", SEPARATORS.item);
|
|
255
|
+
const outcome =
|
|
256
|
+
job.status === "failed" ? paint(theme, "bad", jobOutcome(job)) : paint(theme, "faint", jobOutcome(job));
|
|
234
257
|
return (
|
|
235
258
|
statusGlyph(job.status, theme) +
|
|
236
259
|
" " +
|
|
237
|
-
theme
|
|
260
|
+
paint(theme, "accent", job.id) +
|
|
238
261
|
" " +
|
|
239
|
-
theme
|
|
262
|
+
paint(theme, "meta", shortLabel(job)) +
|
|
240
263
|
sep +
|
|
241
264
|
outcome +
|
|
242
265
|
sep +
|
|
243
|
-
theme
|
|
266
|
+
paint(theme, "faint", formatDuration(elapsedMs(job, now)))
|
|
244
267
|
);
|
|
245
268
|
}
|
|
246
269
|
|
package/extensions/job/index.ts
CHANGED
|
@@ -4,18 +4,19 @@
|
|
|
4
4
|
* Registers the `job` tool and `/jobs` command. Jobs run as detached shell
|
|
5
5
|
* processes with their output streamed to log files; the status chip shows
|
|
6
6
|
* running and unreported-failure counts, and finished jobs are reported to the
|
|
7
|
-
* model at the next turn
|
|
7
|
+
* model — and shown as a bytefly notice — at the next turn, or by triggering one
|
|
8
|
+
* turn for a `wake` job.
|
|
8
9
|
*
|
|
9
10
|
* Load with: pi --extension ./extensions/job
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
|
-
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
|
13
13
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
14
14
|
import { isExtensionEnabled } from "../../lib/env.ts";
|
|
15
15
|
import { JOB_FINISHED_CHANNEL, type JobFinishedEvent } from "../../lib/events.ts";
|
|
16
|
-
import {
|
|
16
|
+
import { noticeMessage, type NoticeMessage, pruneStaleNotices } from "../../lib/notice.ts";
|
|
17
|
+
import { STATUS_KEYS } from "../../lib/tui/glyphs.ts";
|
|
17
18
|
import { registerCommands } from "./commands.ts";
|
|
18
|
-
import { formatCompletion } from "./format.ts";
|
|
19
|
+
import { formatCompletion, jobOutcome, shortLabel } from "./format.ts";
|
|
19
20
|
import { createJobsRuntime, type JobsRuntime } from "./runtime.ts";
|
|
20
21
|
import { registerTools } from "./tools.ts";
|
|
21
22
|
import type { Job, JobRecord } from "./types.ts";
|
|
@@ -23,16 +24,26 @@ import type { Job, JobRecord } from "./types.ts";
|
|
|
23
24
|
/** Marker embedded in the injected completion context. */
|
|
24
25
|
const JOB_CONTEXT_MARKER = "[BACKGROUND JOBS]";
|
|
25
26
|
|
|
26
|
-
/** Custom-entry type used for the injected completion message. */
|
|
27
|
-
export const JOB_CONTEXT_TYPE = "job-context";
|
|
28
|
-
|
|
29
27
|
function buildContext(jobs: JobRecord[]): string {
|
|
30
28
|
const lines = jobs.map((job) => formatCompletion(job));
|
|
31
29
|
return `${JOB_CONTEXT_MARKER}\n${jobs.length} background job${jobs.length === 1 ? "" : "s"} finished:\n${lines.join("\n")}\nRun \`job logs <id>\` for output.`;
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
/** The shared notice for pending completions: model text plus renderer details. */
|
|
33
|
+
function jobNotice(jobs: JobRecord[]): NoticeMessage {
|
|
34
|
+
const count = jobs.length;
|
|
35
|
+
return noticeMessage({
|
|
36
|
+
content: buildContext(jobs),
|
|
37
|
+
details: {
|
|
38
|
+
source: "job",
|
|
39
|
+
title: `${count} background job${count === 1 ? "" : "s"} finished`,
|
|
40
|
+
items: jobs.map((job) => ({
|
|
41
|
+
label: `${job.id} ${shortLabel(job)}`,
|
|
42
|
+
detail: jobOutcome(job),
|
|
43
|
+
severity: job.status === "failed" ? "bad" : job.status === "exited" ? "ok" : "warn",
|
|
44
|
+
})),
|
|
45
|
+
},
|
|
46
|
+
});
|
|
36
47
|
}
|
|
37
48
|
|
|
38
49
|
/** Trim a finished record to the fields the event bus carries. */
|
|
@@ -67,10 +78,7 @@ export default function jobs(pi: ExtensionAPI, deps: JobsDeps = {}): void {
|
|
|
67
78
|
const pending = runtime.pendingCompletions();
|
|
68
79
|
if (pending.length === 0) return;
|
|
69
80
|
try {
|
|
70
|
-
pi.sendMessage(
|
|
71
|
-
{ customType: JOB_CONTEXT_TYPE, content: buildContext(pending), display: false },
|
|
72
|
-
{ triggerTurn: true },
|
|
73
|
-
);
|
|
81
|
+
pi.sendMessage(jobNotice(pending), { triggerTurn: true });
|
|
74
82
|
// Mark only once the send succeeded; a throw leaves them for the next turn.
|
|
75
83
|
runtime.markReported(pending.map((job) => job.id));
|
|
76
84
|
} catch {
|
|
@@ -113,17 +121,14 @@ export default function jobs(pi: ExtensionAPI, deps: JobsDeps = {}): void {
|
|
|
113
121
|
if (pending.length === 0) return undefined;
|
|
114
122
|
runtime.markReported(pending.map((job) => job.id));
|
|
115
123
|
runtime.setStatus(ctx);
|
|
116
|
-
return {
|
|
117
|
-
message: { customType: JOB_CONTEXT_TYPE, content: buildContext(pending), display: false },
|
|
118
|
-
};
|
|
124
|
+
return { message: jobNotice(pending) };
|
|
119
125
|
});
|
|
120
126
|
|
|
121
|
-
// Keep stale completion
|
|
127
|
+
// Keep stale completion notices out of later turns. Only this extension's
|
|
128
|
+
// notices are pruned; another source's are left for its own handler.
|
|
122
129
|
pi.on("context", (event) => {
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
const last = contexts[contexts.length - 1];
|
|
126
|
-
return { messages: event.messages.filter((message) => !isJobContext(message) || message === last) };
|
|
130
|
+
const pruned = pruneStaleNotices(event.messages, "job");
|
|
131
|
+
return pruned ? { messages: pruned } : undefined;
|
|
127
132
|
});
|
|
128
133
|
|
|
129
134
|
pi.on("session_shutdown", async (_event, ctx) => {
|
package/extensions/job/tools.ts
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
11
11
|
import { sanitizeLine } from "../../lib/format.ts";
|
|
12
|
-
import { reuseText, toolDetails } from "../../lib/tui.ts";
|
|
12
|
+
import { reuseText, toolDetails } from "../../lib/tui/chrome.ts";
|
|
13
|
+
import { SEPARATORS } from "../../lib/tui/glyphs.ts";
|
|
14
|
+
import { paint } from "../../lib/tui/tokens.ts";
|
|
13
15
|
import {
|
|
14
16
|
compareJobs,
|
|
15
17
|
formatCallText,
|
|
@@ -208,8 +210,9 @@ export function registerTools(pi: ExtensionAPI, runtime: JobsRuntime): void {
|
|
|
208
210
|
const text = reuseText(context.lastComponent);
|
|
209
211
|
text.setText(
|
|
210
212
|
theme.fg("toolTitle", theme.bold(`${TOOL_NAME} `)) +
|
|
211
|
-
|
|
212
|
-
|
|
213
|
+
paint(
|
|
214
|
+
theme,
|
|
215
|
+
"meta",
|
|
213
216
|
sanitizeLine(formatCallText(action, args as Record<string, unknown>, context.argsComplete)),
|
|
214
217
|
),
|
|
215
218
|
);
|
|
@@ -225,20 +228,20 @@ export function registerTools(pi: ExtensionAPI, runtime: JobsRuntime): void {
|
|
|
225
228
|
return text;
|
|
226
229
|
}
|
|
227
230
|
if (details.error) {
|
|
228
|
-
text.setText(theme
|
|
231
|
+
text.setText(paint(theme, "bad", `Error: ${sanitizeLine(details.error)}`));
|
|
229
232
|
return text;
|
|
230
233
|
}
|
|
231
234
|
|
|
232
235
|
if (options.isPartial) {
|
|
233
236
|
const id = details.job?.id;
|
|
234
|
-
text.setText(theme
|
|
237
|
+
text.setText(paint(theme, "warn", id ? `Waiting on ${id}…` : "Waiting…"));
|
|
235
238
|
return text;
|
|
236
239
|
}
|
|
237
240
|
|
|
238
241
|
if (details.action === "logs" && details.logs !== undefined) {
|
|
239
242
|
const all = details.logs === "" ? [] : details.logs.split("\n");
|
|
240
243
|
if (all.length === 0) {
|
|
241
|
-
text.setText(theme
|
|
244
|
+
text.setText(paint(theme, "meta", "No output yet."));
|
|
242
245
|
return text;
|
|
243
246
|
}
|
|
244
247
|
const shown = options.expanded ? all : all.slice(Math.max(0, all.length - RESULT_ROWS));
|
|
@@ -250,7 +253,7 @@ export function registerTools(pi: ExtensionAPI, runtime: JobsRuntime): void {
|
|
|
250
253
|
|
|
251
254
|
if (details.action === "list" && details.jobs) {
|
|
252
255
|
if (details.jobs.length === 0) {
|
|
253
|
-
text.setText(theme
|
|
256
|
+
text.setText(paint(theme, "meta", "No jobs."));
|
|
254
257
|
return text;
|
|
255
258
|
}
|
|
256
259
|
const ordered = [...details.jobs].sort(compareJobs);
|
|
@@ -264,7 +267,7 @@ export function registerTools(pi: ExtensionAPI, runtime: JobsRuntime): void {
|
|
|
264
267
|
if (details.action === "clear") {
|
|
265
268
|
const count = details.cleared ?? 0;
|
|
266
269
|
text.setText(
|
|
267
|
-
theme
|
|
270
|
+
paint(theme, "meta", count === 0 ? "Nothing to clear." : `Cleared ${count} job${count === 1 ? "" : "s"}.`),
|
|
268
271
|
);
|
|
269
272
|
return text;
|
|
270
273
|
}
|
|
@@ -272,16 +275,16 @@ export function registerTools(pi: ExtensionAPI, runtime: JobsRuntime): void {
|
|
|
272
275
|
if (details.job) {
|
|
273
276
|
let line = formatJobOutcomeLine(details.job, theme);
|
|
274
277
|
if (details.action === "wait" && details.timedOut) {
|
|
275
|
-
line += theme
|
|
278
|
+
line += paint(theme, "warn", " · still running after the timeout");
|
|
276
279
|
} else if (details.action === "wait" && details.cancelled) {
|
|
277
|
-
line += theme
|
|
280
|
+
line += paint(theme, "warn", " · wait cancelled; job still running");
|
|
278
281
|
} else if (details.action === "kill" && details.signalled) {
|
|
279
|
-
line += theme
|
|
282
|
+
line += paint(theme, "warn", ` · ${details.signal ?? "SIGTERM"} sent`);
|
|
280
283
|
} else if (details.action === "start") {
|
|
281
284
|
const badges: string[] = [];
|
|
282
285
|
if (details.job.detached) badges.push("detached");
|
|
283
286
|
if (details.job.wake) badges.push("wake");
|
|
284
|
-
if (badges.length > 0) line += theme
|
|
287
|
+
if (badges.length > 0) line += paint(theme, "faint", `${SEPARATORS.item}${badges.join(SEPARATORS.item)}`);
|
|
285
288
|
}
|
|
286
289
|
text.setText(line);
|
|
287
290
|
return text;
|