refactor: clean up code formatting and improve readability across multiple components

- Standardized import statements and formatting in various files, including `WalletInfoSection`, `AgentChatPanel`, and `SkillsPanel`.
- Enhanced readability by adjusting line breaks and spacing in JSX elements and function definitions.
- Improved consistency in the use of arrow functions and destructuring across components.
- Updated type definitions and ensured proper alignment of code for better maintainability.
This commit is contained in:
M3gA-Mind
2026-02-23 14:39:09 +05:30
parent b6810429c4
commit 23d21667e2
18 changed files with 534 additions and 636 deletions
+4 -4
View File
@@ -54,16 +54,16 @@ AlphaHuman is designed to be simpler to deploy, cheaper to run, and more intelli
> **Early Beta** — AlphaHuman is under active development. Expect rough edges.
| Platform | Variant | Download |
| ----------- | --------------------------- | ------------------------------------------------------------------------------------------------------------- |
| Platform | Variant | Download |
| ----------- | --------------------------- | -------------------------------------------------------------------------------------------------------------- |
| **macOS** | Apple Silicon (M1/M2/M3/M4) | [`.dmg` (aarch64)](https://github.com/alphahumanai/alphahuman/releases/latest/download/AlphaHuman_aarch64.dmg) |
| **macOS** | Intel | [`.dmg` (x64)](https://github.com/alphahumanai/alphahuman/releases/latest/download/AlphaHuman_x64.dmg) |
| **Windows** | x64 | [`.msi`](https://github.com/alphahumanai/alphahuman/releases/latest/download/AlphaHuman_x64_en-US.msi) |
| **Linux** | Debian / Ubuntu | [`.deb` (amd64)](https://github.com/alphahumanai/alphahuman/releases/latest/download/AlphaHuman_amd64.deb) |
| **Linux** | Fedora / RHEL | [`.rpm` (x86_64)](https://github.com/alphahumanai/alphahuman/releases/latest/download/AlphaHuman_x86_64.rpm) |
| **Linux** | Universal | [`.AppImage`](https://github.com/alphahumanai/alphahuman/releases/latest/download/AlphaHuman_amd64.AppImage) |
| **Android** | — | Coming soon |
| **iOS** | — | Coming soon |
| **Android** | — | Coming soon |
| **iOS** | — | Coming soon |
Browse all releases: [github.com/alphahumanai/alphahuman/releases](https://github.com/alphahumanai/alphahuman/releases)
+5 -5
View File
@@ -4,11 +4,11 @@
We provide security updates for the following versions of AlphaHuman:
| Version | Supported |
| ------- | ------------------ |
| Latest | :white_check_mark: |
| Previous minor | :white_check_mark: |
| Older | :x: |
| Version | Supported |
| -------------- | ------------------ |
| Latest | :white_check_mark: |
| Previous minor | :white_check_mark: |
| Older | :x: |
We recommend always running the [latest release](https://github.com/alphahumanxyz/alphahuman/releases/latest). AlphaHuman is in early beta; older versions may not receive patches.
+13 -9
View File
@@ -1,9 +1,9 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { skillManager } from '../lib/skills/manager';
import { useSkillConnectionStatus } from '../lib/skills/hooks';
import { useAppSelector } from '../store/hooks';
import { useUser } from '../hooks/useUser';
import { useSkillConnectionStatus } from '../lib/skills/hooks';
import { skillManager } from '../lib/skills/manager';
import { useAppSelector } from '../store/hooks';
function truncateAddress(address: string): string {
if (!address || address.length < 12) return address;
@@ -64,8 +64,8 @@ export default function WalletInfoSection() {
};
const networks = Array.isArray(listData.networks) ? listData.networks : [];
// Prefer Ethereum Mainnet (skill always has it); else first EVM, else first network
const ethMainnet = networks.find((n) => n?.chain_id === '1' && n?.chain_type === 'evm');
const firstEvm = networks.find((n) => n && n.chain_type === 'evm');
const ethMainnet = networks.find(n => n?.chain_id === '1' && n?.chain_type === 'evm');
const firstEvm = networks.find(n => n && n.chain_type === 'evm');
const chosen = ethMainnet ?? firstEvm ?? networks.find(Boolean);
if (!chosen || cancelledRef.current) {
if (!cancelledRef.current) setLoading(false);
@@ -121,9 +121,13 @@ export default function WalletInfoSection() {
} catch (e) {
if (!cancelledRef.current) {
const msg = e instanceof Error ? e.message : String(e);
const isTransient = msg.includes('not running') || msg.includes('not started') || msg.includes('transport');
const isTransient =
msg.includes('not running') || msg.includes('not started') || msg.includes('transport');
if (isTransient && attempt < 3) {
retryTimerRef.current = setTimeout(() => fetchWalletInfoRef.current(address, attempt + 1), 2000);
retryTimerRef.current = setTimeout(
() => fetchWalletInfoRef.current(address, attempt + 1),
2000
);
return;
}
console.error('[WalletInfoSection] Failed to load wallet info:', e);
@@ -197,7 +201,7 @@ export default function WalletInfoSection() {
) : error ? (
<span className="text-coral-500 text-xs">{error}</span>
) : (
networkName ?? '—'
(networkName ?? '—')
)}
</span>
</div>
@@ -209,7 +213,7 @@ export default function WalletInfoSection() {
) : error ? (
'—'
) : (
balance ?? '—'
(balance ?? '—')
)}
</span>
</div>
@@ -1,8 +1,8 @@
import { useEffect, useState } from 'react';
import { alphahumanAgentChat } from '../../../utils/tauriCommands';
import SettingsHeader from '../components/SettingsHeader';
import { useSettingsNavigation } from '../hooks/useSettingsNavigation';
import { alphahumanAgentChat } from '../../../utils/tauriCommands';
type ChatMessage = { role: 'user' | 'agent'; text: string };
@@ -46,12 +46,7 @@ const AgentChatPanel = () => {
}, []);
useEffect(() => {
const payload = {
messages,
providerOverride,
modelOverride,
temperature,
};
const payload = { messages, providerOverride, modelOverride, temperature };
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));
} catch {
@@ -65,7 +60,7 @@ const AgentChatPanel = () => {
setError('');
setSending(true);
setInput('');
setMessages((prev) => [...prev, { role: 'user', text }]);
setMessages(prev => [...prev, { role: 'user', text }]);
try {
const response = await alphahumanAgentChat(
text,
@@ -73,7 +68,7 @@ const AgentChatPanel = () => {
modelOverride.trim() ? modelOverride : undefined,
Number.isFinite(Number(temperature)) ? Number(temperature) : undefined
);
setMessages((prev) => [...prev, { role: 'agent', text: response.result }]);
setMessages(prev => [...prev, { role: 'agent', text: response.result }]);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
setError(message);
@@ -96,7 +91,7 @@ const AgentChatPanel = () => {
className="input input-bordered w-full text-slate-900 bg-white"
placeholder="openai"
value={providerOverride}
onChange={(event) => setProviderOverride(event.target.value)}
onChange={event => setProviderOverride(event.target.value)}
/>
</label>
<label className="space-y-2 text-sm text-gray-300">
@@ -105,7 +100,7 @@ const AgentChatPanel = () => {
className="input input-bordered w-full text-slate-900 bg-white"
placeholder="gpt-4.1-mini"
value={modelOverride}
onChange={(event) => setModelOverride(event.target.value)}
onChange={event => setModelOverride(event.target.value)}
/>
</label>
<label className="space-y-2 text-sm text-gray-300">
@@ -114,7 +109,7 @@ const AgentChatPanel = () => {
className="input input-bordered w-full text-slate-900 bg-white"
placeholder="0.7"
value={temperature}
onChange={(event) => setTemperature(event.target.value)}
onChange={event => setTemperature(event.target.value)}
/>
</label>
</div>
@@ -139,8 +134,7 @@ const AgentChatPanel = () => {
<div
className={`text-sm whitespace-pre-wrap ${
message.role === 'user' ? 'text-white' : 'text-emerald-200'
}`}
>
}`}>
{message.text}
</div>
</div>
@@ -151,7 +145,7 @@ const AgentChatPanel = () => {
className="textarea textarea-bordered w-full min-h-[140px] text-slate-900 bg-white"
placeholder="Ask the agent anything..."
value={input}
onChange={(event) => setInput(event.target.value)}
onChange={event => setInput(event.target.value)}
/>
<button className="btn btn-primary" onClick={sendMessage} disabled={sending}>
{sending ? 'Sending…' : 'Send Message'}
+17 -29
View File
@@ -1,9 +1,9 @@
import { useEffect, useMemo, useState } from 'react';
import {
alphahumanListIntegrations,
alphahumanGetConfig,
alphahumanGetRuntimeFlags,
alphahumanListIntegrations,
alphahumanSetBrowserAllowAll,
alphahumanUpdateBrowserSettings,
type IntegrationCategory,
@@ -50,7 +50,7 @@ const SkillsPanel = () => {
const runtimeFlags = await alphahumanGetRuntimeFlags();
setBrowserAllowAll(runtimeFlags.result.browser_allow_all);
const entries = await Promise.all(
response.result.map(async (integration) => {
response.result.map(async integration => {
const skillId = integrationSkillId(integration);
try {
const enabled =
@@ -99,7 +99,8 @@ const SkillsPanel = () => {
<div>
<h3 className="text-lg font-semibold text-white">Browser Access</h3>
<p className="text-xs text-stone-400">
Allow the browser tool to visit any public domain (private and file URLs are still blocked).
Allow the browser tool to visit any public domain (private and file URLs are still
blocked).
</p>
</div>
<label className="flex items-center gap-3 text-sm text-stone-300">
@@ -108,7 +109,7 @@ const SkillsPanel = () => {
className="checkbox checkbox-primary"
checked={browserAllowAll}
disabled={browserAllowAllBusy}
onChange={async (event) => {
onChange={async event => {
const next = event.target.checked;
setBrowserAllowAllBusy(true);
try {
@@ -136,9 +137,7 @@ const SkillsPanel = () => {
</div>
)}
<div className="rounded-xl border border-stone-800/60 bg-black/40">
{loading && (
<div className="p-4 text-sm text-stone-400">Loading integrations...</div>
)}
{loading && <div className="p-4 text-sm text-stone-400">Loading integrations...</div>}
{!loading && integrations.length === 0 && (
<div className="p-4 text-sm text-stone-400">
No integrations registered in Alphahuman.
@@ -159,9 +158,9 @@ const SkillsPanel = () => {
enabled={enabledMap[integration.name] ?? false}
busy={toggleBusy[integration.name] ?? false}
toggleable={isIntegrationToggleable(integration)}
onToggle={async (nextEnabled) => {
onToggle={async nextEnabled => {
const key = integration.name;
setToggleBusy((prev) => ({ ...prev, [key]: true }));
setToggleBusy(prev => ({ ...prev, [key]: true }));
try {
if (integration.name === 'Browser') {
await alphahumanUpdateBrowserSettings({ enabled: nextEnabled });
@@ -173,12 +172,12 @@ const SkillsPanel = () => {
await runtimeDisableSkill(skillId);
}
}
setEnabledMap((prev) => ({ ...prev, [key]: nextEnabled }));
setEnabledMap(prev => ({ ...prev, [key]: nextEnabled }));
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
setError(message);
} finally {
setToggleBusy((prev) => ({ ...prev, [key]: false }));
setToggleBusy(prev => ({ ...prev, [key]: false }));
}
}}
/>
@@ -218,31 +217,23 @@ function IntegrationRow({
<div
className={`flex items-center justify-between gap-4 p-4 ${
isLast ? '' : 'border-b border-stone-800/60'
}`}
>
}`}>
<div className="flex items-center gap-3 text-left flex-1 min-w-0">
<div className="w-6 h-6 flex items-center justify-center text-white/70">
<span className="text-xs font-semibold uppercase">
{integration.name.slice(0, 2)}
</span>
<span className="text-xs font-semibold uppercase">{integration.name.slice(0, 2)}</span>
</div>
<div className="min-w-0">
<div className="text-sm font-semibold text-white truncate">{integration.name}</div>
<div className="text-xs text-stone-400 line-clamp-2">
{integration.description}
</div>
<div className="text-xs text-stone-400 line-clamp-2">{integration.description}</div>
{integration.setup_hints.length > 0 && (
<div className="mt-1 text-[11px] text-stone-500">
{integration.setup_hints[0]}
</div>
<div className="mt-1 text-[11px] text-stone-500">{integration.setup_hints[0]}</div>
)}
</div>
</div>
<div className="flex items-center gap-3">
<span
className={`px-2 py-1 text-[11px] font-semibold uppercase border rounded-full ${statusStyle}`}
>
className={`px-2 py-1 text-[11px] font-semibold uppercase border rounded-full ${statusStyle}`}>
{integration.status}
</span>
<label className="flex items-center gap-2 text-xs text-stone-300">
@@ -251,7 +242,7 @@ function IntegrationRow({
className="checkbox checkbox-primary"
checked={enabled}
disabled={busy || !toggleable}
onChange={(event) => onToggle(event.target.checked)}
onChange={event => onToggle(event.target.checked)}
/>
{busy ? 'Saving…' : enabled ? 'Enabled' : toggleable ? 'Disabled' : 'Managed'}
</label>
@@ -274,8 +265,5 @@ function isIntegrationToggleable(integration: IntegrationInfo): boolean {
if (integration.name === 'Browser') {
return true;
}
return (
integration.category === 'Chat' ||
integration.category === 'ToolsAutomation'
);
return integration.category === 'Chat' || integration.category === 'ToolsAutomation';
}
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,5 @@
import React from 'react';
import { CheckIcon, ExclamationTriangleIcon } from '@heroicons/react/24/outline';
import React from 'react';
interface ActionPanelProps {
children: React.ReactNode;
@@ -14,7 +14,7 @@ const ActionPanel: React.FC<ActionPanelProps> = ({
hasChanges = false,
success = false,
error,
className = ''
className = '',
}) => {
return (
<div className={`space-y-6 ${className}`}>
@@ -60,21 +60,24 @@ const PrimaryButton: React.FC<PrimaryButtonProps> = ({
disabled = false,
variant = 'primary',
children,
className = ''
className = '',
}) => {
const baseClasses = 'px-6 py-3 rounded-lg font-medium transition-all duration-200 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed';
const baseClasses =
'px-6 py-3 rounded-lg font-medium transition-all duration-200 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed';
const variantClasses = {
primary: 'bg-primary-600 hover:bg-primary-500 active:bg-primary-700 text-white shadow-soft hover:shadow-lg hover:shadow-primary-500/25 focus:ring-2 focus:ring-primary-500/50 focus:ring-offset-2 focus:ring-offset-black',
secondary: 'bg-stone-800 hover:bg-stone-700 active:bg-stone-600 text-white border border-stone-600 focus:ring-2 focus:ring-primary-500/50 focus:ring-offset-2 focus:ring-offset-black',
outline: 'border border-stone-600 text-white hover:bg-white/10 active:bg-white/20 focus:ring-2 focus:ring-primary-500/50 focus:ring-offset-2 focus:ring-offset-black'
primary:
'bg-primary-600 hover:bg-primary-500 active:bg-primary-700 text-white shadow-soft hover:shadow-lg hover:shadow-primary-500/25 focus:ring-2 focus:ring-primary-500/50 focus:ring-offset-2 focus:ring-offset-black',
secondary:
'bg-stone-800 hover:bg-stone-700 active:bg-stone-600 text-white border border-stone-600 focus:ring-2 focus:ring-primary-500/50 focus:ring-offset-2 focus:ring-offset-black',
outline:
'border border-stone-600 text-white hover:bg-white/10 active:bg-white/20 focus:ring-2 focus:ring-primary-500/50 focus:ring-offset-2 focus:ring-offset-black',
};
return (
<button
className={`${baseClasses} ${variantClasses[variant]} ${className}`}
onClick={onClick}
disabled={disabled || loading}
>
disabled={disabled || loading}>
{loading && (
<div className="h-4 w-4 border-2 border-white/20 border-t-white rounded-full animate-spin mr-2" />
)}
@@ -84,4 +87,4 @@ const PrimaryButton: React.FC<PrimaryButtonProps> = ({
};
export default ActionPanel;
export { PrimaryButton };
export { PrimaryButton };
@@ -11,23 +11,19 @@ const InputGroup: React.FC<InputGroupProps> = ({
title,
description,
children,
className = ''
className = '',
}) => {
return (
<div className={`space-y-6 ${className}`}>
{title && (
<div className="space-y-2">
<h4 className="text-lg font-medium text-white">{title}</h4>
{description && (
<p className="text-sm text-gray-400">{description}</p>
)}
{description && <p className="text-sm text-gray-400">{description}</p>}
</div>
)}
<div className="rounded-lg border border-white/10 bg-white/5 backdrop-blur-sm p-6">
<div className="grid gap-6 md:grid-cols-2">
{children}
</div>
<div className="grid gap-6 md:grid-cols-2">{children}</div>
</div>
</div>
);
@@ -46,17 +42,14 @@ const Field: React.FC<FieldProps> = ({
children,
helpText,
className = '',
fullWidth = false
fullWidth = false,
}) => {
return (
<label className={`space-y-3 text-sm text-gray-300 ${fullWidth ? 'md:col-span-2' : ''} ${className}`}>
<label
className={`space-y-3 text-sm text-gray-300 ${fullWidth ? 'md:col-span-2' : ''} ${className}`}>
<div>
<span className="font-medium">{label}</span>
{helpText && (
<p className="text-xs text-gray-400 leading-relaxed mt-1">
{helpText}
</p>
)}
{helpText && <p className="text-xs text-gray-400 leading-relaxed mt-1">{helpText}</p>}
</div>
{children}
</label>
@@ -76,7 +69,7 @@ const CheckboxField: React.FC<CheckboxFieldProps> = ({
checked,
onChange,
helpText,
className = ''
className = '',
}) => {
return (
<div className={`flex flex-col gap-3 ${className}`}>
@@ -85,18 +78,14 @@ const CheckboxField: React.FC<CheckboxFieldProps> = ({
type="checkbox"
className="w-5 h-5 rounded border-2 border-stone-600 bg-stone-900/40 text-primary-500 focus:ring-2 focus:ring-primary-500/30 focus:border-primary-500/50 transition-all duration-200"
checked={checked}
onChange={(e) => onChange(e.target.checked)}
onChange={e => onChange(e.target.checked)}
/>
<span className="font-medium">{label}</span>
</label>
{helpText && (
<p className="text-xs text-gray-400 ml-7 leading-relaxed">
{helpText}
</p>
)}
{helpText && <p className="text-xs text-gray-400 ml-7 leading-relaxed">{helpText}</p>}
</div>
);
};
export default InputGroup;
export { Field, CheckboxField };
export { Field, CheckboxField };
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { ChevronDownIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
import React, { useState } from 'react';
interface SectionCardProps {
title: string;
@@ -16,14 +16,14 @@ const priorityStyles = {
critical: 'bg-gradient-to-br from-primary-500/10 to-primary-600/5 border-primary-500/20',
infrastructure: 'bg-gradient-to-br from-slate-500/8 to-slate-600/4 border-slate-500/15',
development: 'bg-gradient-to-br from-amber-500/8 to-amber-600/4 border-amber-500/15',
tools: 'bg-black/30 border-stone-600/30'
tools: 'bg-black/30 border-stone-600/30',
} as const;
const priorityIconColors = {
critical: 'text-primary-400',
infrastructure: 'text-slate-400',
development: 'text-amber-400',
tools: 'text-stone-400'
tools: 'text-stone-400',
} as const;
const SectionCard: React.FC<SectionCardProps> = ({
@@ -34,7 +34,7 @@ const SectionCard: React.FC<SectionCardProps> = ({
collapsible = false,
defaultExpanded = true,
hasChanges = false,
loading = false
loading = false,
}) => {
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
@@ -45,20 +45,18 @@ const SectionCard: React.FC<SectionCardProps> = ({
};
return (
<div className={`rounded-xl border backdrop-blur-sm transition-all duration-200 ${priorityStyles[priority]}`}>
<div
className={`rounded-xl border backdrop-blur-sm transition-all duration-200 ${priorityStyles[priority]}`}>
<div
className={`flex items-center justify-between p-6 ${collapsible ? 'cursor-pointer hover:bg-white/5' : ''}`}
onClick={handleToggle}
>
onClick={handleToggle}>
<div className="flex items-center gap-3">
<div className={`flex-shrink-0 ${priorityIconColors[priority]}`}>
{React.cloneElement(icon, { className: 'h-5 w-5' } as any)}
</div>
<div className="flex items-center gap-2">
<h3 className="text-xl font-semibold text-white font-display">{title}</h3>
{hasChanges && (
<div className="h-2 w-2 rounded-full bg-amber-400 animate-pulse" />
)}
{hasChanges && <div className="h-2 w-2 rounded-full bg-amber-400 animate-pulse" />}
{loading && (
<div className="h-4 w-4 border-2 border-white/20 border-t-white rounded-full animate-spin" />
)}
@@ -77,13 +75,11 @@ const SectionCard: React.FC<SectionCardProps> = ({
{(!collapsible || isExpanded) && (
<div className="px-6 pb-6">
<div className="space-y-8">
{children}
</div>
<div className="space-y-8">{children}</div>
</div>
)}
</div>
);
};
export default SectionCard;
export default SectionCard;
+1 -5
View File
@@ -52,11 +52,7 @@ export function syncGmailMetadataToBackend(gmailState: GmailStateForSync | undef
// metadata.emails = gmailState.emails as GmailEmailSummaryLike[];
// }
const payload = {
requestId: crypto.randomUUID(),
provider: PROVIDER_GOOGLE,
metadata,
};
const payload = { requestId: crypto.randomUUID(), provider: PROVIDER_GOOGLE, metadata };
void emitViaRustSocket(INTEGRATION_METADATA_SYNC_EVENT, payload);
}
+3 -3
View File
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent } from 'react';
import { type KeyboardEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import LottieAnimation from '../components/LottieAnimation';
@@ -92,7 +92,7 @@ const Mnemonic = () => {
inputRefs.current[index + 1]?.focus();
}
},
[importWords],
[importWords]
);
const handleImportKeyDown = useCallback(
@@ -101,7 +101,7 @@ const Mnemonic = () => {
inputRefs.current[index - 1]?.focus();
}
},
[importWords],
[importWords]
);
const handleValidateImport = useCallback(() => {
+7 -7
View File
@@ -8,21 +8,21 @@ import { invoke } from '@tauri-apps/api/core';
import { listen } from '@tauri-apps/api/event';
import { type ReactNode, useEffect, useRef } from 'react';
import {
type GmailStateForSync,
syncGmailMetadataToBackend,
} from '../lib/gmail/services/metadataSync';
import { skillManager } from '../lib/skills/manager';
import type { SkillManifest } from '../lib/skills/types';
import { buildManualSentryEvent, enqueueError } from '../services/errorReportQueue';
import { useAppDispatch, useAppSelector } from '../store/hooks';
import {
setGmailEmails,
setGmailProfile,
type GmailEmailSummary,
type GmailProfile,
setGmailEmails,
setGmailProfile,
} from '../store/gmailSlice';
import { useAppDispatch, useAppSelector } from '../store/hooks';
import { setSkillError, setSkillState, setSkillStatus } from '../store/skillsSlice';
import {
syncGmailMetadataToBackend,
type GmailStateForSync,
} from '../lib/gmail/services/metadataSync';
import { DEV_AUTO_LOAD_SKILL, IS_DEV } from '../utils/config';
// ---------------------------------------------------------------------------
+1 -3
View File
@@ -7,9 +7,7 @@ interface ConsumeLoginTokenResponse {
interface IntegrationTokensResponse {
success: boolean;
data?: {
encrypted: string;
};
data?: { encrypted: string };
}
/**
+1 -4
View File
@@ -23,10 +23,7 @@ interface GmailState {
profile: GmailProfile | null;
}
const initialState: GmailState = {
emails: [],
profile: null,
};
const initialState: GmailState = { emails: [], profile: null };
const gmailSlice = createSlice({
name: 'gmail',
+2 -2
View File
@@ -1,8 +1,8 @@
import { getPublicKey } from '@noble/secp256k1';
import { keccak_256 } from '@noble/hashes/sha3.js';
import { pbkdf2 } from '@noble/hashes/pbkdf2.js';
import { sha256 } from '@noble/hashes/sha2.js';
import { keccak_256 } from '@noble/hashes/sha3.js';
import { bytesToHex } from '@noble/hashes/utils.js';
import { getPublicKey } from '@noble/secp256k1';
import { HDKey } from '@scure/bip32';
import { generateMnemonic, mnemonicToSeedSync, validateMnemonic } from '@scure/bip39';
import { wordlist } from '@scure/bip39/wordlists/english.js';
+4 -9
View File
@@ -4,13 +4,13 @@ import { getCurrent, onOpenUrl } from '@tauri-apps/plugin-deep-link';
import { skillManager } from '../lib/skills/manager';
import { consumeLoginToken, fetchIntegrationTokens } from '../services/api/authApi';
import { store } from '../store';
import { setToken } from '../store/authSlice';
import { setSkillState } from '../store/skillsSlice';
import {
decryptIntegrationTokens,
hexToBase64,
type IntegrationTokensPayload,
} from './integrationTokensCrypto';
import { setToken } from '../store/authSlice';
import { setSkillState } from '../store/skillsSlice';
function getCurrentUserId(): string | null {
const state = store.getState();
@@ -80,9 +80,7 @@ const handlePaymentDeepLink = async (parsed: URL) => {
console.log('[DeepLink] Payment success, session_id:', sessionId);
// Broadcast to the app so billing components can react
window.dispatchEvent(
new CustomEvent('payment:success', { detail: { sessionId } }),
);
window.dispatchEvent(new CustomEvent('payment:success', { detail: { sessionId } }));
// Navigate to billing settings to show confirmation
window.location.hash = '/settings/billing';
@@ -121,7 +119,6 @@ const handleOAuthDeepLink = async (parsed: URL) => {
console.log(`[DeepLink] OAuth success for skill=${skillId} integration=${integrationId}`);
try {
const state = store.getState();
const userId = getCurrentUserId();
if (!userId) {
@@ -283,9 +280,7 @@ export const setupDesktopDeepLinkListener = async () => {
if (typeof window !== 'undefined') {
// window.__simulateDeepLink('alphahuman://auth?token=1234567890')
// window.__simulateDeepLink('alphahuman://oauth/success?integrationId=6989ef9c8e8bf1b6d991a08c&skillId=notion')
const win = window as Window & {
__simulateDeepLink?: (url: string) => Promise<void>;
};
const win = window as Window & { __simulateDeepLink?: (url: string) => Promise<void> };
win.__simulateDeepLink = (url: string) => handleDeepLinkUrls([url]);
}
} catch (err) {
+2 -6
View File
@@ -20,14 +20,10 @@ export function hexToBytes(hex: string): Uint8Array {
const cleanHex = hex.trim().replace(/^0x/i, '');
if (!cleanHex) return new Uint8Array();
if (cleanHex.length % 2 !== 0) {
throw new TypeError(
`hexToBytes: hex string must have even length (got ${cleanHex.length})`
);
throw new TypeError(`hexToBytes: hex string must have even length (got ${cleanHex.length})`);
}
if (!HEX_REGEX.test(cleanHex)) {
throw new TypeError(
'hexToBytes: hex string must contain only [0-9a-fA-F] characters'
);
throw new TypeError('hexToBytes: hex string must contain only [0-9a-fA-F] characters');
}
const bytes = new Uint8Array(cleanHex.length / 2);
for (let i = 0; i < cleanHex.length; i += 2) {
+9 -17
View File
@@ -186,11 +186,7 @@ export interface SkillSnapshot {
skill_id: string;
name: string;
status: unknown;
tools: Array<{
name: string;
description: string;
input_schema?: unknown;
}>;
tools: Array<{ name: string; description: string; input_schema?: unknown }>;
error?: string | null;
state?: Record<string, unknown>;
}
@@ -308,7 +304,11 @@ export interface TunnelConfig {
cloudflare?: { token: string } | null;
tailscale?: { funnel?: boolean; hostname?: string | null } | null;
ngrok?: { auth_token: string; domain?: string | null } | null;
custom?: { start_command: string; health_url?: string | null; url_pattern?: string | null } | null;
custom?: {
start_command: string;
health_url?: string | null;
url_pattern?: string | null;
} | null;
}
export async function alphahumanGetConfig(): Promise<CommandResponse<ConfigSnapshot>> {
@@ -405,9 +405,7 @@ export async function alphahumanAgentChat(
});
}
export async function alphahumanEncryptSecret(
plaintext: string
): Promise<CommandResponse<string>> {
export async function alphahumanEncryptSecret(plaintext: string): Promise<CommandResponse<string>> {
if (!isTauri()) {
throw new Error('Not running in Tauri');
}
@@ -437,10 +435,7 @@ export async function alphahumanDoctorModels(
if (!isTauri()) {
throw new Error('Not running in Tauri');
}
return await invoke('alphahuman_doctor_models', {
providerOverride,
useCache,
});
return await invoke('alphahuman_doctor_models', { providerOverride, useCache });
}
export async function alphahumanListIntegrations(): Promise<CommandResponse<IntegrationInfo[]>> {
@@ -476,10 +471,7 @@ export async function alphahumanMigrateOpenclaw(
if (!isTauri()) {
throw new Error('Not running in Tauri');
}
return await invoke('alphahuman_migrate_openclaw', {
sourceWorkspace,
dryRun,
});
return await invoke('alphahuman_migrate_openclaw', { sourceWorkspace, dryRun });
}
export async function alphahumanHardwareDiscover(): Promise<CommandResponse<DiscoveredDevice[]>> {