Skip to content

Conversation

@JohnC0de
Copy link

@JohnC0de JohnC0de commented Jan 4, 2026

Summary

This PR enhances Sisyphus's parallelism behavior during implementation (not just exploration) and fixes several bugs in the skill loader and Windows compatibility.

Motivation

Observed that agents effectively parallelize during exploration (firing multiple explore/librarian agents) but fall into sequential mode during implementation. This PR addresses the gap by:

  1. Teaching parallelism during implementation - Updated prompts to explicitly guide delegating UI, docs, and research work to background agents while working on core logic
  2. Adding periodic reminders - Instead of one-time reminder, now reminds every N direct tool calls to encourage continued agent usage
  3. Fixing skill loader edge cases - Malformed YAML and scope propagation issues
  4. Improving Windows compatibility - Path normalization and env handling

Changes

Bug Fixes

1. fix(skill-loader): skip skills with malformed frontmatter

  • Problem: Skills with invalid YAML frontmatter loaded with undefined metadata, causing unpredictable behavior
  • Solution: Check parseError from frontmatter parser, return null to skip broken skills
  • Files: loader.ts, loader.test.ts

2. fix(skill-loader): propagate scope parameter through discovery

  • Problem: discoverSkillsInDirAsync hardcoded "opencode-project" scope, ignoring actual context
  • Solution: Accept and propagate scope parameter through the discovery chain
  • Files: async-loader.ts, discover-worker.ts

3. fix: improve Windows compatibility for paths and env handling

  • Problem: Backslash paths break .github/instructions matching; POSIX XDG paths fail on Windows; literal "undefined" strings in env
  • Solution:
    • Normalize paths to forward slashes in rules-injector
    • Preserve POSIX-style XDG_CONFIG_HOME on Windows
    • Filter "undefined" string values in env-cleaner
  • Files: finder.ts, opencode-config-dir.ts, env-cleaner.ts

Features

4. feat(agent-usage-reminder): add periodic reminders during implementation

  • Problem: One-time reminder wasn't enough; developers forgot to parallelize during coding
  • Solution:
    • Track directToolCallsSinceAgent counter
    • Show IMPLEMENTATION_PHASE_REMINDER every 5 direct tool calls
    • Reset counter when agent is used
  • Files: constants.ts, index.ts, types.ts

5. feat(agents): enhance parallelism guidance throughout agent prompts

  • Problem: Prompts emphasized exploration parallelism but not implementation parallelism
  • Solution: Coordinated update across multiple prompt injection points:
    • sisyphus.ts: New "Parallel Implementation" section with task type table and concrete examples
    • keyword-detector: Expanded "AGENT DEPLOYMENT" section with phase-specific guidance
    • todo-continuation-enforcer: Rewritten to scan for delegatable TODOs and fire multiple agents
  • Files: sisyphus.ts, keyword-detector/constants.ts, todo-continuation-enforcer.ts

Testing

  • All 607 tests pass (bun test)
  • Type checking passes (bun run typecheck)

Commits (5 atomic commits)

  1. fix(skill-loader): skip skills with malformed frontmatter
  2. fix(skill-loader): propagate scope parameter through discovery
  3. fix: improve Windows compatibility for paths and env handling
  4. feat(agent-usage-reminder): add periodic reminders during implementation
  5. feat(agents): enhance parallelism guidance throughout agent prompts

Summary by cubic

Improves implementation-phase parallelism with stronger prompt guidance and periodic reminders, and fixes skill loader robustness and Windows compatibility.

  • New Features

    • Added implementation-phase parallelism guidance across prompts (Sisyphus, keyword detector) with examples and clear rules.
    • Periodic reminders during coding: show after 5 direct tool calls; reset when an agent is used.
    • TODO continuation now pushes parallel delegation and collecting background outputs before verification.
  • Bug Fixes

    • Skip skills with malformed YAML frontmatter to avoid loading broken skills.
    • Propagate skill scope in async discovery (no more hardcoded "opencode-project").
    • Improve Windows support: normalize paths for .github/instructions matching, preserve POSIX XDG_CONFIG_HOME, and filter literal "undefined" env vars.

Written for commit e4e6c22. Summary will update on new commits.

Previously, skills with invalid YAML frontmatter would still be loaded
with undefined metadata, causing unpredictable behavior. Now the loader
properly checks for parseError and returns null, skipping broken skills.

