Commit Graph

449 Commits

Author SHA1 Message Date
justsisyphus 959fe81834 fix(test): add nested beforeEach for mainSessionID test isolation
Previous test was setting mainSessionID to 'main-session-123' and the
next test expected undefined. The outer beforeEach wasn't properly
resetting state between tests in the nested describe block.

Adding a nested beforeEach ensures proper test isolation.
2026-01-17 16:47:56 +09:00
justsisyphus 579b70b154 feat(toast): show warning only for fallback models (inherited/system-default)
category-default is the intended behavior for builtin categories,
not a fallback. Only show toast warning when:
- inherited: model from parent session (custom category without model)
- system-default: OpenCode's global default model

User-defined and category-default are both expected behaviors,
so no warning is needed.
2026-01-16 18:47:36 +09:00
justsisyphus cb39218a44 fix(context-injector): add mainSessionID fallback for synthetic part injection
The transform hook was failing to inject synthetic parts because
message.info.sessionID is not always available in the OpenCode SDK.

Fix: Use getMainSessionID() as fallback when message.info.sessionID is undefined.

This ensures keyword-detector and claude-code-hooks content (like ulw/ultrawork)
is properly injected even when the SDK doesn't provide sessionID in message.info.
2026-01-16 18:31:08 +09:00
justsisyphus b439654ec9 test(context-injector): update tests for synthetic part injection
- Remove injectPendingContext test block (~118 lines)
- Remove createContextInjectorHook test block (~50 lines)
- Remove imports of removed functions
- Remove exports of removed functions from index.ts
- Keep createContextInjectorMessagesTransformHook tests (updated in Task 2)
2026-01-16 18:31:08 +09:00
justsisyphus 1695cc22b0 chore(index): remove contextInjector chat.message hook call
- Remove createContextInjectorHook from imports
- Remove contextInjector variable declaration
- Remove contextInjector["chat.message"] call
- Keep contextInjectorMessagesTransform for synthetic part injection
- Update test: prepend → synthetic part insertion verification
2026-01-16 18:31:08 +09:00
justsisyphus 0845e91b43 refactor(context-injector): remove chat.message hook, insert synthetic part in transform
- Remove injectPendingContext function (no longer needed)
- Remove createContextInjectorHook function (chat.message hook removed)
- Change transform hook from prepend to synthetic part insertion
- Follow empty-message-sanitizer pattern (minimal field set)
- synthetic: true flag hides content from UI but passes to model
- Synthetic part inserted BEFORE user text part
2026-01-16 18:31:08 +09:00
justsisyphus 7897650c5c refactor: rename sisyphus_task to delegate_task
- Rename directories: sisyphus-task → delegate-task
- Rename types: SisyphusTaskArgs → DelegateTaskArgs, etc.
- Rename functions: createSisyphusTask → createDelegateTask
- Rename constants: SISYPHUS_TASK_* → DELEGATE_TASK_*
- Update tool name: sisyphus_task → delegate_task
- Update all prompts, docs, and tests
2026-01-16 18:31:08 +09:00
ewjin 815475e383 fix(background-agent): pass model on resume to preserve category config
The resume method was not passing the stored model from the task,
causing Sisyphus-Junior to revert to the default model when resumed.

This fix adds the model to the prompt body in resume(), matching
the existing behavior in launch().

Fixes #826
2026-01-16 18:21:31 +09:00
justsisyphus 97d15e1d68 refactor: remove legacy tools format, use permission only
BREAKING: Requires OpenCode 1.1.1+

- Remove supportsNewPermissionSystem/usesLegacyToolsSystem checks
- Simplify permission-compat.ts to permission format only
- Unify explore/librarian deny lists: write, edit, task, sisyphus_task, call_omo_agent
- Add sisyphus_task to oracle deny list
- Update agent-tool-restrictions.ts with correct per-agent restrictions
- Clean config-handler.ts conditional version checks
- Update tests for simplified API
2026-01-16 17:11:34 +09:00
justsisyphus 227cc52f20 fix(hooks): extract model from assistant messages with flat modelID/providerID
OpenCode API returns different structures for user vs assistant messages:
- User: info.model = { providerID, modelID } (nested)
- Assistant: info.modelID, info.providerID (flat top-level)

