Documentation
Vérifier et restaurer une modification de projet
Enregistrez la base de données de travail, isolez une branche de proposition, examinez les différences, exécutez des vérifications validées et fusionnez ou restaurez avec des effets secondaires clairs.
Traduit automatiquement de l'anglais. Voir l'original en anglais
Séparez les ressources enregistrées de l’historique engagé
L'enregistrement d'un projet, d'un dessin ou d'un parcours d'outil met à jour la copie de travail SQLite. La création d'un commit de projet capture les ressources de travail dans des objets compatibles Git et déplace la référence de branche actuelle. Ce sont des opérations distinctes : un dessin enregistré peut être non validé et un programme validé peut rester local sans aucun miroir distant.
Le service d'historique du sidecar crée un fichier JSON canonique par ressource. L'arborescence comprend project.json, les dessins, les composants, les parcours d'outils, les matériaux/outils/configurations de machines référencés et les coûts de production. Le flux de travail YAML et d'autres textes non-entités transportés se trouvent dans l'arborescence du référentiel, plutôt que dans les enregistrements de dessin ordinaires. Une modification apportée à une entité ne nécessite pas de traiter l’intégralité de la base de données comme une différence binaire opaque.
Choisissez un projet jetable ou prévu avant de suivre les exemples de mutation. Ensemble PROJECT_ID à son véritable identifiant et utiliser une URL de connexion/support d'application actuel. L'historique du projet et les points finaux du flux de travail sont documentés dans le référence de l'API d'historique; les écritures de métadonnées du projet utilisent le aPI de projets.
Les objets utilisent le format d'objet libre exact en octets de git, donc les ID de validation et d'arborescence correspondent à ce qui git calcule pour le même contenu. Les références des succursales se trouvent sous refs/heads/, et la branche par défaut est main.
Inspecter l’identité et l’état de fonctionnement
L'accès en lecture, les validations, la création de branche, l'ouverture des demandes d'extraction, les révisions et l'envoi de flux de travail nécessitent un accès au projet. L'extraction, la restauration, la configuration à distance, le push/pull et la fusion nécessitent un accès du responsable : le propriétaire du projet ou l'ADMIN/MANAGER de l'organisation. Un en-tête de session de compte facultatif sélectionne l'utilisateur actif ; sans session de compte valide, l'application utilise son profil local.
curl --fail-with-body \
-H "Authorization: Bearer $CADCAMFUN_TOKEN" \
"$CADCAMFUN_URL/api/projects/$PROJECT_ID/vcs/status" La réponse nomme la branche, le HEAD nullable et les chemins modifiés. Dirty signifie que les fichiers de ressources actuels diffèrent de HEAD. Une liste non vide constitue une information de révision utile et non un échec de stockage. Avant de déplacer la copie de travail, décidez si ces modifications appartiennent à une validation ou si elles doivent être délibérément restaurées/supprimées.
Si HEAD est nul, enregistrez la première validation du projet avant de créer une branche à partir de HEAD. L'API de branche résout une véritable validation de source ; il n'y a pas d'engagement d'espace réservé à partir duquel créer une branche dans un nouveau projet.
Créer une référence ou enregistrer les modifications souhaitées
Une validation nécessite un message non vide et capture les ressources actuelles sauvegardées dans la base de données. Examinez d'abord les chemins modifiés : l'API ne prépare pas les fichiers d'entités individuels. Le champ Fichiers facultatifs ajoute des définitions de flux de travail sécurisées, décrites plus loin ; il ne sélectionne pas les modifications de dessin à inclure.
curl --fail-with-body \
-H "Authorization: Bearer $CADCAMFUN_TOKEN" \
-H "Content-Type: application/json" \
--data '{"message":"Record baseline blank"}' \
"$CADCAMFUN_URL/api/projects/$PROJECT_ID/vcs/commit" La réponse est un enregistrement de validation 201 avec l'ID d'objet, les ID de parent, le message et les informations sur l'auteur. Enregistrez son OID pour une comparaison ou une restauration ultérieure. Un arbre inchangé est rejeté avec NothingToCommit plutôt que de fabriquer une autre révision à partir du même contenu.
authorKind par défaut, l'utilisateur. Les validations générées par l'assistant utilisent ai et ne peuvent pas être validées sur main. La politique des acteurs est appliquée par le service du projet ; un autre message affiché ne le contourne pas. La création d'une validation peut déclencher des flux de travail une fois la validation enregistrée. Un flux de travail échoué ultérieur n’annule pas cette validation.
Créer et consulter une proposition
La création d'une branche écrit une référence ; cela ne change pas la base de données de travail. Le paiement est explicite et refuse les modifications de travail non validées. Les appels suivants créent une branche à partir du HEAD actuel et la chargent en tant que branche extraite.
curl --fail-with-body \
-H "Authorization: Bearer $CADCAMFUN_TOKEN" -H "Content-Type: application/json" \
--data '{"name":"proposal/blank-label"}' \
"$CADCAMFUN_URL/api/projects/$PROJECT_ID/vcs/branches"
curl --fail-with-body \
-H "Authorization: Bearer $CADCAMFUN_TOKEN" -H "Content-Type: application/json" \
--data '{"branch":"proposal/blank-label"}' \
"$CADCAMFUN_URL/api/projects/$PROJECT_ID/vcs/checkout" Pour commencer ailleurs, ajoutez une révision à la création de branche. Les noms doivent être des références sûres : la traversée, les barres obliques répétées, un suffixe barre oblique/.lock et les fragments d'expression de référence sont rejetés. La réutilisation d'un nom existant est également refusée.
Après le paiement, enregistrez les modifications prévues au projet via leurs API de ressources. Pour une petite démonstration, mettez à jour les métadonnées du projet avec PUT /api/projects/:id et un nouveau nom, puis validez-le. La différence résultante change project.json ; cela n’implique pas de changement de géométrie. Dans une révision de pièce réelle, enregistrez le dessin et tous les parcours d'outils régénérés avant de valider.
Lisez les changements exacts en cours d'examen
GET /vcs/log prend en charge rev, limit et un chemin suivi en option. GET /vcs/diff nécessite et accepte un from facultatif. Utilisez des OID explicites pour une comparaison reproductible. Encodez les noms de branches et les chemins JSON en tant que valeurs de requête plutôt que d'intégrer des signes de ponctuation sans échappement dans les URL.
curl --fail-with-body --get \
-H "Authorization: Bearer $CADCAMFUN_TOKEN" \
--data-urlencode "from=main" \
--data-urlencode "to=proposal/blank-label" \
"$CADCAMFUN_URL/api/projects/$PROJECT_ID/vcs/diff" Les modifications d'entité incluent le chemin, le type de ressource, le statut ajouté/modifié/supprimé, l'ID/nom facultatif et les modifications de propriété décrites par les pointeurs JSON. Canonical JSON trie les clés d'objet de manière récursive tout en préservant l'ordre du tableau. Les modifications de propriétés d'objet qui ne se chevauchent pas peuvent fusionner structurellement ; les modifications de tableau simultanées incompatibles sont des conflits atomiques, et non des rapprochements élément par élément.
Examinez les preuves de fabrication dans le cadre de l'enregistrement du parcours d'outil : la correspondance du code G et de l'identité de l'artefact est plus importante qu'un nom de fichier familier. Une validation de projet capture les données enregistrées ; il n'exécute pas une demande de fabrication native manquante simplement parce que l'arborescence contient du texte CN.
Valider les contrôles exécutables avec le projet
Les fichiers supplémentaires du point de terminaison de validation publique sont limités à .cadcamfun/workflows/<safe-name>.yml ou yaml. Il accepte les valeurs de texte, pas les correctifs arbitraires du système de fichiers. Vous ne pouvez pas utiliser ce champ pour remplacer le dessin JSON, écrire des scripts shell ou supprimer un fichier en envoyant null.
Une définition est validée sous forme de texte YAML, puis le coureur la charge à partir de cette référence validée. L'exemple ci-dessous valide les fichiers structurels, requiert la CN pour les parcours d'outils existants, vérifie le séquencement des opérations et tente de rejouer les parcours d'outils contenant une requête de générateur stockée.
name: Review checks
on:
manual: true
pullRequest:
branches: [main]
jobs:
inspect:
steps:
- id: structure
uses: project/validate
- uses: project/require-gcode
- uses: cam/sequence
- id: replay
uses: cam/verify Pour le valider à partir d'un script, construisez le corps JSON avec un sérialiseur plutôt que d'échapper manuellement YAML :
const body = {
message: "Add committed review checks",
files: { ".cadcamfun/workflows/review.yml": await Bun.file("review.yml").text() }
}
const encoded = JSON.stringify(body) Le commit capture toujours toutes les ressources de travail actuelles. Validez le YAML avant de l'enregistrer : la validation de l'historique peut réussir tandis que le flux de travail non valide qui en résulte est ensuite enregistré comme une exécution ayant échoué. Le moteur de production vérifie le schéma, les dépendances, les cycles, les ID d'étape en double et les identifiants d'utilisation enregistrés.
Expédier les chèques et interpréter leurs preuves
POST /api/projects/:id/actions/dispatch accepte une référence facultative et exécute chaque flux de travail manuel correspondant à cette référence validée. Il ne s'agit pas d'un sélecteur de nom de flux de travail unique. Lire les définitions des actions/flux de travail et les résultats persistants des actions/exécutions. Le service renvoie les dernières 50 exécutions par défaut.
Une exécution enregistre le flux de travail, le déclencheur, la référence, le SHA, les horodatages, le statut et les événements. Les emplois suivent les niveaux de dépendance ; les tâches indépendantes peuvent s'exécuter simultanément, tandis que les étapes d'une tâche sont séquentielles. Les identifiants d'utilisation inconnue échouent avant l'exécution. Une valeur if est le succès, l'échec ou toujours, pas une expression arbitraire. Une dépendance défaillante ignore entièrement sa tâche en aval.
Interprétez attentivement les sorties CAM. cam/verify et cam/gcode inspecter engagé Toolpath.data.request. Les requêtes manquantes, les parcours d'outils non pris en charge ou les CN manquantes peuvent être signalés dans les sorties ignorées. Une exécution réussie avec verify=0 ne constitue pas une preuve de vérification. project/require-gcode vérifie les parcours d'outils existants ; un projet sans parcours d'outils peut le satisfaire de manière vide de sens.
L'intégration automatique du déclencheur HTTP push ne fournit actuellement aucun chemin modifié, donc un filtre de chemins push ne correspond pas à ces événements. Utilisez des filtres de branche uniquement ou une répartition manuelle explicite pour cette intégration. Les événements HTTP live démarrés/terminés sont publiés après le retour de l'exécution synchrone ; utilisez des analyses enregistrées pour des résultats durables.
L'étape du flux de travail d'écriture lit l'état actuel
L'étape vcs/commit actuelle délègue la validation du projet sans protection contre la copie de travail propre. Il valide les ressources de base de données de travail actuelles sur la branche extraite, qui peuvent différer de la référence de l'exécution. Ses fichiers supplémentaires autorisés n’empêchent pas cet effet secondaire d’instantané plus large. Utilisez-le uniquement lorsque cette branche actuelle et cet état de fonctionnement sont destinés à être validés.
Ouvrir, réviser et fusionner une proposition
Ouvrez une pull request locale avec le titre, l'en-tête, le corps facultatif et la base (principale par défaut). La tête et la base doivent différer, et une base contenant déjà la tête n'a rien à fusionner. La réponse inclut un numéro local du projet utilisé par les points de terminaison de révision et de fusion.
curl --fail-with-body \
-H "Authorization: Bearer $CADCAMFUN_TOKEN" -H "Content-Type: application/json" \
--data '{"title":"Review blank label","head":"proposal/blank-label","base":"main","body":"Metadata change and committed checks."}' \
"$CADCAMFUN_URL/api/projects/$PROJECT_ID/pulls" GET /pulls/:number renvoie la demande, les révisions et les modifications. Les avis acceptent les commentaires, approuvent ou demandent des modifications, avec un chemin/pointeur facultatif. Le dernier verdict de non-commentaire par réviseur contrôle le bloc de demande de modification. Un commentaire ultérieur ne l'éclaircit pas ; cet évaluateur doit soumettre un verdict d'approbation mis à jour. L'implémentation n'a aucune exigence de décompte d'approbations positives lorsqu'il ne reste aucun verdict de blocage.
POST /pulls/:number/merge nécessite un accès du responsable. Les acteurs de l'IA ne peuvent pas fusionner dans main. Si la base est extraite, le service nécessite une copie de travail propre et applique l'instantané fusionné à la base de données. Si une autre branche est extraite, elle met à jour la référence de base sans remplacer cette base de données de travail actuelle. Les fusions peuvent avancer rapidement ou créer une validation de fusion ; inspecter l'ascendance plutôt que de supposer qu'il y a deux parents.
Les différences de demande d'extraction fusionnées utilisent la validation de fusion enregistrée, préservant la vue de révision après le déplacement des références. Les demandes d'extraction locales sont des enregistrements d'examen des applications, et non automatiquement des demandes d'extraction GitHub.
Restaurer le contenu sans réécrire l'historique
POST /vcs/restore prend un rev et des chemins facultatifs. Il nécessite un accès du responsable et une copie de travail propre, et crée un nouveau commit contenant le contenu précédent. Il ne réinitialise pas la branche en arrière et n'efface pas les validations intermédiaires. Le service applique ensuite le nouveau HEAD à la base de données de travail.
{
"rev": "earlier-commit-oid",
"paths": ["drawings/actual-drawing-id.json"]
} Remplacez le chemin par une véritable ressource suivie et inspectez d'abord sa différence. L'omission des chemins restaure l'arborescence précédente complète ; qui peut remplacer ou supprimer plusieurs ressources associées. Les instantanés de l'ensemble du projet contiennent également des éléments de bibliothèque et des coûts référencés afin que les parcours d'outils restaurés puissent conserver les dépendances. La restauration de la version des ressources et la restauration de l'historique du projet ont des portées différentes.
Après avoir restauré la source de fabrication, vérifiez si la sortie native enregistrée correspond toujours à la révision du dessin prévue. Une opération d'historique préserve l'artefact antérieur ; cela ne transforme pas cet artefact en preuve d’un dessin nouvellement modifié.
Reflétez l’histoire engagée et récupérez les conflits
Un miroir GitHub est facultatif. Définissez Remote sur une chaîne de propriétaire/dépôt avec PUT /vcs/remote ou null pour le détacher. Push et pull utilisent le jeton GitHub de l'utilisateur dans x-github-token pour cet appel ; il n'est pas enregistré dans le projet JSON. L'accès du responsable est requis pour ces opérations HTTP.
Push télécharge les objets accessibles et refuse d'écraser les validations à distance non extraites. Pull nécessite une copie de travail propre, récupère la branche distante et fusionne. Un conflit JSON structurel identifie les chemins et les pointeurs sans écrire de validation de fusion de référentiel partielle. Inspectez les deux côtés, créez une résolution délibérée et réessayez au lieu de forcer un côté sur l’autre.
HTTP 409 signifie généralement un état sale ou un conflit de fusion ; 403 peut signifier une restriction du responsable ou de l'IA principale ; 404 peut signifier un projet inaccessible ou une révision inconnue ; 400 couvre les noms non valides, les messages vides ou aucune modification. Une défaillance de la base de données correspond à une erreur de stockage du serveur. Conservez les OID et le message d’échec lors du diagnostic d’une incompatibilité.
Provenance des sources : packages/vcs/src/repository.ts, json.ts, snapshot.ts, github.ts; apps/sidecar/src/services/project-vcs.ts, repos/project-vcs-repo.ts, et http/vcs.ts; schéma/exécuteur de workflow dans packages/workflow/src et sidecar workflow-runner.ts/workflow-steps.ts.
Comment les avis décident d'une fusion
- Ouvrez une pull request depuis une branche de fonctionnalités (un acteur IA doit utiliser un
ai/*succursale) dansmain. - Les évaluateurs soumettent
comment,approve, ourequest-changes, éventuellement ancré à un fichierpathet un JSONpointer. - Au moment de la fusion, le service prend le dernier verdict de non-commentaire de chaque réviseur. Si l'un d'entre eux est
request-changes, la fusion échoue avecblocked: "Un évaluateur a demandé des modifications". - Si la branche de base est extraite, sa copie de travail doit être vierge.
- La fusion est à trois voies par propriété JSON. Les conflits sont renvoyés avec leurs chemins et leurs pointeurs, et rien n'est commis.
- Flux de travail avec
on.pullRequestcorrespondant à la branche de base exécutée lorsque la demande d'extraction est ouverte, afin que leurs résultats soient disponibles lors de l'examen.
| Situation | Ce qu'il faut faire |
|---|---|
blocked pour un acteur de l'IA sur main | S'engager sur un ai/* créer une branche et ouvrir une pull request ; une personne le fusionne. |
conflict sur /width de drawings/d1.json | Décidez de la valeur sur une branche, validez et fusionnez à nouveau. |
dirty | Validez ou supprimez d'abord les modifications locales ; les étapes automatisées n’absorbent jamais le travail inachevé. |
nothing-to-commit | Les ressources enregistrées correspondent déjà au dernier commit. |
Restaurer les recettes
// Bring back one drawing as it was three commits ago
const old = repo.log()[3].oid
repo.restorePaths(old, ["drawings/d1.json"], me, "Restore plate outline")
// Make the whole tree equal to an older commit (a new commit on top)
repo.revertTo(old, me) // message defaults to "Restore <rev>"
// Who changed a toolpath, most recent first
repo.fileLog("toolpaths/op1.json").map((e) => e.message) Les deux opérations de restauration ajoutent une nouvelle validation, de sorte que l'ancien état peut lui-même être annulé et que l'historique reste partageable. La restauration d'un fichier de parcours d'outil sans le matériau ou l'outil auquel il fait référence peut laisser des références en suspens ; restaurez ces fichiers de bibliothèque dans le même appel.
Une séance de révision complète, capturée
Chaque réponse ci-dessous a été capturée à partir d'un sidecar en cours d'exécution sur un nouveau projet (identifiants raccourcis). Les chemins sont relatifs à /api/projects/{id}/.
# fresh project with one drawing
GET vcs/status
{"branch":"main","head":null,"dirty":["drawings/2f315a02-….json","project.json"]}
POST vcs/commit {"message":"Baseline"}
{"oid":"8bdded63…","parents":[],"message":"Baseline\n","author":{"name":"Local user",…}}
POST vcs/branches {"name":"thicker"}
{"current":"main","branches":{"main":"8bdded63…","thicker":"8bdded63…"}}
POST vcs/checkout {"branch":"thicker"}
{"branch":"thicker","head":"8bdded63…","dirty":[]}
PUT /api/drawings/{id} {"name":"Plate 12mm"}
GET vcs/status
{"branch":"thicker","head":"8bdded63…","dirty":["drawings/2f315a02-….json"]}
POST vcs/commit {"message":"Rename plate"}
{"oid":"a6869011…","parents":["8bdded63…"],…}
GET vcs/diff?from=main&to=thicker
[{"path":"drawings/2f315a02-….json","kind":"drawings","id":"2f315a02-…","name":"Plate 12mm",
"status":"modified","changes":[
{"pointer":"/name","before":"Plate","after":"Plate 12mm"},
{"pointer":"/updatedAt","before":"…09:20.069Z","after":"…09:20.168Z"}]}]
POST pulls {"title":"Thicker plate","head":"thicker","base":"main"}
{"number":1,"state":"open","authorKind":"user","mergeCommit":null,…}
POST pulls/1/reviews {"verdict":"approve","body":"Looks good"}
{"verdict":"approve","body":"Looks good","path":null,"pointer":null,…}
POST pulls/1/merge
{"number":1,"state":"merged","mergeCommit":"a6869011…",…}
POST pulls/1/merge (again)
{"_tag":"BadRequest","message":"Pull request is not open"} | Ce que tu vois | Ce que cela signifie |
|---|---|
head: null avant le premier commit | Le référentiel existe mais n'a pas encore de validation ; chaque ressource est sale |
Des chemins sales tels que drawings/<id>.json, project.json | La copie de travail est sérialisée sous la forme d'un fichier JSON par ressource |
| Une nouvelle succursale pointe vers la tête actuelle | Sans from, la branche commence à la tête actuelle |
| Les changements de différence sont des pointeurs JSON | Les modifications sont signalées par propriété (/name), pas par ligne |
updatedAt a également changé | Les horodatages sont versionnés avec la ressource, donc chaque sauvegarde apparaît |
mergeCommit est égal à la tête de branche | main n'avait pas bougé, donc la fusion a avancé rapidement |
| Fusionner deux fois → 400 | Seules les demandes d'extraction ouvertes peuvent être fusionnées ou fermées |
Champs de révision et de requête
| Demande | Champs |
|---|---|
POST pulls/{number}/reviews | verdict (requis): comment, approve ou request-changes; facultatif body, et path + pointer pour ancrer l'avis sur une propriété. Tout autre verdict est rejeté avec 400. |
GET pulls/{number} | Retours pullRequest, c'est reviews et la structure changes entre la base et la tête |
GET pulls?state=… | Filtrer la liste par état |
GET vcs/log?rev=&limit=&path= | Historique d'une révision, limité, éventuellement pour un chemin de ressource |
GET vcs/diff?from=&to= | Différent structurel entre deux révisions ou branches |
POST vcs/restore | rev (obligatoire), facultatif paths. Une révision inconnue répond 404 Unknown revision <rev>. |
GET/PUT vcs/remote, POST vcs/push, POST vcs/pull | Configurez la télécommande miroir et poussez ou tirez une branche |