Commit Graph

720 Commits

Author SHA1 Message Date
YeonGyu-Kim d781b7537f Merge pull request #3226 from code-yeongyu/fix/plan-progress-and-trust
fix(plan): skill MCP trust + non-ASCII names + simple-mode progress + ralph-loop cap
2026-04-08 17:40:51 +09:00
YeonGyu-Kim bdf6e4195a Merge pull request #3225 from code-yeongyu/fix/agent-name-safety
fix(agent): narrow ULW auto-start + strip ZWSP on background path + fix auto-update identity
2026-04-08 17:40:48 +09:00
YeonGyu-Kim c37e440ba8 Merge pull request #3224 from code-yeongyu/fix/oauth-wiring
fix(oauth): wire refresh mutex + post-request auth handler
2026-04-08 17:40:46 +09:00
YeonGyu-Kim 7f8ed7b056 test(tmux): add missing tmux exports to zombie-pane mock module 2026-04-08 17:36:27 +09:00
YeonGyu-Kim 600d68da04 test(tmux): add missing tmux exports to zombie-pane mock module 2026-04-08 17:36:26 +09:00
YeonGyu-Kim d53be83634 test(tmux): add missing tmux exports to zombie-pane mock module 2026-04-08 17:36:24 +09:00
YeonGyu-Kim 4c0225a23f test(tmux): add missing tmux exports to zombie-pane mock module 2026-04-08 17:36:23 +09:00
YeonGyu-Kim 85fa939051 test(skill-mcp): fix connection env var tests after oauth-handler import changes
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 17:26:00 +09:00
YeonGyu-Kim 119c23342a test(background): fix variant propagation test to match parent-context resolution 2026-04-08 17:25:54 +09:00
YeonGyu-Kim bbbbf68382 fix(ralph-loop): update template to reflect 500 iteration cap
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 17:18:37 +09:00
YeonGyu-Kim 0cb938e3ac fix(boulder): count only top-level checkboxes in simple-mode plan progress
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 17:18:29 +09:00
YeonGyu-Kim 001d29ea8e fix(skill-mcp): treat opencode-project and local scopes as untrusted for env var access
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 17:18:17 +09:00
YeonGyu-Kim 359f74132a fix(delegate-task): strip ZWSP from agent names on background launch path
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 17:17:26 +09:00
YeonGyu-Kim 0479693ca3 fix(oauth): wire post-request 401/403 handler into skill-mcp withOperationRetry
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 17:16:36 +09:00
YeonGyu-Kim 63ba16bcce fix(oauth): wire refresh mutex into provider.refresh() for concurrent deduplication
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 17:16:28 +09:00
YeonGyu-Kim 80c74c8849 fix(background): prevent double-decrement of descendant quota in processKey error cleanup 2026-04-08 17:15:18 +09:00
YeonGyu-Kim 1cf4119dd4 fix(background): use parent session variant in notifyParentSession instead of child task variant 2026-04-08 17:15:02 +09:00
YeonGyu-Kim ed16dc0608 fix(chat-params): complete maxOutputTokens migration in session prompt params 2026-04-08 17:14:17 +09:00
YeonGyu-Kim 06b825dd74 fix(start-work): reuse registered opencode agent names 2026-04-08 16:18:26 +09:00
YeonGyu-Kim b28567251d fix(plugin-loader): filter project-scoped plugins by cwd
discoverInstalledPlugins read scope from installed_plugins.json but
never filtered by it, so project/local scoped Claude Code plugins
leaked into every session regardless of process.cwd().

Add projectPath to PluginInstallation and InstalledPluginEntryV3,
propagate it through v3EntryToInstallation, and introduce
shouldLoadPluginForCwd which reuses shared/contains-path for safe
symlink- and ancestor-aware matching and expands a leading tilde.
user and managed scopes still always load; project and local without
a projectPath are skipped as a safe default.

Covered by 13 new shouldLoadPluginForCwd unit tests (including tilde
expansion against a mocked homedir) and 13 new discoverInstalledPlugins
integration tests spanning v1, v2, and v3 database formats plus the
existing enabledPluginsOverride path.

