* fix(skills): normalize backslash in ZIP entry names for Windows compatibility
ZIP archives created on Windows may use backslash (\) as path separator
instead of forward slash (/). When extracted on Linux, this causes files
like 'scripts\search.py' to be created as a single flat file instead of
the proper 'scripts/search.py' directory structure.
The ZIP specification (PKZIP APPNOTE) requires forward slashes, but many
Windows tools produce non-conforming archives.
This adds a strings.ReplaceAll backslash normalization step during skill
ZIP extraction to handle this edge case.
* test(skills): cover backslash zip extraction
---------
Co-authored-by: buidackim <221586880+buidackim@users.noreply.github.com>
Co-authored-by: Mỹ Ngân <goclaw-maintain@users.noreply.github.com>
Add explicit per-agent manage grants for skills so granted agents can patch/delete skills when ownership identity drifts.
Expose skill owner and manage-grant controls in the web skills UI, and add PostgreSQL/SQLite migrations plus coverage for preserve/revoke behavior.
Upload handler previously archived skills immediately when deps were
missing. Now calls InstallDeps() first (owner/master tenant only) and
falls back to archive on failure.
Changes:
- Auto-install missing deps during skill upload (same flow as seeder)
- Atomic DB persist: deps state written with CreateSkillManaged in one call
- Per-slug upload mutex prevents concurrent race conditions
- Frontend: warning state (amber triangle) instead of throwing error
- Non-cancellable context for DB write after dep install
- SQLite StoreMissingDeps now works for custom skills (not just system)
- Comprehensive unit + integration tests
Closes#468