Rewrite opencode-message-dir.test.ts to use real temp directories instead
of mocking node:fs/node:path. Rewrite opencode-storage-detection.test.ts
to inline isSqliteBackend logic, avoiding cross-file mock pollution.
Resolves all 195 bun test failures (195 → 0). Full suite: 2707 pass.
- Create src/shared/opencode-storage-paths.ts with all 4 constants
- Update 4 previous declaration sites to import from shared file
- Update additional OPENCODE_STORAGE usages for consistency
- Re-export from src/shared/index.ts
- No duplicate constant declarations remain
- Use shared OPENCODE_STORAGE, MESSAGE_STORAGE, PART_STORAGE constants
- Make isCallerOrchestrator async with SDK fallback for beta
- Fix cache implementation using Symbol sentinel
- Update atlas hooks and sisyphus-junior-notepad to use async isCallerOrchestrator
- Add src/shared/opencode-storage-paths.ts with consolidated constants
- Update imports in hook-message-injector and session-manager
- Add src/shared/opencode-storage-detection.ts with isSqliteBackend()
- Add OPENCODE_SQLITE_VERSION constant
- Export all from shared/index.ts
- Make id field optional in all Todo interfaces (TodoInfo, Todo, TodoItem)
- Fix null-unsafe comparisons in todo-sync.ts to handle missing ids
- Add test case for todos without id field preservation
- All tests pass and typecheck clean
In-memory Map-based store that records tool restriction objects (e.g.,
question: false) by sessionID when prompts are sent. This enables
retrieving the original session's tool parameters when background tasks
complete and need to notify the parent session.
resolveSymlink and resolveSymlinkAsync incorrectly resolved relative
symlinks by using path.resolve(filePath, '..', linkTarget). This fails
when symlinks use multi-level relative paths (e.g. ../../skills/...) or
when symlinks are chained (symlink pointing to a directory containing
more symlinks).
Replace with fs.realpathSync/fs.realpath which delegates to the OS for
correct resolution of all symlink types: relative, absolute, chained,
and nested.
Fixes#1738
AI-assisted-by: claude-opus-4.6 via opencode
AI-contribution: partial
AI-session: 20260212-120629-4gTXvDGV
Allow individual categories to be disabled via `disable: true` in
config. Introduce shared `mergeCategories()` utility to centralize
category merging and disabled filtering across all 7 consumption sites.
Migration changes were only applied to rawConfig if file write succeeded,
leaving the running process on stale config. Also stops logging backup
path when the backup copy itself failed.
OpenCode SDK does not expose client.model.list API. This caused the
provider-models cache to always be empty (models: {}), which in turn
caused delegate-task categories with requiresModel (e.g., 'deep',
'artistry') to fail with misleading 'Unknown category' errors.
Changes:
- connected-providers-cache.ts: Extract models from provider.list()
response's .all array instead of calling non-existent client.model.list
- category-resolver.ts: Distinguish between 'unknown category' and
'model not available' errors with clearer error messages
- Add comprehensive tests for both fixes
Bug chain:
client.model?.list is undefined -> empty cache -> isModelAvailable
returns false for requiresModel categories -> null returned from
resolveCategoryConfig -> 'Unknown category' error (wrong message)
Replace mock.module with spyOn + mockRestore to prevent fs module
pollution across test files. mock.module replaces the entire module
and caused 69 test failures in other files that depend on fs.
Skill loaders previously only told agents that @path references are
relative to the skill directory, but agents often failed to resolve
them. Now @path/with/slash patterns are automatically expanded to
absolute paths during template construction.
Previously, migrateConfigFile() mutated rawConfig directly. If the file
write failed (e.g. read-only file, permissions), the in-memory config was
already changed to the migrated values, causing the plugin to use migrated
models even though the user's file was untouched. On the next run, the
migration would fire again since _migrations was never persisted.
Now all mutations happen on a structuredClone copy. The original rawConfig
is only updated after the file write succeeds. If the write fails,
rawConfig stays untouched and the function returns false.
- Use namespace import for connected-providers-cache for better clarity
- Add explicit type annotation for modelsByProvider to improve type safety
- Update tests to reflect refactored module organization
- Improve code organization while maintaining functionality
🤖 Generated with assistance of OhMyOpenCode
Migrate imports from monolithic `model-availability` to split modules
(`model-name-matcher`, `available-models-fetcher`, `model-cache-availability`).
Replace XDG_CACHE_HOME env var manipulation with `mock.module` for
`data-path`, ensuring test isolation without polluting process env.
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Update main AGENTS.md with current file sizes
- Update complexity hotspot line counts
- Update agent count from 11 to 32 files
- Update CLI utility count to 70
- Update test file count from 100+ to 163
🤖 Generated with assistance of OhMyOpenCode
PR #1620 migrated all prompt calls from session.prompt (blocking) to
session.promptAsync (fire-and-forget HTTP 204). This broke look_at which
needs the multimodal-looker response to be available immediately after
the prompt call returns.
Fix: add promptSyncWithModelSuggestionRetry() that uses session.prompt
(blocking) with model suggestion retry support. look_at now uses this
sync variant while all other callers keep using promptAsync.
- Add promptSyncWithModelSuggestionRetry to model-suggestion-retry.ts
- Switch look_at from promptWithModelSuggestionRetry to sync variant
- Add comprehensive tests for the new sync function
- No changes to other callers (delegate-task, background-agent)