mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-23 15:08:16 +02:00
v0.9.1 : le poste distant est integre a ajean (fini le binaire ajean-remote separe)
- nouvelle sous-commande `ajean remote install|connect|run|status|uninstall|logout` (reutilise internal/nodeclient), remplace le binaire cmd/ajean-remote supprime - le service (Windows/systemd/launchd) lance desormais `ajean remote run` - UI Postes distants : commande affichee `ajean remote install ...` - CI release : retrait du cross-build des 6 binaires ajean-remote
This commit is contained in:
1 parent
1454dff2a7
commit
88d1e79e80
12 files changed
+97
-98
No files matched your search
@@ -114,18 +114,6 @@ jobs:
|
|||||||
GOOS=$os GOARCH=$arch CGO_ENABLED=0 \
|
GOOS=$os GOARCH=$arch CGO_ENABLED=0 \
|
||||||
go build -trimpath -ldflags="$ldflags" -o "dist/$name" ./cmd/ajean
|
go build -trimpath -ldflags="$ldflags" -o "dist/$name" ./cmd/ajean
|
||||||
done
|
done
|
||||||
# Client léger « poste distant » ajean-remote : pas de CGO (ni UI ni
|
|
||||||
# systray), donc les 6 cibles se cross-compilent ici, macOS compris.
|
|
||||||
# Noms d'asset ajean-remote-<os>[-arm][.exe] — la page /download les
|
|
||||||
# présente à part (« piloter un autre PC »).
|
|
||||||
for t in linux/amd64:ajean-remote-linux linux/arm64:ajean-remote-linux-arm \
|
|
||||||
windows/amd64:ajean-remote-windows.exe windows/arm64:ajean-remote-windows-arm.exe \
|
|
||||||
darwin/amd64:ajean-remote-macos darwin/arm64:ajean-remote-macos-arm; do
|
|
||||||
target=${t%%:*}; name=${t#*:}
|
|
||||||
os=${target%/*}; arch=${target#*/}
|
|
||||||
GOOS=$os GOARCH=$arch CGO_ENABLED=0 \
|
|
||||||
go build -trimpath -ldflags="-s -w" -o "dist/$name" ./cmd/ajean-remote
|
|
||||||
done
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: macos
|
name: macos
|
||||||
|
|||||||
+12
-8
@@ -1,15 +1,19 @@
|
|||||||
Piloter un autre PC fonctionne maintenant à distance, à travers ajean.link, sans que le relais ne voie jamais rien.
|
Le poste distant est maintenant intégré à AJEAN : plus de binaire séparé, plus de téléchargement à part.
|
||||||
|
|
||||||
## Le poste distant passe par ajean.link, chiffré de bout en bout
|
## Une seule application
|
||||||
|
|
||||||
La 0.8.9 a introduit le poste distant, mais uniquement sur le réseau local. Il fonctionne désormais **depuis n'importe où**, via ajean.link — et avec la même exigence que le reste d'ajean.link : le **relais reste aveugle**.
|
Jusqu'ici, piloter un autre PC demandait d'installer un second binaire, « ajean-remote ». C'était une application de plus à télécharger, à suivre et à mettre à jour. On l'a supprimée : tout vit désormais dans **AJEAN**.
|
||||||
|
|
||||||
Concrètement, l'identité d'un poste n'est plus une clé partagée mais une **paire de clés** qui lui est propre. À l'appairage, le poste scelle sa demande vers la clé publique de ton serveur : le relais ne voit ni le code, ni rien d'autre. Ensuite, tout ce qui circule entre le poste et ton serveur — les commandes de l'IA comme leurs résultats — est **chiffré de bout en bout** avec une clé que seuls ton serveur et ton poste peuvent calculer. Le relais ne transporte que de l'opaque.
|
Sur le PC à piloter, tu installes simplement AJEAN, puis tu lances :
|
||||||
|
|
||||||
## Rien à changer pour toi
|
```
|
||||||
|
ajean remote install https://ajean.link --machine <id> --key <clé> --code <code> --allow shell,read,write,list
|
||||||
|
```
|
||||||
|
|
||||||
Dans **Réglages → Postes distants**, générer un code affiche maintenant deux commandes : une pour l'**accès à distance** (via ajean.link) et une pour le **réseau local** (connexion directe). Tu choisis, tu copies, tu colles sur l'autre PC.
|
La commande s'installe en service — invisible, au démarrage, reconnexion automatique — exactement comme avant. Rien ne change au chiffrement : l'accès reste **chiffré de bout en bout**, le relais ajean.link ne voit toujours rien.
|
||||||
|
|
||||||
## Un client, toujours aussi léger
|
## Rien à changer dans ton usage
|
||||||
|
|
||||||
Le petit client s'appelle **ajean-remote** (quelques mégaoctets, aucune interface). Il s'installe en service — invisible, au démarrage, reconnexion automatique — et se télécharge depuis ajean.link, section « Piloter un autre PC ».
|
Dans **Réglages → Postes distants**, générer un code affiche la commande prête à copier — à distance (via ajean.link) ou en réseau local. Seul le nom de la commande change : `ajean remote install …` au lieu de `ajean-remote install …`.
|
||||||
|
|
||||||
|
Les postes déjà appairés continuent de fonctionner sans réappairage.
|
||||||
Binary file not shown.
Binary file not shown.
@@ -3,13 +3,13 @@
|
|||||||
"FileVersion": {
|
"FileVersion": {
|
||||||
"Major": 0,
|
"Major": 0,
|
||||||
"Minor": 9,
|
"Minor": 9,
|
||||||
"Patch": 0,
|
"Patch": 1,
|
||||||
"Build": 0
|
"Build": 0
|
||||||
},
|
},
|
||||||
"ProductVersion": {
|
"ProductVersion": {
|
||||||
"Major": 0,
|
"Major": 0,
|
||||||
"Minor": 9,
|
"Minor": 9,
|
||||||
"Patch": 0,
|
"Patch": 1,
|
||||||
"Build": 0
|
"Build": 0
|
||||||
},
|
},
|
||||||
"FileFlagsMask": "3f",
|
"FileFlagsMask": "3f",
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"LegalCopyright": "Copyright (c) 2026 AJEAN contributors. MIT License.",
|
"LegalCopyright": "Copyright (c) 2026 AJEAN contributors. MIT License.",
|
||||||
"OriginalFilename": "ajean.exe",
|
"OriginalFilename": "ajean.exe",
|
||||||
"ProductName": "AJEAN",
|
"ProductName": "AJEAN",
|
||||||
"ProductVersion": "0.9.0",
|
"ProductVersion": "0.9.1",
|
||||||
"Comments": "https://github.com/nathaninline/ajean — projet open source (MIT)"
|
"Comments": "https://github.com/nathaninline/ajean — projet open source (MIT)"
|
||||||
},
|
},
|
||||||
"VarFileInfo": {
|
"VarFileInfo": {
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
// ajean-remote — client LÉGER « poste distant ». Binaire séparé et minuscule
|
// Sous-commande « ajean remote » — client « poste distant » intégré au binaire
|
||||||
// (protocole partagé + WebSocket, sans UI ni moteur) : on l'installe sur un PC
|
// principal. On l'installe sur un PC pour que l'IA d'un serveur AJEAN puisse agir
|
||||||
// pour que l'IA d'un serveur AJEAN puisse agir dessus.
|
// dessus (shell/fichiers), chiffré de bout en bout via ajean.link (relais aveugle)
|
||||||
|
// ou en direct sur le réseau local.
|
||||||
//
|
//
|
||||||
// ajean-remote install <url-serveur> --code CODE [--allow shell,read,write,list] [--root DIR]
|
// ajean remote install <url-serveur> --machine ID --key CLÉ --code CODE [--allow shell,read,write,list] [--root DIR]
|
||||||
// appaire ce PC et l'installe en service (démarrage auto)
|
// appaire ce PC et l'installe en service (démarrage auto)
|
||||||
// ajean-remote connect <url> --code CODE [...] même chose mais en avant-plan (test)
|
// ajean remote connect <url> ... idem mais en avant-plan (test)
|
||||||
// ajean-remote run boucle client (utilisé par le service)
|
// ajean remote run boucle client (utilisé par le service)
|
||||||
// ajean-remote status | uninstall | logout
|
// ajean remote status | uninstall | logout
|
||||||
package main
|
//
|
||||||
|
// Historiquement un binaire séparé « ajean-remote » ; fusionné dans ce binaire
|
||||||
|
// pour n'avoir qu'une seule application.
|
||||||
|
package ajean
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -19,65 +23,64 @@ import (
|
|||||||
"github.com/nathaninline/ajean/internal/nodeclient"
|
"github.com/nathaninline/ajean/internal/nodeclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func cmdRemote(args []string) error {
|
||||||
args := os.Args[1:]
|
sub := ""
|
||||||
cmd := ""
|
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
cmd = args[0]
|
sub = args[0]
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
}
|
}
|
||||||
var err error
|
switch sub {
|
||||||
switch cmd {
|
|
||||||
case "install":
|
case "install":
|
||||||
err = doConnect(args, true)
|
return remoteConnect(args, true)
|
||||||
case "connect":
|
case "connect":
|
||||||
err = doConnect(args, false)
|
return remoteConnect(args, false)
|
||||||
case "run":
|
case "run":
|
||||||
err = doRun()
|
return remoteRun()
|
||||||
case "uninstall":
|
case "uninstall":
|
||||||
err = nodeclient.Uninstall()
|
if err := nodeclient.Uninstall(); err != nil {
|
||||||
if err == nil {
|
return err
|
||||||
fmt.Println("[ok] service retiré")
|
|
||||||
}
|
}
|
||||||
|
fmt.Println("[ok] service retiré")
|
||||||
|
return nil
|
||||||
case "logout":
|
case "logout":
|
||||||
_ = nodeclient.Uninstall()
|
_ = nodeclient.Uninstall()
|
||||||
err = os.Remove(nodeclient.ConfigPath())
|
err := os.Remove(nodeclient.ConfigPath())
|
||||||
if err == nil || os.IsNotExist(err) {
|
if err != nil && !os.IsNotExist(err) {
|
||||||
err = nil
|
return err
|
||||||
fmt.Println("[ok] configuration oubliée")
|
|
||||||
}
|
}
|
||||||
|
fmt.Println("[ok] configuration oubliée")
|
||||||
|
return nil
|
||||||
case "status":
|
case "status":
|
||||||
err = doStatus()
|
return remoteStatus()
|
||||||
default:
|
default:
|
||||||
usage()
|
remoteUsage()
|
||||||
}
|
return nil
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, "[err]", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func usage() {
|
func remoteUsage() {
|
||||||
fmt.Print(`ajean-remote — client léger « poste distant » pour AJEAN
|
fmt.Print(`ajean remote — piloter CE PC depuis l'IA d'un serveur AJEAN
|
||||||
|
|
||||||
ajean-remote install <url-serveur> --code CODE [options] appaire + installe en service (démarrage auto, invisible)
|
ajean remote install <url-serveur> --code CODE [options] appaire + installe en service (démarrage auto, invisible)
|
||||||
ajean-remote connect <url-serveur> --code CODE [options] idem en avant-plan (pour tester)
|
ajean remote connect <url-serveur> --code CODE [options] idem en avant-plan (pour tester)
|
||||||
ajean-remote status état de la configuration
|
ajean remote status état de la configuration
|
||||||
ajean-remote uninstall retire le service (garde la config)
|
ajean remote uninstall retire le service (garde la config)
|
||||||
ajean-remote logout retire le service ET oublie la clé
|
ajean remote logout retire le service ET oublie la clé
|
||||||
|
|
||||||
Options :
|
Options :
|
||||||
--code CODE code d'appairage (généré dans l'UI AJEAN → Postes distants)
|
--machine ID machine à joindre via ajean.link (fournie par l'UI → Postes distants)
|
||||||
--allow LISTE capacités acceptées : shell,read,write,list (défaut : ce que le serveur autorise)
|
--key CLÉ clé publique de l'agent (le poste scelle vers elle)
|
||||||
--root DIR dossier autorisé (confine lecture/écriture)
|
--code CODE code d'appairage (10 min, généré dans l'UI AJEAN → Postes distants)
|
||||||
--yes auto-approuve les actions (obligatoire pour le service, sans terminal)
|
--allow LISTE capacités acceptées : shell,read,write,list (défaut : ce que le serveur autorise)
|
||||||
|
--root DIR dossier autorisé (confine lecture/écriture)
|
||||||
|
--yes auto-approuve les actions (obligatoire pour le service, sans terminal)
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// doConnect appaire au besoin, sauvegarde, puis installe (service) ou lance
|
// remoteConnect appaire au besoin, sauvegarde, puis installe (service) ou lance
|
||||||
// (avant-plan) selon install.
|
// (avant-plan) selon install.
|
||||||
func doConnect(args []string, install bool) error {
|
func remoteConnect(args []string, install bool) error {
|
||||||
f := parseFlags(args)
|
f := parseRemoteFlags(args)
|
||||||
cfg, lerr := nodeclient.LoadConfig()
|
cfg, lerr := nodeclient.LoadConfig()
|
||||||
needEnroll := lerr != nil || cfg.Priv == ""
|
needEnroll := lerr != nil || cfg.Priv == ""
|
||||||
if f.url != "" {
|
if f.url != "" {
|
||||||
@@ -91,7 +94,7 @@ func doConnect(args []string, install bool) error {
|
|||||||
}
|
}
|
||||||
if needEnroll {
|
if needEnroll {
|
||||||
if cfg.ServerURL == "" {
|
if cfg.ServerURL == "" {
|
||||||
return fmt.Errorf("url du serveur requise (ex: http://192.168.1.127:8090)")
|
return fmt.Errorf("url du serveur requise (ex: https://ajean.link)")
|
||||||
}
|
}
|
||||||
if f.code == "" {
|
if f.code == "" {
|
||||||
return fmt.Errorf("code d'appairage requis : --code CODE")
|
return fmt.Errorf("code d'appairage requis : --code CODE")
|
||||||
@@ -104,17 +107,16 @@ func doConnect(args []string, install bool) error {
|
|||||||
}
|
}
|
||||||
fmt.Printf("[ok] appairé (id %s)\n", cfg.ID)
|
fmt.Printf("[ok] appairé (id %s)\n", cfg.ID)
|
||||||
}
|
}
|
||||||
allow, root, yes := f.allow, f.root, f.yes
|
if len(f.allow) > 0 {
|
||||||
if len(allow) > 0 {
|
cfg.Caps = nodeclient.SanitizeCaps(f.allow)
|
||||||
cfg.Caps = nodeclient.SanitizeCaps(allow)
|
|
||||||
}
|
}
|
||||||
if root != "" {
|
if f.root != "" {
|
||||||
cfg.Root = root
|
cfg.Root = f.root
|
||||||
}
|
}
|
||||||
if cfg.Root == "" {
|
if cfg.Root == "" {
|
||||||
cfg.Root = nodeclient.DataDir() + string(os.PathSeparator) + "workspace"
|
cfg.Root = nodeclient.DataDir() + string(os.PathSeparator) + "workspace"
|
||||||
}
|
}
|
||||||
if yes || install {
|
if f.yes || install {
|
||||||
cfg.AutoYes = true // un service n'a pas de terminal pour confirmer
|
cfg.AutoYes = true // un service n'a pas de terminal pour confirmer
|
||||||
}
|
}
|
||||||
if cfg.Name == "" {
|
if cfg.Name == "" {
|
||||||
@@ -137,15 +139,15 @@ func doConnect(args []string, install bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doRun() error {
|
func remoteRun() error {
|
||||||
cfg, err := nodeclient.LoadConfig()
|
cfg, err := nodeclient.LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("aucune configuration — lance d'abord « ajean-remote install … »")
|
return fmt.Errorf("aucune configuration — lance d'abord « ajean remote install … »")
|
||||||
}
|
}
|
||||||
return nodeclient.RunService(cfg)
|
return nodeclient.RunService(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func doStatus() error {
|
func remoteStatus() error {
|
||||||
cfg, err := nodeclient.LoadConfig()
|
cfg, err := nodeclient.LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("aucun poste configuré")
|
fmt.Println("aucun poste configuré")
|
||||||
@@ -160,14 +162,14 @@ func doStatus() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type flags struct {
|
type remoteFlags struct {
|
||||||
url, code, root, key, machine string
|
url, code, root, key, machine string
|
||||||
allow []string
|
allow []string
|
||||||
yes bool
|
yes bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFlags(args []string) flags {
|
func parseRemoteFlags(args []string) remoteFlags {
|
||||||
var f flags
|
var f remoteFlags
|
||||||
for i := 0; i < len(args); i++ {
|
for i := 0; i < len(args); i++ {
|
||||||
a := args[i]
|
a := args[i]
|
||||||
next := func() string {
|
next := func() string {
|
||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const Version = "0.9.0"
|
const Version = "0.9.1"
|
||||||
|
|
||||||
// Main est le vrai main() du binaire (cmd/ajean ne fait que l'appeler).
|
// Main est le vrai main() du binaire (cmd/ajean ne fait que l'appeler).
|
||||||
func Main() {
|
func Main() {
|
||||||
@@ -74,6 +74,8 @@ func Main() {
|
|||||||
mustExit(cmdWeb(args))
|
mustExit(cmdWeb(args))
|
||||||
case "link":
|
case "link":
|
||||||
mustExit(cmdLink(args))
|
mustExit(cmdLink(args))
|
||||||
|
case "remote":
|
||||||
|
mustExit(cmdRemote(args))
|
||||||
case "ui":
|
case "ui":
|
||||||
mustExit(cmdUI(args))
|
mustExit(cmdUI(args))
|
||||||
case "oai":
|
case "oai":
|
||||||
@@ -158,9 +160,12 @@ Accès distant (ajean.link) :
|
|||||||
link code code d'appairage (10 min, usage unique) pour le portail
|
link code code d'appairage (10 min, usage unique) pour le portail
|
||||||
link status | logout état du jeton / l'oublier
|
link status | logout état du jeton / l'oublier
|
||||||
|
|
||||||
Poste distant (piloter un autre PC depuis l'IA) :
|
Poste distant (piloter CE PC depuis l'IA d'un serveur AJEAN) :
|
||||||
le poste s'installe avec le binaire LÉGER séparé « ajean-remote » (cmd/ajean-remote),
|
remote install <url> --machine ID --key CLÉ --code CODE [--allow shell,read,write,list]
|
||||||
pas avec ce binaire : ajean-remote install <url-serveur> --code CODE
|
appaire ce PC + installe le service (démarrage auto)
|
||||||
|
remote connect <url> … idem en avant-plan (pour tester)
|
||||||
|
remote status | uninstall | logout
|
||||||
|
(commande d'appairage prête à copier : UI web → Postes distants)
|
||||||
|
|
||||||
Backend llama.cpp :
|
Backend llama.cpp :
|
||||||
llamacpp install clone + compile llama.cpp (CUDA/ROCm/Metal/CPU), pointe BIN dessus
|
llamacpp install clone + compile llama.cpp (CUDA/ROCm/Metal/CPU), pointe BIN dessus
|
||||||
|
|||||||
@@ -1303,7 +1303,7 @@ button:hover{border-color:var(--dim);color:var(--text)}
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="node-block" class="gated-group">
|
<div id="node-block" class="gated-group">
|
||||||
<div class="subhead">Postes distants<span id="node-badge" class="sbadge"></span><span class="help" tabindex="0" onclick="event.preventDefault();event.stopPropagation();this.classList.toggle('open')">?<span class="tip">Pilote un <b>autre PC</b> depuis l'IA. installe le petit client <b>ajean-remote</b> sur le PC secondaire et lance <code>ajean-remote install <url> --code CODE</code> : il se connecte en sortant (aucun port à ouvrir) et expose à l'IA un jeu d'outils restreint (shell, fichiers). ⚠ tu décides des capacités et du dossier autorisé pour chaque poste ; le poste peut aussi demander confirmation localement.</span></span></div>
|
<div class="subhead">Postes distants<span id="node-badge" class="sbadge"></span><span class="help" tabindex="0" onclick="event.preventDefault();event.stopPropagation();this.classList.toggle('open')">?<span class="tip">Pilote un <b>autre PC</b> depuis l'IA. installe <b>ajean</b> sur le PC secondaire et lance <code>ajean remote install <url> --code CODE</code> : il se connecte en sortant (aucun port à ouvrir) et expose à l'IA un jeu d'outils restreint (shell, fichiers). ⚠ tu décides des capacités et du dossier autorisé pour chaque poste ; le poste peut aussi demander confirmation localement.</span></span></div>
|
||||||
<div class="slist">
|
<div class="slist">
|
||||||
<div class="rowbody">
|
<div class="rowbody">
|
||||||
<div id="node-list" class="mcp-list"><div class="muted" style="font-size:12px">(aucun poste — appaire un PC pour que l'IA puisse agir dessus)</div></div>
|
<div id="node-list" class="mcp-list"><div class="muted" style="font-size:12px">(aucun poste — appaire un PC pour que l'IA puisse agir dessus)</div></div>
|
||||||
@@ -1723,7 +1723,7 @@ button:hover{border-color:var(--dim);color:var(--text)}
|
|||||||
<div class="subhead" style="margin-top:6px">Code d'appairage</div>
|
<div class="subhead" style="margin-top:6px">Code d'appairage</div>
|
||||||
<div class="node-code" id="node-pair-code">——</div>
|
<div class="node-code" id="node-pair-code">——</div>
|
||||||
<div class="muted" style="font-size:12px;line-height:1.5">
|
<div class="muted" style="font-size:12px;line-height:1.5">
|
||||||
Sur le PC à piloter, installe <b>ajean-remote</b> (ajean.link/download) puis lance — <b>accès à distance</b>, chiffré de bout en bout :
|
Sur le PC à piloter, installe <b>ajean</b> (ajean.link/download) puis lance — <b>accès à distance</b>, chiffré de bout en bout :
|
||||||
<pre class="node-cmd" id="node-pair-cmd"></pre>
|
<pre class="node-cmd" id="node-pair-cmd"></pre>
|
||||||
<span style="opacity:.8">Ou en <b>réseau local</b> (connexion directe) :</span>
|
<span style="opacity:.8">Ou en <b>réseau local</b> (connexion directe) :</span>
|
||||||
<pre class="node-cmd" id="node-pair-cmd-lan"></pre>
|
<pre class="node-cmd" id="node-pair-cmd-lan"></pre>
|
||||||
@@ -5509,10 +5509,10 @@ async function genNodeCode(){
|
|||||||
// Commande d'accès À DISTANCE (partout) via ajean.link : chiffrée de bout en
|
// Commande d'accès À DISTANCE (partout) via ajean.link : chiffrée de bout en
|
||||||
// bout, le relais reste aveugle. --key = clé publique de l'agent (le poste
|
// bout, le relais reste aveugle. --key = clé publique de l'agent (le poste
|
||||||
// scelle vers elle), --machine = quelle machine joindre.
|
// scelle vers elle), --machine = quelle machine joindre.
|
||||||
const remote = 'ajean-remote install https://ajean.link --machine '+r.machine+
|
const remote = 'ajean remote install https://ajean.link --machine '+r.machine+
|
||||||
' --key '+r.agent_pub+' --code '+r.code+' --allow '+allow+rootArg;
|
' --key '+r.agent_pub+' --code '+r.code+' --allow '+allow+rootArg;
|
||||||
// Variante RÉSEAU LOCAL (connexion directe, sans passer par le relais).
|
// Variante RÉSEAU LOCAL (connexion directe, sans passer par le relais).
|
||||||
const lan = 'ajean-remote install '+location.origin+
|
const lan = 'ajean remote install '+location.origin+
|
||||||
' --key '+r.agent_pub+' --code '+r.code+' --allow '+allow+rootArg;
|
' --key '+r.agent_pub+' --code '+r.code+' --allow '+allow+rootArg;
|
||||||
document.getElementById('node-pair-cmd').textContent = remote;
|
document.getElementById('node-pair-cmd').textContent = remote;
|
||||||
const lanEl = document.getElementById('node-pair-cmd-lan');
|
const lanEl = document.getElementById('node-pair-cmd-lan');
|
||||||
|
|||||||
@@ -147,7 +147,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="node-block" class="gated-group">
|
<div id="node-block" class="gated-group">
|
||||||
<div class="subhead">Postes distants<span id="node-badge" class="sbadge"></span><span class="help" tabindex="0" onclick="event.preventDefault();event.stopPropagation();this.classList.toggle('open')">?<span class="tip">Pilote un <b>autre PC</b> depuis l'IA. installe le petit client <b>ajean-remote</b> sur le PC secondaire et lance <code>ajean-remote install <url> --code CODE</code> : il se connecte en sortant (aucun port à ouvrir) et expose à l'IA un jeu d'outils restreint (shell, fichiers). ⚠ tu décides des capacités et du dossier autorisé pour chaque poste ; le poste peut aussi demander confirmation localement.</span></span></div>
|
<div class="subhead">Postes distants<span id="node-badge" class="sbadge"></span><span class="help" tabindex="0" onclick="event.preventDefault();event.stopPropagation();this.classList.toggle('open')">?<span class="tip">Pilote un <b>autre PC</b> depuis l'IA. installe <b>ajean</b> sur le PC secondaire et lance <code>ajean remote install <url> --code CODE</code> : il se connecte en sortant (aucun port à ouvrir) et expose à l'IA un jeu d'outils restreint (shell, fichiers). ⚠ tu décides des capacités et du dossier autorisé pour chaque poste ; le poste peut aussi demander confirmation localement.</span></span></div>
|
||||||
<div class="slist">
|
<div class="slist">
|
||||||
<div class="rowbody">
|
<div class="rowbody">
|
||||||
<div id="node-list" class="mcp-list"><div class="muted" style="font-size:12px">(aucun poste — appaire un PC pour que l'IA puisse agir dessus)</div></div>
|
<div id="node-list" class="mcp-list"><div class="muted" style="font-size:12px">(aucun poste — appaire un PC pour que l'IA puisse agir dessus)</div></div>
|
||||||
@@ -567,7 +567,7 @@
|
|||||||
<div class="subhead" style="margin-top:6px">Code d'appairage</div>
|
<div class="subhead" style="margin-top:6px">Code d'appairage</div>
|
||||||
<div class="node-code" id="node-pair-code">——</div>
|
<div class="node-code" id="node-pair-code">——</div>
|
||||||
<div class="muted" style="font-size:12px;line-height:1.5">
|
<div class="muted" style="font-size:12px;line-height:1.5">
|
||||||
Sur le PC à piloter, installe <b>ajean-remote</b> (ajean.link/download) puis lance — <b>accès à distance</b>, chiffré de bout en bout :
|
Sur le PC à piloter, installe <b>ajean</b> (ajean.link/download) puis lance — <b>accès à distance</b>, chiffré de bout en bout :
|
||||||
<pre class="node-cmd" id="node-pair-cmd"></pre>
|
<pre class="node-cmd" id="node-pair-cmd"></pre>
|
||||||
<span style="opacity:.8">Ou en <b>réseau local</b> (connexion directe) :</span>
|
<span style="opacity:.8">Ou en <b>réseau local</b> (connexion directe) :</span>
|
||||||
<pre class="node-cmd" id="node-pair-cmd-lan"></pre>
|
<pre class="node-cmd" id="node-pair-cmd-lan"></pre>
|
||||||
|
|||||||
@@ -115,10 +115,10 @@ async function genNodeCode(){
|
|||||||
// Commande d'accès À DISTANCE (partout) via ajean.link : chiffrée de bout en
|
// Commande d'accès À DISTANCE (partout) via ajean.link : chiffrée de bout en
|
||||||
// bout, le relais reste aveugle. --key = clé publique de l'agent (le poste
|
// bout, le relais reste aveugle. --key = clé publique de l'agent (le poste
|
||||||
// scelle vers elle), --machine = quelle machine joindre.
|
// scelle vers elle), --machine = quelle machine joindre.
|
||||||
const remote = 'ajean-remote install https://ajean.link --machine '+r.machine+
|
const remote = 'ajean remote install https://ajean.link --machine '+r.machine+
|
||||||
' --key '+r.agent_pub+' --code '+r.code+' --allow '+allow+rootArg;
|
' --key '+r.agent_pub+' --code '+r.code+' --allow '+allow+rootArg;
|
||||||
// Variante RÉSEAU LOCAL (connexion directe, sans passer par le relais).
|
// Variante RÉSEAU LOCAL (connexion directe, sans passer par le relais).
|
||||||
const lan = 'ajean-remote install '+location.origin+
|
const lan = 'ajean remote install '+location.origin+
|
||||||
' --key '+r.agent_pub+' --code '+r.code+' --allow '+allow+rootArg;
|
' --key '+r.agent_pub+' --code '+r.code+' --allow '+allow+rootArg;
|
||||||
document.getElementById('node-pair-cmd').textContent = remote;
|
document.getElementById('node-pair-cmd').textContent = remote;
|
||||||
const lanEl = document.getElementById('node-pair-cmd-lan');
|
const lanEl = document.getElementById('node-pair-cmd-lan');
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func Install() error {
|
|||||||
case "darwin":
|
case "darwin":
|
||||||
return installLaunchd(dst)
|
return installLaunchd(dst)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("installation auto non gérée sur %s — lance « ajean-remote connect » via ton propre gestionnaire de démarrage", runtime.GOOS)
|
return fmt.Errorf("installation auto non gérée sur %s — lance « ajean remote connect » via ton propre gestionnaire de démarrage", runtime.GOOS)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Uninstall() error {
|
func Uninstall() error {
|
||||||
@@ -58,7 +58,7 @@ func Uninstall() error {
|
|||||||
|
|
||||||
func installSystemd(exe string) error {
|
func installSystemd(exe string) error {
|
||||||
unit := "[Unit]\nDescription=AJEAN poste distant\nAfter=network-online.target\n\n" +
|
unit := "[Unit]\nDescription=AJEAN poste distant\nAfter=network-online.target\n\n" +
|
||||||
"[Service]\nExecStart=" + exe + " run\nRestart=always\nRestartSec=5\n\n" +
|
"[Service]\nExecStart=" + exe + " remote run\nRestart=always\nRestartSec=5\n\n" +
|
||||||
"[Install]\nWantedBy=default.target\n"
|
"[Install]\nWantedBy=default.target\n"
|
||||||
dir := filepath.Join(os.Getenv("HOME"), ".config/systemd/user")
|
dir := filepath.Join(os.Getenv("HOME"), ".config/systemd/user")
|
||||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||||
@@ -79,7 +79,7 @@ func installLaunchd(exe string) error {
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0"><dict>
|
<plist version="1.0"><dict>
|
||||||
<key>Label</key><string>link.ajean.remote</string>
|
<key>Label</key><string>link.ajean.remote</string>
|
||||||
<key>ProgramArguments</key><array><string>` + exe + `</string><string>run</string></array>
|
<key>ProgramArguments</key><array><string>` + exe + `</string><string>remote</string><string>run</string></array>
|
||||||
<key>RunAtLoad</key><true/>
|
<key>RunAtLoad</key><true/>
|
||||||
<key>KeepAlive</key><true/>
|
<key>KeepAlive</key><true/>
|
||||||
</dict></plist>
|
</dict></plist>
|
||||||
|
|||||||
@@ -73,13 +73,13 @@ func Install() error {
|
|||||||
defer m.Disconnect()
|
defer m.Disconnect()
|
||||||
if s, err := m.OpenService(serviceName); err == nil {
|
if s, err := m.OpenService(serviceName); err == nil {
|
||||||
s.Close()
|
s.Close()
|
||||||
return fmt.Errorf("service déjà installé — « ajean-remote uninstall » d'abord")
|
return fmt.Errorf("service déjà installé — « ajean remote uninstall » d'abord")
|
||||||
}
|
}
|
||||||
s, err := m.CreateService(serviceName, dst, mgr.Config{
|
s, err := m.CreateService(serviceName, dst, mgr.Config{
|
||||||
StartType: mgr.StartAutomatic,
|
StartType: mgr.StartAutomatic,
|
||||||
DisplayName: "AJEAN — poste distant",
|
DisplayName: "AJEAN — poste distant",
|
||||||
Description: "Pont léger permettant à votre serveur IA AJEAN d'agir sur ce PC.",
|
Description: "Pont léger permettant à votre serveur IA AJEAN d'agir sur ce PC.",
|
||||||
}, "run")
|
}, "remote", "run")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("création du service: %w", err)
|
return fmt.Errorf("création du service: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user