Commit graph

1358 commits

Author SHA1 Message Date
XiaoSeS
a88b09e51b fix(publish): accept case-insensitive SKILL.md uploads 2026-06-11 16:34:13 +08:00
yuchangfu
ffbaa15243 Merge branch 'main-1' 2026-06-11 11:53:47 +08:00
yuchangfu
92e7bd3def feat(redis): add standalone and cluster mode support with backward compatibility 2026-06-11 11:52:25 +08:00
dongmucat
8045e52f5e feat(bootstrap): add skillhub hello builtin skill
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-11 11:20:27 +08:00
dongmucat
d58c934d64
Merge pull request #482 from iflytek/feature/namespace-search-download
feat(skill): add namespace search and bundle download
2026-06-10 20:10:32 +08:00
dongmucat
920e6889e7 fix(web): remove namespace download residuals
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-10 19:48:32 +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
201e636858 test(web): add namespace search-only regression
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-10 19:48:16 +08:00
dongmucat
04348f5022 chore: sync schema.d.ts — remove namespace bundle download paths and operations
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-10 19:48:06 +08:00
dongmucat
738e8f8cee fix(web): stabilize frontend validation
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-10 18:00:10 +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
6779c1eecd
feat(web): preview relative markdown package links (#502)
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-10 16:31:22 +08:00
dongmucat
1b09ab88a2 fix(bootstrap): enforce strict builtin skill skips
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-10 14:19:41 +08:00
dongmucat
dd3e511a91 fix(bootstrap): support skill directory archives
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-10 10:31:40 +08:00
jangrui
2b1be5ccf8 fix(ci): kubeconform 加载 CRD schema 修复 cert-manager 校验失败
ingress-tls-certmanager 场景渲染出 cert-manager 的 Certificate CRD,
kubeconform 默认仅内置原生 k8s schema,遇到 CRD 报 "could not find schema"。

追加 -schema-location 从 datreeio/CRDs-catalog 远程加载 CRD schema,
覆盖整个 catalog 收录的 CRD 资源,9 场景矩阵无需差异化处理。

Signed-off-by: jangrui <admin@jangrui.com>
2026-06-09 17:17:06 +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
973c37613e fix(bootstrap): harden builtin skill sync
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-09 14:19:25 +08:00
dongmucat
b5edfb850e fix(web): clarify namespace bundle download limits
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-09 10:02:26 +08:00
dongmucat
973c336c82 fix(auth): protect builtin system account boundaries
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-08 18:01:20 +08:00
Xudong Sun
7e23508a32
chore(logging): include idempotency cleanup threshold 2026-06-08 17:31:07 +08:00
dongmucat
5cc934a294 fix(bootstrap): harden builtin skill startup sync
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-08 15:20:10 +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
dongmucat
6dc62ddfb8
feat(web): add install method tabs (#496)
* feat(web): add install method tabs

Signed-off-by: dongmucat <1127093059@qq.com>

* test(web): stabilize real service e2e checks

Signed-off-by: dongmucat <1127093059@qq.com>

* style(web): simplify install tab indicator

Signed-off-by: dongmucat <1127093059@qq.com>

---------

Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-05 17:27:34 +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
dongmucat
0f752e2305 docs(bootstrap): add built-in skill cloud setup guide
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-05 17:16:25 +08:00
dongmucat
9bb6b31db7 feat(bootstrap): sync built-in skills from cloud manifest
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-05 16:27:02 +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
04caf21e76
fix(audit): resolve 8-hour timezone offset in audit log timestamps (#472)
## Problem
Audit log timestamps displayed 8 hours later than actual time when JVM
default timezone != UTC. Root cause: `audit_log.created_at` was
`TIMESTAMP without time zone`, and `rs.getTimestamp()` interprets bare
values using JVM timezone.

## Solution
### Backend
- **V42 migration**: Upgrade `audit_log.created_at` from `TIMESTAMP` to
  `TIMESTAMPTZ`, anchor historical data as UTC via `USING created_at AT
  TIME ZONE 'UTC'` (same pattern as V18/V19/V23/V25/V36)
- **Read path**: `AdminAuditLogAppService.readInstant()` uses
  `rs.getObject(col, OffsetDateTime.class).toInstant()`, result
  independent of JVM timezone
- **Write path (filter params)**: `startTime`/`endTime` binding changed
  from `Timestamp.from()` to `OffsetDateTime.ofInstant(instant,
  ZoneOffset.UTC)` via `toUtcOffsetDateTime()` helper, symmetric with
  read path

### Migration Safety
- `SET LOCAL lock_timeout = '30s'` (transaction-scoped, won't leak to pool)
- `DO $$ ... IF data_type = 'timestamp without time zone' THEN ... ELSE
  ... END $$` idempotent guard with dual-branch `RAISE NOTICE`
- Safe retry: re-running won't double-apply `AT TIME ZONE 'UTC'`

### Test Coverage (10 tests, 477 total suite)
- `rowMapper_readsCreatedAtAsInstant` — UTC offset regression
- `rowMapper_normalisesNonUtcOffsetToInstant` — Non-UTC offset (+08:00)
- `rowMapper_returnsNullTimestampWhenColumnIsNull` — Null path
- `rowMapper_isIndependentOfJvmDefaultTimezone` — JVM TZ=Asia/Shanghai
  drift prevention with `verify(rs, never()).getTimestamp()`
- `@ParameterizedTest buildWhereClause_bindsTimeRangeAsOffsetDateTime` —
  3 cases (both/startOnly/endOnly) for filter param binding
- `@BeforeEach setUp()` — Mock isolation to prevent cross-test stub
  accumulation

## Quality Gates
- [x] `make test-backend-app` passes (477 tests, 0 failures)
- [x] No Controller changes, `make generate-api` not needed
- [x] No frontend changes, typecheck/lint/e2e not needed

## Deployment
V42 must run before new code (guaranteed by Spring Boot startup sequence
→ Flyway executes before app accepts traffic). Rolling deployment:
- New pod + migrated column: correct
- Old pod + migrated column: old code reads TIMESTAMPTZ correctly (pgjdbc
  returns absolute instant)

## Related Docs
- `docs/15-backend-time-governance-plan.md` §3.1: V42 progress registered
- `docs/16-backend-time-inventory.md` §3.1: V42 listed
- Same migration pattern: V18/V19/V23/V25/V36
2026-06-05 15:28:12 +08:00
dongmucat
1ec93db0d6
Revert "feat(bootstrap): initialize built-in skills (#481)" (#487)
This reverts commit 90fc97e740.
2026-06-05 11:25:02 +08:00
dongmucat
90fc97e740
feat(bootstrap): initialize built-in skills (#481)
* feat(bootstrap): initialize built-in skills

Signed-off-by: dongmucat <1127093059@qq.com>

* docs(builtin-skills): remove implementation plan

Signed-off-by: dongmucat <1127093059@qq.com>

---------

Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-05 10:27:37 +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
204f52dd30 test(web): add namespace search download e2e coverage
Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-04 15:49:40 +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
jangrui
0605357316 fix(chart): 修复 PR review 反馈项
- 删除 subchart image block,使用 Bitnami 默认版本
- 移除 Ingress cert-manager annotation,消除双重签发
- 清空默认明文密码,改为空字符串
- 排除 tgz 进 git,CI 添加 helm dependency build
- checksum 改为模板级渲染,修复文件末尾换行
- sentinel default 3,列表生成改用 append+join
- 添加 externalRedis.sentinel.password 字段
- README 补充 existingSecret key 清单
- CI 添加 kubeconform -strict 校验
- RedissonConfig 添加注释,补充空密码测试用例

Signed-off-by: jangrui <admin@jangrui.com>
2026-06-04 06:35:28 +08:00
yaffir
f5f42454f7
自动屏蔽 placeholder OAuth provider
Added a method to validate OAuth provider configurations based on client ID.

Signed-off-by: yaffir <97219715+yaffir@users.noreply.github.com>
2026-06-03 16:31:48 +08:00
Cheney
0b1c366f8d
refactor(cli): improve publish-cli script reliability (#441)
* refactor(cli): improve publish-cli script reliability

- Move version computation and pre-flight checks before build-and-test
  to fail fast on conflicts (existing branch/tag) instead of wasting
  minutes on lint/test/build
- Add INT/TERM signal handlers to cleanup trap so Ctrl+C during build
  properly restores working tree state
- Update Makefile help text to reflect PR-based workflow

* fix(cli): use git checkout -f for robust cleanup

Address code review feedback from gemini-code-assist bot:

- Use `git checkout -f` in on-release and committed cleanup stages
  to ensure reliable branch switching even when files are staged
  but not committed (e.g., interrupted after `git add` but before
  `git commit`)
- Remove redundant `git checkout -- <file>` in on-release stage
  since `-f` already discards all local changes

This prevents cleanup failures when the script is interrupted
between staging and committing.

* fix(cli): address PR #441 review findings

- Fix ERR trap bypass: remove `if !` wrapper around `gh pr create` so
  set -e triggers the trap and prints pushed-stage recovery instructions
- Fix command injection: all node -e/-p calls now use process.env
  instead of interpolating shell variables into JS string literals
- Rewrite cli/RELEASE.md to document the new PR-based release flow
- Rewrite scripts/tests/publish-cli-test.sh with 10 tests covering
  the new flow (stubs for bun/gh, pre-flight checks, happy path,
  cleanup state machine stages)

* fix(cli): address PR #441 review findings from @dongmucat

- Bind release tag to origin/main: PR body, end-of-run hint, and
  cli/RELEASE.md now use `git tag $TAG origin/main` so the tag is
  always placed on the merged commit, regardless of local branch state
- Reject prerelease tags in version computation: if the latest cli-v*
  tag contains non-X.Y.Z characters (e.g., -rc.1), exit with a clear
  message instead of crashing in node parsing
- Add pr-scripts.yml workflow: runs publish-cli-test.sh on scripts/**
  changes so the release script regression suite gates PRs
- Add Test 11 covering prerelease tag rejection

* fix(cli): compute publish baseline from origin tags only

A failed `git push origin cli-vX.Y.Z` after a successful local tag
leaves an orphan tag locally. The previous `git tag --list` baseline
would then treat it as the latest release, causing skipped versions or
publishes based on an unreleased tag.

Switch to `git ls-remote --tags --refs origin 'cli-v*' | sort -V` so
the baseline reflects only what is actually on origin. Local orphan
tags can still collide with the computed target tag, which fails fast
with a clear message as before.

Adds test 12 covering the orphan-tag scenario.
2026-06-02 14:30:39 +08:00
dongmucat
b7b8fd3d5d
fix(deps): bump vitest to 4.1 to patch GHSA-5xrq-8626-4rwp (#474)
Vitest <4.1.0 allows arbitrary file read/execution when the UI server is
listening (GHSA-5xrq-8626-4rwp, severity: critical). Bumps vitest from
3.2.4 to 4.1.x, which also flows through to the bundled @vitest/* packages
in pnpm-lock.yaml.

Adjusts two tests for the stricter v4 mock contract: `new`-callable mocks
must be backed by a `function`/`class` implementation rather than an
arrow function (web/src/shared/lib/date-time.test.ts,
web/src/app/providers.test.ts).

Signed-off-by: dongmucat <1127093059@qq.com>
2026-06-02 10:52:29 +08:00
jangrui
07c97cf7cd feat(server): 支持 Redis Sentinel 模式密码配置
- RedissonConfig 根据 spring.profiles.active 切换普通/Sentinel密码
- 新增 application-redis-sentinel.yml 专属 Spring profile
- 新增 RedissonConfigTest 覆盖普通和 Sentinel 两种模式用例

Signed-off-by: jangrui <admin@jangrui.com>
2026-06-01 20:59:58 +08:00
jangrui
906c7f9884 feat(chart): 集成 Bitnami 组件并重构高可用配置
- 使用 Bitnami PostgreSQL/Redis subchart 替代内置 StatefulSet
- 新增 sentinel 模式密码分离(redis-sentinel-password)
- 修复证书 secretName 与 Ingress 动态一致性
- 清理 ConfigMap 未引用字段,Service 模板去重
- CI 矩阵修复 sentinel 参数并扩展至 9 场景
- 命名空间硬编码替换为动态 $.Release.Namespace

Signed-off-by: jangrui <admin@jangrui.com>
2026-06-01 20:59:58 +08:00
jangrui
5909bc1a1a 修复 Helm:解决 CI 流水线故障与模板边界场景
- 修复 S3 存储模式下卷挂载条件渲染
- CI 多行参数不再被 YAML 尾随换行符截断
- 移除未使用的 database.architecture 字段
- 简化 Helm Chart 发布工作流

Signed-off-by: jangrui <admin@jangrui.com>
2026-06-01 20:59:58 +08:00
jangrui
6ed5fb34dc commit -m "fix(ci): 修复 helm lint 缺少路径参数和 grep -c 在 bash -e 下的退出码问题"
Signed-off-by: jangrui <admin@jangrui.com>
2026-06-01 20:59:58 +08:00
jangrui
396ae4a55f feat(chart): 添加组件级镜像标签配置以支持个性化镜像版本
Signed-off-by: jangrui <admin@jangrui.com>
2026-06-01 20:59:58 +08:00
jangrui
0ddb392086 feat(chart): 添加 Helm Chart 发布工作流
Signed-off-by: jangrui <admin@jangrui.com>
2026-06-01 20:59:58 +08:00
jangrui
58bb062993 feat(chart): 镜像 tag 与 Chart.yaml appVersion 联动
values.yaml 中 images.tag 留空时自动取 Chart.yaml 的 appVersion,
格式为 v{appVersion}(如 0.2.8 → v0.2.8)。
用户仍可通过 --set images.tag=xxx 显式覆盖。

Signed-off-by: jangrui <admin@jangrui.com>
2026-06-01 20:59:58 +08:00
jangrui
8a37801862 fix(chart): 修复安全、兼容及可维护性问题
- secret.yaml: lookup 检查现有 Secret 避免 upgrade 重新生成密码
- secret.yaml: Redis/S3 凭据通过 Secret 引用,移除明文环境变量
- backend/frontend/scanner: 新增 checksum 注解,配置变更自动触发滚动更新
- backend/frontend/scanner: 镜像地址支持 global.imageRegistry 覆盖
- postgres: internal 模式仅支持单副本,移除伪集群配置
- postgres: 探针用户名改用 POSTGRES_USER 环境变量
- values.yaml: accessMode 默认 ReadWriteMany,tag 指定 v0.2.8

Signed-off-by: jangrui <admin@jangrui.com>
2026-06-01 20:59:58 +08:00
jangrui
dd1e87f1f3 feat(chart): 添加 SkillHub Helm Chart 部署方案
新增 Helm Chart 支持完整的 SkillHub 私有化部署,包括:

- PostgreSQL/Redis 内置 StatefulSet 及外部模式切换
- 零依赖设计,无需 Bitnami 子 Chart
- 支持 standalone/cluster 数据库架构
- NodePort/LoadBalancer/ClusterIP 多种服务类型
- HPA、PDB、ServiceMonitor 完整运维支持
- cert-manager 证书自动签发
- initContainer 等待数据库和 Redis 就绪
- PVC 卸载保护 (helm.sh/resource-policy: keep)
- GitHub Actions: PR 校验 + 发布到 GHCR OCI

Signed-off-by: jangrui <admin@jangrui.com>
2026-06-01 20:59:58 +08:00