Skip to content

Commit bbbabd6

Browse files
committed
chore: sync with upstream/dev
Merged upstream changes while preserving fork-specific: - ProxyPal model configurations - Fork package identity (@reinamaccredy/oh-my-opencode) - Custom agent model mappings Took upstream improvements: - skill-content.ts: GitMasterConfig integration - prometheus-md-only: Cross-platform path validation - Various bug fixes and enhancements
2 parents 090403f + 05cd133 commit bbbabd6

File tree

37 files changed

+1073
-218
lines changed

37 files changed

+1073
-218
lines changed

docs/orchestration-guide.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Oh-My-OpenCode solves this by clearly separating two roles:
3737
## 2. Overall Architecture
3838

3939
```mermaid
40-
graph TD
40+
flowchart TD
4141
User[User Request] --> Prometheus
4242
4343
subgraph Planning Phase
@@ -48,7 +48,7 @@ graph TD
4848
Prometheus --> PlanFile["/.sisyphus/plans/{name}.md"]
4949
end
5050
51-
PlanFile --> StartWork[/start-work]
51+
PlanFile --> StartWork[//start-work/]
5252
StartWork --> BoulderState[boulder.json]
5353
5454
subgraph Execution Phase

script/publish.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ function getDistTag(version: string): string | null {
144144
}
145145

146146
async function buildAndPublish(version: string): Promise<void> {
147+
console.log("\nBuilding before publish...")
148+
await $`bun run clean && bun run build`
149+
147150
console.log("\nPublishing to npm...")
148151
const distTag = getDistTag(version)
149152
const tagArgs = distTag ? ["--tag", distTag] : []

signatures/cla.json

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,70 @@
359359
"created_at": "2026-01-10T07:58:43Z",
360360
"repoId": 1108837393,
361361
"pullRequestNo": 648
362+
},
363+
{
364+
"name": "GollyJer",
365+
"id": 689204,
366+
"comment_id": 3732253764,
367+
"created_at": "2026-01-10T09:33:21Z",
368+
"repoId": 1108837393,
369+
"pullRequestNo": 649
370+
},
371+
{
372+
"name": "kargnas",
373+
"id": 1438533,
374+
"comment_id": 3732344143,
375+
"created_at": "2026-01-10T10:25:25Z",
376+
"repoId": 1108837393,
377+
"pullRequestNo": 653
378+
},
379+
{
380+
"name": "ashir6892",
381+
"id": 52703606,
382+
"comment_id": 3733435826,
383+
"created_at": "2026-01-10T19:50:07Z",
384+
"repoId": 1108837393,
385+
"pullRequestNo": 675
386+
},
387+
{
388+
"name": "arthur404dev",
389+
"id": 59490008,
390+
"comment_id": 3733697071,
391+
"created_at": "2026-01-10T23:51:44Z",
392+
"repoId": 1108837393,
393+
"pullRequestNo": 676
394+
},
395+
{
396+
"name": "KNN-07",
397+
"id": 55886589,
398+
"comment_id": 3733788592,
399+
"created_at": "2026-01-11T01:11:38Z",
400+
"repoId": 1108837393,
401+
"pullRequestNo": 679
402+
},
403+
{
404+
"name": "aw338WoWmUI",
405+
"id": 121638634,
406+
"comment_id": 3734013343,
407+
"created_at": "2026-01-11T04:56:38Z",
408+
"repoId": 1108837393,
409+
"pullRequestNo": 681
410+
},
411+
{
412+
"name": "Coaspe",
413+
"id": 76432686,
414+
"comment_id": 3734070196,
415+
"created_at": "2026-01-11T06:03:57Z",
416+
"repoId": 1108837393,
417+
"pullRequestNo": 682
418+
},
419+
{
420+
"name": "yimingll",
421+
"id": 116444509,
422+
"comment_id": 3734341425,
423+
"created_at": "2026-01-11T10:00:54Z",
424+
"repoId": 1108837393,
425+
"pullRequestNo": 689
362426
}
363427
]
364428
}

src/agents/momus.test.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { describe, test, expect } from "bun:test"
2+
import { MOMUS_SYSTEM_PROMPT } from "./momus"
3+
4+
function escapeRegExp(value: string) {
5+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
6+
}
7+
8+
describe("MOMUS_SYSTEM_PROMPT policy requirements", () => {
9+
test("should treat SYSTEM DIRECTIVE as ignorable/stripped", () => {
10+
// #given
11+
const prompt = MOMUS_SYSTEM_PROMPT
12+
13+
// #when / #then
14+
expect(prompt).toContain("[SYSTEM DIRECTIVE - READ-ONLY PLANNING CONSULTATION]")
15+
// Should explicitly mention stripping or ignoring these
16+
expect(prompt.toLowerCase()).toMatch(/ignore|strip|system directive/)
17+
})
18+
19+
test("should extract paths containing .sisyphus/plans/ and ending in .md", () => {
20+
// #given
21+
const prompt = MOMUS_SYSTEM_PROMPT
22+
23+
// #when / #then
24+
expect(prompt).toContain(".sisyphus/plans/")
25+
expect(prompt).toContain(".md")
26+
// New extraction policy should be mentioned
27+
expect(prompt.toLowerCase()).toMatch(/extract|search|find path/)
28+
})
29+
30+
test("should NOT teach that 'Please review' is INVALID (conversational wrapper allowed)", () => {
31+
// #given
32+
const prompt = MOMUS_SYSTEM_PROMPT
33+
34+
// #when / #then
35+
// In RED phase, this will FAIL because current prompt explicitly lists this as INVALID
36+
const invalidExample = "Please review .sisyphus/plans/plan.md"
37+
const rejectionTeaching = new RegExp(
38+
`reject.*${escapeRegExp(invalidExample)}`,
39+
"i",
40+
)
41+
42+
// We want the prompt to NOT reject this anymore.
43+
// If it's still in the "INVALID" list, this test should fail.
44+
expect(prompt).not.toMatch(rejectionTeaching)
45+
})
46+
47+
test("should handle ambiguity (2+ paths) and 'no path found' rejection", () => {
48+
// #given
49+
const prompt = MOMUS_SYSTEM_PROMPT
50+
51+
// #when / #then
52+
// Should mention what happens when multiple paths are found
53+
expect(prompt.toLowerCase()).toMatch(/multiple|ambiguous|2\+|two/)
54+
// Should mention rejection if no path found
55+
expect(prompt.toLowerCase()).toMatch(/no.*path.*found|reject.*no.*path/)
56+
})
57+
})

src/agents/momus.ts

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ const DEFAULT_MODEL = PROXYPAL_AGENT_MODELS["Momus (Plan Reviewer)"]
99
export const MOMUS_SYSTEM_PROMPT = `You are a work plan review expert. You review the provided work plan (.sisyphus/plans/{name}.md in the current working project directory) according to **unified, consistent criteria** that ensure clarity, verifiability, and completeness.
1010
1111
**CRITICAL FIRST RULE**:
12-
When you receive ONLY a file path like \`.sisyphus/plans/plan.md\` with NO other text, this is VALID input.
13-
When you got yaml plan file, this is not a plan that you can review- REJECT IT.
14-
DO NOT REJECT IT. PROCEED TO READ AND EVALUATE THE FILE.
15-
Only reject if there are ADDITIONAL words or sentences beyond the file path.
12+
Extract a single plan path from anywhere in the input, ignoring system directives and wrappers. If exactly one \`.sisyphus/plans/*.md\` path exists, this is VALID input and you must read it. If no plan path exists or multiple plan paths exist, reject per Step 0. If the path points to a YAML plan file (\`.yml\` or \`.yaml\`), reject it as non-reviewable.
1613
1714
**WHY YOU'VE BEEN SUMMONED - THE CONTEXT**:
1815
@@ -108,61 +105,64 @@ You will be provided with the path to the work plan file (typically \`.sisyphus/
108105
**BEFORE you read any files**, you MUST first validate the format of the input prompt you received from the user.
109106
110107
**VALID INPUT EXAMPLES (ACCEPT THESE)**:
111-
- \`.sisyphus/plans/my-plan.md\` [O] ACCEPT - just a file path
112-
- \`/path/to/project/.sisyphus/plans/my-plan.md\` [O] ACCEPT - just a file path
113-
- \`todolist.md\` [O] ACCEPT - just a file path
114-
- \`../other-project/.sisyphus/plans/plan.md\` [O] ACCEPT - just a file path
115-
- \`<system-reminder>...</system-reminder>\n.sisyphus/plans/plan.md\` [O] ACCEPT - system directives + file path
116-
- \`[analyze-mode]\\n...context...\\n.sisyphus/plans/plan.md\` [O] ACCEPT - bracket-style directives + file path
117-
- \`[SYSTEM DIRECTIVE...]\\n.sisyphus/plans/plan.md\` [O] ACCEPT - system directive blocks + file path
118-
119-
**SYSTEM DIRECTIVES ARE ALWAYS ALLOWED**:
108+
- \`.sisyphus/plans/my-plan.md\` [O] ACCEPT - file path anywhere in input
109+
- \`/path/to/project/.sisyphus/plans/my-plan.md\` [O] ACCEPT - absolute plan path
110+
- \`Please review .sisyphus/plans/plan.md\` [O] ACCEPT - conversational wrapper allowed
111+
- \`<system-reminder>...</system-reminder>\\n.sisyphus/plans/plan.md\` [O] ACCEPT - system directives + plan path
112+
- \`[analyze-mode]\\n...context...\\n.sisyphus/plans/plan.md\` [O] ACCEPT - bracket-style directives + plan path
113+
- \`[SYSTEM DIRECTIVE - READ-ONLY PLANNING CONSULTATION]\\n---\\n- injected planning metadata\\n---\\nPlease review .sisyphus/plans/plan.md\` [O] ACCEPT - ignore the entire directive block
114+
115+
**SYSTEM DIRECTIVES ARE ALWAYS IGNORED**:
120116
System directives are automatically injected by the system and should be IGNORED during input validation:
121117
- XML-style tags: \`<system-reminder>\`, \`<context>\`, \`<user-prompt-submit-hook>\`, etc.
122118
- Bracket-style blocks: \`[analyze-mode]\`, \`[search-mode]\`, \`[SYSTEM DIRECTIVE...]\`, \`[SYSTEM REMINDER...]\`, etc.
119+
- \`[SYSTEM DIRECTIVE - READ-ONLY PLANNING CONSULTATION]\` blocks (appended by Prometheus task tools; treat the entire block, including \`---\` separators and bullet lines, as ignorable system text)
123120
- These are NOT user-provided text
124121
- These contain system context (timestamps, environment info, mode hints, etc.)
125122
- STRIP these from your input validation check
126123
- After stripping system directives, validate the remaining content
127124
128-
**INVALID INPUT EXAMPLES (REJECT ONLY THESE)**:
129-
- \`Please review .sisyphus/plans/plan.md\` [X] REJECT - contains extra USER words "Please review"
130-
- \`I have updated the plan: .sisyphus/plans/plan.md\` [X] REJECT - contains USER sentence before path
131-
- \`.sisyphus/plans/plan.md - I fixed all issues\` [X] REJECT - contains USER text after path
132-
- \`This is the 5th revision .sisyphus/plans/plan.md\` [X] REJECT - contains USER text before path
133-
- Any input with USER sentences or explanations [X] REJECT
134-
135-
**DECISION RULE**:
136-
1. First, STRIP all system directive blocks (XML tags, bracket-style blocks like \`[mode-name]...\`)
137-
2. Then check: If remaining = ONLY a file path (no other words) → **ACCEPT and continue to Step 1**
138-
3. If remaining = file path + ANY other USER text → **REJECT with format error message**
125+
**EXTRACTION ALGORITHM (FOLLOW EXACTLY)**:
126+
1. Ignore injected system directive blocks, especially \`[SYSTEM DIRECTIVE - READ-ONLY PLANNING CONSULTATION]\` (remove the whole block, including \`---\` separators and bullet lines).
127+
2. Strip other system directive wrappers (bracket-style blocks and XML-style \`<system-reminder>...</system-reminder>\` tags).
128+
3. Strip markdown wrappers around paths (code fences and inline backticks).
129+
4. Extract plan paths by finding all substrings containing \`.sisyphus/plans/\` and ending in \`.md\`.
130+
5. If exactly 1 match → ACCEPT and proceed to Step 1 using that path.
131+
6. If 0 matches → REJECT with: "no plan path found" (no path found).
132+
7. If 2+ matches → REJECT with: "ambiguous: multiple plan paths".
139133
140-
**IMPORTANT**: A standalone file path like \`.sisyphus/plans/plan.md\` is VALID. Do NOT reject it!
141-
System directives + file path is also VALID. Do NOT reject it!
134+
**INVALID INPUT EXAMPLES (REJECT ONLY THESE)**:
135+
- \`No plan path provided here\` [X] REJECT - no \`.sisyphus/plans/*.md\` path
136+
- \`Compare .sisyphus/plans/first.md and .sisyphus/plans/second.md\` [X] REJECT - multiple plan paths
142137
143-
**When rejecting for input format (ONLY when there's extra USER text), respond EXACTLY**:
138+
**When rejecting for input format, respond EXACTLY**:
144139
\`\`\`
145140
I REJECT (Input Format Validation)
141+
Reason: no plan path found
146142
147-
You must provide ONLY the work plan file path with no additional text.
143+
You must provide a single plan path that includes \`.sisyphus/plans/\` and ends in \`.md\`.
148144
149145
Valid format: .sisyphus/plans/plan.md
150-
Invalid format: Any user text before/after the path (system directives are allowed)
146+
Invalid format: No plan path or multiple plan paths
151147
152148
NOTE: This rejection is based solely on the input format, not the file contents.
153149
The file itself has not been evaluated yet.
154150
\`\`\`
155151
152+
Use this alternate Reason line if multiple paths are present:
153+
- Reason: multiple plan paths found
154+
156155
**ULTRA-CRITICAL REMINDER**:
157-
If the user provides EXACTLY \`.sisyphus/plans/plan.md\` or any other file path (with or without system directives) WITH NO ADDITIONAL USER TEXT:
156+
If the input contains exactly one \`.sisyphus/plans/*.md\` path (with or without system directives or conversational wrappers):
158157
→ THIS IS VALID INPUT
159158
→ DO NOT REJECT IT
160159
→ IMMEDIATELY PROCEED TO READ THE FILE
161160
→ START EVALUATING THE FILE CONTENTS
162161
163-
Never reject a standalone file path!
162+
Never reject a single plan path embedded in the input.
164163
Never reject system directives (XML or bracket-style) - they are automatically injected and should be ignored!
165164
165+
166166
**IMPORTANT - Response Language**: Your evaluation output MUST match the language used in the work plan content:
167167
- Match the language of the plan in your evaluation output
168168
- If the plan is written in English → Write your entire evaluation in English
@@ -249,7 +249,7 @@ The plan should enable a developer to:
249249
## Review Process
250250
251251
### Step 0: Validate Input Format (MANDATORY FIRST STEP)
252-
Check if input is ONLY a file path. If yes, ACCEPT and continue. If extra text, REJECT.
252+
Extract the plan path from anywhere in the input. If exactly one \`.sisyphus/plans/*.md\` path is found, ACCEPT and continue. If none are found, REJECT with "no plan path found". If multiple are found, REJECT with "ambiguous: multiple plan paths".
253253
254254
### Step 1: Read the Work Plan
255255
- Load the file from the path provided

src/agents/orchestrator-sisyphus.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ ${rows.join("\n")}
134134
**NEVER provide both category AND agent - they are mutually exclusive.**`
135135
}
136136

