Skip to content

Sam/skill marketplace - #7003

Closed
SamWang9803 wants to merge 535 commits into
QuantumNous:mainfrom
deeprouter-ai:sam/skill-marketplace
Closed

Sam/skill marketplace#7003
SamWang9803 wants to merge 535 commits into
QuantumNous:mainfrom
deeprouter-ai:sam/skill-marketplace

Conversation

@SamWang9803

@SamWang9803 SamWang9803 commented Aug 25, 2026

Copy link
Copy Markdown

Opened against the wrong base repository by mistake (GitHub defaults to the
upstream parent for forks).
Closed — nothing to review here.

hades217 and others added 30 commits June 21, 2026 18:00
…ate (#78)

The previous roll still failed: the box .env has no SMART_ROUTER_IMAGE, and
docker-compose.prod.yml declares smart-router.image: ${SMART_ROUTER_IMAGE:?...},
so every `docker compose` invocation errored at interpolation before doing
anything ("required variable SMART_ROUTER_IMAGE is missing a value"). The old
ci-deploy.sh masked this as a benign "skip roll"; the new roll surfaced it as a
hard failure.

We only roll new-api, so export both image vars inline (a syntactically valid
smart-router ref suffices — it's never pulled or recreated) and add --no-deps so
the up only touches new-api. Smart-router and the other services are left as-is.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The Resources doc renderer (src/features/docs/components/doc-markdown.tsx) styles
markdown entirely through Tailwind Typography `prose`/`prose-*` classes, but the
plugin was never installed — so every one of those classes was a no-op and the
guides rendered as flat, unstyled HTML (headings, code blocks, blockquotes, and
tables all visually broken).

Add `@tailwindcss/typography` (v0.5.20) and register it in the Tailwind v4 entry
CSS via `@plugin`. Verified: `bun run build` exit 0 and `.prose*` rules now emit
into the CSS bundle.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…-entry-point

DR-73 add skill package analytics entry point
…y-guard

Implement DR-80 runtime dependency guard
Load model_whitelist_snapshot from active SkillVersion at request time,
override the client-supplied model with the first server-authoritative
whitelist entry, inject instruction_template as system message, and
strip all multi-turn history to enforce FR-G19 stateless single-turn.
Empty whitelist → 500 SKILL_INTERNAL_ERROR; missing user message → 400
INVALID_REQUEST. Provider credentials and routing remain server-side
throughout; package-supplied model hints are discarded entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
D5 (BLOCKER): move LoadAndApply to after applyAirbotixPolicy so kids-mode
model eligibility is checked against the client-supplied model name, not the
server-selected whitelist alias ("deeprouter-auto"). Virtual model aliases are
not in kids.EligibleModels and would cause a false 400 for every kids-session
skill request.

D4 (HIGH): skip channel-level SystemPrompt injection for skill relay requests.
instruction_template from SkillVersion is the authoritative system message
(DR-68); channel SystemPrompt must not prepend or override it.

D7 (cleanup): collapse dead errors.Is branch in loadSnapshot — both the
ErrRecordNotFound case and the else case returned identical ErrSkillInternalError.
Remove unused "errors" import.

D3 (documentation): add explicit V1 text-only comment in rewriteForSingleTurn
so the StringContent()-returns-"" behaviour for ContentPart arrays is a
documented limitation, not an invisible gap.

All 12 internal/... packages pass; relay/ passes (19+13 tests).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
applySystemPromptIfNeeded (Responses path) lacked the D4 guard — fixed
by adding skillrelay.Get(c) check at function entry, mirroring the guard
already in compatible_handler.go's conversion path.

New unit tests (executor_test.go, +11 tests):
- parseModelWhitelist: valid array, empty array, malformed JSON, zero-length raw
- rewriteForSingleTurn: empty template allowed, assistant-only → ErrInvalidRequest,
  ContentPart text+image → text extracted (V1 documented), pure-image →
  ErrInvalidRequest (V1 text-only)
- loadSnapshot: malformed whitelist_snapshot JSON → ErrSkillInternalError

New integration tests (compatible_handler_skill_test.go, +4 tests):
- TestTextHelper_SkillRelay_DR68_EmptyWhitelist_Returns500
- TestTextHelper_SkillRelay_DR68_NoUserMessage_Returns400
- TestApplySystemPromptIfNeeded_SkippedForSkillRelay (D4 Responses path guard)
- TestApplySystemPromptIfNeeded_InjectsForNonSkillRelay (regression guard)

All 12 internal/... packages pass; relay/ passes (45 total tests).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
prepareSkillRelayForDistribution runs in Distribute() before token model
limits, smart-router, and channel selection. It unmarshal+resolve+LoadAndApply
the SkillVersion snapshot and replaceReusableRequestBody replaces the raw
BodyStorage so every downstream reader (model-limit check, smart-router sidecar,
channel picker, TextHelper) sees only the server-selected model and the
whitelist-constructed payload — never the client or package-supplied model,
system prompt, history, or routing hints.

- middleware/distributor.go: prepareSkillRelayForDistribution + replaceReusableRequestBody
- middleware/distributor_skill_test.go: new tests — smart-router gets server snapshot model,
  client model never visible to downstream, package identity can't steer routing
- Accompanying gofmt formatting: executor.go, compatible_handler.go, context.go,
  webhook.go, webhook_extra_test.go, smart_router_client/client.go

Security invariants enforced end-to-end:
  - Package/client model → dropped before routing
  - smart-router only sees server whitelist model
  - provider payload = instruction_template + last user message only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
compatible_handler.go lines 101-126: the two-path description was inaccurate.
The comment implied applyAirbotixPolicy always sees the client model (D5 intent),
but in the Distribute path prepareSkillRelayForDistribution has already called
LoadAndApply and replaced the body, so policy sees the server whitelist model.
Update comment to describe both paths accurately and note that kids-session model
filtering against virtual aliases is V1 out-of-scope per DR-68 PRD.

compatible_handler_skill_test.go: apply gofmt alignment (Model/Messages/Deeprouter
struct literal fields).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Scan packages individually (not as a batch) so a single package failure
doesn't silently truncate the test list; collect output in mktemp with trap
cleanup; export GOCACHE to a local path for consistent CI behaviour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
146 tests PASS / 0 FAIL across:
  internal/skill/relay  (executor, loadSnapshot, selectModel, rewriteForSingleTurn)
  middleware            (prepareSkillRelayForDistribution, replaceReusableRequestBody)
  relay                 (TextHelper skill paths, D4 SystemPrompt guards, kids-mode matrix)

Command: go test -count=1 -p 1 -v ./internal/skill/relay/ ./middleware/ ./relay/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
executor.go: replace direct encoding/json.Unmarshal with common.Unmarshal
(common/json.go wrapper) per AGENTS.md Rule 1; drop encoding/json import.

compatible_handler.go: guard TextHelper's LoadAndApply call with
skillCtx.SkillVersionID == "". When SkillVersionID is already set,
Distribute's prepareSkillRelayForDistribution already loaded the snapshot
and rewrote the body; re-loading here would be a TOCTOU race — if
active_version_id changes between Distribute and TextHelper, the provider
payload could be rebuilt from a different snapshot than channel selection
used, breaking the server-authoritative routing invariant. Skip the reload
in that path; only load for the direct-TextHelper path (unit tests / callers
that bypass Distribute), where SkillVersionID is still empty.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pliance, add tests

TOCTOU (root cause fixed):
  compatible_handler.go — Resolve block now checks for existing SkillVersionID.
  If set (Distribute path), reuse the pinned context and only update entry_point;
  do NOT call Resolve again. A second Resolve returns a fresh zero-SkillVersionID
  context; skillrelay.Set would overwrite the pin, making the SkillVersionID guard
  always-true and triggering a second LoadAndApply against a potentially different
  active_version_id — breaking server-authoritative routing.

Error path ordering (distributor.go replaceReusableRequestBody):
  Seek new storage before closing old storage. If Seek fails, old storage remains
  valid so any retry/panic-recovery path is not left with a closed BodyStorage.

Rule 1 — encoding/json replaced with common wrappers in all three test files:
  executor_test.go:     json.Marshal → common.Marshal; json.RawMessage → []byte
  compatible_handler_skill_test.go: json.Marshal → common.Marshal
  distributor_skill_test.go: json.Marshal → common.Marshal;
                              json.NewEncoder.Encode → common.Marshal + w.Write

Rule 2 — cross-DB SQL compatibility (executor_test.go):
  datetime('now') (SQLite-only) → CURRENT_TIMESTAMP (SQL standard, all three DBs)

TestGap — prepareSkillRelayForDistribution error branches (distributor_skill_test.go):
  + TestPrepareSkillRelay_NilModelRequest_ReturnsEmpty
  + TestPrepareSkillRelay_NonChatPath_ReturnsEmpty
  + TestPrepareSkillRelay_NoSkillID_ReturnsEmpty
  + TestPrepareSkillRelay_UnknownSkillID_ReturnsError
  + TestPrepareSkillRelay_EmptyWhitelist_ReturnsInternalError
  + TestPrepareSkillRelay_NoUserMessage_ReturnsInvalidRequest
  + TestPrepareSkillRelay_TOCTOU_SkillVersionIDPinned (regression guard)
  prepareSkillRelayForDistribution coverage: 68.4% → 89.5%

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ns deep-copy

- Rule 8: extract prepareSkillRelayForDistribution + replaceReusableRequestBody
  from middleware/distributor.go into new middleware/skill_distributor.go so
  upstream cherry-picks to distributor.go do not conflict with skill-relay code

- TOCTOU test fix: old TestPrepareSkillRelay_TOCTOU_SkillVersionIDPinned called
  prepareSkillRelayForDistribution twice against the same DB row — passed by
  coincidence, not because the guard fired. Replaced with
  TestTextHelper_SkillRelay_TOCTOU_PinnedVersionIDPreserved which pre-seeds a
  distinct pinnedID on the gin context and calls TextHelper, asserting that the
  Resolve block does NOT overwrite the already-pinned SkillVersionID

- rewriteForSingleTurn: deep-copy StreamOptions (pointer, not aliased value) to
  prevent future in-place mutations from affecting the caller's original request;
  add TODO(DR-67) comment explaining intentional MaxTokens omission

- compatible_handler.go direct path: add explicit skillrelay.Set after LoadAndApply
  to make the SkillVersionID update safe against any future Get-by-value refactor

- Add kids-mode virtual alias TODO and replaceReusableRequestBody typed-nil comment

- Update dr68-unit-regression.txt (154 PASS / 0 FAIL) with per-function coverage;
  add Coverage comments to all three test file headers per review guidance

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix formatting flagged by CI gofmt check.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lection

feat(DR-68): server-side skill routing with server-authoritative model selection
新增 docs/tasks/dr76-ops-overview-dashboard-prd.md(PRD-first, Rule 11)。
新增 features/skill-analytics/:types.ts 定義 DR-75 API 合約、api.ts 封裝 GET /api/v1/admin/skill-analytics/overview、metric-card.tsx(loading/no-data/tracking-failure 三態)、date-range-control.tsx(24h/7d/30d 預設,custom P1 disabled)、index.tsx 主頁面。
新增路由 _authenticated/skill-analytics/index.tsx(beforeLoad 守衛 ROLE.ADMIN,否則 /403)。
sidebar admin 組加入 Skill Analytics 導航項(BarChart2 icon)。
en.json + zh.json 新增 30 項 i18n key。
P0 卡片:WASU、Total Skill Runs、Skill Detail CTR、Enable Rate、First Use Rate、Repeat Use Rate、Block Rate、Top Block Reason、Revenue Attribution(charging_enabled=false 時隱藏)。
追蹤失敗橫幅(failed=橙色/delayed=黃色);DR-75 未部署時顯示 error state。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…verage)

安裝 Vitest + @testing-library/react 測試框架(首個前端測試套件)。

測試範圍:
  types.test.ts — getDateRange(三個 preset、ISO8601 格式、start < end)
                  formatBlockReason(全部 6 個 BlockReason 值)
  metric-card.test.tsx — loading/no-data/tracking-failed/normal 四態
  date-range-control.test.tsx — preset 渲染、active variant、onChange、
                                 disabled Custom range button
  dashboard.integration.test.tsx — 21 個整合測試(vi.hoisted 確保 mock 在
    factory 前初始化):9 P0 卡片渲染、WASU/percent/USD 格式、Top Block Reason
    標籤、tracking failed/delayed 橫幅、Revenue 條件隱藏、null 指標顯示 no-data
    state、API error banner、日期切換觸發新 API 呼叫含範圍驗證

Production bug fixed during tests:
  getDateRange(preset) 在 render 直接 new Date() 未 memoize,
  每次 re-render 產生不同 queryKey,TanStack Query 無限 re-fetch。
  Fix: useMemo(() => getDateRange(preset), [preset])

Coverage (src/features/skill-analytics/**):
  Stmts 95.2% | Branch 98.2% | Funcs 93.3% | Lines 94.7%
  api.ts 0% — intentionally mocked (expected)
  types.ts branch 83.3% — unreachable ?? fallback in BlockReason union

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds per-file coverage breakdown from coverage-summary.json:
index.tsx / metric-card.tsx / date-range-control.tsx all at 100%.
api.ts 0% is intentional (mocked). types.ts branch 83.33% is
an unreachable fallback in the BlockReason exhaustive map.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
taowis and others added 27 commits June 30, 2026 10:34
…e-grant-isolation

DR-98: Isolate referral grant from Skill purchase
…ion-migration

Fix skill version instruction migration
…struction-migration-prd

Mark skill version instruction migration shipped
…ompts-layout

Fix Skill usage consent prompts and admin layout
…-analytics

Add visual Skill usage analytics
…regression tests (#153)

Seedance video models advertised in relay/channel/task/doubao ModelList were
missing default model ratios, so any non-self-use deployment rejected them with
价格未配置. Add family-anchored default ratios (scaled off the 2.0 anchor by
official Ark ¥/M-token pricing), a type-54 火山引擎 Seedance 视频 seed channel
(reuses VOLCENGINE_API_KEY), and pricing-coverage regression tests wired into
both CI gates. Task PRD included per AGENTS.md Rule 11.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
PR #153 merged (both CI gates green), production deploy auto-triggered.
Records local e2e verification: all 6 Seedance models resolve pricing and
reach Ark auth; pre-consumed quota refunded on failed submission.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* fix: reprice Seedance video from measured usage (per-call price, not token ratio)

defaultModelPrice holds PER-CALL USD prices (quota = modelPrice * QuotaPerUnit;
the task path keeps the pre-charge because BaseBilling.AdjustBillingOnComplete
returns 0). The previous Seedance values were derived from the official ¥/M-token
unit price as though this map held per-token ratios, underpricing every clip.

Recalibrated from a real Ark task: a 5s 1080p Seedance-2.0 clip is 108,900
completion tokens, so cost is $0.69 and the old $0.15 charge lost $0.54 per
video. New prices are measured cost x ~1.45. The residual exposure (flat price
vs per-token upstream on longer clips) is documented in code and in the PRD,
with the token-ratio migration named as the real fix if long clips take off.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix: add the dated Ark model ids that real calls dispatch

GET /api/v3/models on a live Ark account returns DATED ids
(doubao-seedream-5-0-260128), while the repo only carried undated aliases
(doubao-seedream-5.0), so a real call hit 价格未配置. Adds the six ids present on
that account. Two Seedance tiers have no published ¥/M — priced between the
tiers above and below them and marked as estimates, erring toward over-charging
rather than losing money.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…t billing (#156)

* feat(models): refresh model catalogue to 2026-08 + fix Claude 5 output billing

Anthropic's Claude 5 generation (Opus 5 / Sonnet 5 / Fable 5 / Mythos 5) was
missing from every channel list, and — more seriously — none of the "-5" IDs
matched a branch in getHardcodedCompletionModelRatio (which only knew claude-3
and claude-*-4). They fell through to a 1x completion ratio, i.e. output tokens
billed at the input price for a family whose output costs 5x input. Same class
of bug on GPT-5.6, which inherited the generic gpt-5 rule (8x) instead of 6x.

Catalogue refresh across relay/channel/*/constants.go:
  - Anthropic: Claude 5 family (+ Opus 5 effort tiers), claude-sonnet-4-6
  - OpenAI:    GPT-5.5, GPT-5.6 (sol/terra/luna/cyber), realtime-2.x, transcribe
  - Gemini:    3.5 / 3.6 / 3.7 Flash, flash-lite, omni, deep-research
  - xAI:       grok-4.6 / 4.5 / 4.3 / 4.20 / build-0.1
  - Qwen:      qwen3.7-* and qwen3.8-max
  - Kimi:      kimi-k3, kimi-k2.7-code(-highspeed), k2.6
  - GLM:       glm-5.x moved to the v4 channel (zhipu_4v); relay/channel/zhipu
               keeps chatglm_* because it targets the retired v3 endpoint
  - Doubao:    Seed 2.0; DeepSeek / Perplexity / Mistral / MiniMax synced

scripts/seed-models/channels.yaml now seeds current models only and drops IDs
retired upstream (all of Claude 3.x, deepseek-chat/reasoner, dall-e-*,
llama-3-sonar-*, gemini-1.5-*). Two test_model values were pointing at retired
IDs, so channel health checks could never pass.

New guard TestSeededModelsArePriced walks the seed file and fails if an enabled
channel seeds a model with no price — it surfaced 11 pre-existing gaps, now in a
documented shrink-only allowlist. Priced Perplexity Sonar, gemini-2.5-flash-lite
and omni-moderation-* along the way.

kids_mode whitelist gains claude-haiku-4-5 (successor to the retired
claude-3-5-haiku) with an assertion that frontier models stay out.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NdKYxR4pQUXsJoWc1aUg9m

* feat(volcengine): add Seedance 2.5 + Ark-hosted DeepSeek

Both reach us through the same VolcEngine Ark key.

Seedance 2.5 (doubao-seedance-2-5-260628, 2026-07-31) is deliberately NOT added
to defaultModelPrice. That map holds flat per-call prices calibrated against a
measured ~5s clip; 2.5 generates up to 30s per segment, so duration alone swings
cost 6x and a flat charge loses money on every long generation — exactly the
exposure the 2026-07-25 repricing note flagged.

It goes in defaultModelRatio instead ($10.85/1M no-video-input rate → 5.425).
Because it has a ratio and no per-call price, settleTaskBillingOnComplete
re-settles from the task's actual TotalTokens. The $6.51/1M video-input rate
rides the existing videoInputRatioMap discount (0.60), so the ratio has to stay
the higher no-video figure.

This failure mode is silent — a per-call price still bills, just too little —
so TestSeedance25IsRatioBilledNotPerCall asserts the absence of a per-call
price, the exact ratio, and the discount entry.

DeepSeek on Ark: undated aliases (deepseek-v4-pro / -flash, which resolve on the
Coding and Agent Plan endpoints) plus the dated ids I could verify against
VolcEngine's docs (deepseek-v3-1-250821, deepseek-r1-250120), with ratios and
completion ratios for the dated pair. Ark's dated V4 ids are not published
anywhere I could confirm, so they are not guessed here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NdKYxR4pQUXsJoWc1aUg9m

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The creator marketplace needs a schema that can express ownership, a review
workflow, prompt variables, per-call billing and ratings. This PRD is the
prerequisite for P2-P7 and settles three things the task card got wrong.

- D1: the user-rating table is skill_ratings, not skill_reviews. The latter is
  already spec'd as the ops moderation queue and is where enums.ReviewStatus
  comes from. Building ratings on it and reusing that enum would make every
  rating summary read zero forever, silently, because the reader filters
  status IN ('approved','published').
- D2: SQLite cannot ALTER an existing CHECK. Production is PostgreSQL and dev
  SQLite databases are disposable, so the degradation is accepted and a
  log-only boot probe tells the developer to delete one-api.db.
- D3: skills.status gains only submitted/sandbox/pending_launch. The
  pending_review and suspended that downstream cards mention map onto
  submitted+review_status and deprecated.

Also records three migration hazards found while reading the code: a new
check: struct tag on an existing table crashes the SQLite migrator at boot,
a CHECK expression edit without a drop hook is a permanent silent no-op on
existing PG/MySQL, and skills vs skill_versions take completely different
add-column paths.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Module3 P1, steps 1-2. Purely additive: nothing writes the new status values
yet, so this is safe to ship ahead of P2-P7.

- enums.SkillStatus gains submitted/sandbox/pending_launch, declared in
  lifecycle order. The test's invalid list now asserts pending_review and
  suspended are NOT statuses, turning the PRD's D3 mapping into something a
  future change trips over rather than a paragraph nobody reads.
- skills gains 8 columns for ownership and the review trail. None of them
  carry a check: struct tag - a new constraint name against an existing table
  makes gorm call CreateConstraint, and the glebarez/sqlite migrator then
  rebuilds a table whose DDL contains IN(...) and fails with 'invalid DDL,
  unbalanced brackets'. Their CHECKs go in migrate.go's raw-DDL slice instead
  (PG/MySQL only). See PRD M1.
- chk_skills_status is widened in the struct tag; the constraint NAME is
  unchanged, so a fresh database gets the new expression while an existing one
  short-circuits on HasConstraint. Existing PG/MySQL need the drop hook that
  lands with step 3.

TestSkillStatusCheckTagCoversEveryEnumValue is new and covers a real gap:
TestEnumDBValues_MatchCheckConstraints only compares each constant against a
hardcoded literal and never reads the constraint, so adding an enum value
without widening the CHECK passes it silently. The new guard reflects on the
struct tag and was red-green checked by removing 'sandbox' from the expression.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…tabases

Module3 P1, steps 3-4. Still purely additive - nothing writes the new status
values yet.

Two mechanisms here are the ones that fail silently if omitted:

- refreshSkillsStatusConstraint. The apply loop in migrateSkillsConstraints
  skips any constraint whose NAME already exists, and widening the status
  expression did not change the name. Without an explicit drop, every existing
  PostgreSQL/MySQL database keeps the old four-value CHECK forever: no error,
  no failing test, just a status the application can never write. Written
  dialect-explicit (PG DROP CONSTRAINT IF EXISTS vs MySQL DROP CHECK) rather
  than via Migrator().DropConstraint, which infers the type from a struct tag
  the P1 columns deliberately do not have.
- migrateSkillsCreatorColumns runs BEFORE AutoMigrate, so the columns and the
  source backfill land even when AutoMigrate later fails - which it does on
  SQLite, see below.

chk_skills_source, chk_skills_review_status and chk_skills_creator_has_creator_id
exist only in the raw-DDL slice, never as struct tags: a new constraint name
against an existing table sends the glebarez/sqlite migrator into a table
rebuild that fails at boot. The cost is that those three do not exist on SQLite
at all; enums.Valid() and the SkillSource* constants are the gate there.

skill_versions gains variables_schema and minhash_signature through the DR-93
three-site dance: struct, both hand-written CREATE TABLEs, and a backfilling
add-column helper called on either side of AutoMigrate on the PG path.

Also documents a PRE-EXISTING bug found while verifying this: a SQLite database
cannot be migrated twice, so it fails to boot a second time
(invalid DDL, unbalanced brackets). Verified on e1c0d12 both in-process and
across a genuine close-and-reopen, so it is not a gorm schema-cache artifact.
Production runs PostgreSQL and is unaffected; make dev users have to delete
one-api.db. TestMigrateSkills_SQLite_RestartIsBroken asserts the current
failure so it goes red when the driver is fixed. Tracked separately.

The relay fixture needed variables_schema added to its raw INSERT - the
expected consequence of a NOT NULL column, and the reason the whole suite gets
run rather than just the touched package.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…or invite

Module3 P1, steps 5-7. Two new tables and one column; nothing writes to any of
them yet.

skill_calls is the billing ledger, deliberately separate from
skill_usage_events. That table is analytics - losing a row costs a point on a
chart. This one answers 'what do we owe this creator this month' and has to
survive an audit, so it carries a request_id unique index as the
double-billing guard. request_id is *string rather than a defaulted empty
string so rows without one (backfills, internal calls) can coexist under that
index on every engine. Amounts are quota units, not cents: the commission is
credited to users.quota, an int of quota units, so cents would force a lossy
conversion at the moment money changes hands. No foreign keys, for the reason
skill_usage_events has none - an append-only ledger must outlive a hard delete
of the skill it refers to.

The rating table is skill_ratings, NOT skill_reviews. skill_reviews is already
spec'd as the ops moderation queue and is where enums.ReviewStatus comes from;
publicRatingSource() probes skill_ratings first anyway. Had ratings taken that
name and reused that enum, the reader's status IN ('approved','published')
filter would intersect open/assigned/escalated/resolved/reopened at exactly
zero values - every rating summary would read zero forever, with no error and
no failing test. Status defaults to approved because there is no
rating-moderation queue; defaulting to pending would ship a table whose every
row is invisible.

The DR-89 social-proof fixture hand-rolled a skill_reviews lookalike. With the
real table migrated those rows are never read, so it now builds rows through
the model. Its four assertions are unchanged, and the fixture can no longer
drift from the schema.

users.creator_invited_at is a timestamp rather than a bool: non-nil IS the
invite and it records when. Note for whoever wires the invite endpoint -
User.Update() uses Updates(struct), which skips zero values, so a nil pointer
never reaches the database; use an explicit Model().Update().

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 740 files, which is 440 over the limit of 300.

To get a review, reduce the PR to 300 files or fewer by splitting it into smaller PRs or changing its base branch.

Usage-priced reviews support at most 300 files.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ecc73e69-42c9-41f7-a7cb-4f4b56b73c8a

📥 Commits

Reviewing files that changed from the base of the PR and between 2d8e50b and cb54810.

⛔ Files ignored due to path filters (30)
  • docs/brand/assets/brand-logo-panel.png is excluded by !**/*.png
  • docs/brand/assets/colors-typography-panel.png is excluded by !**/*.png
  • docs/brand/assets/components-panel.png is excluded by !**/*.png
  • docs/brand/assets/controls-panel.png is excluded by !**/*.png
  • docs/brand/assets/icons-illustrations-panel.png is excluded by !**/*.png
  • docs/brand/assets/mobile-panel.png is excluded by !**/*.png
  • docs/brand/assets/routing-panel.png is excluded by !**/*.png
  • docs/brand/assets/sidebar-layout-panel.png is excluded by !**/*.png
  • docs/brand/logo-icon.png is excluded by !**/*.png
  • docs/brand/logo-transparent.png is excluded by !**/*.png
  • docs/brand/logo.png is excluded by !**/*.png
  • docs/brand/reference-board.png is excluded by !**/*.png
  • docs/tickets/dr-tickets.csv is excluded by !**/*.csv
  • web/default/bun.lock is excluded by !**/*.lock
  • web/default/public/apple-touch-icon.png is excluded by !**/*.png
  • web/default/public/docs/integrations/images/01-concept-before-after.png is excluded by !**/*.png
  • web/default/public/docs/integrations/images/02-signin.png is excluded by !**/*.png
  • web/default/public/docs/integrations/images/03-api-keys.png is excluded by !**/*.png
  • web/default/public/docs/integrations/images/04-welcome-default-key.png is excluded by !**/*.png
  • web/default/public/docs/integrations/images/05-base-url-table.png is excluded by !**/*.png
  • web/default/public/docs/integrations/images/06-style-a-settings.png is excluded by !**/*.png
  • web/default/public/docs/integrations/images/07-style-b-terminal.png is excluded by !**/*.png
  • web/default/public/docs/integrations/images/08-style-c-ccswitch.png is excluded by !**/*.png
  • web/default/public/docs/integrations/images/09-verify.png is excluded by !**/*.png
  • web/default/public/favicon-32.png is excluded by !**/*.png
  • web/default/public/favicon-64.png is excluded by !**/*.png
  • web/default/public/home-media/ai-video-product-demo.mp4 is excluded by !**/*.mp4
  • web/default/public/home-media/ai-video-scene-demo.mp4 is excluded by !**/*.mp4
  • web/default/public/logo-full.png is excluded by !**/*.png
  • web/default/public/logo.png is excluded by !**/*.png
📒 Files selected for processing (740)
  • .agents/skills/design-system/SKILL.md
  • .claude/commands/dr-pr.md
  • .claude/commands/dr-status.md
  • .claude/commands/dr-test.md
  • .dockerignore
  • .gitattributes
  • .githooks/pre-commit
  • .github/workflows/airbotix-internal.yml
  • .github/workflows/deploy.yml
  • .github/workflows/dr40-skill-integration.yml
  • .github/workflows/frontend-test.yml
  • .github/workflows/unit-test.yml
  • .gitignore
  • AGENTS.md
  • AIRBOTIX.md
  • ARCHITECTURE.md
  • CHANGELOG.md
  • CLAUDE.md
  • DEV.md
  • Dockerfile
  • Dockerfile.dev
  • LICENSE
  • NOTICE
  • PLAN.md
  • README.en.md
  • README.fr.md
  • README.ja.md
  • README.md
  • README.zh_CN.md
  • README.zh_TW.md
  • THIRD-PARTY-LICENSES.md
  • bin/.env.dr13.example
  • bin/airbotix-set-tenant-fields.sh
  • bin/run-dr13-human-test.sh
  • bin/seed-airbotix-kids.sh
  • bin/setup-dr12-test-accounts.sh
  • bin/test-dr12-kids-mode.sh
  • bin/test-dr13-human.sh
  • bin/test-dr13.sh
  • cmd/seed-skills/main.go
  • common/api_type.go
  • common/constants.go
  • common/email_template.go
  • constant/api_type.go
  • constant/channel.go
  • constant/context_key.go
  • controller/channel-test.go
  • controller/channel_test_internal_test.go
  • controller/internal_catalog.go
  • controller/internal_catalog_test.go
  • controller/misc.go
  • controller/model.go
  • controller/model_list_test.go
  • controller/payment_webhook_availability.go
  • controller/payment_webhook_availability_test.go
  • controller/purpose.go
  • controller/referral.go
  • controller/referral_conversion.go
  • controller/relay.go
  • controller/relay_cross_model.go
  • controller/relay_cross_model_test.go
  • controller/subscription_payment_epay.go
  • controller/token.go
  • controller/token_test.go
  • controller/topup.go
  • controller/topup_airwallex.go
  • controller/topup_airwallex_test.go
  • controller/topup_creem.go
  • controller/topup_stripe.go
  • controller/topup_waffo.go
  • controller/topup_waffo_pancake.go
  • controller/user.go
  • controller/user_create_test.go
  • controller/user_telemetry_consent_test.go
  • docker-compose.smart-router.yml
  • docs/BUSINESS-LOGIC.md
  • docs/CONNECT.md
  • docs/DEPLOYMENT.md
  • docs/DESIGN.md
  • docs/DeepRouter-BP.md
  • docs/DeepRouter-PRD-brand.md
  • docs/OPTIMIZATION-PRD.md
  • docs/PRD.md
  • docs/adr/0001-license-process-boundary.md
  • docs/adr/0002-two-layer-routing.md
  • docs/adr/0003-sidecar-topology.md
  • docs/adr/0004-channel-key-plaintext.md
  • docs/adr/0005-triple-db-compatibility.md
  • docs/adr/0006-internal-isolation.md
  • docs/adr/README.md
  • docs/brand/deeprouter-brand.css
  • docs/brand/index.html
  • docs/compliance-prd.md
  • docs/data-model.md
  • docs/kids-coverage-matrix.md
  • docs/onboarding-v2-prd.md
  • docs/skill-marketplace/R2_Change_Handoff.md
  • docs/skill-marketplace/Skill_Marketplace_PRD_Main.md
  • docs/skill-marketplace/Skill_Marketplace_PRD_v1.1_Implementation_Ready.md
  • docs/skill-marketplace/compliance/01_Safety_And_Kids_Mode.md
  • docs/skill-marketplace/compliance/02_Audit_RBAC_Privacy.md
  • docs/skill-marketplace/compliance/03_Release_Readiness_Checklist.md
  • docs/skill-marketplace/compliance/README.md
  • docs/skill-marketplace/compliance/Skill_Marketplace_Compliance.md
  • docs/skill-marketplace/tasks/00_Overview.md
  • docs/skill-marketplace/tasks/01_Functional_Requirements.md
  • docs/skill-marketplace/tasks/02_UX_Design.md
  • docs/skill-marketplace/tasks/03_Data_Model_and_API_Spec.md
  • docs/skill-marketplace/tasks/04_Analytics_and_Operations.md
  • docs/skill-marketplace/tasks/05_Security_and_NFR.md
  • docs/skill-marketplace/tasks/06_Module_Breakdown_WBS.md
  • docs/skill-marketplace/tasks/07_CTO_PRD_Review_Action_Items.md
  • docs/skill-marketplace/tasks/08_R2_Jira_Impact_Map.md
  • docs/skill-marketplace/tasks/README.md
  • docs/skill-marketplace/tasks/Skill_Marketplace_Tasks.md
  • docs/system-settings-guide.md
  • docs/tasks/admin-create-user-validation-prd.md
  • docs/tasks/airwallex-autocharge-design.md
  • docs/tasks/api-key-simple-advanced-prd.md
  • docs/tasks/auto-topup-and-topup-guidance-prd.md
  • docs/tasks/casual-journey-readiness-prd.md
  • docs/tasks/casual-ux-prd.md
  • docs/tasks/dr-57-marketplace-list-ui-prd.md
  • docs/tasks/dr-66-lifecycle-enabled-gate-prd.md
  • docs/tasks/dr-73-skill-package-entry-point-prd.md
  • docs/tasks/dr100-one-time-skill-purchase-prd.md
  • docs/tasks/dr101-api-token-skill-auth-entitlement-prd.md
  • docs/tasks/dr102-client-runner-usage-telemetry-prd.md
  • docs/tasks/dr103-weekly-top-skills-digest-re-engagement-prd.md
  • docs/tasks/dr105-pro-paid-skill-seeds-prd.md
  • docs/tasks/dr108-admin-users-skill-usage-ui-prd.md
  • docs/tasks/dr47-skill-version-api-prd.md
  • docs/tasks/dr48-publish-skill-api-prd.md
  • docs/tasks/dr49-admin-skill-list-ui-prd.md
  • docs/tasks/dr50-admin-skill-editor-ui-prd.md
  • docs/tasks/dr52-marketplace-list-api-prd.md
  • docs/tasks/dr56-remove-from-my-skills-prd.md
  • docs/tasks/dr59-my-skills-ui-prd.md
  • docs/tasks/dr63-public-routing-api-contract-prd.md
  • docs/tasks/dr67-use-time-entitlement-check-prd.md
  • docs/tasks/dr68-routing-model-selection-prd.md
  • docs/tasks/dr69-provider-response-usage-events-prd.md
  • docs/tasks/dr70-relay-block-skill-blocked-prd.md
  • docs/tasks/dr71-non-skill-api-compatibility-regression-guard-prd.md
  • docs/tasks/dr74-event-schema-version-occurred-at-prd.md
  • docs/tasks/dr75-analytics-aggregation-api-prd.md
  • docs/tasks/dr76-ops-overview-dashboard-prd.md
  • docs/tasks/dr78-growth-surfaces-prd.md
  • docs/tasks/dr79-publish-time-skill-packaging-prd.md
  • docs/tasks/dr80-runtime-dependency-guard-prd.md
  • docs/tasks/dr82-public-api-abuse-controls-prd.md
  • docs/tasks/dr85-token-model-whitelist-wildcard-prd.md
  • docs/tasks/dr86-public-routing-runner-response-parse-prd.md
  • docs/tasks/dr87-paywall-upsell-ui-prd.md
  • docs/tasks/dr88-user-home-own-token-purchase-status-personalized-prd.md
  • docs/tasks/dr89-social-proof-on-cards-rating-stars-download-coun-prd.md
  • docs/tasks/dr90-new-this-week-trending-rising-rails-prd.md
  • docs/tasks/dr91-weekly-monthly-download-leaderboards-prd.md
  • docs/tasks/dr92-save-bookmark-skill-most-saved-prd.md
  • docs/tasks/dr93-per-skill-instructions-readme-prd.md
  • docs/tasks/dr94-admin-per-user-drill-down-downloads-token-consum-prd.md
  • docs/tasks/dr95-category-demand-analytics-merchandising-signal-prd.md
  • docs/tasks/dr96-monetization-linked-skill-funnels-prd.md
  • docs/tasks/dr97-personalized-recommendations-prd.md
  • docs/tasks/dr98-referral-program-invite-two-sided-reward-attribution-prd.md
  • docs/tasks/dr98-referral-skill-purchase-grant-isolation-prd.md
  • docs/tasks/dr99-tiered-pricing-model-prd.md
  • docs/tasks/home-motion-interactive-prd.md
  • docs/tasks/key-setup-guide-prd.md
  • docs/tasks/load-immutable-execution-snapshot-prd.md
  • docs/tasks/onboarding-prd.md
  • docs/tasks/phase-1-admin-ui.md
  • docs/tasks/pricing-catalog-2026h1-prd.md
  • docs/tasks/pricing-page-style-refresh-prd.md
  • docs/tasks/resources-docs-prd.md
  • docs/tasks/skill-creator-data-model-prd.md
  • docs/tasks/skill-usage-consent-prompt-layout-prd.md
  • docs/tasks/skill-usage-visual-analytics-prd.md
  • docs/tasks/skill-version-instruction-migration-prd.md
  • docs/tasks/skill-versions-table-migration-prd.md
  • docs/tasks/user-tier2-telemetry-consent-prd.md
  • docs/tasks/volcengine-seedance-readiness-prd.md
  • docs/tasks/welcome-goal-first-prd.md
  • docs/tenant-onboarding.md
  • docs/test-results/admin-create-user-validation.txt
  • docs/test-results/dr102-client-runner-usage-telemetry.txt
  • docs/test-results/dr103-weekly-top-skills-digest-re-engagement.txt
  • docs/test-results/dr105-pro-paid-skill-seeds.txt
  • docs/test-results/dr108-admin-users-skill-usage-ui.txt
  • docs/test-results/dr56-remove-from-my-skills.txt
  • docs/test-results/dr63-public-routing-api-contract.txt
  • docs/test-results/dr66-unit-regression.txt
  • docs/test-results/dr67-use-time-entitlement-check.txt
  • docs/test-results/dr68-unit-regression.txt
  • docs/test-results/dr69-unit-regression.txt
  • docs/test-results/dr74-unit-regression.txt
  • docs/test-results/dr76-frontend-unit-regression.txt
  • docs/test-results/dr87-paywall-upsell-ui.txt
  • docs/test-results/dr88-user-home-own-token-purchase-status-personalized.txt
  • docs/test-results/dr89-social-proof-on-cards-rating-stars-download-coun.txt
  • docs/test-results/dr91-weekly-monthly-download-leaderboards.txt
  • docs/test-results/dr94-admin-per-user-drill-down-downloads-token-consum.txt
  • docs/test-results/dr95-category-demand-analytics-merchandising-signal.txt
  • docs/test-results/dr96-monetization-linked-skill-funnels.txt
  • docs/test-results/dr97-personalized-recommendations.txt
  • docs/test-results/dr98-referral-program-invite-two-sided-reward-attribution.txt
  • docs/test-results/dr99-tiered-pricing-model.txt
  • docs/test-results/skill-usage-consent-prompt-layout.txt
  • docs/test-results/skill-usage-visual-analytics.txt
  • docs/test-results/user-tier2-telemetry-consent.txt
  • docs/wiki/Architecture-Decisions.md
  • docs/wiki/Bug-Log.md
  • docs/wiki/Dev-Setup.md
  • docs/wiki/Home.md
  • docs/wiki/Sprint-1-Progress.md
  • docs/workflows/README.md
  • docs/workflows/add-provider.md
  • docs/workflows/add-user-field.md
  • docs/workflows/debug-relay-issues.md
  • docs/workflows/dr-10-chat-completions-smoke.md
  • dto/deeprouter_extension.go
  • dto/openai_request.go
  • dto/user_settings.go
  • internal/abuse/public_routing.go
  • internal/abuse/public_routing_test.go
  • internal/billing/README.md
  • internal/billing/webhook.go
  • internal/billing/webhook_extra_test.go
  • internal/billing/webhook_test.go
  • internal/kids/README.md
  • internal/kids/kids.go
  • internal/kids/kids_test.go
  • internal/policy/README.md
  • internal/policy/enforcement.go
  • internal/policy/enforcement_test.go
  • internal/policy/profile.go
  • internal/policy/profile_test.go
  • internal/quota/tenant_quota.go
  • internal/quota/tenant_quota_test.go
  • internal/referral/model/referral.go
  • internal/referral/service/service.go
  • internal/referral/service/service_test.go
  • internal/skill/analytics/kids.go
  • internal/skill/api/envelope.go
  • internal/skill/api/envelope_test.go
  • internal/skill/api/pagination.go
  • internal/skill/api/pagination_test.go
  • internal/skill/availability/availability.go
  • internal/skill/availability/availability_test.go
  • internal/skill/enums/README.md
  • internal/skill/enums/enums.go
  • internal/skill/enums/enums_test.go
  • internal/skill/errcodes/README.md
  • internal/skill/errcodes/errcodes.go
  • internal/skill/errcodes/errcodes_test.go
  • internal/skill/handler/admin_user_usage.go
  • internal/skill/handler/admin_user_usage_test.go
  • internal/skill/handler/analytics.go
  • internal/skill/handler/analytics_test.go
  • internal/skill/handler/download.go
  • internal/skill/handler/download_test.go
  • internal/skill/handler/lifecycle.go
  • internal/skill/handler/purchase.go
  • internal/skill/handler/purchase_test.go
  • internal/skill/handler/seed_download_test.go
  • internal/skill/handler/skills.go
  • internal/skill/handler/skills_test.go
  • internal/skill/handler/telemetry.go
  • internal/skill/handler/telemetry_test.go
  • internal/skill/handler/user_home.go
  • internal/skill/handler/versions.go
  • internal/skill/model/migrate.go
  • internal/skill/model/purchase.go
  • internal/skill/model/skill.go
  • internal/skill/model/skill_audit_log.go
  • internal/skill/model/skill_audit_log_test.go
  • internal/skill/model/skill_call.go
  • internal/skill/model/skill_call_rating_test.go
  • internal/skill/model/skill_integration_test.go
  • internal/skill/model/skill_notification_event.go
  • internal/skill/model/skill_pg_mysql_test.go
  • internal/skill/model/skill_rating.go
  • internal/skill/model/skill_test.go
  • internal/skill/model/skill_usage_event.go
  • internal/skill/model/skill_usage_event_dr74_test.go
  • internal/skill/model/skill_usage_event_integration_test.go
  • internal/skill/model/skill_version.go
  • internal/skill/model/skill_version_integration_test.go
  • internal/skill/model/sue_event_migrate.go
  • internal/skill/model/telemetry_quarantine.go
  • internal/skill/model/ues_migrate.go
  • internal/skill/model/ues_pg_mysql_test.go
  • internal/skill/model/user_enabled_skill.go
  • internal/skill/model/user_enabled_skill_test.go
  • internal/skill/model/user_saved_skill.go
  • internal/skill/model/uss_migrate.go
  • internal/skill/notify/notify.go
  • internal/skill/notify/notify_test.go
  • internal/skill/packageassets/assets.go
  • internal/skill/packageassets/runtime/README.md
  • internal/skill/packageassets/runtime/deeprouter_skill_runner.py
  • internal/skill/pricing/matrix.go
  • internal/skill/pricing/matrix_test.go
  • internal/skill/relay/blocked.go
  • internal/skill/relay/blocked_test.go
  • internal/skill/relay/context.go
  • internal/skill/relay/entitlement.go
  • internal/skill/relay/entrypoint.go
  • internal/skill/relay/executor.go
  • internal/skill/relay/executor_test.go
  • internal/skill/relay/lifecycle.go
  • internal/skill/relay/lifecycle_test.go
  • internal/skill/relay/resolver.go
  • internal/skill/relay/resolver_lifecycle_test.go
  • internal/skill/relay/resolver_snapshot_test.go
  • internal/skill/relay/resolver_test.go
  • internal/skill/relay/tier_resolution_test.go
  • internal/skill/relay/usage_events.go
  • internal/skill/relay/usage_events_test.go
  • internal/skill/seed/definitions.go
  • internal/skill/seed/demo_skills.go
  • internal/skill/seed/demo_skills_test.go
  • internal/skill/seed/paid_definitions.go
  • internal/skill/tiers/tiers.go
  • internal/skill/tiers/tiers_test.go
  • internal/smart_router_client/README.md
  • internal/smart_router_client/client.go
  • internal/smart_router_client/client_test.go
  • main.go
  • middleware/auth.go
  • middleware/distributor.go
  • middleware/distributor_skill_test.go
  • middleware/internal_token.go
  • middleware/internal_token_test.go
  • middleware/policy.go
  • middleware/policy_test.go
  • middleware/public_routing_abuse.go
  • middleware/public_routing_abuse_test.go
  • middleware/rate-limit.go
  • middleware/skill-auth.go
  • middleware/skill_auth_test.go
  • middleware/skill_distributor.go
  • middleware/smart_router.go
  • middleware/smart_router_test.go
  • middleware/tenant_quota.go
  • model/main.go
  • model/option.go
  • model/token.go
  • model/token_model_limit_test.go
  • model/topup.go
  • model/user.go
  • model/user_airbotix_test.go
  • relay/README.md
  • relay/airbotix_billing_relay_test.go
  • relay/airbotix_policy.go
  • relay/airbotix_policy_test.go
  • relay/audio_handler.go
  • relay/channel/README.md
  • relay/channel/ali/constants.go
  • relay/channel/aws/constants.go
  • relay/channel/claude/chat_completions_smoke_test.go
  • relay/channel/claude/constants.go
  • relay/channel/claude/relay-claude.go
  • relay/channel/deepseek/constants.go
  • relay/channel/elevenlabs/adaptor.go
  • relay/channel/elevenlabs/adaptor_test.go
  • relay/channel/elevenlabs/constant.go
  • relay/channel/elevenlabs/dto.go
  • relay/channel/elevenlabs/tts.go
  • relay/channel/gemini/constant.go
  • relay/channel/minimax/constants.go
  • relay/channel/mistral/constants.go
  • relay/channel/moonshot/constants.go
  • relay/channel/openai/chat_via_responses_smoke_test.go
  • relay/channel/openai/constant.go
  • relay/channel/perplexity/constants.go
  • relay/channel/task/doubao/constants.go
  • relay/channel/task/doubao/constants_test.go
  • relay/channel/vertex/adaptor.go
  • relay/channel/volcengine/constants.go
  • relay/channel/xai/constants.go
  • relay/channel/zhipu/constants.go
  • relay/channel/zhipu_4v/constants.go
  • relay/chat_completions_via_responses.go
  • relay/claude_handler.go
  • relay/common/stream_status.go
  • relay/compatible_handler.go
  • relay/compatible_handler_skill_test.go
  • relay/constant/relay_mode.go
  • relay/constant/relay_mode_test.go
  • relay/embedding_handler.go
  • relay/gemini_handler.go
  • relay/helper/price_test.go
  • relay/helper/stream_scanner.go
  • relay/image_handler.go
  • relay/kids_coverage_matrix_test.go
  • relay/relay_adaptor.go
  • relay/rerank_handler.go
  • relay/responses_handler.go
  • relay/websocket.go
  • router/api-router.go
  • router/internal-router.go
  • router/main.go
  • router/relay-router.go
  • router/skill-router.go
  • router/skill-router_test.go
  • scripts/check-kids-coverage-matrix.sh
  • scripts/seed-models/.env.example
  • scripts/seed-models/.gitignore
  • scripts/seed-models/README.md
  • scripts/seed-models/channels.yaml
  • scripts/seed-models/seed.py
  • scripts/seed-models/seed_options.py
  • service/airbotix_billing.go
  • service/airbotix_billing_extra_test.go
  • service/airbotix_billing_test.go
  • service/auto_topup.go
  • service/auto_topup_airwallex.go
  • service/auto_topup_airwallex_test.go
  • service/auto_topup_test.go
  • service/log_info_generate.go
  • service/text_quota.go
  • service/text_quota_test.go
  • setting/alias_setting/alias_setting.go
  • setting/alias_setting/alias_setting_test.go
  • setting/alias_setting/seed/aliases.yaml
  • setting/operation_setting/auto_topup_setting.go
  • setting/payment_airwallex.go
  • setting/ratio_setting/cache_ratio.go
  • setting/ratio_setting/group_ratio.go
  • setting/ratio_setting/model_catalog_test.go
  • setting/ratio_setting/model_ratio.go
  • setting/ratio_setting/ratio_consistency_test.go
  • setting/ratio_setting/seed_models_test.go
  • types/error.go
  • web/default/.gitignore
  • web/default/index.html
  • web/default/package.json
  • web/default/public/docs/integrations/GUIDE.md
  • web/default/public/docs/integrations/GUIDE.zh.md
  • web/default/public/docs/integrations/botgem.md
  • web/default/public/docs/integrations/botgem.zh.md
  • web/default/public/docs/integrations/cc-switch.md
  • web/default/public/docs/integrations/cc-switch.zh.md
  • web/default/public/docs/integrations/chatbox.md
  • web/default/public/docs/integrations/chatbox.zh.md
  • web/default/public/docs/integrations/cherry-studio.md
  • web/default/public/docs/integrations/cherry-studio.zh.md
  • web/default/public/docs/integrations/claude-code.md
  • web/default/public/docs/integrations/claude-code.zh.md
  • web/default/public/docs/integrations/claude-coworks.md
  • web/default/public/docs/integrations/claude-coworks.zh.md
  • web/default/public/docs/integrations/cline.md
  • web/default/public/docs/integrations/cline.zh.md
  • web/default/public/docs/integrations/codex.md
  • web/default/public/docs/integrations/codex.zh.md
  • web/default/public/docs/integrations/copilot.md
  • web/default/public/docs/integrations/copilot.zh.md
  • web/default/public/docs/integrations/cursor.md
  • web/default/public/docs/integrations/cursor.zh.md
  • web/default/public/docs/integrations/gemini-cli.md
  • web/default/public/docs/integrations/gemini-cli.zh.md
  • web/default/public/docs/integrations/images/README.md
  • web/default/public/docs/integrations/immersive-translate.md
  • web/default/public/docs/integrations/immersive-translate.zh.md
  • web/default/public/docs/integrations/langchain.md
  • web/default/public/docs/integrations/langchain.zh.md
  • web/default/public/docs/integrations/llamaindex.md
  • web/default/public/docs/integrations/llamaindex.zh.md
  • web/default/public/docs/integrations/lobehub.md
  • web/default/public/docs/integrations/lobehub.zh.md
  • web/default/public/docs/integrations/nextchat.md
  • web/default/public/docs/integrations/nextchat.zh.md
  • web/default/public/docs/integrations/openai-sdk.md
  • web/default/public/docs/integrations/openai-sdk.zh.md
  • web/default/public/docs/integrations/opencat.md
  • web/default/public/docs/integrations/opencat.zh.md
  • web/default/public/docs/integrations/openclaw.md
  • web/default/public/docs/integrations/openclaw.zh.md
  • web/default/public/docs/integrations/opencode.md
  • web/default/public/docs/integrations/opencode.zh.md
  • web/default/public/docs/integrations/others.md
  • web/default/public/docs/integrations/others.zh.md
  • web/default/public/docs/integrations/workbuddy.md
  • web/default/public/docs/integrations/workbuddy.zh.md
  • web/default/public/docs/integrations/zed.md
  • web/default/public/docs/integrations/zed.zh.md
  • web/default/rsbuild.config.ts
  • web/default/src/assets/logo.tsx
  • web/default/src/components/balance-widget.tsx
  • web/default/src/components/casual-gates.tsx
  • web/default/src/components/command-menu.tsx
  • web/default/src/components/config-drawer.tsx
  • web/default/src/components/help-fab.tsx
  • web/default/src/components/language-switcher.tsx
  • web/default/src/components/layout/components/app-header.tsx
  • web/default/src/components/layout/components/app-sidebar.tsx
  • web/default/src/components/layout/components/authenticated-layout.tsx
  • web/default/src/components/layout/components/footer.tsx
  • web/default/src/components/layout/components/public-header.tsx
  • web/default/src/components/layout/components/system-brand.tsx
  • web/default/src/components/persona-picker-dialog.tsx
  • web/default/src/components/persona-picker-host.tsx
  • web/default/src/components/role-badge.tsx
  • web/default/src/components/ui/button.tsx
  • web/default/src/components/ui/field-hint.tsx
  • web/default/src/features/about/index.tsx
  • web/default/src/features/admin-skills/__tests__/admin-skills.test.ts
  • web/default/src/features/admin-skills/api.ts
  • web/default/src/features/admin-skills/components/admin-skill-dialogs.tsx
  • web/default/src/features/admin-skills/components/admin-skill-editor-dialog.tsx
  • web/default/src/features/admin-skills/components/admin-skill-icon.tsx
  • web/default/src/features/admin-skills/components/admin-skill-row-actions.tsx
  • web/default/src/features/admin-skills/components/admin-skills-columns.tsx
  • web/default/src/features/admin-skills/components/admin-skills-mobile-list.tsx
  • web/default/src/features/admin-skills/components/admin-skills-table.tsx
  • web/default/src/features/admin-skills/constants.ts
  • web/default/src/features/admin-skills/index.tsx
  • web/default/src/features/admin-skills/types.ts
  • web/default/src/features/auth/auth-layout.tsx
  • web/default/src/features/auth/lib/storage.ts
  • web/default/src/features/auth/sign-in/components/user-auth-form.tsx
  • web/default/src/features/auth/sign-in/index.tsx
  • web/default/src/features/auth/sign-up/components/sign-up-form.tsx
  • web/default/src/features/auth/types.ts
  • web/default/src/features/channels/components/channels-dialogs.tsx
  • web/default/src/features/channels/components/channels-primary-buttons.tsx
  • web/default/src/features/channels/components/channels-provider.tsx
  • web/default/src/features/channels/components/dialogs/channel-test-dialog.tsx
  • web/default/src/features/channels/components/dialogs/quick-import-providers-dialog.tsx
  • web/default/src/features/channels/constants.ts
  • web/default/src/features/channels/lib/channel-type-config.ts
  • web/default/src/features/channels/lib/provider-presets.ts
  • web/default/src/features/dashboard/api.ts
  • web/default/src/features/dashboard/components/overview/onboarding-status-banner.tsx
  • web/default/src/features/dashboard/components/overview/overview-dashboard.tsx
  • web/default/src/features/dashboard/components/overview/summary-cards.tsx
  • web/default/src/features/dashboard/components/topup-nudge.tsx
  • web/default/src/features/dashboard/index.tsx
  • web/default/src/features/docs/catalog.ts
  • web/default/src/features/docs/components/doc-markdown.tsx
  • web/default/src/features/docs/index.tsx
  • web/default/src/features/docs/use-doc-content.ts
  • web/default/src/features/help/faq.tsx
  • web/default/src/features/help/pricing-cheatsheet.tsx
  • web/default/src/features/home/components/hero-access-wizard.tsx
  • web/default/src/features/home/components/hero-terminal-demo.tsx
  • web/default/src/features/home/components/index.ts
  • web/default/src/features/home/components/sections/cta.tsx
  • web/default/src/features/home/components/sections/features.tsx
  • web/default/src/features/home/components/sections/hero.tsx
  • web/default/src/features/home/components/sections/how-it-works.tsx
  • web/default/src/features/home/components/sections/smart-routing.tsx
  • web/default/src/features/home/components/sections/stats.tsx
  • web/default/src/features/home/components/sections/video-examples.tsx
  • web/default/src/features/home/components/sections/voice-examples.tsx
  • web/default/src/features/home/components/smart-routing-demo.tsx
  • web/default/src/features/home/components/value-calculator.tsx
  • web/default/src/features/home/constants.ts
  • web/default/src/features/home/index.tsx
  • web/default/src/features/home/lib/icon-mapper.tsx
  • web/default/src/features/keys/api.ts
  • web/default/src/features/keys/components/api-key-brand-filter.tsx
  • web/default/src/features/keys/components/api-key-group-combobox.tsx
  • web/default/src/features/keys/components/api-key-integration-dialog.tsx
  • web/default/src/features/keys/components/api-key-mode-picker-dialog.tsx
  • web/default/src/features/keys/components/api-key-price-tier.tsx
  • web/default/src/features/keys/components/api-key-purpose-picker.tsx
  • web/default/src/features/keys/components/api-key-success-dialog.tsx
  • web/default/src/features/keys/components/api-keys-cells.tsx
  • web/default/src/features/keys/components/api-keys-columns.tsx
  • web/default/src/features/keys/components/api-keys-dialogs.tsx
  • web/default/src/features/keys/components/api-keys-empty-state.tsx
  • web/default/src/features/keys/components/api-keys-mutate-drawer.tsx
  • web/default/src/features/keys/components/api-keys-primary-buttons.tsx
  • web/default/src/features/keys/components/api-keys-table.tsx
  • web/default/src/features/keys/components/api-keys-tutorial-card.tsx
  • web/default/src/features/keys/components/data-table-row-actions.tsx
  • web/default/src/features/keys/index.tsx
  • web/default/src/features/keys/lib/api-key-form.ts
  • web/default/src/features/keys/lib/api-key-purposes-fallback.ts
  • web/default/src/features/keys/lib/index.ts
  • web/default/src/features/keys/lib/integration.ts
  • web/default/src/features/keys/test/index.tsx
  • web/default/src/features/keys/types.ts
  • web/default/src/features/marketplace/__tests__/api.test.ts
  • web/default/src/features/marketplace/__tests__/growth-surfaces.test.tsx
  • web/default/src/features/marketplace/__tests__/lib.test.ts
  • web/default/src/features/marketplace/__tests__/marketplace-events.test.tsx
  • web/default/src/features/marketplace/__tests__/my-skills-row-state.test.ts
  • web/default/src/features/marketplace/__tests__/my-skills.test.tsx
  • web/default/src/features/marketplace/api.ts
  • web/default/src/features/marketplace/components/badges.tsx
  • web/default/src/features/marketplace/components/empty-state.tsx
  • web/default/src/features/marketplace/components/error-banner.tsx
  • web/default/src/features/marketplace/components/index.ts
  • web/default/src/features/marketplace/components/lock-state-utils.ts
  • web/default/src/features/marketplace/components/lock-state.tsx
  • web/default/src/features/marketplace/components/my-skills-cells.tsx
  • web/default/src/features/marketplace/components/my-skills-filter.tsx
  • web/default/src/features/marketplace/components/my-skills-mobile-list.tsx
  • web/default/src/features/marketplace/components/my-skills-table.tsx
  • web/default/src/features/marketplace/components/new-skill-banner.tsx
  • web/default/src/features/marketplace/components/skill-card.tsx
  • web/default/src/features/marketplace/components/skill-cta.tsx
  • web/default/src/features/marketplace/components/skill-paywall-dialog.test.tsx
  • web/default/src/features/marketplace/components/skill-paywall-dialog.tsx
  • web/default/src/features/marketplace/download-utils.test.ts
  • web/default/src/features/marketplace/download-utils.ts
  • web/default/src/features/marketplace/hooks/use-skill-telemetry-consent-prompt.tsx
  • web/default/src/features/marketplace/index.tsx
  • web/default/src/features/marketplace/lib.ts
  • web/default/src/features/marketplace/lib/growth-surfaces.ts
  • web/default/src/features/marketplace/lib/my-skills-row-state.ts
  • web/default/src/features/marketplace/marketplace.test.tsx
  • web/default/src/features/marketplace/my-skills.tsx
  • web/default/src/features/marketplace/saved-skills.tsx
  • web/default/src/features/marketplace/skill-detail.test.tsx
  • web/default/src/features/marketplace/skill-detail.tsx
  • web/default/src/features/marketplace/types.ts
  • web/default/src/features/models/components/dialogs/quick-import-models-dialog.tsx
  • web/default/src/features/models/components/models-dialogs.tsx
  • web/default/src/features/models/components/models-primary-buttons.tsx
  • web/default/src/features/models/components/models-provider.tsx
  • web/default/src/features/models/lib/model-presets.ts
  • web/default/src/features/onboarding/index.tsx
  • web/default/src/features/onboarding/tutorials/chatbox.ts
  • web/default/src/features/onboarding/tutorials/cherry-studio.ts
  • web/default/src/features/onboarding/tutorials/claude-code.ts
  • web/default/src/features/onboarding/tutorials/code.ts
  • web/default/src/features/onboarding/tutorials/cursor.ts
  • web/default/src/features/onboarding/tutorials/lobechat.ts
  • web/default/src/features/onboarding/tutorials/registry.ts
  • web/default/src/features/playground/__tests__/growth-surfaces.test.tsx
  • web/default/src/features/playground/components/message-error.tsx
  • web/default/src/features/playground/components/playground-empty-state.tsx
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/pricing/components/model-details.tsx
  • web/default/src/features/pricing/components/pricing-sidebar.tsx
  • web/default/src/features/pricing/components/pricing-toolbar.tsx
  • web/default/src/features/pricing/index.tsx
  • web/default/src/features/profile/__tests__/telemetry-consent-card.test.tsx
  • web/default/src/features/profile/api.ts
  • web/default/src/features/profile/components/language-preferences-card.tsx
  • web/default/src/features/profile/components/onboarding-preferences-card.tsx
  • web/default/src/features/profile/components/profile-extension-card.tsx
  • web/default/src/features/profile/components/sidebar-modules-card.tsx
  • web/default/src/features/profile/components/telemetry-consent-card.tsx
  • web/default/src/features/profile/index.tsx
  • web/default/src/features/profile/lib/persona-presets.ts
  • web/default/src/features/profile/types.ts
  • web/default/src/features/skill-analytics/__tests__/dashboard.integration.test.tsx
  • web/default/src/features/skill-analytics/__tests__/date-range-control.test.tsx
  • web/default/src/features/skill-analytics/__tests__/metric-card.test.tsx
  • web/default/src/features/skill-analytics/__tests__/types.test.ts
  • web/default/src/features/skill-analytics/api.ts
  • web/default/src/features/skill-analytics/components/date-range-control.tsx
  • web/default/src/features/skill-analytics/components/metric-card.tsx
  • web/default/src/features/skill-analytics/index.tsx
  • web/default/src/features/skill-analytics/types.ts
  • web/default/src/features/system-settings/billing/index.tsx
  • web/default/src/features/system-settings/billing/section-registry.tsx
  • web/default/src/features/system-settings/integrations/payment-settings-section.tsx
  • web/default/src/features/system-settings/maintenance/config.ts
  • web/default/src/features/system-settings/maintenance/header-navigation-section.tsx
  • web/default/src/features/system-settings/maintenance/sidebar-modules-section.tsx
  • web/default/src/features/system-settings/site/index.tsx
  • web/default/src/features/system-settings/types.ts
  • web/default/src/features/usage-logs/components/columns/common-logs-columns.tsx
  • web/default/src/features/usage-logs/components/dialogs/details-dialog.tsx
  • web/default/src/features/usage-logs/components/usage-logs-table.tsx
  • web/default/src/features/user-home/__tests__/user-home.test.tsx
  • web/default/src/features/user-home/api.ts
  • web/default/src/features/user-home/index.tsx
  • web/default/src/features/user-home/types.ts
  • web/default/src/features/users/__tests__/skill-usage-dialog.test.tsx
  • web/default/src/features/users/__tests__/users-mutate-drawer.test.tsx
  • web/default/src/features/users/api.ts
  • web/default/src/features/users/components/data-table-row-actions.tsx
  • web/default/src/features/users/components/dialogs/user-skill-usage-dialog.tsx
  • web/default/src/features/users/components/users-mutate-drawer.tsx
  • web/default/src/features/users/constants.ts
  • web/default/src/features/users/index.tsx
  • web/default/src/features/users/lib/user-form.ts
  • web/default/src/features/users/types.ts
  • web/default/src/features/wallet/api.ts
  • web/default/src/features/wallet/components/auto-topup-card.tsx
  • web/default/src/features/wallet/components/dialogs/auto-topup-prompt-dialog.tsx
  • web/default/src/features/wallet/components/dialogs/billing-history-dialog.tsx
  • web/default/src/features/wallet/components/recharge-form-card.tsx
  • web/default/src/features/wallet/components/wallet-stats-card.tsx
  • web/default/src/features/wallet/constants.ts
  • web/default/src/features/wallet/hooks/index.ts
  • web/default/src/features/wallet/hooks/use-airwallex-payment.ts
  • web/default/src/features/wallet/index.tsx
  • web/default/src/features/wallet/lib/ui.tsx
  • web/default/src/features/wallet/types.ts
  • web/default/src/features/welcome/index.tsx
  • web/default/src/hooks/use-casual.ts
  • web/default/src/hooks/use-persona.ts
  • web/default/src/hooks/use-sidebar-config.ts
  • web/default/src/hooks/use-sidebar-data.ts
  • web/default/src/hooks/use-top-nav-links.ts
  • web/default/src/i18n/config.ts
  • web/default/src/i18n/locales/_reports/_sync-report.json
  • web/default/src/i18n/locales/_reports/fr.untranslated.json
  • web/default/src/i18n/locales/_reports/ja.untranslated.json
  • web/default/src/i18n/locales/_reports/ru.untranslated.json
  • web/default/src/i18n/locales/_reports/vi.untranslated.json
  • web/default/src/i18n/locales/_reports/zh.untranslated.json
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh.json
  • web/default/src/i18n/static-keys.ts
  • web/default/src/lib/constants.ts
  • web/default/src/lib/usage-estimate.ts
  • web/default/src/routeTree.gen.ts
  • web/default/src/routes/_authenticated/errors/$error.tsx
  • web/default/src/routes/_authenticated/help/faq.tsx
  • web/default/src/routes/_authenticated/help/pricing.tsx
  • web/default/src/routes/_authenticated/home/index.tsx
  • web/default/src/routes/_authenticated/keys/test.tsx
  • web/default/src/routes/_authenticated/playground/index.tsx
  • web/default/src/routes/_authenticated/skill-analytics/index.tsx
  • web/default/src/routes/_authenticated/skills/$slug.tsx
  • web/default/src/routes/_authenticated/skills/admin/index.tsx
  • web/default/src/routes/_authenticated/skills/index.tsx
  • web/default/src/routes/_authenticated/skills/my/index.tsx
  • web/default/src/routes/_authenticated/skills/saved/index.tsx
  • web/default/src/routes/onboarding/$slug.tsx
  • web/default/src/routes/resources/$slug.tsx
  • web/default/src/routes/resources/index.tsx
  • web/default/src/routes/welcome.tsx
  • web/default/src/styles/index.css
  • web/default/src/styles/theme.css
  • web/default/src/test-utils/setup.ts
  • web/default/vitest.config.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@SamWang9803
SamWang9803 deleted the sam/skill-marketplace branch August 25, 2026 11:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants