Pular para o conteúdo
CADCAMFUN
Docs

Documentação

IU da área de trabalho

Espaços de trabalho SolidJS, um cliente API local e um shell Tauri que possui integração nativa.

Traduzido automaticamente do inglês. Ver o original em inglês

Arquitetura de aplicativo

O aplicativo de desktop combina um webview SolidJS, Vite, Three.js e um shell Tauri v2 Rust. O webview possui telas e estados de interação. O sidecar Bun possui manipuladores de API, acesso a banco de dados, sessões de IA e serviços de projeto. O processo Rust possui a janela, os menus, a bandeja, as caixas de diálogo do sistema operacional, o acesso às chaves, as atualizações e o ciclo de vida do sidecar.

apps/desktop/src/main.tsx monta o aplicativo. app/App.tsx estabelece a conexão API e fornece estado compartilhado; app/routes.tsx mapeia URLs para módulos de páginas lentas. Telas de recursos ao vivo features/. A presença de uma rota não estabelece a disponibilidade de seus serviços externos: o faturamento precisa da configuração do Stripe e a IA precisa de um provedor configurado.

Inicialização e recuperação de conexão

  1. O shell inicia o sidecar empacotado com um token de inicialização gerado e dados de aplicativo e diretórios de migração.
  2. O sidecar vincula uma porta efêmera em 127.0.0.1, aguarda a resposta de sua rota de integridade e grava um JSON ready evento contendo a porta.
  3. A visualização da web invoca get_sidecar_endpoint e cria um cliente API e um tempo de execução de efeito gerenciado.
  4. Uma solicitação de integridade bem-sucedida cria o estado do aplicativo e monta o roteador e o shell.

O webview permite 150 segundos para recuperação de conexão, com um tempo limite de 30 segundos por tentativa e uma pausa de repetição de 750 milissegundos. Tentativas fracassadas descartam o endpoint armazenado em cache para que um sidecar reiniciado possa fornecer uma nova porta. O supervisor Rust espera 60 segundos para cada handshake pronto e permite uma reinicialização automática. A nova tentativa fica disponível quando o orçamento de conexão do webview expira.

A visualização do navegador usa uma API na memória

Fora do Tauri, um navegador sem VITE_SIDECAR_URL usa src/testing/fake-api.ts. Os dados de visualização são locais na página em execução; coleções não suportadas retornam HTTP 501. Para conectar um navegador a um sidecar real, forneça ambos VITE_SIDECAR_URL e VITE_SIDECAR_TOKEN ao iniciar o Vite.

Rotas de tela

ÁreaRotas e módulos
Projetos/projects, /projects/create, /projects/:id, e /projects/:id/history; telas em features/projects/screens.
Projeto e fabricação/cad montagens CadPage; /cam montagens CamPage. Desenhos e percursos da ferramenta salvos possuem rotas de detalhe separadas.
Recursos/library, /materials, /tools, /machinee suas páginas de detalhes usam módulos de recursos de biblioteca. Os componentes possuem rotas de lista e detalhe.
Assistente/ai e o painel do assistente acoplado compartilha o estado do recurso AI. A atividade de IA alterna o painel.
Configurações/settings, /settings/companion, configurações de MCP e configurações de assinatura.
Conta e colaboraçãoAutenticação, perfil, organização, convite, bate-papo, mercado, plug-in, custos, análises e rotas de administração carregam módulos de recursos.

Usar app/routes.tsx para nomes exatos de parâmetros e pages/ para localizar a tela montada em um URL. Os adaptadores de rota são intencionalmente pequenos; leia a tela e suas chamadas de API ao diagnosticar uma visualização vazia ou uma ação com falha.

Organização de origem

  • app/: inicialização, roteador, cliente API global, integração nativa, shell e atalhos de teclado.
  • pages/: adaptadores de rota importando ou reexportando telas.
  • features/: áreas de produtos com telas, componentes, ganchos, estado e auxiliares específicos de domínio.
  • shared/: controles reutilizáveis, componentes do shell, estado do aplicativo, cache de consultas e histórico de comandos.
  • viewport/: desenho de tela, encaixe, gestos de ferramentas, renderização Three.js, malha e reprodução.
  • i18n/, styles/, e testing/: traduções, estilos globais e acessórios de teste.

A área de trabalho depende de @cadcamfun/api para o contrato HTTP e em @cadcamfun/core para geometria e operações CAM. A persistência do banco de dados permanece por trás da API secundária. O histórico do editor local é diferente das versões persistentes de desenho ou percurso e do controle de versão do projeto.

