@oh-my-pi/pi-coding-agent 15.2.1 → 15.2.2
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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [15.2.2] - 2026-05-22
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fixed `RULES.md` not being injected. The documented sticky-rules file at `~/.omp/agent/RULES.md` and `<repo>/.omp/RULES.md` was never read by any discovery provider; only `.omp/rules/*.md` was scanned. The native provider now loads both as always-apply rules so they re-attach every turn as documented ([#1266](https://github.com/can1357/oh-my-pi/issues/1266)).
|
|
10
|
+
|
|
5
11
|
## [15.2.1] - 2026-05-21
|
|
6
12
|
|
|
7
13
|
### Fixed
|
|
@@ -48,6 +48,8 @@ export interface UserAgentSession {
|
|
|
48
48
|
override: UserAgentOverride;
|
|
49
49
|
browserSession: CDPSession | null;
|
|
50
50
|
}
|
|
51
|
+
/** Builds the browser-page stealth bootstrap source for regression tests. */
|
|
52
|
+
export declare function buildStealthInjectionScriptForTest(scripts?: readonly string[]): string;
|
|
51
53
|
/** Apply stealth patches + UA override to a headless page. Idempotent within a tab. */
|
|
52
54
|
export declare function applyStealthPatches(browser: Browser, page: Page, state: {
|
|
53
55
|
browserSession: CDPSession | null;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "15.2.
|
|
4
|
+
"version": "15.2.2",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"@agentclientprotocol/sdk": "0.21.0",
|
|
48
48
|
"@babel/parser": "^7.29.3",
|
|
49
49
|
"@mozilla/readability": "^0.6.0",
|
|
50
|
-
"@oh-my-pi/omp-stats": "15.2.
|
|
51
|
-
"@oh-my-pi/pi-agent-core": "15.2.
|
|
52
|
-
"@oh-my-pi/pi-ai": "15.2.
|
|
53
|
-
"@oh-my-pi/pi-natives": "15.2.
|
|
54
|
-
"@oh-my-pi/pi-tui": "15.2.
|
|
55
|
-
"@oh-my-pi/pi-utils": "15.2.
|
|
50
|
+
"@oh-my-pi/omp-stats": "15.2.2",
|
|
51
|
+
"@oh-my-pi/pi-agent-core": "15.2.2",
|
|
52
|
+
"@oh-my-pi/pi-ai": "15.2.2",
|
|
53
|
+
"@oh-my-pi/pi-natives": "15.2.2",
|
|
54
|
+
"@oh-my-pi/pi-tui": "15.2.2",
|
|
55
|
+
"@oh-my-pi/pi-utils": "15.2.2",
|
|
56
56
|
"@puppeteer/browsers": "^2.13.0",
|
|
57
57
|
"@types/turndown": "5.0.6",
|
|
58
58
|
"@xterm/headless": "^6.0.0",
|
package/src/discovery/builtin.ts
CHANGED
|
@@ -346,9 +346,39 @@ async function loadRules(ctx: LoadContext): Promise<LoadResult<Rule>> {
|
|
|
346
346
|
if (result.warnings) warnings.push(...result.warnings);
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
+
// Top-level RULES.md is a sticky always-apply rule. Documented in
|
|
350
|
+
// https://omp.sh/docs/context-files as the file that gets "re-injected near
|
|
351
|
+
// the current turn so they keep hold across long conversations".
|
|
352
|
+
// User scope: ~/.omp/agent/RULES.md
|
|
353
|
+
// Project scope: nearest .omp/RULES.md walking up from cwd to repoRoot
|
|
354
|
+
const userRulesFile = path.join(ctx.home, PATHS.userAgent, "RULES.md");
|
|
355
|
+
const userRule = await loadStickyRulesFile(userRulesFile, "user");
|
|
356
|
+
if (userRule) items.push(userRule);
|
|
357
|
+
|
|
358
|
+
const nearestProjectConfigDir = await findNearestProjectConfigDir(ctx.cwd, ctx.repoRoot);
|
|
359
|
+
if (nearestProjectConfigDir) {
|
|
360
|
+
const projectRulesFile = path.join(nearestProjectConfigDir.dir, "RULES.md");
|
|
361
|
+
const projectRule = await loadStickyRulesFile(projectRulesFile, "project");
|
|
362
|
+
if (projectRule) items.push(projectRule);
|
|
363
|
+
}
|
|
364
|
+
|
|
349
365
|
return { items, warnings };
|
|
350
366
|
}
|
|
351
367
|
|
|
368
|
+
/**
|
|
369
|
+
* Read a top-level `RULES.md` and synthesize an always-apply rule.
|
|
370
|
+
* Returns null when the file is absent or empty so callers can short-circuit.
|
|
371
|
+
*/
|
|
372
|
+
async function loadStickyRulesFile(filePath: string, level: "user" | "project"): Promise<Rule | null> {
|
|
373
|
+
const content = await readFile(filePath);
|
|
374
|
+
if (!content) return null;
|
|
375
|
+
const source = createSourceMeta(PROVIDER_ID, filePath, level);
|
|
376
|
+
const rule = buildRuleFromMarkdown("RULES.md", content, filePath, source, { ruleName: "RULES" });
|
|
377
|
+
// Force alwaysApply regardless of frontmatter — the whole point of RULES.md
|
|
378
|
+
// is to be reattached every turn.
|
|
379
|
+
return { ...rule, alwaysApply: true };
|
|
380
|
+
}
|
|
381
|
+
|
|
352
382
|
registerProvider<Rule>(ruleCapability.id, {
|
|
353
383
|
id: PROVIDER_ID,
|
|
354
384
|
displayName: DISPLAY_NAME,
|
|
@@ -76,6 +76,7 @@ import {
|
|
|
76
76
|
} from "@oh-my-pi/pi-ai";
|
|
77
77
|
import { MacOSPowerAssertion } from "@oh-my-pi/pi-natives";
|
|
78
78
|
import {
|
|
79
|
+
extractRetryHint,
|
|
79
80
|
getAgentDbPath,
|
|
80
81
|
isEnoent,
|
|
81
82
|
isUnexpectedSocketCloseMessage,
|
|
@@ -6949,6 +6950,11 @@ export class AgentSession {
|
|
|
6949
6950
|
}
|
|
6950
6951
|
}
|
|
6951
6952
|
|
|
6953
|
+
const retryHintMs = extractRetryHint(undefined, errorMessage);
|
|
6954
|
+
if (retryHintMs !== undefined) {
|
|
6955
|
+
return retryHintMs;
|
|
6956
|
+
}
|
|
6957
|
+
|
|
6952
6958
|
const resetMsMatch = /x-ratelimit-reset-ms\s*[:=]\s*(\d+)/i.exec(errorMessage);
|
|
6953
6959
|
if (resetMsMatch) {
|
|
6954
6960
|
const resetMs = Number(resetMsMatch[1]);
|
|
@@ -540,24 +540,24 @@ async function withSoftTimeout<T>(promise: Promise<T>, timeoutMs: number, label:
|
|
|
540
540
|
}
|
|
541
541
|
}
|
|
542
542
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
];
|
|
543
|
+
const STEALTH_PATCH_SCRIPTS = [
|
|
544
|
+
stealthTamperingScript,
|
|
545
|
+
stealthActivityScript,
|
|
546
|
+
stealthHairlineScript,
|
|
547
|
+
stealthBotdScript,
|
|
548
|
+
stealthIframeScript,
|
|
549
|
+
stealthWebglScript,
|
|
550
|
+
stealthScreenScript,
|
|
551
|
+
stealthFontsScript,
|
|
552
|
+
stealthAudioScript,
|
|
553
|
+
stealthLocaleScript,
|
|
554
|
+
stealthPluginsScript,
|
|
555
|
+
stealthHardwareScript,
|
|
556
|
+
stealthCodecsScript,
|
|
557
|
+
stealthWorkerScript,
|
|
558
|
+
];
|
|
560
559
|
|
|
560
|
+
function buildStealthInjectionScript(scripts: readonly string[] = STEALTH_PATCH_SCRIPTS): string {
|
|
561
561
|
const joint = scripts
|
|
562
562
|
.map(
|
|
563
563
|
script => `
|
|
@@ -568,43 +568,55 @@ async function injectStealthScripts(page: Page): Promise<void> {
|
|
|
568
568
|
)
|
|
569
569
|
.join(";\n");
|
|
570
570
|
|
|
571
|
-
|
|
571
|
+
return `(() => {
|
|
572
572
|
// Native function cache - captured before any tampering
|
|
573
573
|
const iframe = document.createElement("iframe");
|
|
574
574
|
iframe.style.display = "none";
|
|
575
|
-
document.head.
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
575
|
+
const container = document.head ?? document.documentElement;
|
|
576
|
+
if (!container) return;
|
|
577
|
+
container.appendChild(iframe);
|
|
578
|
+
try {
|
|
579
|
+
const nativeWindow = iframe.contentWindow;
|
|
580
|
+
if (!nativeWindow) return;
|
|
581
|
+
|
|
582
|
+
// Cache pristine native functions
|
|
583
|
+
const Function_toString = nativeWindow.Function.prototype.toString;
|
|
584
|
+
const Object_getOwnPropertyDescriptor = nativeWindow.Object.getOwnPropertyDescriptor;
|
|
585
|
+
const Object_getOwnPropertyDescriptors = nativeWindow.Object.getOwnPropertyDescriptors;
|
|
586
|
+
const Object_getPrototypeOf = nativeWindow.Object.getPrototypeOf;
|
|
587
|
+
const Object_defineProperty = nativeWindow.Object.defineProperty;
|
|
588
|
+
const Object_getOwnPropertyDescriptorOriginal = nativeWindow.Object.getOwnPropertyDescriptor;
|
|
589
|
+
const Object_create = nativeWindow.Object.create;
|
|
590
|
+
const Object_keys = nativeWindow.Object.keys;
|
|
591
|
+
const Object_getOwnPropertyNames = nativeWindow.Object.getOwnPropertyNames;
|
|
592
|
+
const Object_entries = nativeWindow.Object.entries;
|
|
593
|
+
const Object_setPrototypeOf = nativeWindow.Object.setPrototypeOf;
|
|
594
|
+
const Object_assign = nativeWindow.Object.assign;
|
|
595
|
+
const Window_setTimeout = nativeWindow.setTimeout;
|
|
596
|
+
const Math_random = nativeWindow.Math.random;
|
|
597
|
+
const Math_floor = nativeWindow.Math.floor;
|
|
598
|
+
const Math_max = nativeWindow.Math.max;
|
|
599
|
+
const Math_min = nativeWindow.Math.min;
|
|
600
|
+
const Window_Event = nativeWindow.Event;
|
|
601
|
+
const Promise_resolve = nativeWindow.Promise.resolve.bind(nativeWindow.Promise);
|
|
602
|
+
const Window_Blob = nativeWindow.Blob;
|
|
603
|
+
const Window_Proxy = nativeWindow.Proxy;
|
|
604
|
+
const Intl_DateTimeFormat = nativeWindow.Intl.DateTimeFormat;
|
|
605
|
+
const Date_constructor = nativeWindow.Date;
|
|
606
|
+
|
|
607
|
+
${joint}
|
|
608
|
+
} finally {
|
|
609
|
+
if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
|
|
610
|
+
}})();`;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
async function injectStealthScripts(page: Page): Promise<void> {
|
|
614
|
+
await page.evaluateOnNewDocument(buildStealthInjectionScript());
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/** Builds the browser-page stealth bootstrap source for regression tests. */
|
|
618
|
+
export function buildStealthInjectionScriptForTest(scripts: readonly string[] = STEALTH_PATCH_SCRIPTS): string {
|
|
619
|
+
return buildStealthInjectionScript(scripts);
|
|
608
620
|
}
|
|
609
621
|
|
|
610
622
|
/** Apply stealth patches + UA override to a headless page. Idempotent within a tab. */
|