- Add parseError check in loadSkillFromPath() and loadSkillFromPathAsync()
- Return empty string on load() if frontmatter is invalid
- Update test to expect undefined for malformed skill instead of fallback
The discoverSkillsInDirAsync function was hardcoding 'opencode-project'
as the scope for all discovered skills, ignoring the actual scope
context. This fix:

- Add scope parameter to discoverSkillsInDirAsync() with default value
- Propagate scope from worker input to discovery function
- Ensure skills inherit correct scope from their source directory
Address cross-platform issues that cause problems on Windows:

- rules-injector/finder: Normalize backslash paths to forward slashes
  for consistent .github/instructions matching across platforms

- opencode-config-dir: Preserve POSIX-style XDG_CONFIG_HOME paths on
  Windows (common in CI/test environments using WSL-style paths)

- env-cleaner: Filter out literal 'undefined' string values in env
  vars, not just undefined type (occurs when stringified incorrectly)
The original reminder only fired once when agents hadn't been used.
This enhancement adds recurring reminders during the implementation
phase to encourage continued parallelism:

- Track directToolCallsSinceAgent counter in session state
- Show IMPLEMENTATION_PHASE_REMINDER every 5 direct tool calls
- Reset counter when agent is used (background_task, call_omo_agent)
- New reminder focuses on delegating UI/docs work during coding

This addresses the pattern where developers use agents for exploration
but forget to parallelize during implementation.
Strengthen the message that agents should be used during ALL phases,
not just exploration. This is a coordinated update across multiple
prompt injection points:

sisyphus.ts:
- Add 'Parallel Implementation' section with task type table
- Include concrete example showing UI + Backend + Docs parallelism
- Add 5 implementation parallelism rules

keyword-detector (ultrawork mode):
- Update TODO rules to mention 'strategic parallelism'
- Expand AGENT DEPLOYMENT section with phase-specific examples
- Add code example showing exploration AND implementation parallelism

todo-continuation-enforcer:
- Rewrite continuation prompt to scan for delegatable TODOs
- Add explicit instructions to fire multiple background agents
- Focus on verification via background_output before completion

The goal is consistent reinforcement: 'Don't stop parallelizing just
because you're implementing!'
@github-actions
Copy link
Contributor

github-actions bot commented Jan 4, 2026

Thank you for your contribution! Before we can merge this PR, we need you to sign our Contributor License Agreement (CLA).

To sign the CLA, please comment on this PR with:

I have read the CLA Document and I hereby sign the CLA

This is a one-time requirement. Once signed, all your future contributions will be automatically accepted.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@greptile-apps
Copy link

greptile-apps bot commented Jan 4, 2026

Greptile Summary

This PR enhances agent parallelism guidance during the implementation phase and fixes several robustness issues in the skill loader and Windows compatibility.

Key Changes:

  • Parallelism guidance: Updated Sisyphus, keyword-detector, and todo-continuation-enforcer prompts to emphasize delegating UI, documentation, and research work to background agents during implementation (not just exploration)
  • Periodic reminders: Added directToolCallsSinceAgent tracking to remind users every 5 direct tool calls to consider parallelization
  • Skill loader robustness: Skills with malformed YAML frontmatter are now skipped entirely instead of loading with undefined metadata
  • Scope propagation: Added scope parameter to discoverSkillsInDirAsync (though the worker implementation has a bug - see comment)
  • Windows compatibility: Path normalization for .github/instructions matching, POSIX XDG_CONFIG_HOME preservation, and filtering of literal "undefined" env values

Issues Found:

  • The scope propagation fix in discover-worker.ts only uses scopes[0] for all directories, which defeats the purpose when multiple directories with different scopes are passed

Confidence Score: 4/5

  • Generally safe to merge - mostly prompt/documentation changes with one logic bug in scope propagation that may not be actively triggered
  • Score of 4: The majority of changes are prompt content updates which pose no runtime risk. Bug fixes for malformed YAML handling and Windows compatibility are well-implemented. However, the scope propagation fix has a logic bug where only the first scope is applied to all directories. This is mitigated by the fact that discoverAllSkillsBlocking appears to only be used in tests currently.
  • src/features/opencode-skill-loader/discover-worker.ts - scope propagation bug

Important Files Changed

