Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Requise pour toute modification de documentation :
Requise si la PR ne concerne pas uniquement la documentation :

- [ ] `npm ci --no-audit --no-fund` réussit sans modifier le lockfile.
- [ ] `npm run check` réussit.
- [ ] `npm run check` réussit, y compris le build et les tests du GUI.
- [ ] Aucun changement involontaire n'apparaît dans les profils générés.
- [ ] Le GUI a été testé sans erreur ni avertissement inattendu dans la console,
s'il est affecté.
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
with:
node-version: 22
cache: npm
cache-dependency-path: |
package-lock.json
prototype/package-lock.json
- name: Install locked dependencies
run: npm ci --no-audit --no-fund
- name: Validate manifests, documentation and tests
Expand Down
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,13 @@
/work/
node_modules/
*.log

# Local GUI builds and design-review artifacts
/prototype/dist/
/prototype/audit-ux-ui/
/prototype/design-reference/
/prototype/qa/
/prototype/design-qa.md
/prototype/public/assets/ai-controller-generated*.png
/prototype/public/assets/ai-controller-glass-v3.png
/prototype/public/assets/glass-background-v1.png
40 changes: 34 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Le dépôt contient désormais :
- un manifeste portable V1 et des schémas réutilisables ;
- un mapping physique Claude avec couleur, cadran, joystick et AppSense ;
- une représentation SVG originale du Codex Micro ;
- un configurateur graphique local lancé par `npm run configure` ;
- un outil Node.js de diagnostic, inventaire, sauvegarde, dry-run, sanitation et
rollback ;
- un générateur local de profile Input `0.17.3` qui préserve le layer natif et
Expand All @@ -44,9 +45,11 @@ L'analyse du package officiel confirme des commandes **Import layer** et
attendue. Le vrai fichier Claude n'est volontairement pas fabriqué : ses objets
internes doivent provenir d'un export réel du Codex Micro.

Le preset est `hardware-observed` : le générateur a été validé sur un export
Input `0.17.3`, mais le round-trip d'un artefact `*-layer.json` et la checklist
matérielle complète restent ouverts.
Le manifeste V1 est `hardware-observed` : le générateur a été validé sur un
export Input `0.17.3`, mais le round-trip d'un artefact `*-layer.json` et la
checklist matérielle complète restent ouverts. Le fichier logique
`macos.example.json` reste séparément `proposal-not-applied` : ce n'est pas un
preset universel à importer.

## Mapping Claude proposé

Expand All @@ -69,6 +72,10 @@ AppSense et `Auto detect`.

![Mapping physique Claude](profiles/claude-shortcuts/assets/layout.svg)

Les raccourcis globaux de Claude restent hors du layer AppSense : double appui
sur Option pour la saisie rapide et Verr. Maj. pour la dictée globale. Ils
doivent rester disponibles quand une autre application est au premier plan.

## Ce qui est interdit par défaut

- Retour/Entrée et envoi de message ;
Expand All @@ -93,6 +100,23 @@ actif.
Voir la [matrice de compatibilité](docs/compatibility.md) pour distinguer les
faits, tests de fixture et validations matérielles manquantes.

## Configurateur graphique

```sh
npm run configure
```

La première ouverture peut installer les dépendances verrouillées du GUI, puis
lance l'interface uniquement sur `127.0.0.1` et ouvre le navigateur.

Le parcours demande un export officiel Work Louder Input qui contient
exactement un layer `Claude`, hors index `0`, déjà lié à Claude Desktop avec
AppSense. L'utilisateur peut vérifier et personnaliser les quatre touches, le
cadran et le joystick, puis télécharger son propre
`Claude-macOS-profile.json`. Le fichier source, le layer natif, les autres
layers et les autres liens AppSense sont conservés. Le JSON logique public
n'est jamais présenté comme directement importable.

## Démarrage sans modification

Prérequis : Node.js 18 ou version ultérieure. Les dépendances de validation
Expand Down Expand Up @@ -168,13 +192,17 @@ profiles/
assets/layout.svg aperçu original
artifacts/ futur export officiel assaini
scripts/
configure.mjs lancement local du configurateur graphique
prepare-gui.mjs préparation verrouillée des dépendances du GUI
build-input-profile.mjs génération locale du profile importable
input-layer.mjs diagnostic, sauvegarde et installation guidée
lib/ fonctions de validation et de preset
validate-profile.mjs contrat logique Claude historique
validate-presets.mjs invariants de la bibliothèque
prototype/
src/ interface locale du configurateur
shared/
input-profile.mjs transformation canonique partagée avec le GUI
lib/ fonctions testables
validate-profile.mjs contrat Claude historique
validate-presets.mjs invariants de la bibliothèque
tests/
input-layer.test.mjs sauvegarde, rollback, sanitation et idempotence
docs/
Expand Down
12 changes: 8 additions & 4 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,17 @@ Tant que la piste n'est pas auditée :
## Dépendances et scripts

