Commit graph

1475 commits

Author SHA1 Message Date
FenjuFu
91d0ae1504
feat(api): return skill labels from the skill listing endpoints on request (#730)
* feat(api): return skill labels from the skill listing endpoints on request

Skill labels were reachable only one skill at a time, through
/api/{v1,web}/skills/{namespace}/{slug}/labels, so a client rendering a list had
to issue a follow-up request per row.

Add includeLabels=true to GET /api/v1/skills and GET /api/web/skills. The labels
array is populated only when the parameter is set and left out of the payload
otherwise, so existing responses are byte-identical.

Labels for the whole page are resolved by SkillLabelProjectionService in three
queries — assignments, definitions, translations — rather than three per skill.

Closes #710

Signed-off-by: FenjuFu <fufenjupku@gmail.com>

* fix(api): use include parameter for skill labels

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

* test(api): reject unsupported include before search

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

---------

Signed-off-by: FenjuFu <fufenjupku@gmail.com>
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
Co-authored-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-25 13:49:24 +08:00
FenjuFu
1c3e9be9e9
fix(web): self-host Inter and JetBrains Mono fonts (#753)
* fix(web): self-host Inter and JetBrains Mono fonts

web/index.html loaded Inter + JetBrains Mono from fonts.googleapis.com at
runtime. On networks where Google Fonts is slow or unreachable (e.g. CN),
that stylesheet blocks first paint for tens of seconds (#716).

Vendor the same woff2 (from the @fontsource distribution) under
web/public/fonts and declare them in fonts.css with latin/latin-ext
unicode-range splits and font-display: swap, then point index.html at the
local stylesheet and drop the fonts.googleapis.com / fonts.gstatic.com hosts
from the page CSP. Only Inter and JetBrains Mono were ever fetched from the
CDN, so families and weights are unchanged; no external font requests remain.

Closes #716

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>

* docs(web): record vendored font licenses

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

---------

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
Co-authored-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-25 13:49:08 +08:00
FenjuFu
954dfce7a4
fix(publish): accept Windows zip directory entries (#742)
* fix(publish): accept Windows zip directory entries

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>

* chore: restore repository line endings

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>

---------

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
2026-08-24 19:58:18 +08:00
FenjuFu
d5c6411ce6
fix(i18n): disable host locale fallback (#741)
Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
2026-08-24 19:54:05 +08:00
wurongjie
b807fb3ee1 fix(security): harden CSP policy and hide nginx server tokens
- Remove 'unsafe-inline' and 'unsafe-eval' from script-src directive
- Restrict connect-src to 'self' only
- Disable nginx server_tokens to hide version information

Signed-off-by: wurongjie <wurongjie@uniontech.com>
2026-08-24 17:02:42 +08:00
FenjuFu
f846da230c
feat: add initial RISC-V image support (#725)
Some checks failed
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
Deploy Docs / build (push) Has been cancelled
Deploy Docs / Deploy (push) Has been cancelled
* feat: add initial RISC-V image support

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>

* chore(ci): tighten riscv64 image guardrails

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

---------

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
Co-authored-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-24 16:37:34 +08:00
XiaoSeS
1b7a6d5544
chore(deps): resolve dependabot npm alerts
Resolve open npm Dependabot alerts for the web app and docs site by refreshing dependency overrides and lockfiles.

Also sets the staging web forwarded-proto default so `make staging` can render the shared Nginx template when using the bare nginx image.

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-24 16:08:07 +08:00
XiaoSeS
9fa6c52a4d
docs(troubleshooting): broaden postgres volume permission guidance (#745)
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-24 14:25:28 +08:00
FenjuFu
183729613c
docs(faq): add CLI namespace-not-found and PostgreSQL permission entries (#743)
Add two entries collected from community support, to both the zh docs and
the en i18n mirror:

- FAQ: installing a skill via CLI reporting `namespace not found` — set the
  registry / log in with an API token, and use the correct namespace slug
  (`@team/skill` -> `team--skill`); the web UI Install button provides a
  ready-made command.
- Troubleshooting: PostgreSQL container failing to start with
  `operation not permitted` on bind mounts — fix data volume ownership
  (`chown 999:999`), check SELinux, or use the `runtime.sh` script.

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
2026-08-24 13:39:49 +08:00
XiaoSeS
e8cab7389f
Merge pull request #739 from iflytek/docs/weekly-w34-official
Some checks failed
Deploy Docs / build (push) Has been cancelled
Security / Dependency Review (push) Has been cancelled
Security / CodeQL (java-kotlin) (push) Has been cancelled
Security / CodeQL (javascript-typescript) (push) Has been cancelled
Security / CodeQL (python) (push) Has been cancelled
Deploy Docs / Deploy (push) Has been cancelled
docs(weekly): publish 2026 W34 report
2026-08-21 18:46:19 +08:00
XiaoSeS
67d39f04f6 docs(weekly): mirror reviewed W34 report
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-21 18:42:52 +08:00
XiaoSeS
15ce199e1a
fix(publish): emit event on confirm publish (#738)
Some checks are pending
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-21 17:52:25 +08:00
FenjuFu
fa04d2fa23
fix(auth): close API token policy gaps against the authorization list (#729)
RouteSecurityPolicyRegistry keeps two policy lists — AUTHORIZATION_POLICIES for
session/cookie access and API_TOKEN_POLICIES for Bearer tokens — with nothing
keeping them in step. Routes the authorization list opens but the token list
never registers fall through to the catch-all and answer
API token cannot access endpoint: <path>.

Register the routes reported in #713 (/api/v1/labels, the star and rating
writes) plus the same-class gaps for /api/v1/auth/methods and paths below
/api/v1/download, and add a guard test that walks the authorization list and
fails when a route is neither token-reachable nor declared session-only.

DELETE /api/v1/skills/{id}/star also matched the SUPER_ADMIN rule for
DELETE /api/v1/skills/*/*, so un-starring was refused for ordinary accounts on
the session path too. Star and rating writes now have their own authorization
entries ahead of that rule.

Closes #713

Signed-off-by: FenjuFu <fufenjupku@gmail.com>
2026-08-21 16:08:50 +08:00
FenjuFu
51457bfa2c
fix(security): 扫描任务改为事务提交后发布 (Closes #612) (#733)
* fix(security): publish scan task after transaction commit

SecurityScanService.triggerScan is @Transactional but published the Redis
Stream scan task inline, before the transaction committed. The stream
consumer could receive the task before the skill_version / security_audit
rows were visible, fail with "SkillVersion not found" / "SecurityAudit not
found", exhaust its immediate retries while the publishing transaction was
still open, and leave the committed version stuck in SCANNING.

Defer the publish to an afterCommit transaction synchronization so the
consumer only ever sees the task once the rows are committed and visible; on
rollback the task is never published. Falls back to an inline publish when
called outside a transaction.

Closes #612

Signed-off-by: FenjuFu <fufenjupku@gmail.com>

* test(security): cover scan task after-commit publishing

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

* refactor(security): hide scan publish transaction callback

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

---------

Signed-off-by: FenjuFu <fufenjupku@gmail.com>
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
Co-authored-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-21 14:18:40 +08:00
FenjuFu
bbdc0f7a0c
fix(dev): use bash for backend launchers (#721)
Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
2026-08-21 09:35:52 +08:00
XiaoSeS
c3ecafb206
Merge pull request #736 from iflytek/docs/weekly-w33-official
Some checks failed
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
Deploy Docs / build (push) Has been cancelled
Deploy Docs / Deploy (push) Has been cancelled
docs(weekly): mirror reviewed W33 report
2026-08-20 17:22:32 +08:00
XiaoSeS
f77e32ada5 docs(weekly): mirror reviewed W33 report
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-20 17:19:01 +08:00
mrLi
84feb38931 feat(cli): add namespace workspace sync
Signed-off-by: mrLi <50289372+15258725278@users.noreply.github.com>
2026-08-18 18:24:11 +08:00
青柠
7247defd5d feat(web): pick default namespaces from a list instead of typing slugs
The setting took a comma-separated string, which puts the operator in the
position of remembering exact slugs and getting the punctuation right. The
server rejects a bad slug, but only after a round trip, and only for the
first mistake in the list.

Offer the active namespaces as checkboxes instead. Nothing to spell.

One case the list alone would get wrong: a slug that is configured but has
since been deleted, archived or renamed is not among the choices, so
rendering only the choices would quietly drop it on the next save. Those are
appended as their own rows, ticked and flagged, so dropping one is a decision
rather than a side effect.

The choice list is capped, and a directory larger than the cap says so rather
than presenting a partial list as complete.
2026-08-17 00:44:02 +08:00
青柠
a9e7f43e5a feat(namespace): let operators choose which namespaces new accounts join
A deployment that stands up its own organisation-wide namespace — to use
instead of the built-in global one — finds it invisible to everybody. The
namespace listing only returns namespaces the caller belongs to, and the
only thing that ever added members automatically was hard-wired to the slug
"global".

Make that list a setting. namespace.default-membership holds the slugs every
newly activated account is enrolled in, defaulting to ["global"], which is
what every deployment did before. Publishing only requires membership of any
role, so being enrolled is enough to publish there; no extra grant needed.

GlobalNamespaceMembershipService becomes DefaultNamespaceMembershipService,
since it no longer means one specific namespace.

Where the strictness sits:

- Saving validates every slug resolves to an ACTIVE namespace, so a typo
  fails at the moment an administrator makes it.
- Enrolling tolerates a slug that no longer resolves: it logs and skips.
  A namespace that was deleted or renamed must not cost somebody their
  login.

Adding a namespace to the list after people have signed up leaves them out,
the same trap the personal-namespace work hit, so this ships with the same
preview-then-apply backfill.

Verified against a real PostgreSQL, end to end: create a namespace, reject an
unknown slug, save with whitespace and duplicates and see them normalised,
preview, apply, re-preview showing nothing left, and a fresh registration
landing in the global namespace, the new shared one, and its own personal one
at once.
2026-08-16 20:31:46 +08:00
青柠
4fe6948f87 fix(web): stop the settings form from reverting the saved value
Enabling personal namespace provisioning appeared to save — the request
succeeded and the row held enabled=true — but a refresh showed it disabled
again, and the template inputs stayed greyed out.

The form mounted before the fetched settings reached it. Radix's Select
keeps a hidden native <select> for form integration, and its <option>s only
exist while the dropdown content is mounted. Changing the controlled value
from "disabled" to "enabled" therefore assigned a value that native select
had no option for, which lands on "" and fires a real change event. Radix
forwarded it as onValueChange(""), which read as "disabled" and put the
form straight back where it started.

Hold the form state as null until the settings arrive, so the Select mounts
once with the value it will keep and the controlled value never changes
underneath it. Also ignore any value that is not one of the two real
choices, so a stray event cannot decide the setting.

The page's other Select-bearing sibling never hit this because it lives in
a dialog whose form state is set before the dialog mounts.

The old test rendered with renderToStaticMarkup, which never runs effects
and so could not see this at all. The page tests now run in jsdom via
@testing-library/react; the new one was confirmed to fail against the
previous code and pass against this one. Also verified in a browser against
a real backend: enable, save, reload, disable, save, reload.
2026-08-16 19:20:28 +08:00
青柠
639e081ca7 fix(namespace): stop the backfill from querying with a null keyword
The backfill preview returned 500 on PostgreSQL:

    SQLState 42883: function lower(bytea) does not exist

It reused UserAccountRepository.search(keyword, status, pageable) with a
null keyword. That query compares the keyword with lower(...), and a null
bind leaves PostgreSQL to infer the parameter type as bytea, so lower()
has no matching signature.

Nothing had exercised that branch before: the admin user list goes through
AdminUserSearchRepository, and the member-candidate lookup always passes a
real keyword. The backfill was the first caller to pass null.

Give callers that want every account in a status a query without a keyword
to bind, rather than papering over the null with a cast or an empty string.

Neither test layer would have caught this. The unit tests mock the
repository, and the integration tests run on H2 in PostgreSQL mode, which
accepts the null-typed bind that PostgreSQL rejects. Verified instead
against a real PostgreSQL: preview, apply, and a second preview showing
alreadyProvisioned with nothing left to do, with namespace_member rows
confirming each owner holds OWNER on a TEAM namespace.
2026-08-15 18:10:48 +08:00
青柠
2d50437e4f feat(namespace): backfill personal namespaces for existing accounts
Turning provisioning on only affects accounts activated afterwards, which
on a registry that has already been running means nobody. The first person
to hit this on our deployment was the operator who enabled it: they signed
in, got no namespace, and had no way to find out why.

Two fixes.

Backfill. POST /api/v1/admin/settings/personal-namespace/backfill walks the
active accounts and gives a namespace to those without one, skipping system
accounts and anyone who already owns a non-global namespace. Details worth
knowing:

- dryRun reports the plan — each account and the slug it would take —
  without writing. The console requires a preview before it will enable the
  apply button.
- The response lists only accounts that changed or could not be placed;
  the rest are counted, so an operator reads the work rather than the whole
  directory.
- A run stops at a per-run account cap and reports truncated rather than
  looking like it covered everything.
- Slugs promised earlier in a run are reserved, so one batch cannot hand
  the same slug to two accounts.
- Not @Transactional: each namespace is created in its own transaction, so
  an account that cannot be placed does not discard the rest of the run.

Diagnosability. The skip paths — provisioning disabled, account already owns
a namespace, no slug available — were silent returns, which is why "nothing
happened and I cannot tell why" was the actual user experience. They now log
their reason; account activation is rare enough that the extra lines cost
nothing.
2026-08-15 01:11:51 +08:00
青柠
ae23d1a051 feat(namespace): auto-provision a personal namespace on registration
Self-hosted deployments want every new account to have somewhere of its
own to publish, without asking an administrator for a namespace first and
without pushing drafts into `global`.

Add an operator-controlled policy, off by default so upgrading changes no
behaviour. When enabled, an account that becomes usable gets a namespace
it owns. "Private" here means a team namespace whose only member is that
account: namespaces have no visibility flag, and skill visibility stays a
property of each skill.

Trigger points. UserActivatedEvent is published wherever an account first
becomes usable:

- LocalAuthService.register
- IdentityBindingService.bindOrCreate, for ACTIVE first logins
- AdminUserAppService.updateUserStatus, on a transition into ACTIVE

The third matters for deployments that gate access behind approval: those
accounts are created PENDING at the first OAuth attempt and only become
usable when an administrator approves them.

Why an AFTER_COMMIT listener rather than a call alongside
GlobalNamespaceMembershipService.ensureMember. Both namespace.created_by
and namespace_member.user_id reference user_account(id), which rules out
each obvious alternative:

- Joining the registration transaction lets a slug clash roll the
  registration back, so a namespace failure costs the user their account
  — or, on OAuth, their login.
- Suspending it with REQUIRES_NEW leaves the new transaction unable to see
  the uncommitted user_account row, so the foreign key check blocks on the
  outer transaction's row lock and the two wait on each other.

Provisioning after commit avoids both. The listener is deliberately not
@Async, so the namespace exists by the time the user's next request
arrives, and it swallows failures.

Naming. Two templates over ${username}, ${email_prefix} and ${user_id};
unknown placeholders are left in place so a typo is visible rather than
silently dropped. ${username} falls back to the email local part and then
to the user id. Slugs go through the existing slug rules, which is why the
console renders a live preview: underscores are not legal in a slug, so
`${username}_space` yields `alice-space`. A taken or reserved candidate
gets a numeric suffix, so `admin` becomes `admin-2`. Owning any non-global
namespace already skips provisioning, which keeps re-enabling an account
from handing out a second one.

The templates are not exposed in application.yml: they contain ${...},
which Spring would resolve as property references, and Boot 3.2 predates
placeholder escaping. Only the enable flag lives there; templates are set
in the console and default from PersonalNamespaceProvisioningProperties.

Updating the policy writes an audit entry with the before and after.
2026-08-13 18:17:25 +08:00
青柠
68f120c5e1 feat(admin): add system settings storage
SkillHub has no mechanism for settings an operator can change without a
redeploy: the only per-deployment knobs live in application.yml, and the
only stored preferences are per-user notification preferences.

Add a generic store. One row holds one setting group serialized as JSON,
so a group can gain fields without a schema migration.

Reads take the caller's defaults:

    <T> T get(String settingKey, Class<T> type, T defaults)

which gives two properties worth keeping:

- A group nobody has overridden has no row, and resolves to whatever the
  deployment configured. Configuration-file-only deployments keep working
  exactly as before, and an upgrade changes no behaviour.
- A stored document that can no longer be parsed also falls back to the
  defaults, with a warning. One malformed row must not take down the flows
  that read settings, such as login.

Groups are deserialized with unknown fields ignored so a rolling upgrade
can read documents written by a newer node.

No consumer yet; the following commit adds the first one.
2026-08-13 18:17:02 +08:00
XiaoSeS
d2403bb591
feat(namespace): add admin namespace management
Some checks failed
Security / Dependency Review (push) Has been cancelled
Security / CodeQL (java-kotlin) (push) Has been cancelled
Security / CodeQL (javascript-typescript) (push) Has been cancelled
Security / CodeQL (python) (push) Has been cancelled
Closes #580
2026-08-12 12:39:24 +08:00
XiaoSeS
81be20a6b5
fix(namespace): let super admin view namespaces (#705)
Some checks failed
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
Deploy Docs / build (push) Has been cancelled
Deploy Docs / Deploy (push) Has been cancelled
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-11 16:04:28 +08:00
XiaoSeS
76d95b615e
docs(compliance): document runtime integration contract (#704)
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-11 13:43:42 +08:00
XiaoSeS
2fe7514a4e
feat(review): show compliance declaration diffs (#703) 2026-08-11 10:44:11 +08:00
XiaoSeS
0690e3f256
Merge pull request #698 from iflytek/fix/runtime-aliyun-stop-url
Some checks are pending
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
fix(deploy): correct Aliyun runtime stop URL
2026-08-10 16:13:10 +08:00
XiaoSeS
c56e21e4bb
Merge pull request #699 from iflytek/feat/compliance-search-detail-projection
feat(search): surface compliance mappings in discovery
2026-08-10 15:00:39 +08:00
XiaoSeS
1dfe3756a9 feat(search): refine compliance discovery interactions
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-10 10:42:19 +08:00
XiaoSeS
4efeed18c8 fix(deploy): preserve Aliyun source mode in stop command
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-07 18:20:06 +08:00
XiaoSeS
8de293b38f fix(deploy): correct Aliyun runtime stop URL
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-07 16:45:12 +08:00
XiaoSeS
00f55c2db3 feat(search): surface compliance mappings in discovery
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-07 16:37:07 +08:00
XiaoSeS
460304eed8
Merge pull request #697 from iflytek/feat/compliance-metadata-snapshot
Some checks failed
Security / CodeQL (python) (push) Has been cancelled
Security / Dependency Review (push) Has been cancelled
Security / CodeQL (java-kotlin) (push) Has been cancelled
Security / CodeQL (javascript-typescript) (push) Has been cancelled
feat(metadata): add compliance snapshot mappings
2026-08-07 16:06:44 +08:00
XiaoSeS
da5c3cba3b feat(search): index compliance snapshot mappings
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-07 15:46:06 +08:00
XiaoSeS
a7b25b072b feat(metadata): expose compliance snapshots in version views
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-07 15:46:06 +08:00
XiaoSeS
725bbe165b feat(metadata): add x-astron compliance snapshot
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-07 15:46:06 +08:00
XiaoSeS
6e133c006e
Merge pull request #694 from iflytek/docs/weekly-w32-official
Some checks failed
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
Deploy Docs / build (push) Has been cancelled
Deploy Docs / Deploy (push) Has been cancelled
docs(weekly): mirror reviewed W32 report
2026-08-07 10:37:36 +08:00
XiaoSeS
77e0ff3749 docs(weekly): mirror reviewed W32 report
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-07 10:34:32 +08:00
XiaoSeS
da8a888469
Merge pull request #576 from Phil-OSophy-42/feat/configurable-base-path
feat(web): support deployment under a configurable base path
2026-08-06 20:10:46 +08:00
XiaoSeS
c272811213 docs(deploy): document manual sub-path env setup
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-06 19:08:57 +08:00
XiaoSeS
9668f3cd5a fix(deploy): avoid changing runtime helper for PR 576
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-06 19:06:55 +08:00
XiaoSeS
5e3f4e72e7 fix(deploy): keep PR 576 backport focused
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-06 19:05:36 +08:00
XiaoSeS
d0b7a7c5d4 fix(deploy): backport sub-path runtime fixes to PR 576
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-06 18:59:37 +08:00
XiaoSeS
f0164fe8ba
Merge pull request #693 from iflytek/docs/weekly-w32-star-clarity
docs(weekly): publish 2026 W32 report
2026-08-06 18:06:45 +08:00
XiaoSeS
53cb3b4757 docs(weekly): publish 2026 W32 report
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-06 18:03:14 +08:00
philsun
34f244e7a4 feat(web): support configurable base-path deployment
Signed-off-by: philsun <xinyi.sun@daocloud.io>
2026-08-05 12:50:26 +08:00
ylhu16
833270bb31 fix(auth): enforce trusted OAuth identity attributes
Signed-off-by: ylhu16 <ylhu16@iflytek.com>
2026-08-05 11:21:41 +08:00