feat: back up omp config (agent settings, commands, extensions, themes, loops, plugins)

This commit is contained in:
Prad Nukala committed 2026-10-16 10:51:26 -04:00
commit 31c9602d0c
22 files changed
+1154

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
---
description: Convert a LeetCode solution file into a Fumadocs MDX docs page
---
Convert the LeetCode solution file at `$1` into a Fumadocs-formatted MDX page.
Extra instructions (optional, may include output dir override): $@
## Input format
The source file follows the standard on-disk format:
- A `/* ... */` header block: problem number, title, difficulty, LeetCode URL, problem description, examples, constraints
- A JSDoc `@param`/`@return` block
- One or more solution functions (possibly with line-by-line beginner comments and `// ====` banners)
## Output location
Default: write next to the content root at `content/docs/leetcode/<difficulty>/<category>/<number>-<slug>.mdx`, mirroring the source tree (e.g. `Easy/Array/1365.how-many-numbers.js` → `content/docs/leetcode/easy/array/1365-how-many-numbers.mdx`). Lowercase all path segments. If the extra instructions specify a different output path or content root, use that instead. Create directories as needed.
## Page structure
Produce exactly this shape:
```mdx
---
title: 1365. How Many Numbers Are Smaller Than the Current Number
description: <one-sentence summary of the technique, e.g. "Frequency map + prefix count — the counting hammer.">
---
<Callout title="Easy · Array · Hash Table">
[View on LeetCode](https://leetcode.com/problems/how-many-numbers-are-smaller-than-the-current-number/)
</Callout>
## Problem
<problem description from the header block, reflowed into clean Markdown prose — no hard-wrapped 70-char lines>
## Examples
<each example as a fenced code block:>
```txt title="Example 1"
Input: nums = [8,1,2,2,3]
Output: [4,0,1,1,3]
```
<if an example has an Explanation, put it as plain prose under its code block>
## Constraints
<bulleted list from the header block, with values in inline code: `2 <= nums.length <= 500`>
## Solution
<one-paragraph intuition: name the pattern (frequency map, prefix sum, two pointers, etc.) and the key insight in 2–3 sentences. Derive this from the code itself.>
```js title="solution.js" lineNumbers
<the solution function, verbatim — including any existing beginner comments>
```
<Callout type="idea" title="Complexity">
**Time:** O(n log n) — **Space:** O(n)
</Callout>
```
## Rules
1. **Frontmatter `title` carries the h1** — Fumadocs renders it as the page title, so never emit a `# heading` in the body.
2. **Escape MDX hazards.** The header text may contain `<`, `>`, `{`, `}` (e.g. `j != i and nums[j] < nums[i]`, `2 <= nums.length <= 500`). Anything with these characters must be wrapped in inline code or fenced blocks, or the MDX compile will fail. When in doubt, inline-code it.
3. **Code is verbatim.** Copy the solution function(s) exactly — do not rewrite, reformat, or strip existing comments. The docs page documents the code as it exists.
4. **Multiple approaches → tab group:**
````mdx
```js tab="Frequency Map" tab-group="approach"
...
```
```js tab="Sort + Map"
...
```
````
5. **Complexity callout is derived, not guessed blindly.** Read the code: nested loop → O(n²), sort → O(n log n), single pass + map → O(n). If genuinely ambiguous, state the dominant term and why in one clause.
6. **Callout header line** = `<Difficulty> · <topic tags>`. Difficulty comes from the header block; infer 1–2 topic tags from the directory path and the technique used.
7. **No invented content.** Problem statement, examples, and constraints come only from the header block. The intuition paragraph and complexity are the only sections you author.
8. **After writing**, print one line: the output path. Nothing else.
+74
View File
@@ -0,0 +1,74 @@
---
description: Add super-simple line-by-line comments to a LeetCode solution file
---
Add beginner-level line-by-line comments to the LeetCode solution file at: $1
## Rules
1. **Read the file first.** It follows the standard on-disk format:
- A `/* ... */` header block containing problem number, title, difficulty, URL, description, examples, and constraints
- A JSDoc `@param`/`@return` block
- The solution function(s)
2. **Never touch the header block or JSDoc block.** Preserve them byte-for-byte.
3. **Never change the code.** Do not rename variables, reformat logic, alter whitespace inside expressions, or "improve" anything. Comments only. The file must produce an identical AST after your edit.
4. **Comment style — explain as if to a complete beginner who has never programmed:**
- One comment line (or short block) ABOVE each meaningful line/statement
- Use plain everyday language and physical metaphors:
- object/map → "box" ("Create an empty box to count how many times each number appears")
- increment → "add 1 to its count"
- `(freq[x] || 0) + 1` → "If we already saw this number, add 1 to its count. If we never saw it before, start counting from 1"
- sort comparator → spell out the rule in words ("put the letter that appears MORE times first; if tied, alphabetical order")
- return → say WHAT is being returned and WHY in plain words
- Explain the WHY, not just the WHAT ("so the next bigger numbers know there are more smaller ones")
- Inline comments (`// ...` at end of line) are fine for short trailing clarifications like `.join('')` → "glue the sorted letters back into a string"
- No jargon without immediate translation: if you must say "index", follow with "(its position)"
5. **Add a section banner** above the solution function in this exact style:
```js
// ============================================
// <problem number>. <problem title>
// ============================================
```
Pull the number and title from the header block.
6. **Multiple solutions in one file:** comment every one of them, each with its own banner (append "– Approach 2" etc. to the banner title).
7. **Extra instructions** (if provided after the file path): $@
8. **After editing**, print a one-line confirmation: file path + number of comment lines added. Nothing else.
## Example transformation
Input body:
```js
var smallerNumbersThanCurrent = function (nums) {
const freq = {};
for (let x of nums) freq[x] = (freq[x] || 0) + 1;
return nums.map((x) => smaller[x]);
};
```
Output body:
```js
// ============================================
// 1365. How Many Numbers Are Smaller Than the Current Number
// ============================================
var smallerNumbersThanCurrent = function (nums) {
// Create an empty box to store how many times each number appears
const freq = {};
// Go through every number in the list one by one
// If we already saw this number, add 1 to its count
// If we never saw it before, start counting from 1
for (let x of nums) freq[x] = (freq[x] || 0) + 1;
// Go through the original list and replace each number
// with "how many numbers are smaller than it"
return nums.map((x) => smaller[x]);
};
```
+31
View File
@@ -0,0 +1,31 @@
theme:
dark: titanium
light: light
symbolPreset: nerd
setupVersion: 2
hideThinkingBlock: false
modelRoles:
plan: anthropic/claude-fable-5-1:high
default: anthropic/claude-opus-5-5:high
smol: anthropic/claude-haiku-5-5
task: anthropic/claude-sonnet-5-5
web: web/exa
dictation: local/parakeet-tdt-0.6b-v3
speech: local/kokoro
image: openai/gpt-image-2
advisor: anthropic/claude-mythos-5-1:xhigh
slow: anthropic/claude-fable-5-1:high
vision: openai/gpt-6-astra:high
commit: cerebras/qwen-3-coder-480b
tiny: opencode-go/step-5-preview:auto
memory: opencode-go/gemini-4-argon-contributor:medium
judge: anthropic/claude-fable-5-1:max
composer:
shape: rule
modelPresets:
Primary:
modelRoles:
plan: anthropic/claude-fable-5-1:high
default: anthropic/claude-opus-5-5:high
smol: anthropic/claude-haiku-5-5
defaultThinkingLevel: high
+471
View File
@@ -0,0 +1,471 @@
// installed by herdr
// managed by herdr; reinstalling or updating the integration overwrites this file.
// add custom hooks/plugins beside this file instead of editing it.
// HERDR_INTEGRATION_ID=omp
// HERDR_INTEGRATION_VERSION=10
// @ts-nocheck
import net from "node:net";
import path from "node:path";
const HERDR_ENV = process.env.HERDR_ENV;
const socketPath = process.env.HERDR_SOCKET_PATH;
const socketEndpoint =
process.platform === "win32" && socketPath ? `\\\\.\\pipe\\${socketPath}` : socketPath;
const paneId = process.env.HERDR_PANE_ID;
const source = "herdr:omp";
// OMP marks every shell it spawns with OMPCODE=1. A nested `omp` launched from
// a parent session's shell inherits it, so that process is not the pane's root
// agent and must not report its short-lived session over the parent's.
const nestedOmpSession = process.env.OMPCODE === "1";
function enabled() {
return HERDR_ENV === "1" && !!socketPath && !!paneId && !nestedOmpSession;
}
let requestQueue = Promise.resolve();
function sendRequestAttempt(request: unknown, timeoutMs: number): Promise<boolean> {
if (!enabled()) {
return Promise.resolve(true);
}
return new Promise((resolve) => {
let done = false;
let timeout: ReturnType<typeof setTimeout> | undefined;
const finish = (delivered: boolean) => {
if (done) return;
done = true;
if (timeout) {
clearTimeout(timeout);
}
socket.destroy();
resolve(delivered);
};
const socket = net.createConnection(socketEndpoint!);
socket.on("error", () => finish(false));
socket.on("connect", () => socket.write(`${JSON.stringify(request)}\n`));
socket.on("data", () => finish(true));
socket.on("end", () => finish(false));
timeout = setTimeout(() => finish(false), timeoutMs);
timeout.unref?.();
});
}
async function sendRequestNow(request: unknown): Promise<void> {
if (await sendRequestAttempt(request, 500)) {
return;
}
await sendRequestAttempt(request, 1500);
}
function sendRequest(request: unknown): Promise<void> {
requestQueue = requestQueue.then(
() => sendRequestNow(request),
() => sendRequestNow(request),
);
return requestQueue;
}
type AgentState = "working" | "blocked" | "idle";
type QueuedState = {
state: AgentState;
message?: string;
seq: number;
};
const idleDebounceMs = parseDurationEnv("HERDR_OMP_IDLE_DEBOUNCE_MS", 250);
const retryGraceMs = parseDurationEnv("HERDR_OMP_RETRY_GRACE_MS", 2500);
const retryableErrorPattern =
/overloaded|provider.?returned.?error|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|network.?error|connection.?error|connection.?refused|connection.?lost|websocket.?closed|websocket.?error|other side closed|fetch failed|upstream.?connect|reset before headers|socket hang up|ended without|http2 request did not get a response|timed? out|timeout|terminated|retry delay/i;
let reportSeq = Date.now() * 1000;
let currentAgentSessionId: string | undefined;
let currentAgentSessionPath: string | undefined;
function nextReportSeq(): number {
reportSeq += 1;
return reportSeq;
}
export function isAbsoluteSessionPath(file: unknown): file is string {
return (
typeof file === "string" &&
(path.posix.isAbsolute(file) || path.win32.isAbsolute(file))
);
}
function updateSessionRef(ctx: any): void {
try {
const file = ctx?.sessionManager?.getSessionFile?.();
currentAgentSessionPath = isAbsoluteSessionPath(file) ? file : undefined;
} catch {
currentAgentSessionPath = undefined;
}
try {
const id = ctx?.sessionManager?.getSessionId?.();
currentAgentSessionId = typeof id === "string" && id.length > 0 ? id : undefined;
} catch {
currentAgentSessionId = undefined;
}
}
function withSessionRef(params: Record<string, unknown>): Record<string, unknown> {
if (currentAgentSessionPath) {
return { ...params, agent_session_path: currentAgentSessionPath };
}
if (currentAgentSessionId) {
return { ...params, agent_session_id: currentAgentSessionId };
}
return params;
}
function parseDurationEnv(name: string, fallback: number): number {
const raw = process.env[name];
if (!raw) {
return fallback;
}
const parsed = Number.parseInt(raw, 10);
if (!Number.isFinite(parsed) || parsed < 0) {
return fallback;
}
return parsed;
}
function currentSessionRef(): Record<string, unknown> | undefined {
if (currentAgentSessionPath) {
return { agent_session_path: currentAgentSessionPath };
}
if (currentAgentSessionId) {
return { agent_session_id: currentAgentSessionId };
}
return undefined;
}
function reportSession(sessionStartSource = "startup"): Promise<void> {
const sessionRef = currentSessionRef();
if (!sessionRef) {
return Promise.resolve();
}
return sendRequest({
id: `${source}:session:${Date.now()}:${Math.random().toString(36).slice(2)}`,
method: "pane.report_agent_session",
params: {
pane_id: paneId,
source,
agent: "omp",
seq: nextReportSeq(),
session_start_source: sessionStartSource,
...sessionRef,
},
});
}
function sendState(state: AgentState, message?: string, seq = nextReportSeq()): Promise<void> {
return sendRequest({
id: `${source}:${Date.now()}:${Math.random().toString(36).slice(2)}`,
method: "pane.report_agent",
params: withSessionRef({
pane_id: paneId,
source,
agent: "omp",
state,
message,
seq,
}),
});
}
let sendInFlight = false;
let queuedState: QueuedState | undefined;
function queueState(state: AgentState, message?: string): void {
queuedState = { state, message, seq: nextReportSeq() };
if (!sendInFlight) {
void drainStateQueue();
}
}
async function drainStateQueue(): Promise<void> {
if (sendInFlight) {
return;
}
sendInFlight = true;
try {
while (queuedState) {
const next = queuedState;
queuedState = undefined;
await sendState(next.state, next.message, next.seq);
}
} finally {
sendInFlight = false;
if (queuedState) {
void drainStateQueue();
}
}
}
function lastAssistantMessage(messages: unknown[]): any | undefined {
for (let i = messages.length - 1; i >= 0; i -= 1) {
const message = messages[i] as any;
if (message?.role === "assistant") {
return message;
}
}
return undefined;
}
function retryableErrorMessage(event: any): string | undefined {
const messages = Array.isArray(event?.messages) ? event.messages : [];
const assistant = lastAssistantMessage(messages);
if (assistant?.stopReason !== "error") {
return undefined;
}
const errorMessage = String(assistant.errorMessage ?? "");
if (!retryableErrorPattern.test(errorMessage)) {
return undefined;
}
return errorMessage || "retryable provider error";
}
function askBlockedMessage(args: any): string {
const questions = Array.isArray(args?.questions) ? args.questions : [];
const firstQuestion = questions.find((question: any) => typeof question?.question === "string");
if (firstQuestion?.question) {
return firstQuestion.question;
}
return "waiting for user input";
}
export default function (pi) {
if (!enabled()) {
return;
}
let agentActive = false;
let retryHoldActive = false;
let failureBlocked = false;
let failureMessage: string | undefined;
let blockedCount = 0;
let blockedMessage: string | undefined;
let lastState: AgentState | undefined;
let lastMessage: string | undefined;
let idleTimer: ReturnType<typeof setTimeout> | undefined;
let retryTimer: ReturnType<typeof setTimeout> | undefined;
let rootSession = false;
function clearTimer(timer: ReturnType<typeof setTimeout> | undefined) {
if (timer) {
clearTimeout(timer);
}
}
function clearPendingTimers() {
clearTimer(idleTimer);
clearTimer(retryTimer);
idleTimer = undefined;
retryTimer = undefined;
}
function clearFailureState() {
retryHoldActive = false;
failureBlocked = false;
failureMessage = undefined;
}
function desiredState() {
if (blockedCount > 0) {
return { state: "blocked" as const, message: blockedMessage };
}
if (failureBlocked) {
return { state: "blocked" as const, message: failureMessage };
}
if (agentActive || retryHoldActive) {
return { state: "working" as const, message: undefined };
}
return { state: "idle" as const, message: undefined };
}
function publishState(force = false) {
const next = desiredState();
if (!force && next.state === lastState && next.message === lastMessage) {
return;
}
lastState = next.state;
lastMessage = next.message;
queueState(next.state, next.message);
}
function scheduleIdle() {
clearPendingTimers();
clearFailureState();
idleTimer = setTimeout(() => {
idleTimer = undefined;
publishState();
}, idleDebounceMs);
idleTimer.unref?.();
}
function holdForRetry(message: string) {
clearPendingTimers();
retryHoldActive = true;
failureBlocked = false;
failureMessage = message;
publishState();
retryTimer = setTimeout(() => {
retryTimer = undefined;
retryHoldActive = false;
failureBlocked = true;
publishState();
}, retryGraceMs);
retryTimer.unref?.();
}
function activateRootSession(ctx: any, sessionStartSource = "startup"): boolean {
if (ctx?.hasUI !== true) {
return false;
}
rootSession = true;
updateSessionRef(ctx);
void reportSession(sessionStartSource);
return true;
}
function resetSessionState() {
clearPendingTimers();
clearFailureState();
agentActive = false;
blockedCount = 0;
blockedMessage = undefined;
}
function activateBlocked(message: string | undefined) {
clearPendingTimers();
blockedCount += 1;
blockedMessage = message;
publishState();
}
function deactivateBlocked() {
blockedCount = Math.max(0, blockedCount - 1);
if (blockedCount === 0) {
blockedMessage = undefined;
}
publishState();
}
pi.events.on("herdr:blocked", (data) => {
if (!rootSession) {
return;
}
if (!data?.active) {
deactivateBlocked();
return;
}
activateBlocked(data.label);
});
pi.on("session_start", (_event, ctx) => {
if (!activateRootSession(ctx)) {
return;
}
// A reload can replace this extension mid-run without emitting another agent_start.
agentActive = ctx?.isIdle?.() === false;
publishState(true);
});
pi.on("session_switch", (event, ctx) => {
if (!activateRootSession(ctx, event?.reason || "resume")) {
return;
}
resetSessionState();
publishState(true);
});
pi.on("agent_start", (_event, ctx) => {
if (!rootSession && !activateRootSession(ctx)) {
return;
}
updateSessionRef(ctx);
void reportSession();
clearPendingTimers();
clearFailureState();
agentActive = true;
publishState();
});
pi.on("tool_approval_requested", (event, ctx) => {
if (!rootSession && !activateRootSession(ctx)) {
return;
}
const label = event?.reason || `${event?.toolName || "Tool"} approval`;
activateBlocked(label);
});
pi.on("tool_approval_resolved", (_event, ctx) => {
if (!rootSession && !activateRootSession(ctx)) {
return;
}
deactivateBlocked();
});
pi.on("tool_execution_start", (event, ctx) => {
if (event?.toolName !== "ask") {
return;
}
if (!rootSession && !activateRootSession(ctx)) {
return;
}
activateBlocked(askBlockedMessage(event.args));
});
pi.on("tool_execution_end", (event, ctx) => {
if (event?.toolName !== "ask") {
return;
}
if (!rootSession && !activateRootSession(ctx)) {
return;
}
deactivateBlocked();
});
pi.on("agent_end", (event) => {
if (!rootSession) {
return;
}
if (!agentActive) {
// OMP can emit duplicate/late end events while auto-retry is already
// holding the pane in Working. Do not let an unqualified duplicate end
// cancel the retry hold and publish a false Idle.
return;
}
if (event?.willContinue === true) {
// A continuation is already scheduled, so this end is not a settle.
// Older builds omit the field and fall through as before.
return;
}
agentActive = false;
const retryableMessage = retryableErrorMessage(event);
if (retryableMessage) {
holdForRetry(retryableMessage);
return;
}
scheduleIdle();
});
pi.on("session_shutdown", () => {
if (rootSession) {
clearPendingTimers();
}
});
}
+2
View File
@@ -0,0 +1,2 @@
app.editor.external: Ctrl+E
app.exit: Ctrl+Q
+19
View File
@@ -0,0 +1,19 @@
{
"$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/config/mcp-schema.json",
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "!printf 'Bearer %s' \"$(gh auth token)\""
}
},
"obscura": {
"type": "stdio",
"command": "obscura",
"args": [
"mcp"
]
}
}
}
+96
View File
@@ -0,0 +1,96 @@
{
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"name": "cyberdream",
"vars": {
"bg": "#16181a",
"bgAlt": "#1e2124",
"bgHighlight": "#3c4048",
"fg": "#ffffff",
"grey": "#7b8496",
"blue": "#5ea1ff",
"green": "#5eff6c",
"cyan": "#5ef1ff",
"red": "#ff6e5e",
"yellow": "#f1ff5e",
"magenta": "#ff5ef1",
"pink": "#ff5ea0",
"orange": "#ffbd5e",
"purple": "#bd5eff"
},
"colors": {
"accent": "blue",
"border": "blue",
"borderAccent": "cyan",
"borderMuted": "grey",
"success": "green",
"error": "red",
"warning": "yellow",
"muted": "grey",
"dim": "grey",
"text": "",
"thinkingText": "grey",
"selectedBg": "bgHighlight",
"userMessageBg": "bgAlt",
"userMessageText": "fg",
"customMessageBg": "bgAlt",
"customMessageText": "fg",
"customMessageLabel": "cyan",
"toolPendingBg": "bgAlt",
"toolSuccessBg": "bgAlt",
"toolErrorBg": "bgAlt",
"toolTitle": "cyan",
"toolOutput": "fg",
"mdHeading": "orange",
"mdLink": "cyan",
"mdLinkUrl": "blue",
"mdCode": "cyan",
"mdCodeBlock": "fg",
"mdCodeBlockBorder": "grey",
"mdQuote": "grey",
"mdQuoteBorder": "grey",
"mdHr": "grey",
"mdListBullet": "cyan",
"toolDiffAdded": "green",
"toolDiffRemoved": "red",
"toolDiffContext": "grey",
"syntaxComment": "grey",
"syntaxKeyword": "magenta",
"syntaxFunction": "blue",
"syntaxVariable": "yellow",
"syntaxString": "green",
"syntaxNumber": "purple",
"syntaxType": "cyan",
"syntaxOperator": "pink",
"syntaxPunctuation": "grey",
"thinkingOff": "grey",
"thinkingMinimal": "blue",
"thinkingLow": "cyan",
"thinkingMedium": "green",
"thinkingHigh": "yellow",
"thinkingXhigh": "orange",
"thinkingMax": "red",
"bashMode": "yellow",
"pythonMode": "purple",
"statusLineBg": "bgAlt",
"statusLineSep": "grey",
"statusLineModel": "purple",
"statusLinePath": "blue",
"statusLineGitClean": "green",
"statusLineGitDirty": "yellow",
"statusLineContext": "cyan",
"statusLineSpend": "pink",
"statusLineStaged": "green",
"statusLineDirty": "yellow",
"statusLineUntracked": "red",
"statusLineOutput": "fg",
"statusLineCost": "orange",
"statusLineSubagents": "magenta"
}
}