console: sync the registration wizard and issue real API tokens

Mirror the Console registration feature: native hook catalog with
activation plans, one-command install that embeds both credentials in
exclusively created owner-only files (mktemp on POSIX, icacls on
Windows), sh/PowerShell tabs, never-expiring default token, focus-visible
styles, merged i18n keys, and the matching e2e specs.

The server previously answered /v1/auth/token with the 7-day Better Auth
session token and ignored ttl_seconds. It now issues opaque 32-byte API
tokens stored as SHA-256 hashes (migration 003), honours ttl_seconds with
null meaning no expiry, and resolves bearer values as API tokens before
session validation. Issuance requires a session credential.

Claude-Session: https://claude.ai/code/session_01QoUjdc7HGKTsgj5GhG8HvF
This commit is contained in:
雷电芽衣 committed 2026-09-02 09:56:40 -04:00
1 parent 1bb9d4d49d
commit edf9d73c3e
21 files changed
+967 -163

No files matched your search

@@ -32,11 +32,18 @@ function IntegrationGroup({
key={integration.id}
type="button"
onClick={() => onSelect(integration)}
className="group flex items-center justify-between gap-3 px-3 py-3 text-left border-b border-border hover:bg-surface focus-visible:bg-surface focus-visible:outline-none"
className="group flex items-center justify-between gap-3 px-3 py-3 text-left border-b border-border hover:bg-surface focus-visible:bg-surface"
>
<span className="font-mono text-[12px] text-ink">{integration.name}</span>
<span className="font-mono text-[10px] text-ink-dim opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100 transition-opacity" aria-hidden="true">
→
<span className="flex items-center gap-2" aria-hidden="true">
{mode === 'hooks' && (
<span className="font-mono text-[9px] tracking-wider text-ink-dim border border-border px-1.5 py-0.5">
{t('agentRegistration.hookBadge')}
</span>
)}
<span className="font-mono text-[10px] text-ink-dim opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100 transition-opacity">
→
</span>
</span>
</button>
))}
@@ -44,10 +51,11 @@ function IntegrationGroup({
</section>
);
}
export default function IntegrationStep({ onSelect }: IntegrationStepProps) {
return (
<div className="space-y-6">
<IntegrationGroup mode="adapter" onSelect={onSelect} />
<IntegrationGroup mode="hooks" onSelect={onSelect} />
<IntegrationGroup mode="sdk" onSelect={onSelect} />
</div>
);