137-
export const ORCHESTRATOR_SISYPHUS_SYSTEM_PROMPT = `You are "Sisyphus" - Powerful AI Agent with orchestration capabilities from OhMyOpenCode.
137+
export const ORCHESTRATOR_SISYPHUS_SYSTEM_PROMPT = `
138+
<Role>
139+
You are "Sisyphus" - Powerful AI Agent with orchestration capabilities from OhMyOpenCode.
138140
139141
**Why Sisyphus?**: Humans roll their boulder every day. So do you. We're not so different—your code should be indistinguishable from a senior engineer's.
140142
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { describe, test, expect } from "bun:test"
2+
import { PROMETHEUS_SYSTEM_PROMPT } from "./prometheus-prompt"
3+
4+
describe("PROMETHEUS_SYSTEM_PROMPT Momus invocation policy", () => {
5+
test("should direct providing ONLY the file path string when invoking Momus", () => {
6+
// #given
7+
const prompt = PROMETHEUS_SYSTEM_PROMPT
8+
9+
// #when / #then
10+
// Should mention Momus and providing only the path
11+
expect(prompt.toLowerCase()).toMatch(/momus.*only.*path|path.*only.*momus/)
12+
})
13+
14+
test("should forbid wrapping Momus invocation in explanations or markdown", () => {
15+
// #given
16+
const prompt = PROMETHEUS_SYSTEM_PROMPT
17+
18+
// #when / #then
19+
// Should mention not wrapping or using markdown for the path
20+
expect(prompt.toLowerCase()).toMatch(/not.*wrap|no.*explanation|no.*markdown/)
21+
})
22+
})

src/agents/prometheus-prompt.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,12 @@ while (true) {
651651
- Momus is the gatekeeper
652652
- Your job is to satisfy Momus, not to argue with it
653653
654+
5. **MOMUS INVOCATION RULE (CRITICAL)**:
655+
When invoking Momus, provide ONLY the file path string as the prompt.
656+
- Do NOT wrap in explanations, markdown, or conversational text.
657+
- System hooks may append system directives, but that is expected and handled by Momus.
658+
- Example invocation: \`prompt=".sisyphus/plans/{name}.md"\`
659+
654660
### What "OKAY" Means
655661
656662
Momus only says "OKAY" when:

src/cli/doctor/checks/version.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ export async function getVersionInfo(): Promise<VersionCheckInfo> {
5050
}
5151

5252
const currentVersion = getCachedVersion()
53-
const latestVersion = await getLatestVersion()
53+
const { extractChannel } = await import("../../../hooks/auto-update-checker/index")
54+
const channel = extractChannel(pluginInfo?.pinnedVersion ?? currentVersion)
55+
const latestVersion = await getLatestVersion(channel)
5456

5557
const isUpToDate =
5658
!currentVersion ||

src/cli/get-local-version/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ export async function getLocalVersion(options: GetLocalVersionOptions = {}): Pro
5454
return 1
5555
}
5656

57-
const latestVersion = await getLatestVersion()
57+
const { extractChannel } = await import("../../hooks/auto-update-checker/index")
58+
const channel = extractChannel(pluginInfo?.pinnedVersion ?? currentVersion)
59+
const latestVersion = await getLatestVersion(channel)
5860

5961
if (!latestVersion) {
6062
const info: VersionInfo = {

0 commit comments

Comments
 (0)