Fixes #3216
2026-04-08 15:28:17 +09:00
YeonGyu-Kim ab0e1e3be0 fix(oauth): refresh-once handler for 401/403 responses
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 13:28:17 +09:00
YeonGyu-Kim 7ba41d388a fix(oauth): atomic storage writes for token safety
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 13:28:14 +09:00
YeonGyu-Kim 7be285ef89 feat(oauth): add per-server refresh mutex
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 13:28:08 +09:00
YeonGyu-Kim c3fe0ae09e fix(background): propagate variant in parent notifications
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 13:23:08 +09:00
YeonGyu-Kim 35f778db2d test(skill-mcp): add scope field to test fixtures
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 13:11:28 +09:00
YeonGyu-Kim fa140b0375 fix(skill-loader): propagate scope to MCP connections
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 13:10:41 +09:00
YeonGyu-Kim 05efb20fda feat(skill-mcp): add scope field to connection types 2026-04-08 13:10:20 +09:00
YeonGyu-Kim b81fdef5d9 fix(skill-mcp): redact sensitive data from connection errors
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 13:10:06 +09:00
YeonGyu-Kim 78e6d780eb fix(plugin): verify event hook compatibility with v1.4.0
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 13:08:03 +09:00
YeonGyu-Kim 6eb527c914 fix: remove ZWSP from agent display names (#3146) 2026-04-07 15:44:31 +09:00
YeonGyu-Kim e8c8376db4 fix(boulder): support both structured and simple plan formats in getPlanProgress
Structured plans (with ## TODOs section) use strict numbered-label
parsing. Simple plans (without sections) fall back to regex checkbox
counting. This fixes 9 test failures from the #3066 merge.
2026-04-07 15:39:08 +09:00
YeonGyu-Kim 5622d154fd fix: prevent background agent race condition in session prompt (#2932)
Added await for session ready state before sending prompt in
background-agent/manager.ts. Also improved image resizer error handling.

132 tests pass, tsc clean.

Closes #2932
2026-04-07 15:29:11 +09:00
YeonGyu-Kim be562905d6 Merge pull request #3179 from code-yeongyu/fix/issue-3066
fix(start-work): add CHECKED_CHECKBOX_PATTERN for plan progress (#3066)
2026-04-07 15:16:18 +09:00
YeonGyu-Kim b4b9aea849 Merge pull request #3177 from code-yeongyu/fix/issue-3168
fix(mcp): bypass env var allowlist for trusted skill MCP configs (#3168)
2026-04-07 15:15:55 +09:00
YeonGyu-Kim 0ab2370d4e fix(start-work): add CHECKED_CHECKBOX_PATTERN for plan progress tracking (#3066)
Plan progress now correctly counts checked checkboxes when determining
current task vs completed tasks.

TDD verified. tsc clean.

Closes #3066
2026-04-07 15:11:50 +09:00
YeonGyu-Kim 73d407fe73 fix(mcp): bypass env var allowlist for trusted skill MCP configs (#3168)
Added 'trusted' option to expandEnvVars. Skill MCPs are user-controlled
and now bypass the security allowlist. 3 files changed.

TDD verified. tsc clean.

Closes #3168
2026-04-07 15:11:47 +09:00
YeonGyu-Kim f8c626086e fix(agent-names): use HTTP-header-safe display names and config keys for API calls (#3138)
Display names with parentheses like 'Atlas (Plan Executor)' cause HTTP
header validation errors in x-opencode-agent-name. This was blocking
Atlas/Prometheus from working via /start-work and auto-retry.

Changes:
- Display names: parens -> dashes ('Atlas - Plan Executor')
- Hooks (start-work, no-hephaestus-non-gpt, no-sisyphus-gpt): use
  config keys ('atlas', 'sisyphus', 'hephaestus') for agent API fields
- auto-retry: use config key instead of display name for promptAsync
- agent-override-protection: handle dash-suffix normalization
- Updated all test expectations to match new format

Closes #3138
2026-04-07 10:08:04 +09:00
YeonGyu-Kim 03409938ec fix(tests): inject plugin loader dependencies
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-06 18:45:33 +09:00
YeonGyu-Kim 0de7453349 fix(tests): fix globalThis.fetch pollution between test files
- install.test.ts: save and restore globalThis.fetch in beforeEach/afterEach
  to prevent leaking a mock fetch (without .preconnect) into subsequent test files
- provider.test.ts: guard against originalFetch missing .preconnect when captured
  from a leaked mock (defensive null-safe binding)
- discovery.test.ts: add writable:true to all Object.defineProperty fetch assignments
  so downstream plain assignments (globalThis.fetch = ...) are not silently ignored

Root cause: install.test.ts set globalThis.fetch = mock(...) inside test bodies
without restoring it, leaving a mock fetch (no .preconnect method) that caused
provider.test.ts refresh tests to throw TypeError at the fetchMock construction
2026-04-06 18:20:37 +09:00
YeonGyu-Kim e62d5d7a22 fix(agents): strip ZWSP ordering prefixes in session state, config lookups, and override protection
Prevent ZWSP sort prefixes from leaking into stored agent names, config
key lookups, and override-protection normalization. Ensures prefixed
list-display names resolve correctly throughout the pipeline.

🤖 Generated with [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode) assistance
2026-04-06 18:07:26 +09:00
YeonGyu-Kim 0c1202e480 fix(tests): resolve CI test isolation failures in OAuth refresh and ralph-loop
- provider.test.ts: reset discovery cache before/after refresh tests to prevent
  cross-test contamination via module-level discoveryCache singleton
- completion-promise-session-negative.test.ts: update negative test case to use
  non-oracle agent (hephaestus) since oracle tool_result VERIFIED detection was
  intentionally added in 56f2a9df
2026-04-06 17:48:38 +09:00
YeonGyu-Kim 61083d499d fix(oauth+errors): OAuth silent refresh, quota STOP patterns, compaction loop cap
Bug fixes:
1. OAuth token refresh (#3149): buildHttpRequestInit() now attempts silent refresh
   via refresh_token before triggering full browser re-auth. Added refresh() method
   to McpOAuthProvider. Includes test isolation fix for discovery mock.

2. Quota error STOP (#3126): Added STOP_MESSAGE_PATTERNS in model-error-classifier
   that take precedence over RETRYABLE_MESSAGE_PATTERNS. Message-only quota errors
   now non-retryable. Runtime-fallback: quota_exceeded with 'retrying in' signal
   still triggers fallback (provider-managed auto-retry). Restored removed patterns.

3. Compaction loop (#3127): MAX_RECOVERY_ATTEMPTS=3 cap + additional suppression
   guard from opencode session in degradation monitor.

Also: refactored extractAutoRetrySignal to auto-retry-signal.ts, new regression
tests for quota classifier and compaction degradation monitor.
2026-04-06 17:40:12 +09:00
YeonGyu-Kim d555410745 feat(boulder-state): add session_origins tracking for direct vs appended sessions
- Add session_origins field to BoulderState type
- Track direct vs appended session origins in storage layer
- Add migration logic for existing state files
- Add comprehensive tests for session origin tracking

🤖 Generated with assistance of OhMyOpenCode
2026-04-05 18:27:53 +09:00
YeonGyu-Kim 60ccba38e1 feat(hook-message-injector): enhance boulder continuation injector with lineage support
- Add lineage-aware continuation injection logic
- Support for tracking multiple session types (direct vs appended)
- Update tests for new lineage continuation scenarios
- Add session origin validation in continuation flow

🤖 Generated with assistance of OhMyOpenCode
2026-04-05 17:18:10 +09:00
YeonGyu-Kim ec49bd553f feat(boulder-state): add session_origins tracking for direct vs appended sessions
- Add session_origins field to BoulderState type
- Track direct vs appended session origins in storage layer
- Add migration logic for existing state files
- Add comprehensive tests for session origin tracking

🤖 Generated with assistance of OhMyOpenCode
2026-04-05 17:18:10 +09:00
YeonGyu-Kim afd554b2d9 fix(delegate-task): validate description parameter and handle undefined in notifications
OpenCode's fromPlugin wrapper skips Zod validation for plugin tools, so
LLMs can omit required args like description without getting an error.
When Atlas orchestrates and the model omits description, it flows through
as undefined to manager.launch() and background task notifications show
'undefined' for all completed tasks.

Two fixes:
- Add runtime validation for description in delegate-task tool (matches
  existing run_in_background and load_skills validation pattern)
- Defensive fallback in notification template: use task ID when
  description is missing instead of rendering 'undefined'
2026-04-05 17:18:10 +09:00
YeonGyu-Kim 90407a9789 Merge pull request #3135 from jim80net/fix/agent-not-found-fallback
fix(background-agent): retry with fallback agent on Agent not found
2026-04-05 14:46:08 +09:00
Jim Park f8d086ded1 fix: remove overly broad agent+undefined error pattern
The (message.includes("agent") && message.includes("undefined"))
pattern could match unrelated errors like "The agent returned undefined
for the configuration", triggering a false fallback that hides the real
failure.

The two precise patterns are sufficient:
- "Agent not found" — canonical SDK validation error
- "agent.name" — property access error on undefined agent config

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:31:22 -07:00
Jim Park 51508c4949 fix: address cubic review — broaden error detection, add test coverage
1. isAgentNotFoundError now handles:
   - Plain objects with .message field (not just Error instances)
   - "agent.name"/"undefined" error variants from SDK validation
   - The original "Agent not found" format

2. New tests:
   - agent.name/undefined error variant triggers fallback
   - Plain object errors with .message field trigger fallback
   - "fallback also fails" test now verifies retry was attempted (callCount=2)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:17:22 -07:00
Jim Park 9470cbe090 fix: address systems review findings for agent-not-found fallback
1. [HIGH] Tool restrictions recomputed for fallback agent via
   buildFallbackBody() — no longer inherits original agent's restrictions.

2. [HIGH] Double-retry race prevented — handleSessionErrorEvent now
   returns early for agent-not-found errors, since the prompt catch
   block already handles them with agent fallback. This prevents
   tryFallbackRetry from racing with a model-level retry on the same
   error (the "not found" pattern in RETRYABLE_MESSAGE_PATTERNS).

3. [MEDIUM] task.agent updated to FALLBACK_AGENT after successful
   fallback — notifications, toast, and logging reflect actual agent.

4. [MEDIUM] FALLBACK_AGENT exported from spawner.ts and imported into
   manager.ts — single source of truth.

5. [LOW] resumeTask fallback now uses promptWithModelSuggestionRetry
   (consistent with startTask), getting timeout protection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:13:05 -07:00