Documentazione
Associa il compagno iOS
Connetti una build iOS nativa a un desktop in esecuzione, verifica il certificato e controlla l'accesso al dispositivo.
Tradotto automaticamente dall'inglese. Vedi l'originale in inglese
Controllare le due estremità della connessione
Il compagno è un client di un sidecar desktop in esecuzione. Non ospita il database del progetto, il kernel della geometria, il provider del modello o il corridore del flusso di lavoro. Prima dell'accoppiamento, verificare che il desktop apra i suoi progetti e che il telefono possa instradarsi al desktop tramite Wi-Fi, Hotspot personale o una rete overlay/VPN già configurata.
Utilizza una build iOS nativa contenente modules/companion-net. Expo Go non ha questo modulo e non può effettuare la connessione fissata. Il pacchetto dispone anche di un fallback per lo sviluppo del browser, ma il recupero del browser non implementa la politica di blocco nativa. La configurazione Android nel manifest non fornisce un equivalente Android del modulo Swift.
bun install
bun run --cwd apps/mobile typecheck
bun run --cwd apps/mobile test
bun run --cwd apps/mobile ios Il comando Esegui iOS richiede macOS, Xcode e CocoaPods. La creazione di un dispositivo fisico richiede un dispositivo attendibile e un team di firma. bun run --cwd apps/mobile build esporta JavaScript; non crea un IPA installabile. Vedi il riferimento mobile per l'implementazione del layout e dei trasporti.
Abilita il gateway desktop
Apri Impostazioni desktop → Dispositivi e il relativo pannello complementare Mobile, oppure utilizza /settings/companion. Accendi il gateway, quindi crea un abbinamento denominato e mostra il suo codice QR. Questo è un ascoltatore separato dalla normale API di loopback: HTTPS su IPv4 0.0.0.0, porta 8443 per impostazione predefinita.
Il servizio accetta porte intere 1024–65535. Se un'altra applicazione occupa la porta selezionata, l'abilitazione fallisce; scegli una porta libera e crea un collegamento con l'indirizzo risultante. Consenti la connessione tramite il firewall del desktop per la rete che intendi utilizzare. L'applicazione non crea un inoltro pubblico, un port forwarding o una VPN.
Lo stato e la porta abilitati vengono mantenuti. Dopo un riavvio sidecar, il gateway tenta di riprendere una volta che l'API locale è pronta. I file del certificato e della chiave privata si trovano nella directory dei dati sidecar companion/ sottodirectory; la chiave privata viene scritta con autorizzazioni di solo proprietario. L'app nativa si fida del certificato dell'accoppiamento, non di una promessa generica che ogni certificato locale sia sicuro.
Ispeziona e attiva tramite l'API desktop
Per una configurazione di sviluppo riproducibile, utilizza il token di lancio di un sidecar isolato che controlli. Sostituisci la porta 43111 con la sua porta evento pronto. Si tratta di chiamate di gestione del desktop; al token del telefono non è consentito amministrare il proprio gateway.
CADCAM_URL=http://127.0.0.1:43111
CADCAM_TOKEN=local-development-token
CADCAM_PAIR_DIR=$(mktemp -d /tmp/cadcamfun-pair-guide.XXXXXX)
curl --fail-with-body "$CADCAM_URL/api/companion" -H "Authorization: Bearer $CADCAM_TOKEN"
curl --fail-with-body -X POST "$CADCAM_URL/api/companion/enable" -H "Authorization: Bearer $CADCAM_TOKEN" -H 'Content-Type: application/json' -d '{"port":18443}' Lo stato contiene lo stato abilitato, la porta/impronta digitale nullable, l'host suggerito e le voci del dispositivo. L'impronta digitale può essere nulla prima che esista un certificato. Un pubblico sonda sanitaria stabilisce l'integrità del processo di loopback; non dimostra che il gateway HTTPS sia abilitato, raggiungibile o che accetti un token del dispositivo. Usa il API complementare per schemi di gestione esatti.
Crea un abbinamento denominato
curl --fail-with-body -X POST "$CADCAM_URL/api/companion/pair" -H "Authorization: Bearer $CADCAM_TOKEN" -H 'Content-Type: application/json' -d '{"name":"Workshop iPhone","host":"192.168.1.20"}' -o "$CADCAM_PAIR_DIR/pairing.json"
CADCAM_DEVICE_ID=$(bun --no-env-file -e 'console.write((await Bun.file(process.argv[1]).json()).id)' "$CADCAM_PAIR_DIR/pairing.json") Sostituisci l'host di esempio con un indirizzo che il telefono può raggiungere oppure ometti l'host facoltativo per utilizzare il rilevamento. Il nome viene troncato e deve contenere 1–60 caratteri. Il successo è HTTP 201 con id e link. La creazione di un token non abilita il listener; abilitarlo separatamente.
Il collegamento contiene il token del dispositivo, l'impronta digitale del certificato, l'origine HTTPS primaria, il nome e gli host alternativi facoltativi. Visualizzalo o trasferiscilo privatamente sul telefono; è una credenziale. Il desktop memorizza l'hash del token anziché il testo in chiaro. Il record non ha un campo di scadenza in questa implementazione, quindi revoca esplicitamente un dispositivo obsoleto anziché dare per scontato che scadrà.
Carica l'accoppiamento su iOS
- Aprire la schermata Connetti dell'app CADCAMFUN installata.
- Scegli Scansiona il codice QR di accoppiamento e concedi l'accesso alla fotocamera oppure utilizza Incolla un collegamento di accoppiamento.
- Per l'immissione manuale, fornire l'indirizzo del desktop, il token e l'impronta digitale completa del certificato tramite il modulo di connessione.
- Consenti l'accesso alla rete locale quando iOS lo richiede. L'accesso alla telecamera e l'accesso alla rete sono autorizzazioni separate.
- Attendi che il test di integrità/bootstrap abbia esito positivo e che l'app apra Projects.
Il parser richiede un'origine HTTPS senza informazioni sull'utente, contenuto del percorso, query o frammento. I token devono contenere 16–4096 caratteri senza spazi bianchi/caratteri di controllo; le impronte digitali sono esattamente 64 caratteri esadecimali. I collegamenti non validi vengono rifiutati prima dell'inizio delle richieste.
Le origini alternative scoperte vengono deduplicate. Il client gareggia con i candidati, utilizza la prima connessione riuscita, interrompe le altre e salva l'origine riuscita. Discovery pubblicizza fino a sei indirizzi IPv4 privati idonei, inclusi intervalli Wi-Fi, hotspot e IPv4 in stile Tailscale; l'attuale ascoltatore IPv4 non pubblicizza gli host IPv6 rilevati.
Quali controlli del blocco del certificato
Il trasporto Swift utilizza effimero URLSession istanze e un delegato di trust personalizzato. Ottiene i byte DER del certificato foglia, calcola SHA-256 e accetta la connessione solo quando l'hash equivale all'impronta digitale accoppiata. È richiesto HTTPS e i reindirizzamenti vengono rifiutati. I chiamanti nativi non tornano silenziosamente al recupero non bloccato se manca il modulo.
Supporta il certificato autofirmato del desktop senza accettare server autofirmati arbitrari. La decisione di fiducia deriva dall'abbinamento QR/link. La sostituzione del certificato desktop modifica tale decisione; creare un nuovo accoppiamento affidabile invece di eliminare la mancata corrispondenza.
Gli errori ordinari di attendibilità del browser/curl non equivalgono al test del delegato nativo dell'app. Un browser potrebbe rifiutare un server autofirmato correttamente aggiunto perché utilizza un truststore diverso. Verifica tramite l'app installata e controlla l'errore effettivo anziché disabilitare la convalida del certificato a livello globale.
Dopo aver eseguito con successo l'autenticazione del dispositivo, il gateway registra un timestamp dell'ultimo accesso per il suo stato di servizio corrente. Aggiorna lo stato del dispositivo desktop per confermare il traffico autenticato. Ciò indica l'utilizzo del token; non è una prova che ogni azione del progetto abbia avuto successo o una traccia di controllo della sicurezza duratura.
Comprendere l'ambito del token del dispositivo
| Consentito attraverso il gateway | Mantenuto sull'API desktop |
|---|---|
| Elenco/dettagli del progetto; eventi del progetto | File system diretto, caricamento di file e gestione delle credenziali |
| Cronologia/stato VCS e attualmente commit/ramo/estrazione/ripristino | Configurazione remota GitHub, endpoint push e pull |
| Operazioni di revisione/unione/chiusura delle richieste pull e flusso di lavoro | Plugin e amministrazione della fatturazione |
| Notifiche e status/modelli/agenti dell'assistente | Abilita/associa/revoca l'amministrazione del Companion |
| Chat in streaming, coda/interruzione, risposte di autorizzazione, stato/controllo della sessione | Altri metodi/percorsi assenti dall'elenco consentiti |
Il token del dispositivo è limitato dall'elenco consentiti del metodo/percorso. Non è intrinsecamente di sola lettura e non seleziona un progetto. Le richieste accettate vengono inoltrate con l'identità dell'applicazione desktop e rimangono soggette all'autorizzazione dell'endpoint. Non descrivere mai l'accoppiamento come una semplice garanzia di monitoraggio passivo.
Le autorizzazioni dell'assistente e le domande in sospeso sono interazioni di sessione separate. Rispondi nell'interfaccia utente mobile quando richiesto. Un token che può raggiungere l'endpoint di risposta non significa che ogni azione dello strumento sia già stata approvata.
Utilizza le sessioni e ripristina la connettività
Scegli un progetto per esaminarne la panoramica, la cronologia, i pull e le esecuzioni del flusso di lavoro. Le sessioni dell'assistente vengono eseguite sul desktop con le impostazioni del provider. Configura prima il provider lì. Il telefono ricorda un progetto selezionato e l'ultima sessione per progetto per il desktop accoppiato; la modifica dell'identità del desktop cancella tale mappatura.
I controlli in primo piano vengono analizzati con un budget di 15 secondi. I controlli non riusciti vengono ripristinati fino a 30 secondi e portare avanti l'app attiva un'altra analisi. Lo stato in background viene monitorato separatamente dallo stato offline. Tocca la riga del desktop nelle Impostazioni del telefono per ricontrollare manualmente.
I messaggi dell'assistente in coda vengono mantenuti con un massimo di 50 voci, lasciando cadere i più vecchi oltre tale limite. Riprovano più tardi e potrebbero conservare l'identificatore di sessione. Si tratta di un supporto per la consegna limitata dei messaggi, non di calcoli CAD offline o di esecuzione esattamente una volta. Dopo una scrittura/giro interrotta, ispezionare la sessione desktop e il progetto prima di ripetere la stessa modifica.
Revocare o annullare l'abbinamento deliberatamente
curl --fail-with-body -X DELETE "$CADCAM_URL/api/companion/devices/$CADCAM_DEVICE_ID" -H "Authorization: Bearer $CADCAM_TOKEN"
curl --fail-with-body "$CADCAM_URL/api/companion" -H "Authorization: Bearer $CADCAM_TOKEN" I token vengono controllati a ogni nuova richiesta, pertanto le richieste successive che utilizzano il token revocato falliscono. La revoca non termina esplicitamente un flusso già inoltrato. La disabilitazione del gateway arresta l'ascoltatore; POST /api/companion/disable è l'endpoint amministrativo.
Impostazioni telefono → Disaccoppia questo telefono elimina l'abbinamento salvato in locale e torna a Connetti. Non chiama l'endpoint di revoca del desktop. Utilizza entrambe le azioni quando ritiri un dispositivo. Per ruotare solo la credenziale del dispositivo, revocarla ed effettuare un nuovo abbinamento; la sostituzione dell'intero certificato modifica anche il pin di ogni telefono.
Diagnosticare i guasti per livello
| Risultato | Prossimo controllo |
|---|---|
| Nessun modulo di blocco nativo | Apri una build iOS nativa personalizzata invece di Expo Go o una piattaforma nativa non supportata. |
| Il desktop non ha risposto | Gateway abilitato, host/porta corretti, desktop attivo, firewall, autorizzazione di rete locale e percorso Wi-Fi/VPN. |
| Mancata corrispondenza del certificato | Verifica l'identità del desktop corrente e crea una nuova associazione attendibile dopo la sostituzione del certificato. |
| 401 | Token del dispositivo mancante, errato o revocato. |
| 403 | Metodo/percorso esterno all'elenco consentito della route; anche l'autorizzazione di un endpoint può rifiutare il lavoro. |
| 429 | Autenticazione fallita ripetuta dallo stesso indirizzo; il gateway tiene traccia di dieci errori in una finestra di 60 secondi. |
| 502 | Il listener HTTPS non è riuscito a raggiungere la sua API upstream locale. |
La CI nativa crea un'app di simulazione non firmata e controlla l'accoppiamento/elenco dei progetti reali del gateway. Controlli CI separati, typecheck, test logici ed esportazione JavaScript. Questi non dimostrano la firma del dispositivo fisico, la distribuzione TestFlight, il routing di rete remota o un fornitore di modelli reali.
I token danneggiati ripetuti vengono limitati: dieci tentativi falliti da un indirizzo IP entro 60 secondi effettuano ulteriori richieste da esso restituiscono HTTP 429 fino alla scadenza della finestra. Un 429 dopo il riabbinamento di solito significa che è ancora in corso un nuovo tentativo con un vecchio token del dispositivo.
Mappa di implementazione
Il contratto di gestione è packages/api/src/groups/companion.ts. Il ciclo di vita del sidecar e la politica del percorso sono presenti services/companion.ts e companion-gateway.ts. Sono presenti l'analisi del telefono, il ripristino della connessione, l'archiviazione e l'interfaccia utente lib/pairing.ts, server.tsx, storage.ts, e app/connect.tsx. Il delegato della fiducia nativa è modules/companion-net/ios/CompanionNetModule.swift.
Per un rapporto di supporto, conserva la versione dell'app, il metodo di connessione, l'host/porta del gateway non segreto, l'errore/lo stato esatto e se è presente il modulo nativo. Redigere token, collegamenti di accoppiamento, credenziali del modello e chiavi private. Aggiungi il API di sistema risultato della versione quando si confrontano due processi di sviluppo.
Ciò che può chiamare un telefono abbinato
Ogni richiesta tramite il gateway deve contenere un token del dispositivo e corrispondere a questo elenco consentito. Tutto il resto, incluse credenziali, plug-in, file, fatturazione e /api/companion stesso, viene rifiutato. Le richieste ammesse vengono inoltrate all'API di loopback con il token dell'applicazione, che il telefono non vede mai.
| Metodi | Modello del percorso | Scopo |
|---|---|---|
| GET | /api/health | Verifica di raggiungibilità. |
| GET | /api/projects, /api/projects/:id | Elenco progetti e intestazione. |
| OTTIENI, PUBBLICA | /api/projects/:id/vcs/* (tranne remote, push, pull), /pulls/*, /actions/* | Cronologia, richieste pull, revisioni ed esecuzioni del flusso di lavoro. La sincronizzazione GitHub rimane sul desktop perché necessita del token GitHub del proprietario. |
| GET | /api/projects/:id/events | Flusso SSE in tempo reale di cronologia, flusso di lavoro e attività dell'assistente; l'unico canale push del telefono. |
| OTTIENI, PUBBLICA, METTI, ELIMINA | /api/notifications, /mark-all-read, /:id | Leggi, contrassegna come letti ed elimina le notifiche. |
| GET | /api/ai/status, /models, /agents | Scoperta dell'assistente. |
| POST | /api/ai/chat/stream, chat/abort, chat/queue, permission/reply, sessions/state, sessions/control | Sessioni di assistente. |
L'ambito attuale della storia scrive
Il modello di cronologia attualmente corrisponde anche a commit, checkout e ripristino. Considera un telefono associato come in grado di modificare la cronologia del progetto e revocare i dispositivi che non controlli più.
Anatomia del collegamento di accoppiamento
POST /api/companion/pair con un dispositivo name (e facoltativamente a host) crea un token del dispositivo e restituisce il suo ID insieme a un collegamento, che il desktop mostra come codice QR:
cadcamfun://pair?host=https%3A%2F%2F192.168.1.20%3A8443&token=<43-char base64url>&fp=<sha256 hex>&name=Ada%27s+iPhone&hosts=https%3A%2F%2F100.64.0.7%3A8443 | Parametro | Contenuto |
|---|---|
host | Origine preferita: il miglior indirizzo privato del desktop e la porta del gateway. |
token | 32 byte casuali, codifica64URL base. Viene mostrato una volta; il desktop memorizza solo l'hash SHA-256 e gli ID dispositivo sono 12 caratteri esadecimali. |
fp | SHA-256 impronta digitale del certificato del gateway, esadecimale minuscolo senza due punti. Il telefono lo blocca. |
name | Nome del dispositivo mostrato nell'elenco dei dispositivi. |
hosts | Fino a cinque ulteriori origini candidate (sei indirizzi in totale), a cui il telefono fa a gara per trovarne una che risponda. |
Il certificato è un certificato P-256 autofirmato i cui nomi alternativi del soggetto includono localhost, 127.0.0.1e gli indirizzi privati raggiungibili della macchina. È tenuto dentro <dataDir>/companion, quindi gli accoppiamenti sopravvivono ai riavvii. La sua sostituzione modifica l'impronta digitale e richiede nuovamente l'associazione.
API di amministrazione del gateway
| Itinerario | Corpo | Risultato |
|---|---|---|
GET /api/companion | — | enabled, port, fingerprint, host, e devices (id, name, createdAt, lastSeen). |
POST /api/companion/enable | opzionale port (predefinito 8443 o 1024–65535) | Avvia il listener HTTPS 0.0.0.0 e mantiene l'impostazione in modo che riprenda al prossimo avvio. |
POST /api/companion/disable | — | Arresta l'ascoltatore. |
POST /api/companion/pair | name, facoltativo host | { id, link }. |
DELETE /api/companion/devices/:id | — | Revoca immediatamente un token del dispositivo. |
I tentativi di portante falliti vengono limitati per indirizzo IP: dopo 10 fallimenti entro 60 secondi, il gateway risponde HTTP 429 ("Troppi tentativi falliti") fino al superamento della finestra. In caso contrario, un token errato o revocato ottiene HTTP 401.
Stato del gateway, catturato
{ "enabled": false, "port": null, "fingerprint": null, "host": "172.30.0.2", "devices": [] } | Campo | Senso |
|---|---|
enabled | Se il gateway HTTPS è in esecuzione; disattivato per impostazione predefinita |
port | Porta gateway se abilitata, altrimenti null |
fingerprint | SHA-256 impronta digitale del certificato gateway bloccato dal telefono; null finché non esiste un certificato |
host | L'indirizzo LAN pubblicizzato dal collegamento di accoppiamento |
devices | Dispositivi accoppiati; ciascuno può essere revocato singolarmente |
Se host non è l'indirizzo che il tuo telefono può raggiungere (ad esempio un contenitore o un'interfaccia VPN), l'accoppiamento fallirà a livello di rete anche se tutto il resto è corretto.