Previous code only checked nested format, causing model info loss when
continuation hooks fired after assistant messages.

Files modified:
- todo-continuation-enforcer.ts
- ralph-loop/index.ts
- sisyphus-task/tools.ts
- background-agent/manager.ts

Added test for assistant message model extraction.
2026-01-16 13:54:22 +09:00
justsisyphus a1d7acac17 fix: store session agent in chat.message for prometheus-md-only hook
The prometheus-md-only hook was not enforcing file restrictions because
getSessionAgent() returned undefined - setSessionAgent was only called
in message.updated event which doesn't always provide agent info.

- Add setSessionAgent call in chat.message hook when input.agent exists
- Add session state tests for setSessionAgent/getSessionAgent
- Add clearSessionAgent cleanup to prometheus-md-only tests

This ensures prometheus-md-only hook can reliably identify Prometheus
sessions and enforce .sisyphus/*.md write restrictions.
2026-01-16 11:35:37 +09:00
justsisyphus 133be9d17c refactor(lsp): clean up lsp_servers references and update prompts to use PascalCase
- Remove dead lsp_servers function from tools.ts
- Update utils.ts to reference LspServers (OpenCode built-in)
- Update AGENTS.md: 7 tools → 3 tools
- Update init-deep.ts prompts to use PascalCase OpenCode tools
- Update refactor.ts prompts to use PascalCase OpenCode tools
2026-01-16 11:35:37 +09:00
Nguyen Khac Trung Kien 79774737ba fix(git-master): inject watermark only when enabled instead of overriding defaults
The watermark (commit footer and co-author) was inconsistently applied because:
1. The skill tool didn't receive gitMasterConfig
2. The approach was 'default ON, inject DISABLED override' which LLMs sometimes ignored

This refactors to 'inject only when enabled' approach:
- Remove hardcoded watermark section from base templates
- Dynamically inject section 5.5 based on config values
- Default is still ON (both true when no config)
- When both disabled, no injection occurs (clean prompt)

Also fixes missing config propagation to skill tool and createBuiltinAgents.
2026-01-16 08:01:04 +07:00
Jeremy Gollehon 1e080fc55b Merge pull request #803 from GollyJer/concurrency-hardening
feat(concurrency): prevent background task races and leaks

Summary
Fixes race conditions and memory leaks in the background task system that could cause "all tasks complete" notifications to never fire, leaving parent sessions waiting indefinitely.

Why This Change?
When background tasks are tracked for completion notifications, the system maintains a pendingByParent map to know when all tasks for a parent session are done. Several edge cases caused "stale entries" to accumulate in this map:
1. Re-registering completed tasks added them back to pending tracking, but they'd never complete again
2. Changing a task's parent session left orphan entries in the old parent's tracking set
3. Concurrent task operations could cause double-acquisition of concurrency slots
These bugs meant the system would sometimes wait forever for tasks that were already done.

What Changed
- Concurrency management: Added proper acquire/release lifecycle with cleanup on process exit (SIGINT, SIGTERM)
- Parent session tracking: Fixed cleanup order. Now clears old parent's tracking before updating parent ID
- Stale entry prevention: Only tracks tasks that are actually running; actively cleans up completed tasks
- Renamed registerExternalTask → trackTask: Clearer name (the old name implied external API consumers, but it's internal)
2026-01-15 11:09:52 -08:00
Jeremy Gollehon da766d19ee refactor(background-agent): rename registerExternalTask to trackTask
Update BackgroundManager to rename the method for tracking external tasks, improving clarity and consistency in task management. Adjust related tests to reflect the new method name.
2026-01-15 10:53:08 -08:00
justsisyphus 4de2399f22 fix(hooks): use API instead of filesystem to resolve model info for session.prompt
Previously, continuation hooks (todo-continuation, boulder-continuation, ralph-loop)
and background tasks resolved model info from filesystem cache, which could be stale
or missing. This caused session.prompt to fallback to default model (Sonnet) instead
of using the originally configured model (e.g., Opus).

Now all session.prompt calls first try API (session.messages) to get current model
info, with filesystem as fallback if API fails.

Affected files:
- todo-continuation-enforcer.ts
- sisyphus-orchestrator/index.ts
- ralph-loop/index.ts
- background-agent/manager.ts
- sisyphus-task/tools.ts
- hook-message-injector/index.ts (export ToolPermission type)
2026-01-16 02:33:44 +09:00
justsisyphus a736fa7691 fix(skill): unify skill resolution to support user custom skills
sisyphus_task was only loading builtin skills via resolveMultipleSkills().
Now uses resolveMultipleSkillsAsync() which merges discoverSkills() + builtin skills.

- Add getAllSkills(), extractSkillTemplate(), resolveMultipleSkillsAsync()
- Update sisyphus_task to use async skill resolution
- Refactor skill tool to reuse unified getAllSkills()
- Add async skill resolution tests
2026-01-16 01:57:57 +09:00
Jeremy Gollehon af066ff99f fix(background-agent): improve parent session ID handling in task management
Enhance the BackgroundManager to properly clean up pending tasks when the parent session ID changes. This prevents stale entries in the pending notifications and ensures that the cleanup process is only executed when necessary, improving overall task management reliability.
2026-01-15 00:16:35 -08:00
Jeremy Gollehon 3a1f93e5ef fix(background-agent): prevent stale entries in pending notifications
Update BackgroundManager to track batched notifications only for running tasks. Implement cleanup for completed or cancelled tasks to avoid stale entries in pending notifications. Enhance logging to include task status for better debugging.
2026-01-14 23:51:19 -08:00
Jeremy Gollehon ee601d845c feat(background-agent): implement process cleanup for BackgroundManager
Add functionality to manage process cleanup by registering and unregistering signal listeners. This ensures that BackgroundManager instances properly shut down and remove their listeners on process exit. Introduce tests to verify listener removal after shutdown.
2026-01-14 23:11:38 -08:00
justsisyphus 2ad8173144 docs: update AGENTS documentation metadata and agent model references
- Update generated timestamp and commit hash metadata
- Normalize agent model names with provider prefixes (anthropic/, opencode/, google/)
- Remove deprecated Google OAuth/Antigravity references
- Update line counts and complexity hotspot entries
- Adjust test count from 82 to 80+ files and assertions from 2559+ to 2500+

🤖 Generated with assistance of oh-my-opencode
2026-01-15 15:53:51 +09:00
Jeremy Gollehon 02c907e128 fix(background-agent): preserve external concurrency keys
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-01-14 22:40:16 -08:00
Jeremy Gollehon de9e9dbe68 feat(background-agent): add concurrency group field
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-01-14 22:40:14 -08:00
Jeremy Gollehon 09e8546d3a feat(concurrency): prevent background task races and leaks
Ensure queue waiters settle once, centralize completion with status guards, and release slots before async work so shutdown and cancellations don’t leak concurrency. Internal hardening only.
2026-01-14 21:35:01 -08:00
Kenny 45ddfdbaa2 Merge pull request #790 from stranger2904/feat/http-mcp-transport
feat(skill-mcp): add HTTP transport support for remote MCP servers
2026-01-14 15:35:38 -05:00
stranger2904 a90adf6e7f fix: correct test syntax for headers verification
Fix syntax error where expect().rejects.toThrow() was not properly closed
before the headers assertion.
2026-01-14 15:10:45 -05:00
Kenny 5fdbad0892 Merge pull request #736 from Gladdonilli/fix/background-agent-edge-cases
fix(background-agent): address edge cases in task lifecycle
2026-01-14 15:05:09 -05:00
stranger2904 0169035f0f test: mock StreamableHTTPClientTransport for faster, deterministic tests
Add mocks for HTTP transport to avoid real network calls during tests.
This addresses reviewer feedback about test reliability:
- Tests are now faster (no network latency)
- Tests are deterministic across environments
- Test intent is clearer (unit testing error handling logic)

The mock throws immediately with a controlled error message,
allowing tests to validate error handling without network dependencies.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 15:01:10 -05:00
Kenny 3f0fe3b29b refactor(sisyphus-task): use dynamic model fallback from OpenCode config
- Remove hardcoded "anthropic/claude-sonnet-4-5" fallback
- Fetch systemDefaultModel from client.config.get() at tool boundary
- Add 'category-default' and 'system-default' fallback types
- Use switch(actualModel) for cleaner type detection
- Add guard clauses and fail-loud validation for invalid models
- Wrap config fetch in try/catch for graceful degradation
- Update toast messages with typed suffixMap
2026-01-14 14:45:01 -05:00
stranger2904 7ec6d202ee feat(skill-mcp): add HTTP transport support for remote MCP servers
Add support for connecting to remote MCP servers via HTTP in addition to
the existing stdio (local process) connections. This enables skills to
use cloud-hosted MCP servers and aggregated MCP gateways.

## Changes

- Extend SkillMcpManager to detect connection type from config:
  - Explicit `type: "http"` or `type: "sse"` → HTTP connection
  - Explicit `type: "stdio"` → stdio connection
  - Infer from `url` field → HTTP connection
  - Infer from `command` field → stdio connection

- Add StreamableHTTPClientTransport from MCP SDK for HTTP connections
  - Supports custom headers for authentication (e.g., API keys)
  - Proper error handling with helpful hints

- Maintain full backward compatibility with existing stdio configurations

## Usage

```yaml
# HTTP connection (new)
mcp:
  remote-server:
    url: https://mcp.example.com/mcp
    headers:
      Authorization: Bearer ${API_KEY}

# stdio connection (existing, unchanged)
mcp:
  local-server:
    command: npx
    args: [-y, @some/mcp-server]
```

## Tests

Added comprehensive tests for:
- Connection type detection (explicit type vs inferred)
- HTTP URL validation and error messages
- Headers configuration
- Backward compatibility with stdio configs
2026-01-14 11:35:32 -05:00
Nguyen Khac Trung Kien 16c38d7230 feat(sisyphus-task): inherit parent model for categories and show fallback warning
- Change model priority: user override > parent model > category default
- Add ModelFallbackInfo to track model resolution type
- Show warning toast when category uses inherited or default model
- Add tests for model fallback info in task toast
2026-01-14 22:06:24 +07:00
justsisyphus d86917de04 fix: use dynamic message lookup for model/agent context in prompts
Instead of using stale parentModel/parentAgent from task state, now
dynamically looks up the current message to get fresh model/agent values.
Applied across all prompt injection points:
- background-agent notifyParentSession
- ralph-loop continuation
- sisyphus-orchestrator boulder continuation
- sisyphus-task resume

🤖 Generated with [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode) assistance
2026-01-14 18:55:46 +09:00
Gladdonilli f0ac51d4b9 refactor(background-agent): extract cleanupPendingByParent helper
Extract duplicated 8-line pendingByParent cleanup pattern into a
reusable helper method. Reduces code duplication across 5 call sites.

Addresses cubic-dev-ai feedback on PR #736.
2026-01-14 17:34:54 +08:00
Gladdonilli 6f071c172f fix: address remaining PR review feedback
- Add pendingByParent cleanup in pruneStaleTasksAndNotifications
- Add double-release guard in launch error handler (L170)
- Add concurrency release in resume error handler (L326)
2026-01-14 17:34:54 +08:00
Gladdonilli f1c05f47a3 fix: address PR review feedback
- Add pendingByParent cleanup to ALL completion paths (session.idle, polling, stability)
- Add null guard for task.parentSessionID before Map access
- Add consistency guard in prune function (set concurrencyKey = undefined)
- Remove redundant setTimeout release (already released at completion)
2026-01-14 17:34:54 +08:00
Gladdonilli 0b250f9110 fix(background-agent): address 3 edge cases in task lifecycle
- Reset startedAt on resume to prevent immediate false completion
- Release concurrency immediately on completion with double-release guard
- Clean up pendingByParent on session.deleted to prevent stale entries
2026-01-14 17:33:47 +08:00
justsisyphus 85a6f3568b fix(background-agent): omit model field to use session's lastModel
Previously, background task completion notifications passed parentModel when defined, causing OpenCode to use default Sonnet model when parentModel was undefined. Now model field is always omitted, letting OpenCode use the session's existing lastModel (like todo-continuation hook).

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-01-14 18:02:20 +09:00
justsisyphus 72fa8f2c65 refactor(lsp): consolidate LSP tools - remove lsp_hover, lsp_code_actions, lsp_code_action_resolve - merge lsp_document_symbols + lsp_workspace_symbols into lsp_symbols with scope parameter - update all references in hooks, templates, and documentation 2026-01-14 17:30:04 +09:00
justsisyphus 8e46b08aea fix(background-agent): preserve parent model in notifyParentSession
Fixes model switching bug where sisyphus_task with category would
change the main session's model after completion.

- Add parentModel to session.prompt body in notifyParentSession
- Add test verifying model is included when parentModel is defined
2026-01-14 13:50:12 +09:00
Kenny 7e5bb2e67a Merge pull request #731 from oussamadouhou/fix/background-task-directory-inheritance
fix(background-agent): inherit parent session directory for background tasks
2026-01-13 12:38:38 -05:00
YeonGyu-Kim 3efbe5824c fix(agents): enable call_omo_agent for background agents while restricting recursive calls
- Enable call_omo_agent tool for skill execution in BackgroundManager
- Enable call_omo_agent tool for agent execution in BackgroundManager
- Enable call_omo_agent tool for sisyphus_task resume operations
- Enable call_omo_agent tool for sisyphus_task category-based delegation
- Restrict recursive task and sisyphus_task calls to prevent loops
- Allows background agents to delegate to other agents cleanly

🤖 Generated with OhMyOpenCode assistance
2026-01-13 21:00:00 +09:00
YeonGyu-Kim 8b2900e635 fix(background-agent): improve task completion detection and concurrency release
- manager.ts: Release concurrency key immediately on task completion, not after retention
- call-omo-agent: Add polling loop for sync agent completion detection
- sisyphus-task: Add abort handling, improve poll logging for debugging
2026-01-13 21:00:00 +09:00
YeonGyu-Kim c8da697a10 docs: update AGENTS.md hierarchy with latest structure and line counts
- Root: Add Prometheus/Metis/Momus agents, MCP architecture, 82 test files
- agents/: Document 7-section delegation and wisdom notepad
- auth/: Multi-account load balancing (10 accounts), endpoint fallback
- features/: Update background-agent 825 lines, builtin-skills 1230 lines
- hooks/: 22+ hooks with event timing details
- tools/: sisyphus-task 583 lines, LSP client 632 lines
- cli/: config-manager 725 lines, 17+ doctor checks
- shared/: Cross-cutting utilities with usage patterns
2026-01-13 21:00:00 +09:00
Oussama Douhou 8ce8b4b1db fix(background-agent): inherit parent session directory for background tasks
Background tasks were defaulting to $HOME instead of the parent session's
working directory. This caused background agents to scan the entire home
directory instead of the project directory, leading to:
- High CPU/memory load from scanning unrelated files
- Permission errors on system directories
- Task failures and timeouts

The fix retrieves the parent session's directory before creating a new
background session and passes it via the query.directory parameter.

Files modified:
- manager.ts: Look up parent session directory in launch()
- call-omo-agent/tools.ts: Same fix for sync mode
- look-at/tools.ts: Same fix for look_at tool
- sisyphus-task/tools.ts: Same fix + interface update for directory prop
- index.ts: Pass directory to sisyphusTask factory
2026-01-13 06:27:56 +01:00
Jason Kölker 7f67df9bd0 feat(config): add model variant support
Allow optional model variant config for agents and categories.
Propagate category variants into task model payloads so
category-driven runs inherit provider-specific variants.

Closes: #647
2026-01-13 04:37:51 +00:00
Kenny e8d89c50b7 Merge pull request #709 from Momentum96/fix/skill-lazy-loading
fix(skill-loader): implement eager loading for skills
2026-01-12 22:50:31 -05:00
Kenny 6d264f1d9a refactor(skill-loader): eager loading with atomic file reads
- Extract body during initial parseFrontmatter call
- Rename lazyContent → eagerLoader with rationale comment
- Eliminates redundant file read and race condition
2026-01-12 22:46:28 -05:00
YeonGyu-Kim b0961ed5cc feat(tools): disable call_omo_agent by default, enable via sisyphus_task 2026-01-13 11:21:01 +09:00
Nguyen Khac Trung Kien 3dc06225db fix(prometheus): prevent agent fallback to build in background tasks (#695) 2026-01-13 09:39:25 +09:00
Momentum96 20c6752060 fix(skill-loader): implement eager loading to resolve empty slash commands 2026-01-12 17:27:54 +09:00