Concha nativa

A janela de produção é 1440 × 900 por padrão, com um mínimo de 960 × 600. Tauri prepara o frontend de apps/desktop/dist, um sidecar específico do alvo de src-tauri/binariese gerou migrações como recursos. Ele registra .cadcam, .nc, e .gcode associações de arquivos. Abrir um arquivo compatível ou iniciar uma segunda instância encaminha os caminhos dos arquivos para a janela existente.

src-tauri/src/sidecar.rs supervisiona o processo filho. Fechar o aplicativo escreve um {"event":"shutdown"} linha para o stdin da criança e espera um pouco antes de colhê-lo; a criança também observa o fechamento do stdin. O token de inicialização é composto por 32 bytes aleatórios, codificados em hexadecimal como 64 caracteres, e as linhas de log secundárias que podem conter credenciais são editadas. Os logs são separados do stdout, que carrega o handshake de prontidão/erro. Os segredos nativos são acessados por meio de src-tauri/src/secrets.rs usando o chaveiro do sistema operacional.

No macOS, o shell registra o plugin Liquid Glass. A visualização na web segue a configuração do vidro e retrocede quando o efeito não está disponível. A configuração da App Store desativa a opção de API privada; a configuração regular permite isso. Estas são configurações de compilação separadas.

Limites de segurança e persistência

A política de conteúdo de produção permite ativos locais, conexões de API de loopback, imagens de dados/blob e avaliação de WebAssembly. Não permite execução remota arbitrária de scripts. As permissões nativas têm escopo em src-tauri/capabilities; a política de desenvolvimento também permite o Vite e seu websocket.

open_path canoniza caminhos, limita-os a diretórios de usuários/aplicativos permitidos e rejeita extensões executáveis, como .exe, .app, .sh, .bat, .msi, e .jar. .. segmentos e links simbólicos não podem escapar das pastas permitidas porque ambos os lados são canônicos. A seleção e o salvamento de arquivos usam diálogos e validação nativos. Um token de inicialização concede acesso à API do aplicativo local; trate-o separadamente de um token complementar ou de um token de ponte de IA no escopo do projeto.

As configurações da UI, o estado da consulta da API, os comandos do editor, as versões do projeto armazenadas e os segredos nativos têm proprietários diferentes. Diagnostique cada um por meio de seu serviço real, em vez de assumir que todo o estado do aplicativo está armazenado no SQLite.

Integração de recursos

Os módulos de recursos CAD e CAM compõem componentes de viewport reutilizáveis com seus próprios painéis, armazenamentos e fluxos de salvamento. O painel do assistente recebe o contexto do projeto e do editor e transmite eventos da ferramenta por meio do estado do recurso de IA. As telas de recursos usam o cliente API em vez de acessar diretamente o banco de dados.

Para uma alteração na interface do usuário, siga o adaptador de rota até sua tela de recursos e, em seguida, inspecione o feature store ou gancho que envia a solicitação. Reutilize componentes compartilhados somente quando o contrato existente corresponder à interação. Mantenha a geometria pura no pacote principal e o comportamento nativo do sistema operacional no shell Rust.

Carregamento de rota e erros

Cada rota usa o limite de importação lenta do Solid. A tabela inclui uma página abrangente, /500, /offlinee rotas legais. Uma navegação direta do navegador deve ser servida por meio do servidor de desenvolvimento Vite ou do webview empacotado para que o roteador do cliente possa resolver a URL.

A API de visualização implementa um conjunto limitado de coleções e pode injetar deliberadamente falhas de solicitação em testes. Uma renderização de visualização bem-sucedida demonstra o comportamento da UI em relação a esses equipamentos; verifique persistência, permissões, streaming e integrações externas com o sidecar ao vivo.

Interface de comando nativa

ComandoPropósito
get_sidecar_endpointAguarde o sidecar supervisionado e retorne seu URL base e token de lançamento. A espera abrange uma reinicialização: dois tempos limite de prontidão de 60 segundos mais 5 segundos (125 segundos).
get_logs_dir, open_pathResolva o diretório de log do aplicativo como uma string e abra um caminho absoluto existente com o abridor do sistema operacional. Os caminhos devem ser resolvidos nos dados do aplicativo, log, Documentos, Downloads ou pasta Desktop.
secret_get, secret_set, secret_deleteAcesse entradas de chaves nativas no com.cadcamfun.app serviço. As chaves são 1–128 bytes de letras ASCII, dígitos e . _ - : (por exemplo ai.anthropic.apiKey); secret_get retorna null para uma entrada perdida.
pick_file, save_filepick_file({ filters: [{ name, extensions }] }) retorna o caminho escolhido ou null em cancelar. save_file({ defaultName, contents }) escreve texto UTF-8 no caminho escolhido e o retorna, ou null em cancelar; diretórios e extensões executáveis são rejeitados.
set_recent_projectsAtualize o menu de projetos recentes da bandeja.
check_for_updates, install_updateSolicite uma verificação do atualizador ou instale uma atualização pendente. install_update aceita um opcional unsavedWork sinalizador (padrão false) para que uma instalação não interrompa um editor aberto.

