oh-pi 0.1.9 β 0.1.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/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ async function quickFlow(env) {
|
|
|
36
36
|
providers,
|
|
37
37
|
theme,
|
|
38
38
|
keybindings: "default",
|
|
39
|
-
extensions: ["safe-guard", "git-guard", "auto-session-name", "custom-footer"
|
|
39
|
+
extensions: ["safe-guard", "git-guard", "auto-session-name", "custom-footer"],
|
|
40
40
|
skills: ["quick-setup", "debug-helper", "git-workflow"],
|
|
41
41
|
prompts: ["review", "fix", "explain", "commit", "test"],
|
|
42
42
|
agents: "general-developer",
|
|
@@ -5,7 +5,7 @@ const PRESETS = {
|
|
|
5
5
|
labelKey: "preset.starter", hintKey: "preset.starterHint",
|
|
6
6
|
config: {
|
|
7
7
|
theme: "oh-p-dark", keybindings: "default", thinking: "medium",
|
|
8
|
-
extensions: ["safe-guard", "git-guard", "auto-session-name", "custom-footer"
|
|
8
|
+
extensions: ["safe-guard", "git-guard", "auto-session-name", "custom-footer"],
|
|
9
9
|
skills: ["quick-setup", "debug-helper"],
|
|
10
10
|
prompts: ["review", "fix", "explain", "commit"],
|
|
11
11
|
agents: "general-developer",
|
|
@@ -15,7 +15,7 @@ const PRESETS = {
|
|
|
15
15
|
labelKey: "preset.pro", hintKey: "preset.proHint",
|
|
16
16
|
config: {
|
|
17
17
|
theme: "catppuccin-mocha", keybindings: "default", thinking: "high",
|
|
18
|
-
extensions: ["safe-guard", "git-guard", "auto-session-name", "custom-footer"
|
|
18
|
+
extensions: ["safe-guard", "git-guard", "auto-session-name", "custom-footer"],
|
|
19
19
|
skills: ["quick-setup", "debug-helper", "git-workflow"],
|
|
20
20
|
prompts: ["review", "fix", "explain", "commit", "test", "refactor", "optimize", "document", "pr"],
|
|
21
21
|
agents: "fullstack-developer",
|
|
@@ -25,7 +25,7 @@ const PRESETS = {
|
|
|
25
25
|
labelKey: "preset.security", hintKey: "preset.securityHint",
|
|
26
26
|
config: {
|
|
27
27
|
theme: "cyberpunk", keybindings: "default", thinking: "high",
|
|
28
|
-
extensions: ["safe-guard", "custom-footer"
|
|
28
|
+
extensions: ["safe-guard", "custom-footer"],
|
|
29
29
|
skills: ["debug-helper"],
|
|
30
30
|
prompts: ["review", "security", "fix", "explain"],
|
|
31
31
|
agents: "security-researcher",
|
|
@@ -35,7 +35,7 @@ const PRESETS = {
|
|
|
35
35
|
labelKey: "preset.dataai", hintKey: "preset.dataaiHint",
|
|
36
36
|
config: {
|
|
37
37
|
theme: "tokyo-night", keybindings: "default", thinking: "medium",
|
|
38
|
-
extensions: ["safe-guard", "git-guard", "auto-session-name", "custom-footer"
|
|
38
|
+
extensions: ["safe-guard", "git-guard", "auto-session-name", "custom-footer"],
|
|
39
39
|
skills: ["quick-setup", "debug-helper"],
|
|
40
40
|
prompts: ["review", "fix", "explain", "optimize", "document", "test"],
|
|
41
41
|
agents: "data-ai-engineer",
|
|
@@ -52,7 +52,7 @@ const PRESETS = {
|
|
|
52
52
|
labelKey: "preset.full", hintKey: "preset.fullHint",
|
|
53
53
|
config: {
|
|
54
54
|
theme: "oh-p-dark", keybindings: "default", thinking: "high",
|
|
55
|
-
extensions: ["safe-guard", "git-guard", "auto-session-name", "custom-footer", "
|
|
55
|
+
extensions: ["safe-guard", "git-guard", "auto-session-name", "custom-footer", "ant-colony"],
|
|
56
56
|
skills: ["quick-setup", "debug-helper", "git-workflow", "ant-colony"],
|
|
57
57
|
prompts: ["review", "fix", "explain", "commit", "test", "refactor", "optimize", "security", "document", "pr"],
|
|
58
58
|
agents: "colony-operator",
|
package/dist/types.js
CHANGED
|
@@ -42,7 +42,6 @@ export const EXTENSIONS = [
|
|
|
42
42
|
{ name: "git-guard", label: "π¦ Git Guard β Auto stash checkpoint + dirty repo warning + notify", default: true },
|
|
43
43
|
{ name: "auto-session-name", label: "π Auto Session Name β Name sessions from first message", default: true },
|
|
44
44
|
{ name: "custom-footer", label: "π Custom Footer β Enhanced status bar with tokens, cost, time, git, cwd", default: true },
|
|
45
|
-
{ name: "startup-banner", label: "β‘ Startup Banner β Clean compact startup info (replaces verbose output)", default: true },
|
|
46
45
|
{ name: "ant-colony", label: "π Ant Colony β Autonomous multi-agent swarm with adaptive concurrency", default: false },
|
|
47
46
|
];
|
|
48
47
|
export const KEYBINDING_SCHEMES = {
|
package/dist/utils/install.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { writeFileSync, mkdirSync, readFileSync, copyFileSync, existsSync, readdirSync, statSync } from "node:fs";
|
|
1
|
+
import { writeFileSync, mkdirSync, readFileSync, copyFileSync, existsSync, readdirSync, statSync, rmSync } from "node:fs";
|
|
2
2
|
import { join, dirname } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { homedir } from "node:os";
|
|
@@ -8,6 +8,12 @@ const PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
|
8
8
|
function ensureDir(dir) {
|
|
9
9
|
mkdirSync(dir, { recursive: true });
|
|
10
10
|
}
|
|
11
|
+
/** Remove and recreate a directory */
|
|
12
|
+
function cleanDir(dir) {
|
|
13
|
+
if (existsSync(dir))
|
|
14
|
+
rmSync(dir, { recursive: true });
|
|
15
|
+
ensureDir(dir);
|
|
16
|
+
}
|
|
11
17
|
/** Recursively copy a directory */
|
|
12
18
|
function copyDir(src, dest) {
|
|
13
19
|
ensureDir(dest);
|
|
@@ -115,7 +121,7 @@ export function applyConfig(config) {
|
|
|
115
121
|
catch { /* template not found, skip */ }
|
|
116
122
|
// 6. Copy extensions (single file .ts or directory with index.ts)
|
|
117
123
|
const extDir = join(agentDir, "extensions");
|
|
118
|
-
|
|
124
|
+
cleanDir(extDir);
|
|
119
125
|
for (const ext of config.extensions) {
|
|
120
126
|
const dirSrc = join(PKG_ROOT, "pi-package", "extensions", ext);
|
|
121
127
|
const fileSrc = join(PKG_ROOT, "pi-package", "extensions", `${ext}.ts`);
|
|
@@ -131,7 +137,7 @@ export function applyConfig(config) {
|
|
|
131
137
|
}
|
|
132
138
|
// 7. Copy prompts
|
|
133
139
|
const promptDir = join(agentDir, "prompts");
|
|
134
|
-
|
|
140
|
+
cleanDir(promptDir);
|
|
135
141
|
for (const p of config.prompts) {
|
|
136
142
|
const src = join(PKG_ROOT, "pi-package", "prompts", `${p}.md`);
|
|
137
143
|
try {
|
|
@@ -141,7 +147,7 @@ export function applyConfig(config) {
|
|
|
141
147
|
}
|
|
142
148
|
// 8. Copy skills
|
|
143
149
|
const skillDir = join(agentDir, "skills");
|
|
144
|
-
|
|
150
|
+
cleanDir(skillDir);
|
|
145
151
|
for (const s of config.skills) {
|
|
146
152
|
const srcDir = join(PKG_ROOT, "pi-package", "skills", s);
|
|
147
153
|
const destDir = join(skillDir, s);
|
|
@@ -153,7 +159,7 @@ export function applyConfig(config) {
|
|
|
153
159
|
}
|
|
154
160
|
// 9. Copy themes (only custom ones)
|
|
155
161
|
const themeDir = join(agentDir, "themes");
|
|
156
|
-
|
|
162
|
+
cleanDir(themeDir);
|
|
157
163
|
const themeSrc = join(PKG_ROOT, "pi-package", "themes", `${config.theme}.json`);
|
|
158
164
|
try {
|
|
159
165
|
copyFileSync(themeSrc, join(themeDir, `${config.theme}.json`));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Custom Footer Extension β Enhanced status bar
|
|
3
3
|
*
|
|
4
|
-
* Displays:
|
|
4
|
+
* Displays: in/out/remaining tokens, cost, context%, elapsed, cwd, git branch, model
|
|
5
5
|
* Color-coded context usage: green <50%, yellow 50-75%, red >75%
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -39,7 +39,6 @@ export default function (pi: ExtensionAPI) {
|
|
|
39
39
|
dispose() { unsub(); clearInterval(timer); },
|
|
40
40
|
invalidate() {},
|
|
41
41
|
render(width: number): string[] {
|
|
42
|
-
// --- Tokens & Cost ---
|
|
43
42
|
let input = 0, output = 0, cost = 0;
|
|
44
43
|
for (const e of ctx.sessionManager.getBranch()) {
|
|
45
44
|
if (e.type === "message" && e.message.role === "assistant") {
|
|
@@ -50,47 +49,35 @@ export default function (pi: ExtensionAPI) {
|
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
// --- Context usage ---
|
|
54
52
|
const usage = ctx.getContextUsage();
|
|
55
|
-
const tokens = usage?.tokens ?? 0;
|
|
56
53
|
const ctxWindow = usage?.contextWindow ?? 0;
|
|
57
54
|
const pct = usage?.percent ?? 0;
|
|
58
|
-
const remaining = Math.max(0, ctxWindow - tokens);
|
|
55
|
+
const remaining = Math.max(0, ctxWindow - (usage?.tokens ?? 0));
|
|
59
56
|
|
|
60
|
-
// Color by usage level
|
|
61
57
|
const pctColor = pct > 75 ? "error" : pct > 50 ? "warning" : "success";
|
|
62
|
-
const pctStr = `${pct.toFixed(1)}%/${fmt(ctxWindow)}`;
|
|
63
58
|
|
|
64
59
|
const tokenStats = [
|
|
65
|
-
theme.fg("accent",
|
|
66
|
-
theme.fg("dim", `
|
|
67
|
-
theme.fg("muted", `
|
|
68
|
-
theme.fg("warning",
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const cwd = process.cwd();
|
|
79
|
-
const parts = cwd.split("/");
|
|
80
|
-
const short = parts.length > 2 ? parts.slice(-2).join("/") : cwd;
|
|
81
|
-
const cwdStr = theme.fg("muted", `π ${short}`);
|
|
82
|
-
|
|
83
|
-
// --- Git branch ---
|
|
60
|
+
theme.fg("accent", `i${fmt(input)}`),
|
|
61
|
+
theme.fg("dim", `o${fmt(output)}`),
|
|
62
|
+
theme.fg("muted", `r${fmt(remaining)}`),
|
|
63
|
+
theme.fg("warning", `$${cost.toFixed(3)}`),
|
|
64
|
+
theme.fg(pctColor, `${pct.toFixed(0)}%`),
|
|
65
|
+
].join(" ");
|
|
66
|
+
|
|
67
|
+
const elapsed = theme.fg("dim", formatElapsed(Date.now() - sessionStart));
|
|
68
|
+
|
|
69
|
+
const parts = process.cwd().split("/");
|
|
70
|
+
const short = parts.length > 2 ? parts.slice(-2).join("/") : process.cwd();
|
|
71
|
+
const cwdStr = theme.fg("muted", short);
|
|
72
|
+
|
|
84
73
|
const branch = footerData.getGitBranch();
|
|
85
|
-
const branchStr = branch ? theme.fg("accent",
|
|
74
|
+
const branchStr = branch ? theme.fg("accent", branch) : "";
|
|
86
75
|
|
|
87
|
-
// --- Right: model + thinking ---
|
|
88
76
|
const thinking = pi.getThinkingLevel();
|
|
89
77
|
const modelId = ctx.model?.id || "no-model";
|
|
90
|
-
const right = theme.fg("dim", `${modelId}
|
|
78
|
+
const right = theme.fg("dim", `${modelId} ${thinking}`);
|
|
91
79
|
|
|
92
|
-
|
|
93
|
-
const sep = theme.fg("dim", " β ");
|
|
80
|
+
const sep = theme.fg("dim", " | ");
|
|
94
81
|
const leftParts = [tokenStats, elapsed, cwdStr];
|
|
95
82
|
if (branchStr) leftParts.push(branchStr);
|
|
96
83
|
const left = leftParts.join(sep);
|
|
@@ -99,10 +86,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
99
86
|
const rightW = visibleWidth(right);
|
|
100
87
|
const gap = width - leftW - rightW;
|
|
101
88
|
if (gap >= 2) {
|
|
102
|
-
|
|
103
|
-
return [truncateToWidth(left + pad + right, width)];
|
|
89
|
+
return [truncateToWidth(left + " ".repeat(gap) + right, width)];
|
|
104
90
|
}
|
|
105
|
-
// Not enough space for right side β just show left truncated
|
|
106
91
|
return [truncateToWidth(left, width)];
|
|
107
92
|
},
|
|
108
93
|
};
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* oh-pi Startup Banner Extension
|
|
3
|
-
*
|
|
4
|
-
* Replaces the built-in verbose header with a compact one-line info display.
|
|
5
|
-
* Auto-restores the default header after 8 seconds.
|
|
6
|
-
*/
|
|
7
|
-
import type { AssistantMessage } from "@mariozechner/pi-ai";
|
|
8
|
-
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
9
|
-
import { truncateToWidth } from "@mariozechner/pi-tui";
|
|
10
|
-
|
|
11
|
-
export default function (pi: ExtensionAPI) {
|
|
12
|
-
pi.on("session_start", async (_event, ctx) => {
|
|
13
|
-
if (!ctx.hasUI) return;
|
|
14
|
-
|
|
15
|
-
const model = ctx.model;
|
|
16
|
-
const thinking = pi.getThinkingLevel();
|
|
17
|
-
const usage = ctx.getContextUsage();
|
|
18
|
-
const cwd = process.cwd().replace(process.env.HOME ?? "", "~");
|
|
19
|
-
|
|
20
|
-
// Sum cost from branch
|
|
21
|
-
let totalCost = 0;
|
|
22
|
-
for (const e of ctx.sessionManager.getBranch()) {
|
|
23
|
-
if (e.type === "message" && e.message.role === "assistant") {
|
|
24
|
-
totalCost += (e.message as AssistantMessage).usage.cost.total;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Git branch
|
|
29
|
-
let git = "";
|
|
30
|
-
try {
|
|
31
|
-
const { stdout } = await pi.exec("git", ["rev-parse", "--abbrev-ref", "HEAD"], { timeout: 2000 });
|
|
32
|
-
git = stdout.trim();
|
|
33
|
-
} catch { /* not a git repo */ }
|
|
34
|
-
|
|
35
|
-
const modelStr = model ? `${model.provider}/${model.id}` : "no model";
|
|
36
|
-
const thinkStr = thinking !== "off" ? ` β’ π§ ${thinking}` : "";
|
|
37
|
-
const ctxStr = usage ? ` β’ π ${Math.round(usage.percent)}%` : "";
|
|
38
|
-
const gitStr = git ? ` β’ πΏ ${git}` : "";
|
|
39
|
-
const costStr = totalCost > 0 ? ` β’ $${totalCost.toFixed(3)}` : "";
|
|
40
|
-
|
|
41
|
-
const session = ctx.sessionManager.getSessionFile?.() ?? "ephemeral";
|
|
42
|
-
const sessionName = session.split("/").pop();
|
|
43
|
-
|
|
44
|
-
const line = `β‘ ${modelStr}${thinkStr}${ctxStr}${costStr} β π ${cwd}${gitStr} β π ${sessionName}`;
|
|
45
|
-
|
|
46
|
-
ctx.ui.setHeader((_tui, theme) => ({
|
|
47
|
-
render(width: number): string[] {
|
|
48
|
-
return ["", truncateToWidth(theme.fg("accent", line), width), ""];
|
|
49
|
-
},
|
|
50
|
-
invalidate() {},
|
|
51
|
-
}));
|
|
52
|
-
|
|
53
|
-
// Restore default header after 8 seconds
|
|
54
|
-
setTimeout(() => ctx.ui.setHeader(undefined), 8000);
|
|
55
|
-
});
|
|
56
|
-
}
|