Commit graph

194 commits

Author SHA1 Message Date
dongmucat
a85298f7ae
Merge pull request #508 from iflytek/fix/security-review-hardening
fix(security): harden review findings
2026-06-17 11:08:38 +08:00
dongmucat
a23cbd84eb
Merge pull request #530 from iflytek/fix/issue-51-profile-review-notifications
fix: admin notifications for profile review requests
2026-06-17 11:08:10 +08:00
dongmucat
e50140272b fix(security): close review hardening gaps
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-16 17:48:15 +08:00
dongmucat
a865960cf3 fix(notification): ISSUE-51 add profile review notifications
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-16 10:33:02 +08:00
dongmucat
abdad25df3 feat(bootstrap): add agentguard builtin skill
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-15 15:32:35 +08:00
dongmucat
40d7de8462 fix(security): harden review findings
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-12 14:40:30 +08:00
dongmucat
4776550391
Merge pull request #498 from iflytek/feature/cloud-url-builtin-skills
feat(bootstrap): sync built-in skills from cloud manifest
2026-06-11 17:27:26 +08:00
XiaoSeS
a88b09e51b fix(publish): accept case-insensitive SKILL.md uploads 2026-06-11 16:34:13 +08:00
dongmucat
0298823d06 fix(skill): remove namespace bundle backend residues
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-10 19:48:27 +08:00
dongmucat
f93ab170e5 Merge remote-tracking branch 'origin/main' into feature/cloud-url-builtin-skills
Signed-off-by: dongmucat <1127093059@qq.com>

# Conflicts:
#	server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/skill/service/SkillPublishService.java
2026-06-10 16:53:48 +08:00
dongmucat
f35f91616a fix(publish): preserve latest version reference cleanup order
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-10 16:51:35 +08:00
dongmucat
43d66a59e1 Merge remote-tracking branch 'origin/main' into HEAD
Signed-off-by: dongmucat <1127093059@qq.com>

