@gavin-hu/my-pi-agent 0.18.0 → 0.20.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 +66 -52
- package/README.zh-CN.md +56 -46
- package/docs/extensions/README.md +34 -0
- package/docs/extensions/board.md +507 -0
- package/{extensions/bytefly/README.md → docs/extensions/bytefly.md} +774 -574
- package/{extensions/check/README.md → docs/extensions/check.md} +83 -68
- package/{extensions/context/README.md → docs/extensions/context.md} +40 -23
- package/docs/extensions/file-browse.md +561 -0
- package/{extensions/file-open/README.md → docs/extensions/file-open.md} +31 -23
- package/{extensions/file-read/README.md → docs/extensions/file-read.md} +47 -55
- package/{extensions/goal/README.md → docs/extensions/goal.md} +115 -131
- package/{extensions/job/README.md → docs/extensions/job.md} +62 -52
- package/{extensions/memory/README.md → docs/extensions/memory.md} +71 -60
- package/{extensions/plan/README.md → docs/extensions/plan.md} +440 -322
- package/{extensions/question/README.md → docs/extensions/question.md} +54 -31
- package/{extensions/rewind/README.md → docs/extensions/rewind.md} +115 -122
- package/docs/extensions/session-bus.md +298 -0
- package/{extensions/subagent/README.md → docs/extensions/subagent.md} +165 -118
- package/docs/extensions/team.md +254 -0
- package/{extensions/todo/README.md → docs/extensions/todo.md} +85 -88
- package/{extensions/watch/README.md → docs/extensions/watch.md} +54 -36
- package/{extensions/web-access/README.md → docs/extensions/web-access.md} +93 -50
- package/{extensions/wechat/README.md → docs/extensions/wechat.md} +260 -163
- package/{extensions/worktree/README.md → docs/extensions/worktree.md} +137 -79
- package/extensions/board/commands.ts +105 -0
- package/extensions/board/config.ts +36 -0
- package/extensions/board/format.ts +170 -0
- package/extensions/board/index.ts +40 -0
- package/extensions/board/input.ts +54 -0
- package/extensions/board/join.ts +42 -0
- package/extensions/board/page.ts +388 -0
- package/extensions/board/result.ts +108 -0
- package/extensions/board/rows.ts +48 -0
- package/extensions/board/schema.ts +90 -0
- package/extensions/board/seat.ts +28 -0
- package/extensions/board/snapshot.ts +42 -0
- package/extensions/board/tools.ts +444 -0
- package/extensions/board/transport/router.ts +91 -0
- package/extensions/board/transport/server.ts +138 -0
- package/extensions/board/types.ts +121 -0
- package/extensions/board/view/client.ts +51 -0
- package/extensions/board/view/dialog.ts +43 -0
- package/extensions/board/view/keys.ts +125 -0
- package/extensions/board/view/live.ts +231 -0
- package/extensions/board/view/names.ts +91 -0
- package/extensions/board/view/page.ts +118 -0
- package/extensions/board/view/render.ts +519 -0
- package/extensions/board/view/styles.ts +228 -0
- package/extensions/board/view/team.ts +327 -0
- package/extensions/bytefly/footer/budget.ts +6 -5
- package/extensions/bytefly/footer/collect/entries.ts +12 -4
- package/extensions/bytefly/footer/collect/snapshot.ts +8 -17
- package/extensions/bytefly/footer/config.ts +19 -8
- package/extensions/bytefly/footer/price/price.ts +30 -8
- package/extensions/bytefly/footer/register.ts +5 -5
- package/extensions/bytefly/footer/render/format.ts +18 -0
- package/extensions/bytefly/footer/render/lines.ts +23 -7
- package/extensions/bytefly/footer/render/segments.ts +117 -31
- package/extensions/bytefly/footer/types.ts +29 -5
- package/extensions/bytefly/footer/unpriced.ts +42 -17
- package/extensions/bytefly/panel/commands.ts +67 -7
- package/extensions/bytefly/panel/filter.ts +68 -0
- package/extensions/bytefly/panel/format.ts +16 -15
- package/extensions/bytefly/panel/join.ts +56 -13
- package/extensions/bytefly/panel/prices.ts +43 -0
- package/extensions/bytefly/panel/settings-runtime.ts +0 -6
- package/extensions/bytefly/panel/settings.ts +75 -43
- package/extensions/bytefly/panel/tui/entries.ts +26 -8
- package/extensions/bytefly/panel/tui/frame.ts +130 -93
- package/extensions/bytefly/panel/tui/keys.ts +352 -0
- package/extensions/bytefly/panel/tui/list-view.ts +25 -46
- package/extensions/bytefly/panel/tui/panes.ts +76 -0
- package/extensions/bytefly/panel/tui/section-view.ts +126 -0
- package/extensions/bytefly/panel/tui/settings-section.ts +54 -125
- package/extensions/bytefly/panel/tui/settings-view.ts +30 -131
- package/extensions/bytefly/panel/tui/side-pane.ts +224 -0
- package/extensions/bytefly/panel/tui.ts +306 -259
- package/extensions/bytefly/picker/discovery.ts +0 -2
- package/extensions/bytefly/picker/types.ts +0 -2
- package/extensions/bytefly/update/check.ts +39 -0
- package/extensions/bytefly/update/format.ts +15 -0
- package/extensions/bytefly/update/register.ts +73 -34
- package/extensions/bytefly/update/state.ts +6 -3
- package/extensions/check/commands.ts +2 -1
- package/extensions/context/tui.ts +1 -1
- package/extensions/file-browse/{config.ts → config/config.ts} +1 -1
- package/extensions/file-browse/files/classify.ts +136 -0
- package/extensions/file-browse/files/files.ts +12 -0
- package/extensions/file-browse/files/index.ts +90 -0
- package/extensions/file-browse/files/list.ts +261 -0
- package/extensions/file-browse/{paths.ts → files/paths.ts} +1 -1
- package/extensions/file-browse/files/tree.ts +101 -0
- package/extensions/file-browse/{git.ts → git/git.ts} +10 -3
- package/extensions/file-browse/index.ts +4 -4
- package/extensions/file-browse/{live.ts → live/live.ts} +20 -69
- package/extensions/file-browse/{router.ts → transport/router.ts} +21 -17
- package/extensions/file-browse/transport/server.ts +110 -0
- package/extensions/file-browse/{chrome.ts → view/chrome.ts} +4 -4
- package/extensions/file-browse/{client.ts → view/client.ts} +1 -1
- package/extensions/file-browse/{diff-html.ts → view/diff-html.ts} +3 -3
- package/extensions/file-browse/view/emit.ts +51 -0
- package/extensions/file-browse/{html.ts → view/html.ts} +19 -18
- package/extensions/file-browse/{icons.ts → view/icons.ts} +1 -1
- package/extensions/file-browse/{markdown.ts → view/markdown.ts} +18 -20
- package/extensions/file-browse/{raw-html.ts → view/raw-html.ts} +19 -14
- package/extensions/file-browse/{styles.ts → view/styles.ts} +29 -5
- package/extensions/file-browse/{tree.ts → view/tree.ts} +1 -1
- package/extensions/file-browse/{urls.ts → view/urls.ts} +1 -1
- package/extensions/file-read/schema.ts +2 -1
- package/extensions/job/runtime.ts +4 -4
- package/extensions/memory/store.ts +12 -5
- package/extensions/plan/blocks.ts +23 -2
- package/extensions/plan/commands.ts +21 -16
- package/extensions/plan/feedback.ts +185 -52
- package/extensions/plan/format.ts +10 -3
- package/extensions/plan/index.ts +23 -5
- package/extensions/plan/plan-files.ts +88 -0
- package/extensions/plan/plan-index.ts +43 -9
- package/extensions/plan/plan-text.ts +33 -23
- package/extensions/plan/plans.ts +27 -34
- package/extensions/plan/policy.ts +30 -17
- package/extensions/plan/review.ts +3 -27
- package/extensions/plan/runtime.ts +52 -11
- package/extensions/plan/sections.ts +112 -0
- package/extensions/plan/steps.ts +3 -22
- package/extensions/plan/todos.ts +51 -3
- package/extensions/plan/tools/exit.ts +20 -95
- package/extensions/plan/tools/todo-seed.ts +4 -2
- package/extensions/plan/tools/write.ts +12 -1
- package/extensions/plan/tui.ts +5 -34
- package/extensions/plan/types.ts +15 -8
- package/extensions/plan/web-blocks.ts +89 -0
- package/extensions/plan/web-chrome.ts +3 -5
- package/extensions/plan/web-client.ts +179 -330
- package/extensions/plan/web-collab.ts +3 -3
- package/extensions/plan/web-comments.ts +18 -8
- package/extensions/plan/web-composer.ts +80 -0
- package/extensions/plan/web-draft.ts +40 -0
- package/extensions/plan/web-keys.ts +134 -0
- package/extensions/plan/web-outline.ts +192 -0
- package/extensions/plan/web-page.ts +4 -8
- package/extensions/plan/web-plan.ts +150 -0
- package/extensions/plan/web-router.ts +3 -58
- package/extensions/plan/web-settle.ts +194 -0
- package/extensions/plan/web-share-session.ts +24 -30
- package/extensions/plan/web-streams.ts +14 -14
- package/extensions/plan/web-tokens.ts +2 -2
- package/extensions/plan/web.ts +66 -120
- package/extensions/rewind/{commands.ts → commands/commands.ts} +5 -5
- package/extensions/rewind/{review.ts → commands/review.ts} +15 -14
- package/extensions/rewind/{rewind.ts → commands/rewind.ts} +6 -6
- package/extensions/rewind/{config.ts → config/config.ts} +1 -1
- package/extensions/rewind/index.ts +3 -3
- package/extensions/rewind/{policy.ts → state/policy.ts} +4 -4
- package/extensions/rewind/{runtime.ts → state/runtime.ts} +11 -11
- package/extensions/rewind/{snapshot-run.ts → state/snapshot-run.ts} +1 -1
- package/extensions/rewind/{timeline.ts → state/timeline.ts} +2 -2
- package/extensions/rewind/{format.ts → text/format.ts} +3 -3
- package/extensions/rewind/{git.ts → transport/git.ts} +2 -2
- package/extensions/rewind/{restore.ts → transport/restore.ts} +2 -2
- package/extensions/rewind/{snapshot.ts → transport/snapshot.ts} +1 -1
- package/extensions/rewind/{store.ts → transport/store.ts} +1 -1
- package/extensions/rewind/{checklist.ts → view/checklist.ts} +6 -6
- package/extensions/rewind/{hunk-picker.ts → view/hunk-picker.ts} +8 -8
- package/extensions/rewind/{path-picker.ts → view/path-picker.ts} +7 -7
- package/extensions/rewind/{review-tui.ts → view/review-tui.ts} +11 -11
- package/extensions/rewind/{rewind-tui.ts → view/rewind-tui.ts} +17 -11
- package/extensions/rewind/{status.ts → view/status.ts} +4 -4
- package/extensions/session-bus/commands.ts +17 -69
- package/extensions/session-bus/format.ts +22 -45
- package/extensions/session-bus/index.ts +13 -7
- package/extensions/session-bus/join-request.ts +40 -0
- package/extensions/session-bus/mail-watch.ts +134 -0
- package/extensions/session-bus/notice.ts +32 -4
- package/{lib/claims → extensions/session-bus}/overlap.ts +11 -18
- package/extensions/session-bus/protocol.ts +19 -49
- package/extensions/session-bus/resolve.ts +67 -0
- package/extensions/session-bus/result.ts +16 -51
- package/extensions/session-bus/rows.ts +11 -5
- package/extensions/session-bus/runtime.ts +220 -267
- package/extensions/session-bus/store.ts +55 -7
- package/extensions/session-bus/tools.ts +31 -66
- package/extensions/session-bus/tui.ts +5 -5
- package/extensions/session-bus/types.ts +23 -14
- package/extensions/subagent/agents.ts +9 -8
- package/extensions/subagent/commands.ts +2 -1
- package/extensions/subagent/invocation.ts +4 -2
- package/extensions/team/commands.ts +145 -0
- package/extensions/team/dispatch.ts +133 -0
- package/extensions/team/format.ts +119 -0
- package/extensions/team/index.ts +34 -0
- package/extensions/team/schema.ts +29 -0
- package/extensions/team/tools.ts +267 -0
- package/extensions/team/types.ts +65 -0
- package/extensions/todo/index.ts +4 -1
- package/extensions/todo/nudge.ts +8 -2
- package/extensions/web-access/fetch/page.ts +4 -1
- package/extensions/web-access/fetch/structured.ts +447 -0
- package/extensions/web-access/fetch/tool.ts +2 -1
- package/extensions/web-access/search/tool.ts +2 -1
- package/extensions/wechat/bridge.ts +106 -251
- package/extensions/wechat/{commands.ts → commands/commands.ts} +26 -18
- package/extensions/wechat/{doctor.ts → commands/doctor.ts} +5 -5
- package/extensions/wechat/{history.ts → commands/history.ts} +1 -1
- package/extensions/wechat/{login.ts → commands/login.ts} +3 -3
- package/extensions/wechat/{slash.ts → commands/slash.ts} +38 -2
- package/extensions/wechat/dialog/channels.ts +136 -0
- package/extensions/wechat/{interaction.ts → dialog/interaction.ts} +37 -37
- package/extensions/wechat/{prompt.ts → dialog/prompt.ts} +2 -2
- package/extensions/wechat/{remote-ui.ts → dialog/remote-ui.ts} +1 -1
- package/extensions/wechat/index.ts +10 -10
- package/extensions/wechat/intake.ts +245 -0
- package/extensions/wechat/{admission.ts → peer/admission.ts} +2 -2
- package/extensions/wechat/{peer-session.ts → peer/peer-session.ts} +2 -2
- package/extensions/wechat/{peer-worker.ts → peer/peer-worker.ts} +100 -22
- package/extensions/wechat/{presence.ts → peer/presence.ts} +8 -7
- package/extensions/wechat/{reply-pipeline.ts → peer/reply-pipeline.ts} +1 -1
- package/extensions/wechat/{credentials.ts → state/credentials.ts} +2 -2
- package/extensions/wechat/{state.ts → state/state.ts} +14 -2
- package/extensions/wechat/{format.ts → text/format.ts} +3 -3
- package/extensions/wechat/{notices.ts → text/notices.ts} +8 -0
- package/extensions/wechat/tools.ts +29 -12
- package/extensions/wechat/{client.ts → transport/client.ts} +26 -2
- package/extensions/wechat/{deliver.ts → transport/deliver.ts} +72 -28
- package/extensions/wechat/{inbound.ts → transport/inbound.ts} +5 -5
- package/extensions/wechat/{media.ts → transport/media.ts} +11 -5
- package/extensions/wechat/transport/outbound.ts +142 -0
- package/extensions/wechat/{poll.ts → transport/poll.ts} +3 -3
- package/extensions/wechat/types.ts +10 -1
- package/extensions/wechat/{login-screen.ts → view/login-screen.ts} +4 -4
- package/extensions/wechat/{status-screen.ts → view/status-screen.ts} +31 -26
- package/extensions/worktree/commands.ts +24 -17
- package/extensions/worktree/exit.ts +12 -6
- package/extensions/worktree/git.ts +22 -14
- package/extensions/worktree/guard.ts +18 -290
- package/extensions/worktree/handoff.ts +10 -2
- package/extensions/worktree/index.ts +2 -1
- package/extensions/worktree/lifecycle.ts +2 -0
- package/extensions/worktree/registry.ts +20 -11
- package/extensions/worktree/root-tools.ts +13 -3
- package/extensions/worktree/runtime.ts +8 -2
- package/extensions/worktree/screen.ts +15 -8
- package/extensions/worktree/shell.ts +303 -0
- package/extensions/worktree/state.ts +1 -1
- package/extensions/worktree/status.ts +42 -9
- package/extensions/worktree/tools.ts +19 -13
- package/lib/README.md +11 -8
- package/lib/board/card.ts +479 -0
- package/lib/board/links.ts +141 -0
- package/lib/board/page-pointer.ts +310 -0
- package/lib/board/round-text.ts +81 -0
- package/lib/board/round.ts +94 -0
- package/lib/board/rules.ts +437 -0
- package/lib/board/session.ts +105 -0
- package/lib/board/store.ts +497 -0
- package/lib/board/view.ts +234 -0
- package/lib/errors.ts +12 -4
- package/lib/format.ts +35 -0
- package/lib/http/guard.ts +112 -0
- package/lib/http/index.ts +16 -5
- package/lib/http/serve.ts +237 -0
- package/lib/http/server.ts +12 -10
- package/lib/http/sink.ts +135 -0
- package/lib/http/token.ts +38 -0
- package/lib/plan-entry.ts +11 -0
- package/lib/policy.ts +25 -2
- package/lib/requirements.ts +6 -7
- package/lib/session-label.ts +64 -0
- package/lib/session-roster.ts +201 -0
- package/lib/session-tool.ts +184 -0
- package/lib/spawn.ts +37 -3
- package/lib/stray-fields.ts +45 -0
- package/lib/tool-names.ts +38 -2
- package/lib/tui/glyphs.ts +3 -2
- package/lib/web/README.md +57 -4
- package/lib/web/client-runtime.ts +123 -0
- package/lib/web/components.ts +5 -0
- package/lib/web/index.ts +4 -2
- package/lib/web/markup.ts +88 -1
- package/lib/web/names.ts +42 -0
- package/lib/web/runtime.ts +7 -1
- package/lib/web/tokens.ts +25 -2
- package/package.json +26 -14
- package/skills/next/SKILL.md +4 -3
- package/skills/project-docs/SKILL.md +133 -0
- package/skills/project-docs/references/audit.md +131 -0
- package/skills/project-docs/references/changelog.md +105 -0
- package/skills/project-docs/references/discovery.md +127 -0
- package/skills/project-docs/references/readme.md +80 -0
- package/skills/project-docs/references/release.md +84 -0
- package/skills/project-docs/references/roadmap.md +93 -0
- package/skills/project-docs/scripts/state.ts +316 -0
- package/skills/refactor/SKILL.md +100 -125
- package/skills/refactor/references/handoff.md +35 -0
- package/skills/refactor/references/signals.md +54 -0
- package/skills/refactor/scripts/inventory.ts +587 -0
- package/extensions/bytefly/panel/tui/extensions-view.ts +0 -40
- package/extensions/bytefly/panel/tui/skills-view.ts +0 -50
- package/extensions/file-browse/README.md +0 -506
- package/extensions/file-browse/files.ts +0 -564
- package/extensions/file-browse/server.ts +0 -141
- package/extensions/job/process.ts +0 -35
- package/extensions/plan/split.ts +0 -87
- package/extensions/session-bus/README.md +0 -247
- package/extensions/session-bus/team.ts +0 -102
- package/extensions/wechat/outbound.ts +0 -100
- package/lib/plans/sections.ts +0 -172
- package/lib/plans/setting.ts +0 -52
- package/lib/plans/split.ts +0 -215
- package/lib/plans/store.ts +0 -19
- package/lib/plans/team.ts +0 -151
- package/skills/changelog/SKILL.md +0 -148
- package/skills/parallel-dev/SKILL.md +0 -150
- /package/extensions/file-browse/{rev.ts → live/rev.ts} +0 -0
- /package/extensions/file-browse/{diff.ts → text/diff.ts} +0 -0
- /package/extensions/file-browse/{fuzzy.ts → text/fuzzy.ts} +0 -0
- /package/extensions/file-browse/{live-client.ts → view/live-client.ts} +0 -0
- /package/extensions/file-browse/{palette.ts → view/palette.ts} +0 -0
- /package/extensions/rewind/{patch.ts → text/patch.ts} +0 -0
- /package/extensions/rewind/{paths.ts → text/paths.ts} +0 -0
- /package/extensions/rewind/{queue.ts → transport/queue.ts} +0 -0
- /package/extensions/rewind/{temp-index.ts → transport/temp-index.ts} +0 -0
- /package/extensions/wechat/{lock.ts → state/lock.ts} +0 -0
- /package/extensions/wechat/{channel.ts → text/channel.ts} +0 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The focused row's block: what the list row cannot say.
|
|
3
|
+
*
|
|
4
|
+
* One function, because the block is the same thing in both layouts — beside the
|
|
5
|
+
* list on a wide terminal, under it on a narrow one — and one owner is what keeps
|
|
6
|
+
* the two from drifting. It also draws the key table `?` swaps in, so help needs
|
|
7
|
+
* no layout of its own.
|
|
8
|
+
*
|
|
9
|
+
* Pure: the theme, the row and the paths come in, lines come out, already clipped
|
|
10
|
+
* to the width they were given.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
15
|
+
import { wrapTextWithAnsi } from "@earendil-works/pi-tui";
|
|
16
|
+
import { sanitizeLine } from "../../../../lib/format.ts";
|
|
17
|
+
import { clip, clipMiddle } from "../../../../lib/tui/columns.ts";
|
|
18
|
+
import { BODY_INDENT } from "../../../../lib/tui/indent.ts";
|
|
19
|
+
import { keyValueRow } from "../../../../lib/tui/rows.ts";
|
|
20
|
+
import { paint, type TuiRole } from "../../../../lib/tui/tokens.ts";
|
|
21
|
+
import { detailLines as reportDetailLines, reportSummary, reportSeverity, severityRole } from "../../doctor/format.ts";
|
|
22
|
+
import { rowBadge } from "../format.ts";
|
|
23
|
+
import type { SettingView } from "../settings.ts";
|
|
24
|
+
import { configPath } from "../settings-runtime.ts";
|
|
25
|
+
import type { PanelRow, PanelSection } from "../types.ts";
|
|
26
|
+
import { INDENT, savedLine } from "./frame.ts";
|
|
27
|
+
import { helpRows } from "./keys.ts";
|
|
28
|
+
|
|
29
|
+
/** Pi's personal settings file, named where a setting is stored there. */
|
|
30
|
+
const PI_SETTINGS_FILE = "settings.json";
|
|
31
|
+
|
|
32
|
+
/** Columns the fact labels take before their value. */
|
|
33
|
+
const FACT_LABEL_WIDTH = 11;
|
|
34
|
+
|
|
35
|
+
/** Where a value is written, and which file supplied the one on screen. */
|
|
36
|
+
export interface SidePaths {
|
|
37
|
+
scope: "global" | "project";
|
|
38
|
+
cwd: string;
|
|
39
|
+
agentDir: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** What the block needs to know. */
|
|
43
|
+
export interface SideInput {
|
|
44
|
+
theme: Theme;
|
|
45
|
+
width: number;
|
|
46
|
+
section: PanelSection;
|
|
47
|
+
/** The focused resource row, on a list section. */
|
|
48
|
+
row?: PanelRow;
|
|
49
|
+
/** The group heading the row sits under, as the list named it. */
|
|
50
|
+
groupLabel?: string;
|
|
51
|
+
/** The focused setting, on Settings. */
|
|
52
|
+
setting?: SettingView;
|
|
53
|
+
/** Draw the key table instead of the focused row's facts. */
|
|
54
|
+
help: boolean;
|
|
55
|
+
/** The focused row's findings are expanded. */
|
|
56
|
+
expanded: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* The block is drawn under the list, in the space of a few rows, instead of
|
|
59
|
+
* beside it: the row directly above already carries the name, the verdict and
|
|
60
|
+
* the value, so only what it cannot say is worth the rows.
|
|
61
|
+
*/
|
|
62
|
+
compact?: boolean;
|
|
63
|
+
/** Something was changed this session. */
|
|
64
|
+
dirty: boolean;
|
|
65
|
+
paths: SidePaths;
|
|
66
|
+
/** The stored `bytefly.json` section, when the JSON pane is open. */
|
|
67
|
+
json?: { section: string; document: unknown };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* One fact line whose value is a path: the file's own name is what identifies it,
|
|
72
|
+
* so the middle goes first and both ends stay.
|
|
73
|
+
*/
|
|
74
|
+
function pathFact(theme: Theme, width: number, label: string, value: string): string {
|
|
75
|
+
// Sanitize first, then clip: the clipper inserts its own reset sequence, and
|
|
76
|
+
// running a sanitizer over that would leave half of it on screen.
|
|
77
|
+
const room = Math.max(8, width - BODY_INDENT - FACT_LABEL_WIDTH);
|
|
78
|
+
return factCell(theme, width, label, clipMiddle(sanitizeLine(value), room), "meta");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** One fact line: a label column and its value. */
|
|
82
|
+
function fact(theme: Theme, width: number, label: string, value: string, role: TuiRole = "label"): string {
|
|
83
|
+
return factCell(theme, width, label, sanitizeLine(value), role);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** The fact line itself, for a value that is already sanitized and clipped. */
|
|
87
|
+
function factCell(theme: Theme, width: number, label: string, value: string, role: TuiRole): string {
|
|
88
|
+
return keyValueRow(theme, width, {
|
|
89
|
+
label,
|
|
90
|
+
value,
|
|
91
|
+
labelWidth: FACT_LABEL_WIDTH,
|
|
92
|
+
labelRole: "faint",
|
|
93
|
+
valueRole: role,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** A faint `── label ─────` divider inside the block. */
|
|
98
|
+
function blockRule(theme: Theme, width: number, label: string): string {
|
|
99
|
+
const text = ` ${label} `;
|
|
100
|
+
const room = Math.max(0, width - BODY_INDENT - text.length);
|
|
101
|
+
return clip(
|
|
102
|
+
`${" ".repeat(BODY_INDENT)}${paint(theme, "faint", `${"─".repeat(Math.min(2, room))}${text}${"─".repeat(Math.max(0, room - 2))}`)}`,
|
|
103
|
+
width,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** A description, wrapped and indented under a label of its own. */
|
|
108
|
+
function description(theme: Theme, width: number, label: string, text: string, rows: number): string[] {
|
|
109
|
+
const room = Math.max(1, width - BODY_INDENT);
|
|
110
|
+
const wrapped = wrapTextWithAnsi(sanitizeLine(text), room).slice(0, Math.max(1, rows));
|
|
111
|
+
const lines = [clip(`${INDENT}${paint(theme, "faint", label)}`, width)];
|
|
112
|
+
for (const line of wrapped) lines.push(clip(`${INDENT}${paint(theme, "meta", line)}`, width));
|
|
113
|
+
return lines;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** The focused resource's name and verdict, then its facts and findings. */
|
|
117
|
+
function resourceRows(input: SideInput): string[] {
|
|
118
|
+
const { theme, width, row, groupLabel } = input;
|
|
119
|
+
const lines: string[] = [];
|
|
120
|
+
if (row === undefined) return lines;
|
|
121
|
+
const compact = input.compact === true;
|
|
122
|
+
const badge = rowBadge(row);
|
|
123
|
+
if (!compact) {
|
|
124
|
+
const head = paint(theme, "accent", sanitizeLine(row.label));
|
|
125
|
+
const verdict = badge.text === undefined ? "" : ` ${paint(theme, badge.role, sanitizeLine(badge.text))}`;
|
|
126
|
+
lines.push(clip(`${INDENT}${head}${verdict}`, width));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// A skill carries what its own file declares; an extension carries the doctor's
|
|
130
|
+
// findings. Neither invents the other's facts.
|
|
131
|
+
const path = row.item?.path ?? row.report?.extension;
|
|
132
|
+
const report = row.report;
|
|
133
|
+
const findings =
|
|
134
|
+
report === undefined ? [] : reportDetailLines(report, theme, width, compact ? 20 : 40, input.expanded);
|
|
135
|
+
|
|
136
|
+
// Findings first: in the narrow layout they are the reason the block exists, and
|
|
137
|
+
// the row above already says the name. `Path` is the fallback — what a row with
|
|
138
|
+
// nothing to report still cannot say.
|
|
139
|
+
if (findings.length === 0 && compact && path !== undefined) lines.push(pathFact(theme, width, "Path", path));
|
|
140
|
+
if (findings.length > 0) {
|
|
141
|
+
if (!compact) lines.push(blockRule(theme, width, "findings"));
|
|
142
|
+
lines.push(...findings);
|
|
143
|
+
}
|
|
144
|
+
if (compact) return [...lines, ...savedLine(theme, width, input.dirty)];
|
|
145
|
+
|
|
146
|
+
if (path !== undefined) lines.push(pathFact(theme, width, "Path", path));
|
|
147
|
+
if (groupLabel !== undefined) lines.push(fact(theme, width, "Source", groupLabel, "meta"));
|
|
148
|
+
if (row.item !== undefined) {
|
|
149
|
+
lines.push(fact(theme, width, "State", row.item.enabled ? "enabled" : "off", "meta"));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// A skill carries what its own file declares; an extension carries the doctor's
|
|
153
|
+
// findings. Neither invents the other's facts.
|
|
154
|
+
const skill = row.skill;
|
|
155
|
+
if (skill !== undefined && !compact) {
|
|
156
|
+
if (skill.name !== undefined) lines.push(fact(theme, width, "Call", `/skill:${skill.name}`, "meta"));
|
|
157
|
+
if (skill.modelHidden) lines.push(fact(theme, width, "Model", "hidden from the model", "warn"));
|
|
158
|
+
if (skill.problem !== undefined) lines.push(fact(theme, width, "Problem", skill.problem, "warn"));
|
|
159
|
+
if (skill.description !== "") {
|
|
160
|
+
lines.push(...description(theme, width, "About", skill.description, input.expanded ? 6 : 2));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (report !== undefined) {
|
|
164
|
+
lines.push(fact(theme, width, "Health", reportSummary(report), severityRole(reportSeverity(report))));
|
|
165
|
+
}
|
|
166
|
+
lines.push(...savedLine(theme, width, input.dirty));
|
|
167
|
+
return lines;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Where a setting's value is written, and which scope supplied the one shown. */
|
|
171
|
+
function originLine(view: SettingView, paths: SidePaths): string {
|
|
172
|
+
const scope = view.origin === "inherited" ? "global" : paths.scope;
|
|
173
|
+
const file =
|
|
174
|
+
view.source === "app" ? join(paths.agentDir, PI_SETTINGS_FILE) : configPath(scope, paths.cwd, paths.agentDir);
|
|
175
|
+
const origin =
|
|
176
|
+
view.origin === "inherited"
|
|
177
|
+
? "Inherited from Global"
|
|
178
|
+
: view.origin === "project"
|
|
179
|
+
? "Project"
|
|
180
|
+
: view.origin === "global"
|
|
181
|
+
? "Global"
|
|
182
|
+
: "Default";
|
|
183
|
+
return `${origin} · ${file}`;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** The focused setting's sentence, its origin, and the `bytefly.json` section behind it. */
|
|
187
|
+
function settingRows(input: SideInput): string[] {
|
|
188
|
+
const { theme, width, setting } = input;
|
|
189
|
+
const lines: string[] = [];
|
|
190
|
+
if (setting === undefined) return lines;
|
|
191
|
+
const compact = input.compact === true;
|
|
192
|
+
if (!compact) {
|
|
193
|
+
lines.push(clip(`${INDENT}${paint(theme, "accent", sanitizeLine(setting.label))}`, width));
|
|
194
|
+
lines.push(fact(theme, width, "Now", setting.valueLabel, "label"));
|
|
195
|
+
}
|
|
196
|
+
lines.push(...description(theme, width, "About", setting.description, input.expanded ? 6 : compact ? 1 : 2));
|
|
197
|
+
lines.push(pathFact(theme, width, "Stored in", originLine(setting, input.paths)));
|
|
198
|
+
const json = input.json;
|
|
199
|
+
if (json !== undefined && setting.config !== undefined) {
|
|
200
|
+
lines.push(blockRule(theme, width, json.section));
|
|
201
|
+
lines.push(...jsonLines(theme, width, json.document));
|
|
202
|
+
}
|
|
203
|
+
lines.push(...savedLine(theme, width, input.dirty));
|
|
204
|
+
return lines;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** The stored section as JSON, clipped by the caller like any other block. */
|
|
208
|
+
function jsonLines(theme: Theme, width: number, document: unknown): string[] {
|
|
209
|
+
if (document === undefined) return [clip(`${INDENT}${paint(theme, "faint", "Not set in this scope.")}`, width)];
|
|
210
|
+
return JSON.stringify(document, null, 2)
|
|
211
|
+
.split("\n")
|
|
212
|
+
.map((line) => clip(`${INDENT}${paint(theme, "faint", sanitizeLine(line))}`, width));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* The block the focused row gets, in either layout. Empty when nothing is focused,
|
|
217
|
+
* so a caller can compose rows without a special case.
|
|
218
|
+
*/
|
|
219
|
+
export function sideRows(input: SideInput): string[] {
|
|
220
|
+
const { theme, width, section } = input;
|
|
221
|
+
if (input.help) return helpRows(theme, width, section);
|
|
222
|
+
if (section === "settings") return settingRows(input);
|
|
223
|
+
return resourceRows(input);
|
|
224
|
+
}
|