@caph42/pi-ccline 0.2.3 → 0.2.4

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 CHANGED
@@ -91,7 +91,7 @@ After startup the footer is whatever ccline renders. Your terminal needs Nerd Fo
91
91
  | `liveRefreshMs` | `1000` | Interval of the timer that refreshes while the agent runs (so `duration` ticks every second); `0` disables the timer and leaves only event-driven refreshes. When non-zero, anything below 250 is raised to 250 |
92
92
  | `showProvider` | `true` | Whether to append the provider to the model segment, e.g. `Sonnet 4.5 (anthropic)`; `false` shows just the model name. If the terminal is narrow enough for ccline to truncate the model segment, the provider may not be visible |
93
93
  | `env` | `{}` | Extra environment variables for ccline; same-named variables override the values inherited from pi (except `COLUMNS`, which the extension writes from the current width) |
94
- | `statusBadges` | `{}` | Icons and colors for the status row other extensions set through `ctx.ui.setStatus`, shaped `{"<status key>": {"icon": "<glyph>", "color": "<theme token>"}}`. Built in: `pi-herdr-pstack` (its `poteto-mode` status) → rocket `U+F135` in `accent`, and `telegram` → `U+F2C6` in `accent`. Fields merge over the built-in entry, so `{"pi-herdr-pstack": {"icon": ""}}` drops the icon and keeps the color; `""` for both removes the badge. Status keys are matched verbatim against `setStatus` keys. The icon is always added; the color applies to the whole text when the status is plain, and only to the icon when the supplying extension already colored its own text (pi-telegram does). An unknown theme token falls back to uncolored text |
94
+ | `statusBadges` | `{}` | Icons and colors for the status row other extensions set through `ctx.ui.setStatus`, shaped `{"<status key>": {"icon": "<glyph>", "color": "<theme token>"}}`. Built in: `pi-herdr-pstack` (its `poteto-mode` status) → magic wand `U+F0D0` in `accent`, `telegram` → `U+F2C6` in `accent`, and `search` (pi-search's working row, e.g. `Search | gpt-6-luna | think:high`, plus its `Docs Search` / `Context7 …` rows that share the key) → magnifier `U+F002` in `mdLink`. Fields merge over the built-in entry, so `{"pi-herdr-pstack": {"icon": ""}}` drops the icon and keeps the color; `""` for both removes the badge. Status keys are matched verbatim against `setStatus` keys. The icon is always added; the color applies to the whole text when the status is plain, and only to the icon when the supplying extension already colored its own text (pi-telegram does). An unknown theme token falls back to uncolored text |
95
95
 
96
96
  Binary resolution order: `config.binary` → `~/.claude/ccline/ccline` → `ccline` on `PATH`.
97
97
 
@@ -104,7 +104,7 @@ Binary resolution order: `config.binary` → `~/.claude/ccline/ccline` → `ccli
104
104
  - Binary not found: the footer shows a one-line install hint.
105
105
  - Widths are always computed with `visibleWidth` / `truncateToWidth`, never with `.length`.
106
106
  - **Other extensions' `ctx.ui.setStatus` stays visible**: `render(width)` reads `footerData.getExtensionStatuses()`, sorts by key, joins them with spaces into one line, truncates with a dim `…` when too wide, and appends it below the ccline frame, matching pi's built-in footer. It reads the live map and `setStatus` itself triggers a repaint, so status changes are not limited by the 1Hz throttle.
107
- - **A status key can carry a badge**: `setStatus` hands over text, and whether it is styled depends on the extension that sends it (pi's own footer adds nothing). This footer adds a Nerd Font icon and a theme color per status key (`DEFAULT_STATUS_BADGES` in `config.ts` holds the entries for pi-herdr-pstack's `poteto-mode` and for pi-telegram). The icon is counted with the rest of the row before truncating. When the status text already contains ANSI, only the icon takes the badge color so the sending extension keeps the palette it chose, and the color goes through one `theme.fg()` call per badge that degrades to plain text when the token is not in the theme.
107
+ - **A status key can carry a badge**: `setStatus` hands over text, and whether it is styled depends on the extension that sends it (pi's own footer adds nothing). This footer adds a Nerd Font icon and a theme color per status key (`DEFAULT_STATUS_BADGES` in `config.ts` holds the entries for pi-herdr-pstack's `poteto-mode`, for pi-telegram, and for pi-search's `search` row). The icon is counted with the rest of the row before truncating. When the status text already contains ANSI, only the icon takes the badge color so the sending extension keeps the palette it chose, and the color goes through one `theme.fg()` call per badge that degrades to plain text when the token is not in the theme.
108
108
  - Because there is only one footer slot globally, other extensions' custom footers (e.g. pi-cursor-provider's fast badge) get displaced once this extension is installed; their status lines still show. Conversely, when they take over, the ccline frame disappears and `/pi-ccline on` takes it back.
109
109
  - **The provider can only be folded into the model segment.** ccline 2.0.1's input schema has no provider field and the `model` segment renders only `display_name`, so the provider is appended after the model name as `name (provider)`; it isn't appended twice when the name already carries the same suffix. `showProvider: false` turns it off. **At narrow widths the provider may be invisible**: ccline wraps/truncates by `COLUMNS` itself, and in practice at width 40 the model segment is left with just `GPT-5.6` — that's upstream layout behaviour, and this extension only guarantees the provider is written into `display_name`.
110
110
  - The input JSON **omits the `version` field**: ccline 2.0.1 validates it as a Claude Code version and rejects pi's version outright.
package/README_zh.md CHANGED
@@ -91,7 +91,7 @@ pi install .
91
91
  | `liveRefreshMs` | `1000` | agent 运行期间的定时刷新间隔(让 `耗时` 逐秒走);`0` 关闭定时器,只保留事件刷新。非 0 时低于 250 会被抬到 250 |
92
92
  | `showProvider` | `true` | 是否在模型段追加 provider,如 `Sonnet 4.5 (anthropic)`;`false` 只显示模型名。终端窄到模型段被 ccline 截断时 provider 可能不可见 |
93
93
  | `env` | `{}` | 追加给 ccline 的环境变量;同名变量覆盖 pi 继承的值(`COLUMNS` 除外,它由扩展按当前宽度写入) |
94
- | `statusBadges` | `{}` | 给其他扩展 `ctx.ui.setStatus` 那一行加图标和颜色,形状 `{"<status key>": {"icon": "<字形>", "color": "<主题 token>"}}`。内置两条:`pi-herdr-pstack`(它的 `poteto-mode` 状态)→ 火箭 `U+F135` + `accent`,`telegram` → `U+F2C6` + `accent`。字段按项合并到内置条目上,所以 `{"pi-herdr-pstack": {"icon": ""}}` 只去掉图标、保留颜色;两个字段都写 `""` 即去掉徽标。status key 与 `setStatus` 的 key 逐字匹配。图标一律加;颜色在文本没上色时刷整段,在发它的扩展已经自己上色时只刷图标(pi-telegram 就是自己上色的)。主题里不存在的 token 回退成不上色 |
94
+ | `statusBadges` | `{}` | 给其他扩展 `ctx.ui.setStatus` 那一行加图标和颜色,形状 `{"<status key>": {"icon": "<字形>", "color": "<主题 token>"}}`。内置三条:`pi-herdr-pstack`(它的 `poteto-mode` 状态)→ 魔法棒 `U+F0D0` + `accent`,`telegram` → `U+F2C6` + `accent`,`search`(pi-search 的工作行,如 `Search | gpt-6-luna | think:high`,以及共用这个 key 的 `Docs Search` / `Context7 …` 行)→ 放大镜 `U+F002` + `mdLink`。字段按项合并到内置条目上,所以 `{"pi-herdr-pstack": {"icon": ""}}` 只去掉图标、保留颜色;两个字段都写 `""` 即去掉徽标。status key 与 `setStatus` 的 key 逐字匹配。图标一律加;颜色在文本没上色时刷整段,在发它的扩展已经自己上色时只刷图标(pi-telegram 就是自己上色的)。主题里不存在的 token 回退成不上色 |
95
95
 
96
96
  二进制解析顺序:`config.binary` → `~/.claude/ccline/ccline` → `PATH` 中的 `ccline`。
97
97
 
@@ -104,7 +104,7 @@ pi install .
104
104
  - 找不到二进制:footer 显示一行安装提示。
105
105
  - 行宽一律用 `visibleWidth` / `truncateToWidth` 计算,不用 `.length`。
106
106
  - **其他扩展的 `ctx.ui.setStatus` 照样可见**:`render(width)` 读 `footerData.getExtensionStatuses()`,按 key 排序、用空格拼成一行、超宽时用 dim `…` 截断,追加在 ccline 帧下方——行为对齐 pi 内置 footer。读的是实时 map,`setStatus` 自己会触发重绘,所以状态变化不受 1Hz 节流限制。
107
- - **status 可以带徽标**:`setStatus` 交过来的是文本,有没有上色取决于发它的扩展(pi 自带 footer 不再加任何样式)。所以本扩展按 status key 加 Nerd Font 图标和主题色(内置条目在 `config.ts` 的 `DEFAULT_STATUS_BADGES`,目前是 pi-herdr-pstack 的 `poteto-mode` 和 pi-telegram)。图标计入整行的可见宽度再截断;文本自带 ANSI 时只给图标上色,发它的扩展保留自己选的配色;颜色每帧走一次 `theme.fg()`,token 不在主题里就退成纯文本。
107
+ - **status 可以带徽标**:`setStatus` 交过来的是文本,有没有上色取决于发它的扩展(pi 自带 footer 不再加任何样式)。所以本扩展按 status key 加 Nerd Font 图标和主题色(内置条目在 `config.ts` 的 `DEFAULT_STATUS_BADGES`,目前是 pi-herdr-pstack 的 `poteto-mode`、pi-telegram,以及 pi-search 的 `search` 行)。图标计入整行的可见宽度再截断;文本自带 ANSI 时只给图标上色,发它的扩展保留自己选的配色;颜色每帧走一次 `theme.fg()`,token 不在主题里就退成纯文本。
108
108
  - 因为 footer 槽位全局只有一个,本扩展装上后其他扩展的自定义 footer(例如 pi-cursor-provider 的 fast 徽标)会被顶掉;它们的 status 行仍会显示。反过来它们抢占时 ccline 帧会消失,需要 `/pi-ccline on` 取回。
109
109
  - **provider 只能拼进模型段。** ccline 2.0.1 的输入 schema 没有 provider 字段,`model` 段只渲染 `display_name`,所以 provider 以 `名称 (provider)` 的形式追加在模型名后;名字里已经带同样的后缀时不重复追加。`showProvider: false` 可关掉。**窄宽度下 provider 可能看不到**:ccline 按 `COLUMNS` 自己折行/截断,实测宽度 40 时模型段只剩 `GPT-5.6`,这是上游布局行为,本扩展只保证把 provider 写进 `display_name`。
110
110
  - 输入 JSON **省略 `version` 字段**:ccline 2.0.1 会把它当 Claude Code 版本校验,传 pi 的版本会被直接拒绝。
@@ -76,6 +76,17 @@ test("ships a built-in poteto-mode badge and lets the config override it field b
76
76
  });
77
77
  });
78
78
 
79
+ test("ships a built-in badge for pi-search's plain search row", () => {
80
+ const resolved = resolveStatusBadges(undefined);
81
+ assert.deepEqual(resolved.search, { icon: "\uf002", color: "mdLink" });
82
+ // pi-search drives the same key for its docs/context7 rows, so the badge is
83
+ // attached to the key only and a user override still merges field by field.
84
+ assert.deepEqual(resolveStatusBadges(normalizeConfig({ statusBadges: { search: { icon: "" } } }).statusBadges).search, {
85
+ icon: "",
86
+ color: "mdLink",
87
+ });
88
+ });
89
+
79
90
  test("badges can be added for other status keys, and unusable entries are dropped", () => {
80
91
  const config = normalizeConfig({
81
92
  statusBadges: {
@@ -58,9 +58,14 @@ export type StatusBadgeOverride = Partial<StatusBadge>;
58
58
  */
59
59
  export const DEFAULT_STATUS_BADGES: Record<string, StatusBadge> = {
60
60
  // pi-herdr-pstack keeps this key while the sticky poteto methodology is on.
61
- "pi-herdr-pstack": { icon: "\uf135", color: "accent" },
61
+ "pi-herdr-pstack": { icon: "\uf0d0", color: "accent" },
62
62
  // pi-telegram colors its own label and state, so only the icon takes the color.
63
63
  telegram: { icon: "\uf2c6", color: "accent" },
64
+ // pi-search uses one key for its whole working row: `Search | <model> |
65
+ // think:<level>` while a search runs, and `Docs Search` / `Context7 …` for the
66
+ // docs tools, so one magnifier covers all of them. The text is plain, hence
67
+ // the whole row takes the color; blue keeps it apart from the accent badges.
68
+ search: { icon: "\uf002", color: "mdLink" },
64
69
  };