The invoke handler is registered in src-tauri/src/lib.rs. Capabilities and generated command permissions also control availability; command registration alone does not establish webview access. Command errors are serialized as { kind, message } with kinds such as sidecar, invalid_path, io, dialog, and path; no command panics.

Eventos nativos

A casca emite sidecar-status para mudanças no ciclo de vida, open-file com caminhos suportados, menu para seleção de menu e update://status para o progresso do atualizador. As seleções de projetos recentes da bandeja são representadas por tray.recent.<projectId> identificadores de menu. Os módulos de menu e bandeja do shell definem seus conjuntos completos de identificadores.

Os ouvintes devem ter como escopo o ciclo de vida de seu componente ou aplicativo e ser removidos na limpeza. O webview deve resolver novamente o endpoint após a reinicialização do sidecar, em vez de continuar a usar a porta anterior.

Desenvolvimento e verificação

Execute a partir da raiz do repositório
bun run --filter @cadcamfun/desktop dev
bun run desktop:dev
bun run --filter @cadcamfun/desktop typecheck
bun test apps/desktop/src
bun run build:desktop

O primeiro comando executa uma visualização do navegador. desktop:dev compila o sidecar real e prepara as migrações antes de iniciar o Tauri. O pacote desktop tauri:dev em vez disso, o script cria um binário stub somente quando não existe nenhum binário; use-o para trabalho de shell isolado e verifique qual binário está presente antes de interpretar suas respostas de API.

A área de trabalho build script é executado vite build apenas; ele não compila o sidecar nem empacota um pacote Tauri. Usar bun scripts/build.ts para o pipeline de lançamento completo (consulte Liberar).

Preferências e configurações

O armazenamento de configurações compartilhadas mantém um registro validado em cadcamfun.settings no armazenamento local do webview. Campos ausentes, inválidos ou ilegíveis retornam de forma independente. Uma área de armazenamento cheia ou bloqueada não interrompe a edição, mas as alterações de preferência podem não persistir. As preferências de visualização do navegador pertencem à origem do navegador e são separadas das preferências nativas de visualização da web.

ContextoValores aceitos/padrãoEfeito operacional
Temalight, dark, system; sistema padrãoO modo do sistema segue as alterações no esquema de cores do sistema operacional.
Unidades de exibiçãomm ou in; padrão mmApresentação de controles; as coordenadas do desenho central permanecem em milímetros.
DecimaisInteiro 0–6; padrão 3Precisão de apresentação de comprimento.
Postagem padrãogrbl, linuxcnc, smoothwb, gcode, fanuc; grbl padrãoUma gramática de saída selecionada é uma preferência, não uma prova de que a máquina está configurada ou verificada.
Tolerância de desenhoTolerância central validada; padrão 0.01 mmPreferência de precisão compartilhada usada pelos consumidores de desenho/percurso.
Estado instantâneoBooleano; padrão ativadoPreferência de status compartilhada. Editores individuais são donos de seu comportamento instantâneo; o independente Editor2D atualmente habilita seu snap à grade internamente.
VidroBooleano; padrão ativadoSolicita material de janela do macOS quando o host nativo oferece suporte.

A tela Configurações possui guias Perfil, Conta, Segurança, Assinatura, Notificações, IA, Dispositivos e Idioma. A guia Dispositivos incorpora o painel de gateway complementar. As configurações de idioma incluem a alternância do vidro. O armazenamento de localidade comum valida atualmente a localidade padrão; não inferir cobertura de tradução adicional a partir de uma lista de rótulos de exibição.

