Prevent unsolicited Telegram chats from auto-linking to a workspace by requiring /pair <code> for private identities and exposing pairing setup in OpenWork UI.
* fix: support domain-grouped skills and global MCP config
Fixes#621 – Skills in domain subfolders (skills/<domain>/<name>/SKILL.md)
were silently skipped because gather_skills() (Rust) and listSkillsInDir()
(TypeScript) only scanned one level deep. Both functions now treat a
top-level directory that has no SKILL.md as a domain/category folder and
scan its immediate children, keeping full backwards-compatibility with the
flat layout.
Fixes#622 – MCP servers defined in the global opencode config
(~/.config/opencode/opencode.json) were completely ignored by listMcp().
The function now reads global config as well, merging it with the
workspace-level config. Project entries take priority over global ones;
each item carries the correct source field (config.global vs config.project).
* fix: support nested skill paths for local skill actions
---------
Co-authored-by: Benjamin Shafii <benjamin.shafii@gmail.com>
Expose soul status/heartbeat endpoints and wire a dedicated Soul tab so operators can enable soul mode, review heartbeat follow-ups, and steer next prompts directly from OpenWork.
* fix(desktop): suppress unused variable warnings in manager modules
Prefix unused `child` bindings with underscore in engine and openwork_server
managers to silence Rust compiler warnings.
* refactor(app): remove `as any` casts with typed SDK helpers
Create lib/opencode-session.ts that wraps OpenCode SDK session operations
(abort, revert, unrevert, shell, command listing) with proper types.
Replace all `(c.session as any).abort/revert/unrevert` and
`(c.command as any).list` calls in app.tsx with the typed helpers.
The SDK v2 already exposes these methods with full type definitions —
the casts were unnecessary and bypassed type safety on critical API paths.
* refactor(app): extract OpenWork server connection store
Create context/openwork-server.ts that encapsulates all OpenWork server
connection state: 15 signals, 6 polling effects, derived memos for
baseUrl/auth/client, and the health check helper.
This is a standalone module ready to replace the corresponding state in
app.tsx. It follows the same factory pattern as createSessionStore and
createExtensionsStore.
* feat(app): add safe execution utilities for error handling
Create lib/safe-run.ts with safeAsync, safeSync, and fireAndForget
helpers that replace bare `catch {}` blocks. Errors are logged in
development mode and silently swallowed in production.
This provides a migration path for the ~50 silent catch blocks.
* test(server): add unit tests for validators, utils, and token service
Add 41 new tests across 3 test files:
- validators.test.ts: sanitizeCommandName, validateCommandName,
validateMcpName, validateSkillName, validateMcpConfig (22 tests)
- utils.test.ts: hashToken, shortId, parseList, ensureDir/exists (10 tests)
- tokens.test.ts: TokenService CRUD, scope resolution, revocation (9 tests)
Total server test count: 48 (from 7 previously).
---------
Co-authored-by: Benjamin Shafii <benjamin.shafii@gmail.com>