Le projet ne transmet pas les profils ou exports Work Louder à un service
distant. Le générateur et les validateurs les traitent localement.
distant. Le configurateur, le générateur et les validateurs les traitent
localement, sans télémétrie applicative.

Une connexion réseau peut toutefois être utilisée par
`npm ci --no-audit --no-fund` pour télécharger depuis le registre configuré les
versions verrouillées dans `package-lock.json`. Toute nouvelle dépendance ou
communication distante doit être justifiée, verrouillée, documentée et auditée
avant publication.
versions verrouillées dans `package-lock.json`. Lors de leur première
exécution, `npm run configure` et `npm run check` peuvent de même lancer
`npm ci --ignore-scripts` dans `prototype/` si les dépendances du GUI sont
absentes. Une fois installées, le traitement des profils reste local. Toute
nouvelle dépendance ou communication distante doit être justifiée, verrouillée,
documentée et auditée avant publication.

## Sauvegarde et restauration

Expand Down
11 changes: 9 additions & 2 deletions docs/codex-micro/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
Cette intégration utilise les raccourcis HID et AppSense. Elle ne dépend pas du
protocole expérimental Hardware Buddy.

Le manifeste et le mapping V1 décrivent l'état observé du générateur. Le fichier
logique `macos.example.json` reste `proposal-not-applied` et ne doit pas être
importé tel quel. `npm run configure` fabrique uniquement un profile personnel
à partir de l'export officiel de l'utilisateur.

## Préservation obligatoire

Le preset et l'outil imposent les règles suivantes :
Expand Down Expand Up @@ -83,10 +88,12 @@ obligatoire : il ne doit pas être supposé à partir de la seule documentation.
- `git push` ;
- déploiement ;
- terminal, shell ou commande destructive ;
- raccourci global Saisie rapide.
- raccourcis globaux Saisie rapide et Dictée.

Les raccourcis globaux sont volontairement hors du layer AppSense : ils doivent
rester utilisables quand une autre application est au premier plan.
rester utilisables quand une autre application est au premier plan. Sur la
configuration documentée, il s'agit du double appui sur Option pour la saisie
rapide et de Verr. Maj. pour la dictée globale.

## Partage officiel observé

Expand Down
23 changes: 23 additions & 0 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,29 @@ layer dans une copie et produit un nouveau `*-profile.json`.
Il ne clique jamais à votre place, ne lance pas `Reset settings`, ne flashe
aucun firmware et ne modifie aucun raccourci système.

## Parcours GUI recommandé

Depuis la racine du dépôt :

```sh
npm run configure
```

La première ouverture peut préparer les dépendances verrouillées de
`prototype/`. Le configurateur s'ouvre ensuite localement dans le navigateur.

1. exporter le profile actif depuis Work Louder Input ;
2. déposer ce `*-profile.json` dans le configurateur ;
3. vérifier l'unique layer `Claude`, son lien AppSense et l'index natif `0` ;
4. personnaliser les quatre touches, le cadran et le joystick ;
5. télécharger `Claude-macOS-profile.json` ;
6. l'importer avec **Add New**, sans remplacer le profile source.

La génération refuse un mauvais appareil, un layer Claude absent ou dupliqué,
une cible à l'index `0` et un lien AppSense manquant. Elle conserve le layer
natif, les autres layers, les autres profils et les autres liens AppSense. Le
reste de ce guide décrit le même parcours avec les contrôles CLI détaillés.

## 1. Vérifier le dépôt