Salve e reabra um programa CAM

  1. Gere ou carregue o código NC no CAM e abra a caixa de diálogo salvar/exportar a partir do ponto de entrada existente.
  2. Para uma exportação de arquivo, escolha o código G ou o formato de percurso portátil. O código G baixa o texto NC atual; a escolha do percurso grava um texto estruturado .cam.json instantâneo.
  3. Para persistência do aplicativo, escolha um projeto existente, um novo projeto ou atualize o programa já salvo. Forneça o nome do programa e os campos de destino obrigatórios.
  4. Ao atualizar, o fluxo de salvamento registra o programa completo anterior como uma versão do percurso antes de substituir os dados atuais.
  5. Abra o item salvo em sua rota detalhada do percurso para inspecionar ou restaurar versões.

O resumo salvo inclui linhas NC, bytes, movimentos, identificadores de ferramentas, nomes de operações, estoque, unidades, deslocamento de trabalho e identidade de verificação quando essa evidência pertence ao NC atual. Um texto NC modificado pode tornar obsoletas as evidências previamente computadas. Revise a relação código/evidência atual antes de confiar no resumo.

Se a criação de um novo projeto for bem-sucedida, mas uma etapa de salvamento posterior falhar, o modal retém o destino criado para novas tentativas e inclui seu identificador no erro. Tentar novamente nesse modal evita criar o mesmo projeto novamente. Não presuma que o fluxo de salvamento é uma transação atômica entre recursos.

A exportação de arquivos e a persistência do projeto são operações diferentes

Um arquivo de código G baixado não cria uma linha de percurso de projeto. Um instantâneo portátil carrega um estado mais rico do que o NC simples. Verifique um programa salvo reabrindo-o no aplicativo e verifique uma exportação inspecionando o arquivo baixado.

Diagnóstico de teclado e falhas

Cmd/Ctrl+K abre a paleta de comandos e Cmd/Ctrl+J alterna o painel do assistente. Os atalhos do shell são ignorados quando o foco está em um elemento de entrada, área de texto, seleção ou conteúdo editável. As telas do editor têm seu próprio controle de teclado. Vários retornos de chamada de comando shell, incluindo Salvar/Exportar na tabela de atalhos genérica, são espaços reservados; use os controles reais de salvar/exportar do recurso em vez de assumir que cada acelerador listado executa uma operação de documento.

Comportamento observadoVerificar
A inicialização espera e, em seguida, Tentar novamente apareceErro secundário/saída pronta, binário de destino, recurso de migração e logs de aplicativos. Uma porta em cache pode pertencer a um processo anterior.
Uma tela é renderizada, mas as solicitações retornam 501Modo de fixação do navegador. Inicie o sidecar real e passe ambas as variáveis de endpoint do Vite.
Os dados da área de trabalho diferem de um script manualO diretório de dados e token de cada processo; um nome de arquivo por si só não identifica o banco de dados.
Um comando nativo não está disponívelInvoque registro, permissões de capacidade, suporte ao sistema operacional e se o código é executado dentro do Tauri.
As configurações são revertidas após a reinicializaçãoDisponibilidade e validação de armazenamento. Os campos armazenados inválidos retornam aos padrões.
A evidência do programa salvo difere do NCSe o NC foi editado após geração. Recalcule a verificação apropriada para o texto/programa real.

Âncoras de implementação: shared/state/settings.ts, app/shortcuts.ts, features/settings/screens/settings.tsx, e features/cam/components/SaveCamModal.tsx.

Cargas úteis de eventos nativos

EventoCarga útilNotas
sidecar-status{ state: "starting" }, { state: "ready", port }, { state: "restarting" }, { state: "failed", message }Depois restarting, chamar get_sidecar_endpoint de novo; a porta muda.
update://statusstatus: checking, upToDate (version), available (version, notes, date, critical), downloading (downloaded, total), ready (version), failed (message); mais dismissibleUma atualização crítica e uma reinicialização pendente não podem ser descartadas. Uma verificação falhada nunca é mostrada como um erro de bloqueio.
menuID do item de menu, como file.new, file.open, file.save, view.devtools, help.documentationUso de itens da bandeja tray.quit e tray.recent.<projectId>.
open-fileCaminhos de .cadcam, .nc, ou .gcode arquivosEnviado quando o sistema operacional abre um arquivo com o aplicativo ou uma segunda instância é iniciada.
install_update pode ser recusado com um motivo digitado: unsavedWork ("o editor tem trabalho não salvo; aplique a atualização assim que for salvo"), noneAvailable (nada pendente ou já instalado), ou failed (falha no download ou verificação de assinatura). Ele instala apenas a atualização anunciada pela última verificação.
Chamando comandos nativos do webview
import { invoke } from "@tauri-apps/api/core"
import { listen } from "@tauri-apps/api/event"

const { baseUrl, token } = await invoke<{ baseUrl: string; token: string }>("get_sidecar_endpoint")

const path = await invoke<string | null>("pick_file", {
  filters: [{ name: "G-code", extensions: ["nc", "gcode"] }],
})                                    // null when the user cancels

await invoke("save_file", { defaultName: "part.nc", contents: gcodeText })

const unlisten = await listen<{ state: string; port?: number }>("sidecar-status", (e) => {
  if (e.payload.state === "ready") reconnect()
})
// later: unlisten()

try {
  await invoke("install_update", { unsavedWork: editorIsDirty })
} catch (error) {
  // { kind, message }: the update variant carries the refusal (unsavedWork | noneAvailable | failed)
}

get_sidecar_endpoint retorna { baseUrl, token } (serializado em camelCase de SidecarEndpoint). Erros de cada comando chegam como o valor rejeitado de invoke, em forma { kind, message }.

Atalhos de teclado

AtalhoAçãoGrupo
Cmd/Ctrl+KAbra a paleta de comandosnavegação
Cmd/Ctrl+Shift+PNovo projetonavegação
Cmd/Ctrl+Z / Cmd/Ctrl+Shift+ZDesfazer/refazereditar
Cmd/Ctrl+S, Cmd/Ctrl+Shift+ESalvar, exportar (espaços reservados de shell; use os próprios controles do recurso)editar
Cmd/Ctrl+0Zoom para ajustarvisualizar
Cmd/Ctrl+= / Cmd/Ctrl+-Aumentar/diminuir zoomvisualizar
Cmd/Ctrl+JAlternar o painel do assistenteai
Cmd aplica-se ao macOS e Ctrl em outro lugar. O ID de cada atalho também é o sufixo da chave de tradução (por exemplo settings.shortcut.palette), e a tela Configurações renderiza essa mesma tabela, para que a documentação e o aplicativo não possam se separar.

Cada rota de tela

O roteador em apps/desktop/src/app/routes.tsx declara 68 rotas, cada uma carregada lentamente de apps/desktop/src/pages/ (segmentos dinâmicos são _id_.tsx arquivos). Agrupados por primeiro segmento:

ÁreaRotas
**
500/500
admin/admin/analytics /admin/feature-flags
ai/ai
analytics/analytics/history /analytics
auth/auth/forgot-password /auth/magic-link /auth/magic-link/verify /auth/reset-password /auth/signin /auth/signup /auth/two-factor /auth/verify-email /auth/verify
cad/cad
cam/cam
costs/costs
components/components/:id /components
drawings/drawings/:id
//
invitations/invitations/:token
legal/legal/privacy /legal/terms /legal/third-party-licenses
library/library
machine/machine/:id /machine
marketplace/marketplace /marketplace/items/:id /marketplace/purchase/success /marketplace/purchases /marketplace/seller/dashboard
materials/materials/:id /materials
mcp/mcp/directory /mcp/servers/:id
offline/offline
organizations/organizations/:id /organizations/:id/chat/:conversationId /organizations/:id/chat /organizations/:id/chat/new-group /organizations/:id/chat/new /organizations/create /organizations
plugins/plugins/:id /plugins
pricing/pricing
profile/profile /profile/settings
projects/projects/:id/history /projects/:id /projects/create /projects
settings/settings /settings/companion /settings/mcp/config-editor /settings/mcp/edit/:id /settings/mcp /settings/subscription
third-party-licenses/third-party-licenses
toolpaths/toolpaths/:id /toolpaths
tools/tools/:id /tools
waitlist/waitlist
* renderiza a página 404 e /500 a página de erro. /offline renderiza a tela offline; como as páginas de autenticação, convite, 404, 500 e de sucesso de compra, ele usa o layout independente sem o aplicativo Chrome. Como cada página é uma importação lenta, o código da tela só é carregado na primeira visita; um carregamento de bloco com falha aparece como um erro de rota, não como um aplicativo em branco.

Em 3D

Topologia de processo de desktop Arraste para orbitar · role para ampliar · arraste com o botão direito para deslocar
Processes at run time. The Tauri shell spawns the sidecar and waits for its {”event”:”ready”,”port”:N} line on stdout (sidecar.rs); the webview then talks HTTP to 127.0.0.1 on that port with the bearer token. The sidecar owns the SQLite database, the embedded nikcli AI host (CADCAMFUN_AI_HOST=nikcli, the default) and plugins; the mobile app reaches it through companion pairing.