65
70
 
66
71
  /** An icon longer than this is a typo or a whole path, not a glyph. */
@@ -223,6 +223,20 @@ test("pi-telegram's colored status keeps its colors and gains the icon", () => {
223
223
  harness.footer.dispose();
224
224
  });
225
225
 
226
+ test("pi-search's plain search row gets the built-in magnifier badge", () => {
227
+ // pi-search sends `Search | <model> | think:<level>` unstyled and clears it
228
+ // when the tool returns, so the row may only be decorated, never rewritten.
229
+ const harness = attach(
230
+ { binary: fakeBinary("cat > /dev/null; printf 'FAKE-CCLINE\\n'") },
231
+ undefined,
232
+ new Map([["search", "Search | gpt-6-luna | think:high"]]),
233
+ );
234
+ const row = harness.render(120)[1] ?? "";
235
+ assert.equal(row.replace(/\u001b\[[0-9;]*m/g, ""), `${DEFAULT_STATUS_BADGES.search?.icon} Search | gpt-6-luna | think:high`);
236
+ assert.match(row, /\u001b\[2m/, "the whole row takes the badge color through theme.fg");
237
+ harness.footer.dispose();
238
+ });
239
+
226
240
  test("a configured badge override reaches the rendered row", () => {
227
241
  const statuses = new Map([["pi-herdr-pstack", "poteto-mode"]]);
228
242
  const harness = attach(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caph42/pi-ccline",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Pi extension that renders the footer by delegating to the CCometixLine (ccline) statusline binary",
5
5
  "keywords": [
6
6
  "pi-package",