Depuis la copie locale :
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
"node": ">=18"
},
"scripts": {
"configure": "node scripts/configure.mjs",
"build:profile": "node scripts/build-input-profile.mjs",
"validate": "node scripts/validate-profile.mjs && node scripts/validate-presets.mjs && node scripts/check-doc-links.mjs",
"test": "node --test",
"check": "npm run validate && npm test"
"test": "node --test tests/*.test.mjs",
"prepare:gui": "node scripts/prepare-gui.mjs",
"build:gui": "npm run prepare:gui && npm --prefix prototype run build",
"test:gui": "npm --prefix prototype run test:sites",
"check": "npm run validate && npm test && npm run build:gui && npm run test:gui"
},
"devDependencies": {
"ajv": "8.17.1"
Expand Down
24 changes: 20 additions & 4 deletions profiles/claude-shortcuts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ lié avec AppSense et distinct du layer Codex natif protégé à l'index `0`.
- validation complète de toutes les commandes, de la perte de focus et du
rollback matériel : **encore requise**.

Le statut reste `hardware-observed`. Aucun artefact layer ne doit être présenté
comme prêt à l'emploi avant le round-trip matériel et la vérification de son
SHA-256.
Le manifeste V1 reste `hardware-observed`. Le contrat logique
`macos.example.json` reste séparément `proposal-not-applied`. Aucun des deux ne
doit être présenté comme un fichier universel prêt à importer, et aucun
artefact layer ne doit être publié avant le round-trip matériel et la
vérification de son SHA-256.

## Fichiers

```text
manifest.json identité, compatibilité, preuve et installation
mapping.json mapping physique et règles de sécurité
macos.example.json contrat logique historique, aligné sur la V1
macos.example.json proposition logique V0 non importable
schema.json schéma du contrat historique
assets/layout.svg représentation originale du clavier
artifacts/README.md porte d'entrée du futur export officiel
Expand Down Expand Up @@ -64,6 +66,20 @@ com.anthropic.claudefordesktop
La politique exige exactement un layer Claude et conserve son `linkedAppId`.
L'outil ne crée pas de second lien et ne modifie jamais les autres liens.

## Configurateur local

```sh
npm run configure
```

Le GUI charge un export officiel appartenant à l'utilisateur, permet de
personnaliser les contrôles sûrs et génère un nouveau
`Claude-macOS-profile.json`. Seul ce fichier personnel est destiné au flux
**Add New** d'Input ; le contrat logique du dépôt ne l'est pas.

Le double appui sur Option pour la saisie rapide et Verr. Maj. pour la dictée
globale restent hors du layer AppSense.

## Sécurité

Le validateur interdit dans les contrôles actifs : Retour/Entrée, envoi,
Expand Down
11 changes: 8 additions & 3 deletions profiles/claude-shortcuts/macos.example.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "./schema.json",
"id": "claude-desktop-macos-codex-micro-v1",
"status": "hardware-observed",
"id": "claude-desktop-macos-codex-micro-v0",
"status": "proposal-not-applied",
"target": {
"platform": "macOS",
"appBundleId": "com.anthropic.claudefordesktop",
Expand All @@ -14,7 +14,7 @@
"preservation": {
"mode": "update-only-existing-layer",
"protectedLayerIndexes": [0],
"unlistedControls": "no-action-in-new-layer",
"unlistedControls": "no-action-in-target-layer",
"touchLayerControl": "reserved",
"otherLayers": "unchanged",
"otherProfiles": "unchanged",
Expand Down Expand Up @@ -128,6 +128,11 @@
"action": "quick-entry",
"documentedShortcut": "DoublePressOption",
"reason": "Must remain reachable while another application is in the foreground."
},
{
"action": "voice-dictation",
"documentedShortcut": "CapsLock",
"reason": "Claude global dictation must remain independent from the AppSense-linked layer."
}
],
"excludedByDefault": [
Expand Down
66 changes: 53 additions & 13 deletions profiles/claude-shortcuts/schema.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/thannous/claude-codex-micro/raw/main/profiles/claude-shortcuts/schema.json",
"title": "Codex Micro Claude shortcut profile v1",
"title": "Codex Micro Claude logical shortcut proposal v0",
"type": "object",
"additionalProperties": false,
"required": [
Expand All @@ -19,8 +19,8 @@
],
"properties": {
"$schema": { "type": "string" },
"id": { "const": "claude-desktop-macos-codex-micro-v1" },
"status": { "const": "hardware-observed" },
"id": { "const": "claude-desktop-macos-codex-micro-v0" },
"status": { "const": "proposal-not-applied" },
"target": {
"type": "object",
"additionalProperties": false,
Expand Down Expand Up @@ -68,7 +68,7 @@
"minContains": 1,
"uniqueItems": true
},
"unlistedControls": { "const": "no-action-in-new-layer" },
"unlistedControls": { "const": "no-action-in-target-layer" },
"touchLayerControl": { "const": "reserved" },
"otherLayers": { "const": "unchanged" },
"otherProfiles": { "const": "unchanged" },
Expand Down Expand Up @@ -168,16 +168,56 @@
},
"outsideAppLinkedLayer": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["action", "documentedShortcut", "reason"],
"properties": {
"action": { "const": "quick-entry" },
"documentedShortcut": { "const": "DoublePressOption" },
"reason": { "type": "string", "minLength": 1 }
"minItems": 2,
"maxItems": 2,
"uniqueItems": true,
"allOf": [
{
"contains": {
"type": "object",
"required": ["action"],
"properties": {
"action": { "const": "quick-entry" }
}
},
"minContains": 1,
"maxContains": 1
},
{
"contains": {
"type": "object",
"required": ["action"],
"properties": {
"action": { "const": "voice-dictation" }
}
},
"minContains": 1,
"maxContains": 1
}
],
"items": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"required": ["action", "documentedShortcut", "reason"],
"properties": {
"action": { "const": "quick-entry" },
"documentedShortcut": { "const": "DoublePressOption" },
"reason": { "type": "string", "minLength": 1 }
}
},
{
"type": "object",
"additionalProperties": false,
"required": ["action", "documentedShortcut", "reason"],
"properties": {
"action": { "const": "voice-dictation" },
"documentedShortcut": { "const": "CapsLock" },
"reason": { "type": "string", "minLength": 1 }
}
}
]
}
},
"excludedByDefault": {
Expand Down
2 changes: 2 additions & 0 deletions prototype/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fund=false
audit=false
4 changes: 4 additions & 0 deletions prototype/.openai/hosting.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"d1": null,
"r2": null
}
Loading
Loading