Filename Overview
src/agents/sisyphus.ts Added "Parallel Implementation" section with task type table and examples showing how to delegate UI/docs/research work to background agents during implementation phase. Prompt content changes only.
src/features/opencode-skill-loader/discover-worker.ts Worker now reads scope from input.scopes[0] but applies same scope to ALL directories. Bug: if dirs and scopes arrays have 1:1 mapping expectation, only first scope is used.
src/features/opencode-skill-loader/loader.ts Added parseError check to skip skills with malformed YAML frontmatter. Both sync and async versions updated to return null/empty content on parse errors.
src/features/skill-mcp-manager/env-cleaner.ts Added filter for literal "undefined" string values in environment variables, preventing MCP servers from receiving invalid env vars.
src/hooks/agent-usage-reminder/index.ts Implemented periodic reminder system: tracks directToolCallsSinceAgent counter, shows IMPLEMENTATION_PHASE_REMINDER every 5 direct tool calls after initial agent use.
src/shared/opencode-config-dir.ts Added POSIX-style XDG_CONFIG_HOME preservation on Windows - uses posix.join when XDG path starts with "/" and has no backslashes (common in tests/CI).

Sequence Diagram

sequenceDiagram
    participant User
    participant Sisyphus as Sisyphus Agent
    participant Hook as agent-usage-reminder Hook
    participant BgAgents as Background Agents
    participant Worker as discover-worker

    Note over User,Worker: Implementation Phase Parallelism Flow
    
    User->>Sisyphus: Request implementation task
    Sisyphus->>Sisyphus: Create TODO list
    
    loop For each TODO
        Sisyphus->>BgAgents: background_task(frontend-ui-ux-engineer)
        Sisyphus->>BgAgents: background_task(document-writer)
        Sisyphus->>Sisyphus: Work on core logic directly
        
        alt Direct tool call (Grep, Glob, etc)
            Hook->>Hook: Increment directToolCallsSinceAgent
            alt Count >= 5
                Hook-->>Sisyphus: IMPLEMENTATION_PHASE_REMINDER
                Hook->>Hook: Reset counter
            end
        else Agent tool call
            Hook->>Hook: Reset directToolCallsSinceAgent to 0
        end
        
        Sisyphus->>BgAgents: background_output(task_id)
        BgAgents-->>Sisyphus: Results
        Sisyphus->>Sisyphus: Mark TODO complete
    end

    Note over Worker: Skill Discovery with Scope
    Worker->>Worker: discoverSkillsInDirAsync(dir, scope)
    Worker-->>Worker: Return skills with correct scope
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Comments (1)

  1. src/features/opencode-skill-loader/discover-worker.ts, line 34-36 (link)

    logic: Using input.scopes[0] applies the same scope to all directories. If the caller passes multiple directories with corresponding scopes (e.g., dirs: [projectDir, userDir], scopes: ["project", "user"]), all skills will incorrectly receive the first scope.

    Consider iterating with index to apply the correct scope per directory:

13 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 13 files

Confidence score: 3/5

  • Scope handling in src/features/opencode-skill-loader/discover-worker.ts applies only scopes[0], so directories tied to other scopes will execute with the wrong permissions and likely degrade feature isolation.
  • Persisted state created before this PR will load with undefined counters in src/hooks/agent-usage-reminder/index.ts, producing NaN increments and breaking reminder logic for existing users.
  • The claimed Windows POSIX preservation in src/shared/opencode-config-dir.ts never executes because the early return prevents hitting that branch, so Windows paths still normalize unexpectedly.
  • Pay close attention to src/features/opencode-skill-loader/discover-worker.ts, src/hooks/agent-usage-reminder/index.ts, and src/shared/opencode-config-dir.ts - they carry the identified regressions.
Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/features/opencode-skill-loader/discover-worker.ts">

<violation number="1" location="src/features/opencode-skill-loader/discover-worker.ts:34">
P1: Using only `scopes[0]` applies the same scope to all directories, ignoring the parallel array relationship. Each directory should use its corresponding scope from the array.</violation>
</file>

<file name="src/hooks/agent-usage-reminder/index.ts">

<violation number="1" location="src/hooks/agent-usage-reminder/index.ts:46">
P1: Missing backward compatibility for new state fields. When loading persisted state created before this PR, `lastAgentUseAt` and `directToolCallsSinceAgent` will be `undefined`. This causes `undefined++` to produce `NaN`, and the periodic reminder condition `NaN &gt;= N` will always be `false`, breaking the feature for existing users. Provide defaults for the new fields when loading persisted state.</violation>
</file>

<file name="src/shared/opencode-config-dir.ts">