# Conflicts:
#	server/skillhub-domain/src/test/java/com/iflytek/skillhub/domain/skill/service/SkillDownloadServiceTest.java
2026-06-09 14:29:03 +08:00
dongmucat
ed13a41ed8 fix(skill): align anonymous download helper with main
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-09 14:25:17 +08:00
dongmucat
4c4a888b01 fix(bootstrap): harden built-in skill startup sync
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-08 14:01:19 +08:00
dongmucat
6e094f4199 fix(skill): cap namespace bundle downloads
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-08 10:46:30 +08:00
XiaoSeS
531d59caf2
feat(my-skills): add keyword search, namespace filter and clickable pagination (#493)
* feat(my-skills): add keyword search, namespace filter and clickable pagination

Add comprehensive filtering and search capabilities to the My Skills page:

- Keyword search: search by skill name, slug, or description
- Namespace filter: filter skills by namespace
- Clickable pagination: page number buttons with smart ellipsis
- State preservation: sync search state to URL, restore when returning from detail page
- Debounced search: 300ms debounce to avoid excessive queries
- Fix: hide stale rejected preview badge when newer version is published

Backend changes:
- MySkillAppService: add keyword and namespace filtering logic
- SkillLifecycleProjectionService: only show preview versions newer than published
- MeController: add keyword and namespace query parameters
- 6 new test cases covering search and filter scenarios

Frontend changes:
- my-skills.tsx: search input, namespace dropdown, URL state sync
- pagination.tsx: clickable page numbers with ellipsis
- use-user-queries.ts: prevent flicker on query transitions
- skill-detail.tsx: remove invalid rejected badge display
- router.tsx: URL parameter validation
- i18n: add search-related translation keys

Synced from SAAS commits:
- 939fa749 (feat: search and filters)
- dc14df6c (fix: search flicker)
- 0168ea81 (fix: rejected badge)
- c9eefa93 (fix: stale preview)

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(tests): address test failures in PR #493

Backend test fixes:
- Remove unnecessary Mockito stubbing for filtered-out skills
- Add missing findBySkillIdAndStatus stub for published version lookup
- Update MeController test mocks to match new method signature (keyword, namespace params)

Frontend fixes:
- Fix TypeScript error: useMyNamespaces returns ManagedNamespace[] not PagedResponse
- Add type annotation for namespace map callback parameter

E2E test fix:
- Update URL regex to allow query parameters (returnTo from search page)

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(tests): resolve test failures in PR #493

Backend:
- Remove unnecessary mock stubbings for skillId 2 and 3 in MySkillAppServiceTest.listMySkills_combinesKeywordNamespaceAndStatusFilters
- The test filters results to only return skill with id=1, so mocks for id 2 and 3 were never called, causing UnnecessaryStubbingException

Frontend:
- Add missing mocks for useLocation, useSearch, useMyNamespaces, and useDebounce in my-skills.test.ts
- MySkillsPage component uses these hooks but the test setup didn't provide mocks, causing 'No QueryClient set' and 'No export' errors

All 4 frontend tests now pass locally.

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

---------

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-06-05 17:24:51 +08:00
XiaoSeS
31b25fb6c5
fix(domain): clear skill.latest_version_id before deleting skill_version (#495)
The PG FK constraint fk_skill_latest_version blocks deleting a
SkillVersion whenever Skill.latest_version_id still references it.
Two services had the wrong order:

- SkillPublishService.deleteReplaceableVersionArtifacts: triggered
  when re-uploading the same version (UPLOADED -> overwritten).
  Reproduced by AstronClaw client retrying personal-skills upload.

- SkillGovernanceService.deleteVersion: triggered when admin deletes
  a draft version that happens to be skill.latest_version_id.

Fix: clear skill.latest_version_id and flush BEFORE deleting the
SkillVersion row, so PG sees no live reference at delete time.

Synced from SAAS commit 4626f0c117d9c0544c4dc1115c3aac7468f0d277
2026-06-05 16:21:33 +08:00
XiaoSeS
2bb7dedaf4
feat(cli,domain): support non-global namespace skill download (#497)
* feat(cli,domain): support non-global namespace skill download

Parse namespace from skill name using -- separator (e.g.,
astroclaw--api-gateway) so users don't need --namespace flag.
Allow anonymous download for any PUBLIC skill regardless of namespace.

CLI changes:
- Add cli/src/shared/skill-name-parser.ts utility
- Update install and remove commands to parse skill name argument
- 10 unit tests covering edge cases

Domain changes:
- SkillDownloadService.isAnonymousDownloadAllowed: drop namespace
  type check, only require PUBLIC visibility
- Update test to expect success for team-namespace public skill

Synced from SAAS commit 26c67e31b1221249cf9b73321d1b726d8ba6e6df

* fix(cli): use bun:test instead of vitest in skill-name-parser test
2026-06-05 16:20:34 +08:00
dongmucat
6bb89b1c89 fix(skill): address namespace bundle review findings
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-04 17:12:44 +08:00
dongmucat
85c025a1b9 feat(skill): add namespace search and bundle download
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-04 15:23:09 +08:00
dongmucat
943294b558 fix(publish): address Codex review findings for dry-run
Fix three blockers and one contract drift issue surfaced in code review:

1. API token policy: add skill:publish scope policy and authentication
   policy for /api/cli/v1/skills/*/publish/validate. Without these the
   AntPathMatcher pattern /publish would not cover /publish/validate,
   so Bearer-token requests would be rejected by the scope filter.

2. Warnings semantics: dry-run now treats warnings as making valid=false.
   The CLI publish flow uses confirmWarnings=false, so the real publish
   rejects any warnings; dry-run must mirror that to avoid false positives.

3. Visibility parameter: validate endpoint now accepts the same
   visibility multipart field as publish. The CLI forwards --visibility
   so invalid values are caught at dry-run time rather than at publish.

4. Schema drift: resolvedSlug and resolvedVersion are nullable in
   practice (returned as null when validation fails before resolution).
   Updated schema.d.ts to reflect string | null instead of optional string.

Tests added:
- RouteSecurityPolicyRegistryTest: validate endpoint scope check
- CliDryRunValidateTest: custom + invalid visibility cases
- publish-dry-run.test.ts: --visibility forwarded to server
2026-05-18 14:50:14 +08:00
dongmucat
bdc94ad19c fix(publish): address code review findings for dry-run
- Exit non-zero (code 6) when --dry-run validation fails, enabling
  CI/CD pipeline integration
- Add archived skill check: dry-run now detects when the publisher's
  own skill is archived
- Add version-exists check: dry-run now detects when the resolved
  version is already published
- Use StandardCharsets.UTF_8 for SKILL.md content parsing
2026-05-18 10:57:14 +08:00
dongmucat
1067d0ff6e feat(publish): add --dry-run validation endpoint and CLI option
Add a validate-only endpoint (POST /api/cli/v1/skills/{namespace}/publish/validate)
that runs the full pre-publish validation chain without persisting anything.
This allows developers to check their package locally before actual publishing.

The validation covers:
- SKILL.md existence and frontmatter parsing (name, description required)
- File extension whitelist and size limits
- Credential leak scanning with line-number precision
- Slug generation and name conflict detection

CLI usage: `skillhub publish <path> --dry-run`

Closes #429
2026-05-18 10:36:58 +08:00
dongmucat
356e507cf9
Merge pull request #434 from iflytek/worktree-fix-promotion-download
fix(promotion): copy bundleReady and downloadReady when promoting skill to global
2026-05-14 15:50:06 +08:00
dongmucat
2af0bf184b fix(promotion): copy bundleReady and downloadReady when promoting skill to global
When approving a promotion, the new SkillVersion was created without copying
bundleReady and downloadReady from the source version, causing the download
button to be permanently disabled for promoted skills.
2026-05-14 14:32:36 +08:00
dongmucat
cebad0bbd7 refactor(security): use explicit SCANNING check in processScanResult
Gemini review feedback: the previous != PUBLISHED condition was too broad
and could inadvertently overwrite terminal states like REJECTED or YANKED.
Now explicitly check == SCANNING before transitioning status.
2026-05-11 13:56:08 +08:00
dongmucat
ec4598efec fix(security): trigger security scan for admin-published skills
Super admin auto-publish flow was skipping security scanning entirely.
Now triggerScan is called regardless of autoPublish flag, while preserving
the PUBLISHED status (scan runs as post-publish audit rather than blocking).

Closes #415
2026-05-11 11:36:08 +08:00
dongmucat
2821262fa4
Merge pull request #408 from iflytek/fix/namespace-delete-341
fix(namespace): support team namespace deletion
2026-05-09 15:04:06 +08:00
dongmucat
8dd1668555 fix(namespace): support team namespace deletion 2026-05-08 10:15:17 +08:00
dongmucat
5c95ab2b38 feat(skill): add version compare page with unified diff
Introduce a dedicated `/space/$namespace/$slug/compare` page that compares
two published skill versions GitHub-style: left file list + right unified
diff. Backend exposes `GET /versions/compare` returning structured diff
(computed via java-diff-utils) with per-file hunks, binary placeholder,
and truncation flags. Frontend uses two version selectors scoped to
PUBLISHED versions, a file search box, active-file highlighting, and
whitespace-preserving unified view. E2E covers the publish + rerelease
+ approve round trip; controller/domain tests cover happy path and
same-version rejection.
2026-05-07 09:45:26 +08:00
XiaoSeS
a3c07725e5
feat(publish): skill upload limits, nested SKILL.md, session fix (#364)
* feat(publish): increase max file count from 100 to 500

Configurable via SKILLHUB_PUBLISH_MAX_FILE_COUNT env var.

* feat(publish): support SKILL.md in subdirectory with warning for ignored files

When SKILL.md is found in a single subdirectory (e.g. my-skill/SKILL.md),
promote that directory's contents to root and discard files outside it.
Discarded files are reported as warnings through the existing confirm flow.

* feat(publish): pass extraction warnings through confirm flow

When files are ignored during SKILL.md subdirectory promotion,
warnings are surfaced to the user via the existing precheck confirm dialog.

* fix(security): add invalidSessionStrategy to return 401 on expired session

Handles the case where Spring Security detects an invalid session cookie,
returning a clean 401 JSON response instead of triggering cascading exceptions.
Closes #360 (part 1/2)

* fix(security): handle session invalidation IllegalStateException as 401

Catches IllegalStateException with "Session was invalidated" message and
returns 401 instead of letting it fall through to the generic 500 handler.
Non-session IllegalStateExceptions are re-thrown to the catch-all handler.
Closes #360 (part 2/2)

* feat(publish): filter macOS metadata and add integration tests

Skip __MACOSX/, .DS_Store, and ._ resource fork entries during zip
extraction. Add integration tests for nested SKILL.md warning flow,
session invalidation 401 response, and macOS metadata filtering.

* test(publish): add real-world macOS zip and edge case integration tests

Covers: macOS zip with nested SKILL.md + __MACOSX + .DS_Store + stray files,
simple macOS single-folder case, and missing SKILL.md fallback behavior.
2026-04-30 11:20:51 +08:00
dongmucat
4882abc043 fix(subscription): expose subscription count in skill detail API
Include subscriptionCount in SkillDetailDTO and SkillDetailResponse
so the frontend SubscribeButton receives the updated count after
subscribe/unsubscribe mutations.
2026-04-29 10:56:20 +08:00
dongmucat
6f0103f013 feat(subscription): publish SkillVersionYankedEvent on version yank 2026-04-27 16:50:38 +08:00
dongmucat
a2aa4c3fb1 feat(subscription): update subscription count on subscribe/unsubscribe 2026-04-27 16:47:14 +08:00
dongmucat
9d4422cd6c feat(subscription): add increment/decrement subscription count methods 2026-04-27 16:46:34 +08:00
dongmucat
79f1aa4db1 feat(subscription): add subscriptionCount field to Skill entity 2026-04-27 16:44:34 +08:00
dongmucat
1567a67bdd feat(subscription): add SkillSubscriptionService domain service 2026-04-27 16:43:15 +08:00
dongmucat
7391c26843 feat(subscription): add subscription and version yanked domain events 2026-04-27 16:42:50 +08:00
dongmucat
9c05e91a6c feat(subscription): add SkillSubscription entity and repository interface 2026-04-27 16:40:34 +08:00
dongmucat
3739c7879b
Merge pull request #305 from iflytek/fix/bootstrap-admin-role-backfill
fix(auth): backfill bootstrap admin role binding
2026-04-23 10:11:43 +08:00
dongmucat
2cfd4a730b
Merge pull request #302 from iflytek/fix/rerelease-precheck-warnings
fix(rerelease): support precheck warning confirmation flow
2026-04-14 20:28:00 +08:00
dongmucat
5d87a0ccd3
Merge pull request #304 from iflytek/feat/oss-02-super-admin-visibility
feat(access): add SUPER_ADMIN platform role support
2026-04-14 20:27:39 +08:00
dongmucat
2334aa6a5a fix(review): avoid stale promotion approval save 2026-04-14 20:02:41 +08:00
xiose
7c2f06d1b6 test(rerelease): add confirmWarnings coverage and sync generated schema
- Add domain tests for rerelease with precheck warnings (reject + confirm)
- Add controller test verifying confirmWarnings passthrough
- Sync SkillVersionRereleaseRequest generated type with backend DTO
2026-04-14 17:55:56 +08:00
dongmucat
1246cca930
Merge pull request #279 from iflytek/fix/issue-276-review-own-namespace
fix(review): allow namespace admins to review own submissions
2026-04-14 17:22:08 +08:00
xiose
edcc248244 fix(portal): keep skill detail on viewer permissions 2026-04-14 16:42:22 +08:00
dongmucat
082d97a69d fix(review): handle promotion target skill conflicts 2026-04-14 16:23:31 +08:00
xiose
9801b549fc feat(access): add SUPER_ADMIN platform role support
- Add platformRoles parameter to VisibilityChecker.canAccess() for platform-level access control
- SUPER_ADMIN can access all skills regardless of visibility or publication status
- Add archived namespace check to SkillQueryService.getSkillDetail()
- Extract platformRoles from AuthContext in SkillController
- Replace VisibilityChecker mock with real instance in SkillQueryServiceTest
- Add 5 new tests for SUPER_ADMIN access scenarios
- Add version-status-badge.tsx component for frontend status display

Tests: 347 domain tests + 16 app tests passing
2026-04-14 14:18:43 +08:00
dongmucat
9644d50fbb Revert "fix(review): allow super admins to approve own promotions"
This reverts commit 738f8b33b8.
2026-04-14 14:02:48 +08:00
dongmucat
738f8b33b8 fix(review): allow super admins to approve own promotions 2026-04-14 13:56:52 +08:00