mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 10:45:22 +00:00
refactor: notify/footer 持久配置收编到 config/,chrome bridge 地址固定
仓库规则要求 config/ 为唯一配置来源、不以环境变量作持久默认值: - pi-notify 改读 config/pi-notify.json(逐字段校验回退,复用原 parsers 钳制) - pi-minimal-footer 改读 config/pi-minimal-footer.json - pi-chrome 移除 PI_CHROME_BRIDGE_HOST/PORT,固定 127.0.0.1:17318 (浏览器端 service_worker.js 硬编码同一地址,单侧可配只会断连) Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
0c45b1a438
commit
e996f59469
@@ -34,14 +34,14 @@ pi install npm:@ogulcancelik/pi-minimal-footer
|
||||
|
||||
## Configuration
|
||||
|
||||
Environment variables (all optional):
|
||||
Persistent defaults are read from `config/pi-minimal-footer.json` inside the installed bundle; a missing or invalid file falls back to the defaults shown:
|
||||
|
||||
| Variable | Description | Default |
|
||||
| ------------------------------- | -------------------------------------------------------- | ------- |
|
||||
| `PI_MINIMAL_FOOTER_SHOW_CWD` | Show current working directory in footer status line | `1` |
|
||||
| `PI_MINIMAL_FOOTER_SHOW_BRANCH` | Show git branch/dirty/ahead/behind in footer status line | `1` |
|
||||
| Field | Description | Default |
|
||||
| ------------ | -------------------------------------------------------- | ------- |
|
||||
| `showCwd` | Show current working directory in footer status line | `true` |
|
||||
| `showBranch` | Show git branch/dirty/ahead/behind in footer status line | `true` |
|
||||
|
||||
Accepted false values: `0`, `false`, `no`, `off` (case-insensitive).
|
||||
Only `true`/`false` values are honoured; anything else falls back to the default for that field.
|
||||
|
||||
## How it works
|
||||
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
- 导入包版本:`@ogulcancelik/pi-minimal-footer@0.1.10`
|
||||
- 导入日期:2026-08-19
|
||||
|
||||
本目录由 `my-pi` 直接维护;它不是 submodule,也不保留上游 Git 元数据。本地改动新增了 Pi 扩展状态渲染(把 `ctx.ui.setStatus()` 发布的每个非空状态渲染为普通 footer 片段)。
|
||||
本目录由 `my-pi` 直接维护;它不是 submodule,也不保留上游 Git 元数据。本地改动新增了 Pi 扩展状态渲染(把 `ctx.ui.setStatus()` 发布的每个非空状态渲染为普通 footer 片段),并把 showCwd/showBranch 持久配置由 `PI_MINIMAL_FOOTER_*` 环境变量改为组合包 `config/pi-minimal-footer.json`。
|
||||
|
||||
@@ -15,6 +15,7 @@ import { existsSync, readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { homedir } from "node:os";
|
||||
import { collectFooterStatusItems } from "./status.ts";
|
||||
import { readFooterSettings } from "./settings.ts";
|
||||
|
||||
// ============ Types ============
|
||||
|
||||
@@ -43,19 +44,6 @@ interface GitCache {
|
||||
const USAGE_REFRESH_INTERVAL = 5 * 60_000; // 5 minutes
|
||||
const usageCache = new Map<string, UsageSnapshot>(); // keyed by provider
|
||||
|
||||
// ============ Env Flags ============
|
||||
|
||||
function parseBooleanEnv(value: string | undefined, fallback: boolean): boolean {
|
||||
if (value === undefined) return fallback;
|
||||
|
||||
const normalized = value.trim().toLowerCase();
|
||||
if (!normalized) return fallback;
|
||||
|
||||
if (["1", "true", "yes", "on"].includes(normalized)) return true;
|
||||
if (["0", "false", "no", "off"].includes(normalized)) return false;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
// ============ Identity Cache ============
|
||||
|
||||
let codexEmailPrefix: string | null | undefined; // undefined = not yet resolved
|
||||
@@ -754,9 +742,8 @@ export default function (pi: ExtensionAPI) {
|
||||
const BAR_FILLED = "━";
|
||||
const BAR_EMPTY = "─";
|
||||
|
||||
// Optional visibility toggles (default: enabled)
|
||||
const showCwd = parseBooleanEnv(process.env.PI_MINIMAL_FOOTER_SHOW_CWD, true);
|
||||
const showBranch = parseBooleanEnv(process.env.PI_MINIMAL_FOOTER_SHOW_BRANCH, true);
|
||||
// Optional visibility toggles from bundle config (default: enabled)
|
||||
const { showCwd, showBranch } = readFooterSettings();
|
||||
|
||||
function formatTokenCount(tokens: number): string {
|
||||
if (tokens >= 1_000_000) {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
export interface FooterSettings {
|
||||
showCwd: boolean;
|
||||
showBranch: boolean;
|
||||
}
|
||||
|
||||
// Bundle-level `config/` is the single source of truth: the extension reads
|
||||
// `config/pi-minimal-footer.json` from inside the installed bundle (resolved
|
||||
// relative to this source file), never environment variables.
|
||||
export const FOOTER_CONFIG_PATH = fileURLToPath(
|
||||
new URL("../config/pi-minimal-footer.json", import.meta.url),
|
||||
);
|
||||
|
||||
export function readFooterSettings(configPath: string = FOOTER_CONFIG_PATH): FooterSettings {
|
||||
try {
|
||||
const parsed = JSON.parse(readFileSync(configPath, "utf8")) as unknown;
|
||||
const raw =
|
||||
parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)
|
||||
? (parsed as Record<string, unknown>)
|
||||
: {};
|
||||
return {
|
||||
showCwd: typeof raw.showCwd === "boolean" ? raw.showCwd : true,
|
||||
showBranch: typeof raw.showBranch === "boolean" ? raw.showBranch : true,
|
||||
};
|
||||
} catch {
|
||||
return { showCwd: true, showBranch: true };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, describe, it } from "node:test";
|
||||
|
||||
import { readFooterSettings } from "../settings.ts";
|
||||
|
||||
let tempDir: string | undefined;
|
||||
|
||||
afterEach(() => {
|
||||
if (tempDir) {
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
tempDir = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
function configPath(contents: string): string {
|
||||
tempDir = mkdtempSync(join(tmpdir(), "pi-minimal-footer-settings-"));
|
||||
const path = join(tempDir, "pi-minimal-footer.json");
|
||||
writeFileSync(path, contents);
|
||||
return path;
|
||||
}
|
||||
|
||||
const expectedDefaults = { showCwd: true, showBranch: true };
|
||||
|
||||
describe("readFooterSettings", () => {
|
||||
it("returns all defaults when the config file is missing", () => {
|
||||
assert.deepEqual(readFooterSettings("/does/not/exist/pi-minimal-footer.json"), expectedDefaults);
|
||||
});
|
||||
|
||||
it("returns all defaults for malformed or non-object JSON", () => {
|
||||
for (const contents of ["not json", "[1,2]", "42"]) {
|
||||
assert.deepEqual(readFooterSettings(configPath(contents)), expectedDefaults, contents);
|
||||
}
|
||||
});
|
||||
|
||||
it("adopts explicit boolean values", () => {
|
||||
assert.deepEqual(
|
||||
readFooterSettings(configPath(JSON.stringify({ showCwd: false, showBranch: false }))),
|
||||
{ showCwd: false, showBranch: false },
|
||||
);
|
||||
});
|
||||
|
||||
it("falls back per-field for non-boolean values", () => {
|
||||
assert.deepEqual(
|
||||
readFooterSettings(configPath(JSON.stringify({ showCwd: "no", showBranch: 0 }))),
|
||||
expectedDefaults,
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user