Five gaps closed against the updated product-package spec
(http://gitee.ath.cx:3000/xiaohei/heicode/src/branch/main/docs/product-package):
P1. /dashboard hero rewritten per §10 §"初始首页"
features/dashboard/components/home-hero.tsx replaces the technical
CockpitView with four blocks the spec mandates: 主输入 / 继续任务 /
今日焦点 / 辅助入口. Main input is "你想把什么想法变成可以上线的软件?".
Submit only stashes the idea to localStorage + toast — the actual task
conversation belongs in the desktop client per §13 §5.1.
P2. /tasks/$id TaskCard route per §10 §"任务卡" + §11 §3
features/tasks/task-card-view.tsx renders one AgnetDeployment as the
user-facing task object: 目标 / 第一版范围 / 自动生成 / 待确认上下文 +
Manager 辅助按钮. Linked from Home hero's 继续任务 list.
P3. /sk-sources 推荐摘要 dialog per §10 §"推荐确认卡"
features/agnet-console/pages.tsx RecommendationSummaryDialog. Five
blocks (本次会做 / 本次允许使用 / 本次不会做 / 高危规则 / 预计消耗) +
Launch Agnet button with "参数由 Heicode 自动生成" caption. No JSON
editor, no permission manifest — §10 高级展开禁令.
P4. /audit redacted card view per §10 §"任务用量与审计" + §6
features/agnet-console/pages.tsx AgnetAuditPage. Old裸 table replaced
with脱敏 cards exposing only the fields docs allows: resource_id /
resource_type / allowed_actions / constraints / secret_ref. Helper
function maskIfSecret() catches any stray plaintext credential the
backend might leak. Banner says explicitly "明文密钥从不展示".
P5. Login screen filters Claude Official provider per §8
cc-haha/desktop/src/components/login/HeicodeLoginPage.tsx hides the
legacy `official` preset so the login carries Heicode brand alone.
i18n fix (BIG):
i18next defaults to `defaultNS = 'translation'`. The earlier custom
keys had been written to the JSON root, NOT into translation, so
every t('Preparation checklist') was returning the English key as
fallback all along. Moved 67 orphan keys (zh+en, both files) into
the translation namespace where they're actually resolvable. Verified
by loading i18next + zh.json in bun and confirming all keys resolve
to the expected Chinese strings.
Cache-busting from earlier session (already deployed via SFTP, never
committed): index.html / constants.ts / footer.tsx now hold the
?v=h-glass-2 suffixed asset URLs in git, so future docker rebuilds
preserve them.
Per user directive: tested locally only (TS check clean, i18next
resolves correctly). NOT deploying to the VM in this commit — user
asked to keep production untouched until they verify the changes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Theme tokens (theme.css)
- --primary retuned to the brand violet oklch(0.58 0.17 278) ≈ #7B6BE3
(was a saturated pink oklch ... 286 that read off-brand against the H
glass logo)
- New tokens: --brand-from #B888E5, --brand #7B6BE3, --brand-to #6B7CE0,
--gradient-brand (135deg three-stop), --gradient-brand-btn for primary
CTAs. Both light and dark modes hold the same brand identity.
Login page (auth-layout.tsx + sign-in/index.tsx + user-auth-form.tsx)
- Inlined H glass mark SVG replaces the abstract ShieldCheck pictogram
- Brand wordmark uses gradient text-fill so the word "Heicode" reads as
the same gradient as the logo
- "Tenant access" pill and h2 heading both pick up brand violet via
border / bg / gradient text
- Sign-in button switches from solid var(--primary) to the three-stop
--gradient-brand-btn with violet drop shadow + lift-on-hover
Header user info (profile-dropdown.tsx)
- The right-side trigger used to be a bare 36px avatar — invisible user
identity unless you click. Now it is a pill: gradient-filled avatar
initials + display name + email + role badge, always visible on >=sm
- Avatar fallback fills with --gradient-brand so even pre-image, the
user pill carries Heicode color identity
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per docs §10 "禁止普通用户体验出现:模型供应商配置 / 模型提供方
选择" — the dashboard landing hero showed "OpenAI / Claude /
Gemini / DeepSeek / Qwen / Llama" as a marketing matrix, which
leaks upstream provider branding into the user-facing surface.
Replaced with Heicode capability tags (通用 / 长上下文 / 推理 /
代码 / 多模态 / 高性价比). This is the landing the user lands on
after login; admins still see real upstream provider names in
the system-settings → models tabs (those are technically the
channel protocol names and removing them would mislead admins).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CORS unblock — add /api/heicode-auth/*proxyPath backend proxy to
HEICODE_AUTH_BASE_URL. Frontend defaults to same-origin path so
the browser never hits APIM directly.
Sidebar — replace backend jargon (Git sources / Deployments /
Events / Wallet / Available models / Profile) with the user-facing
labels docs §10 mandates: 总览 / 准备清单 / 任务总览 / 审计 /
模型与余额 / 客户端 / 账号安全.
/sk-sources rewritten as 4-card preparation wizard with progress
meter; full Git form moves into a 高级补充 sheet. Drops JSON
editor, permission manifest, snapshots and resource-grant pills.
/deployments simplified to 任务总览: objective + status + last
update. Drops risk / budget / scope / secret_ref pills and the
RunDetailPanel; manifest details only in audit/advanced views.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
index.html: add png/ico/apple-touch favicon links, og:image,
and brand theme-color (#7B6BE3) so all icon surfaces use the
H glass mark.
Hide unused auth UI:
- profile page: drop PasskeyCard + TwoFACard
- system-settings/auth: drop Passkey Authentication section
These features aren't part of the Heicode platform flow (auth
is delegated to the identity service / SSO); leaving them in
the UI confuses tenants.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match Heicode desktop client app icon: violet→blue gradient
rounded-square with white H. Replaces favicon.ico, logo.png
(used in footer / system info), heicode-logo.svg (browser
favicon link), and the inline Logo component.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When the desktop one-click login flow opens
/heicode/oauth/authorize?state=...&redirect_uri=...
in the browser and the user isn't signed in, Manager renders the
"please log in" bridge page that links to /sign-in?redirect=<authUrl>.
After login, useAuthRedirect's `handleLoginSuccess` calls TanStack
Router's `navigate({ to: targetPath })` to send the user back to
that authorize URL.
But TanStack Router only knows about React routes; backend bridges
(`/heicode/oauth/...`, `/api/...`) have no matching route, so the
SPA renders 404. The user has to manually re-enter the URL, at
which point the backend handles it and 302s to the loopback
callback. This produced the 500 → 404 → success symptom users hit
on first-time desktop login.
Fix: detect backend prefixes (`/heicode/oauth/`, `/api/`) and use
`window.location.assign()` to force a full-page navigation so the
server gets the request directly. React-route paths still go
through `navigate()` as before.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Manager now exposes a Resource Grant manifest and the Agnet control-plane response carries runtime state, agent instances, and permission_manifest so frontend runs can submit bounded resource grants without plaintext credentials.
Constraint: Manager remains the user console while NewAPI stays independent and OpenBao is referenced through secret_ref only.
Rejected: platform-side high-risk approval | client approval is the product boundary; Agnet only validates approval evidence.
Confidence: medium
Scope-risk: moderate
Directive: Do not mix child Agnet runtime model selection with NewAPI billing or expose OpenBao as a public route.
Tested: git diff --check; jq empty locale JSON; go vet ./controller ./model ./router; go test -count=1 ./controller ./model ./router
Not-tested: frontend typecheck/build because local node_modules tooling is absent and user requested builds happen on the VM.
Co-authored-by: OmX <omx@oh-my-codex.dev>
- Add hide_from_user_ui on tokens; EnsureUserRelayToken on login and Agnet session
- List/search tokens: end-users see only visible keys; admins see all
- Add /available-models and sidebar entry; i18n en/zh + locales
- desktop download / router hooks if present under heicode/
Extend agnet SK sources with repo_ref and snapshot display; add authenticated
deployment sheet + API types; cockpit toolbar entry; locale strings; minor docs.
Made-with: Cursor
Manager web: Git sources workflow steps and copy; typecheck fixes for auth
and home sections; UsageLog type in usage-log-schema.ts (outside ignored data/).
docs: Agnet platform contract adds runtime_execution and sk_access_policy,
orchestration-plan and acceptance matrix aligned.
Made-with: Cursor
Backend (controller/heicode_agnet_session.go):
- Add HEICODE_ROOT_EMAILS / HEICODE_ADMIN_EMAILS whitelists for JIT role
assignment. Manager no longer trusts Agnet's role claim — admin / root
is granted only by local config.
- Default JIT-synced users to RoleCommonUser.
- Promote-only role sync on every login (never demote).
Frontend auth fixes:
- login() no longer hard-codes id=1; preserves the real manager user id
returned by /api/user/session/from-agnet so the New-Api-User header
matches the cookie session.
- After login, prefer local /api/user/self over Agnet /me so role /
status reflect actual manager state (e.g. whitelist promotion).
- lib/api.ts: scope 401 -> "Session expired" handling to identity
endpoints only; admin-only 401 no longer resets the session.
UI restructuring:
- Default sidebar shows only Code delivery + Console + Personal, plus a
single "System settings" entry for ROLE.ADMIN+.
- system-settings workspace now hosts the full Tenant administration
tree (Channels / Models / Subscriptions / Redemption codes / Tenants /
Templates / Agents / Vendors / All usage logs) for ROLE.ADMIN+, with
System Administration sub-tree gated to ROLE.SUPER_ADMIN.
- Workspace switch triggers on admin paths (channels, users, templates,
agents, subscriptions, models, redemption-codes) — not only
/system-settings.
- system-settings route now allows ROLE.ADMIN+ instead of root-only.
Branding cleanup:
- Drop orphan "NewAPI" i18n keys from web/default locales.
- Rename web/default workspace package newapi-web -> heicode-web.
Config:
- docker-compose.azure-vm.yml exposes HEICODE_ROOT_EMAILS /
HEICODE_ADMIN_EMAILS.
VERSION: 1.1.0-default-user-role
Made-with: Cursor
Replace password-based /api/user/login bridge after external auth with POST /api/user/session/from-agnet: verify access (and optional refresh) against Agnet /api/auth/me, upsert local user by email, then issue the Manager session cookie. Frontend sends bearer tokens only.
Includes HEICODE_AUTH_BASE_URL in compose defaults and .env.example.
Made-with: Cursor
Use a dedicated TwoFactorRequiredError and shared type guard to keep login flow checks type-safe and less brittle than matching magic strings.
Made-with: Cursor
External IdP login alone did not set Gin session; proxied API calls returned 401 and triggered session-expired toast. Call POST /api/user/login after token exchange, support Turnstile on sign-in, handle 2FA pending session, and clear Manager cookie on logout.
Made-with: Cursor