<violation number="1" location="src/shared/opencode-config-dir.ts:72">
P1: This POSIX path preservation logic is unreachable on Windows due to the early return at line 63. The comment says &quot;preserve it even on Windows&quot; but this code only executes on non-Windows platforms where `path.join` and `path.posix.join` are already equivalent. Consider moving this logic inside the Windows block or restructuring to check before the platform-specific early return.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment on lines +34 to +37
const scope = input.scopes[0] ?? "opencode-project"
const results = await Promise.all(
input.dirs.map((dir) => discoverSkillsInDirAsync(dir, scope))
)
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Using only scopes[0] applies the same scope to all directories, ignoring the parallel array relationship. Each directory should use its corresponding scope from the array.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/features/opencode-skill-loader/discover-worker.ts, line 34:

<comment>Using only `scopes[0]` applies the same scope to all directories, ignoring the parallel array relationship. Each directory should use its corresponding scope from the array.</comment>

<file context>
@@ -31,9 +31,10 @@ parentPort.once(&quot;message&quot;, (data: { port: MessagePort }) =&gt; {
-      const results = await Promise.all(
-        input.dirs.map(dir =&gt; discoverSkillsInDirAsync(dir))
-      )
+        const scope = input.scopes[0] ?? &quot;opencode-project&quot;
+        const results = await Promise.all(
+          input.dirs.map((dir) =&gt; discoverSkillsInDirAsync(dir, scope))
</file context>
Suggested change
const scope = input.scopes[0] ?? "opencode-project"
const results = await Promise.all(
input.dirs.map((dir) => discoverSkillsInDirAsync(dir, scope))
)
const results = await Promise.all(
input.dirs.map((dir, index) => discoverSkillsInDirAsync(dir, input.scopes[index] ?? "opencode-project"))
)
Fix with Cubic

agentUsed: false,
reminderCount: 0,
updatedAt: Date.now(),
lastAgentUseAt: 0,
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Missing backward compatibility for new state fields. When loading persisted state created before this PR, lastAgentUseAt and directToolCallsSinceAgent will be undefined. This causes undefined++ to produce NaN, and the periodic reminder condition NaN >= N will always be false, breaking the feature for existing users. Provide defaults for the new fields when loading persisted state.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/hooks/agent-usage-reminder/index.ts, line 46:

<comment>Missing backward compatibility for new state fields. When loading persisted state created before this PR, `lastAgentUseAt` and `directToolCallsSinceAgent` will be `undefined`. This causes `undefined++` to produce `NaN`, and the periodic reminder condition `NaN &gt;= N` will always be `false`, breaking the feature for existing users. Provide defaults for the new fields when loading persisted state.</comment>

<file context>
@@ -37,6 +43,8 @@ export function createAgentUsageReminderHook(_ctx: PluginInput) {
         agentUsed: false,
         reminderCount: 0,
         updatedAt: Date.now(),
+        lastAgentUseAt: 0,
+        directToolCallsSinceAgent: 0,
       };
</file context>
Fix with Cubic

const xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), ".config")

// If user provided a POSIX-style XDG path (common in tests/CI), preserve it even on Windows.
if (process.env.XDG_CONFIG_HOME && xdgConfig.startsWith("/") && !xdgConfig.includes("\\")) {
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: This POSIX path preservation logic is unreachable on Windows due to the early return at line 63. The comment says "preserve it even on Windows" but this code only executes on non-Windows platforms where path.join and path.posix.join are already equivalent. Consider moving this logic inside the Windows block or restructuring to check before the platform-specific early return.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/shared/opencode-config-dir.ts, line 72:

<comment>This POSIX path preservation logic is unreachable on Windows due to the early return at line 63. The comment says &quot;preserve it even on Windows&quot; but this code only executes on non-Windows platforms where `path.join` and `path.posix.join` are already equivalent. Consider moving this logic inside the Windows block or restructuring to check before the platform-specific early return.</comment>

<file context>
@@ -67,6 +67,12 @@ function getCliConfigDir(): string {
   const xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), &quot;.config&quot;)
+
+  // If user provided a POSIX-style XDG path (common in tests/CI), preserve it even on Windows.
+  if (process.env.XDG_CONFIG_HOME &amp;&amp; xdgConfig.startsWith(&quot;/&quot;) &amp;&amp; !xdgConfig.includes(&quot;\\&quot;)) {
+    return posix.join(xdgConfig, &quot;opencode&quot;)
+  }
</file context>
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant