wherdr 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{lBx2yXX9.js → 4gY2mLGX.js} +12 -12
- package/.output/public/_nuxt/4gY2mLGX.js.br +0 -0
- package/.output/public/_nuxt/4gY2mLGX.js.gz +0 -0
- package/.output/public/_nuxt/{xSo3mAHb.js → B8eSr-59.js} +1 -1
- package/.output/public/_nuxt/B8eSr-59.js.br +0 -0
- package/.output/public/_nuxt/B8eSr-59.js.gz +0 -0
- package/.output/public/_nuxt/{JL_QI6J1.js → BsbsvkAK.js} +1 -1
- package/.output/public/_nuxt/BsbsvkAK.js.br +0 -0
- package/.output/public/_nuxt/BsbsvkAK.js.gz +0 -0
- package/.output/public/_nuxt/{CBJ483HL.js → CML5cHwz.js} +1 -1
- package/.output/public/_nuxt/CN39A7L5.js +3 -0
- package/.output/public/_nuxt/CN39A7L5.js.br +0 -0
- package/.output/public/_nuxt/CN39A7L5.js.gz +0 -0
- package/.output/public/_nuxt/{DNAl4698.js → CfQgQDOp.js} +7 -7
- package/.output/public/_nuxt/CfQgQDOp.js.br +0 -0
- package/.output/public/_nuxt/CfQgQDOp.js.gz +0 -0
- package/.output/public/_nuxt/{B8pUlE1v.js → CoRTPMqP.js} +43 -41
- package/.output/public/_nuxt/CoRTPMqP.js.br +0 -0
- package/.output/public/_nuxt/CoRTPMqP.js.gz +0 -0
- package/.output/public/_nuxt/{XlRX1U8d.js → CvGCN0_f.js} +1 -1
- package/.output/public/_nuxt/CvGCN0_f.js.br +0 -0
- package/.output/public/_nuxt/CvGCN0_f.js.gz +0 -0
- package/.output/public/_nuxt/{DOnGrCAZ.js → DmYihq1h.js} +1 -1
- package/.output/public/_nuxt/DoX0nZZb.js +105 -0
- package/.output/public/_nuxt/DoX0nZZb.js.br +0 -0
- package/.output/public/_nuxt/DoX0nZZb.js.gz +0 -0
- package/.output/public/_nuxt/{DZGKxROq.js → DuVQjOfc.js} +1 -1
- package/.output/public/_nuxt/DuVQjOfc.js.br +0 -0
- package/.output/public/_nuxt/DuVQjOfc.js.gz +0 -0
- package/.output/public/_nuxt/{board.B8JX7Yhy.css → board.CeTYM1XN.css} +1 -1
- package/.output/public/_nuxt/board.CeTYM1XN.css.br +0 -0
- package/.output/public/_nuxt/{board.B8JX7Yhy.css.gz → board.CeTYM1XN.css.gz} +0 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/fd79ea32-8bac-487a-afa1-7a6e336fff3f.json +1 -0
- package/.output/public/_nuxt/{entry.6CUQ3EoD.css → entry.Cd2iNkBC.css} +1 -1
- package/.output/public/_nuxt/entry.Cd2iNkBC.css.br +0 -0
- package/.output/public/_nuxt/{entry.6CUQ3EoD.css.gz → entry.Cd2iNkBC.css.gz} +0 -0
- package/.output/public/_nuxt/hSqNtAW9.js +25 -0
- package/.output/public/_nuxt/hSqNtAW9.js.br +0 -0
- package/.output/public/_nuxt/hSqNtAW9.js.gz +0 -0
- package/.output/public/_nuxt/o1wml4Rx.js +31 -0
- package/.output/public/_nuxt/o1wml4Rx.js.br +0 -0
- package/.output/public/_nuxt/o1wml4Rx.js.gz +0 -0
- package/.output/public/sw.js +1 -1
- package/.output/server/chunks/_/package.mjs +1 -1
- package/.output/server/chunks/nitro/nitro.mjs +441 -429
- package/.output/server/chunks/routes/renderer.mjs +1 -1
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/package.json +1 -1
- package/docs/README.md +2 -0
- package/docs/configuration.md +9 -0
- package/docs/release-notes-2.2.0.md +19 -0
- package/package.json +1 -1
- package/.output/public/_nuxt/B8pUlE1v.js.br +0 -0
- package/.output/public/_nuxt/B8pUlE1v.js.gz +0 -0
- package/.output/public/_nuxt/Bo4dpAxE.js +0 -31
- package/.output/public/_nuxt/Bo4dpAxE.js.br +0 -0
- package/.output/public/_nuxt/Bo4dpAxE.js.gz +0 -0
- package/.output/public/_nuxt/CJF9DrFj.js +0 -25
- package/.output/public/_nuxt/CJF9DrFj.js.br +0 -0
- package/.output/public/_nuxt/CJF9DrFj.js.gz +0 -0
- package/.output/public/_nuxt/DNAl4698.js.br +0 -0
- package/.output/public/_nuxt/DNAl4698.js.gz +0 -0
- package/.output/public/_nuxt/DR832Br-.js +0 -3
- package/.output/public/_nuxt/DR832Br-.js.br +0 -0
- package/.output/public/_nuxt/DR832Br-.js.gz +0 -0
- package/.output/public/_nuxt/DZGKxROq.js.br +0 -0
- package/.output/public/_nuxt/DZGKxROq.js.gz +0 -0
- package/.output/public/_nuxt/DclfLrr5.js +0 -105
- package/.output/public/_nuxt/DclfLrr5.js.br +0 -0
- package/.output/public/_nuxt/DclfLrr5.js.gz +0 -0
- package/.output/public/_nuxt/JL_QI6J1.js.br +0 -0
- package/.output/public/_nuxt/JL_QI6J1.js.gz +0 -0
- package/.output/public/_nuxt/XlRX1U8d.js.br +0 -0
- package/.output/public/_nuxt/XlRX1U8d.js.gz +0 -0
- package/.output/public/_nuxt/board.B8JX7Yhy.css.br +0 -0
- package/.output/public/_nuxt/builds/meta/1d193254-809f-48d8-bf27-3640edb58f54.json +0 -1
- package/.output/public/_nuxt/entry.6CUQ3EoD.css.br +0 -0
- package/.output/public/_nuxt/lBx2yXX9.js.br +0 -0
- package/.output/public/_nuxt/lBx2yXX9.js.gz +0 -0
- package/.output/public/_nuxt/xSo3mAHb.js.br +0 -0
- package/.output/public/_nuxt/xSo3mAHb.js.gz +0 -0
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import{A as e,An as t,Dn as n,Fn as r,Mn as i,nn as a,o,yn as s}from"./C25ROUa9.js";import"./CXJnLmWv.js";var c=globalThis.setInterval,l=`wherdr:chunk-reload`;function u(e,t){if(!e||!t||typeof t!=`object`)return!1;let n=t.id;return typeof n==`string`&&n!==``&&n!==e}function d(e,t){return e?t?`activate`:`banner`:`none`}function f(e){let t=e instanceof Error?e.message:typeof e==`string`?e:``;return/Failed to fetch dynamically imported module|Importing a module script failed|error loading dynamically imported module|Unable to preload CSS/i.test(t)}function ee(e,t){if(!e)return!1;try{let n=Number(e.getItem(l)||0);return n&&t-n<3e4?!1:(e.setItem(l,String(t)),!0)}catch{return!1}}var te=i(!1),ne=i(!1),re=null,ie=!1,ae=!0;function oe(){te.value=!0}function se(e,t){e?.addEventListener(`statechange`,()=>{if(e.state!==`installed`)return;let n=d(!!navigator.serviceWorker.controller,t);n===`activate`?e.postMessage({type:`skip-waiting`}):n===`banner`&&oe()})}function ce(){`serviceWorker`in navigator&&navigator.serviceWorker.register(`/sw.js`).then(e=>{re=e,e.waiting?.postMessage({type:`skip-waiting`}),se(e.installing,!0),e.addEventListener(`updatefound`,()=>se(e.installing,ae)),le()}).catch(()=>{})}async function le(){try{let e=await fetch(`/_nuxt/builds/latest.json?${Date.now()}`,{cache:`no-store`});if(!e.ok||!u(o().app.buildId,await e.json()))return;let t=null;try{t=sessionStorage}catch{}ee(t,Date.now())?de():oe()}catch{}}async function ue(){if(!te.value){try{let e=await fetch(`/_nuxt/builds/latest.json?${Date.now()}`,{cache:`no-store`});e.ok&&u(o().app.buildId,await e.json())&&oe()}catch{}ae=!1;try{await re?.update()}catch{}}}async function de(e){if(ie)return;ie=!0;let t=re?.installing;t&&await new Promise(e=>{let n=setTimeout(e,5e3);t.addEventListener(`statechange`,()=>{t.state!==`installing`&&(clearTimeout(n),e())})});let n=re?.waiting;n&&`serviceWorker`in navigator&&await new Promise(e=>{let t=setTimeout(e,3e3);navigator.serviceWorker.addEventListener(`controllerchange`,()=>{clearTimeout(t),e()},{once:!0}),n.postMessage({type:`skip-waiting`})}),e!==void 0&&location.hash!==e&&location.replace(location.pathname+location.search+e),location.reload()}function fe(e){return String(e||``).replace(/```[^\n]*\n?/g,` `).replace(/!\[([^\]]*)\]\([^)]*\)/g,`$1`).replace(/\[([^\]]*)\]\([^)]*\)/g,`$1`).replace(/^\s{0,3}(#{1,6}\s+|>\s?|[-*+]\s+|\d+[.)]\s+)/gm,``).replace(/(\*\*|__|\*|_|`|~~)/g,``).replace(/[«»“”"]/g,`'`).replace(/\s+/g,` `).trim()}function pe(e,t){if(e.length<=t)return e;let n=e.slice(0,Math.max(1,t-1)),r=n.lastIndexOf(` `);return`${(r>t*.6?n.slice(0,r):n).replace(/[\s,;:.]+$/,``)}…`}function me(e,t){if(e.length<=t)return e;let n=t-2,r=pe(e,Math.ceil(n/2)+1).replace(/…$/,``),i=e.slice(e.length-(n-r.length)),a=i.indexOf(` `);return a>=0&&a<i.length*.4&&(i=i.slice(a+1)),`${r}… ${i.replace(/^[\s,;:.]+/,``)}`}var he=/^↳ (?:En réponse à ton message de|Replying to your message from) (\d{1,2}[:h.]\d{2}(?:\s?[AaPp][Mm])?) \((?:« (.*) »|"(.*)")\)[ \t]*(?:\r?\n|$)/;function ge(e){let t=he.exec(String(e||``));if(!t)return null;let n=t[2]??t[3]??``;return{reply:{time:t[1],excerpt:n},body:e.slice(t[0].length).replace(/^\s*\n/,``).trim()}}var _e=e=>fe(e).toLowerCase();function ve(e,t,n=e.length){let r=_e(t.excerpt.split(`…`)[0]).slice(0,60),i=e.slice(0,n).reverse(),a=e=>!!r&&_e(e.text).includes(r),o=t.id?i.filter(e=>e.rid===t.id):[];return o.find(e=>e.time===t.time)||o[0]||i.find(e=>e.time===t.time&&a(e))||i.find(a)||i.find(e=>e.time===t.time)||null}var ye=/^↳ (?:en réponse à ton message de|replying to your message from) .*?(?: »|")\)\s*/,be=String.raw`\d{1,2}[:h.]\d{2}(?:\s?[AaPp][Mm])?`,xe=3,Se=RegExp(`^(↳ Quote (message|point|decisions?)(?: (${be}))?(?: #(\\S+))?(?: ~([0-9a-z]{${xe}}\\d*))? : )(\\S.*?)( —[ \\t]*)$`),Ce=[`Decision:`,`Décision :`,`Problem:`,`Problème :`,`Question:`,`Question :`,`Detail on`,`Précision sur`,`Feedback on`,`Retour sur`],we=RegExp(`^(↳ (${Ce.join(`|`)}) )(\\S.*?)( —[ \\t]*)$`),Te=e=>String(e||``).replace(/\s+/g,` `).trim(),Ee=e=>Te(e||``)||null;function De(e){let t=`${e.ts||``}|${e.text.slice(0,32)}`,n=2166136261;for(let e=0;e<t.length;e++)n=Math.imul(n^t.charCodeAt(e),16777619);return((n>>>0)%36**xe).toString(36).padStart(xe,`0`)}var Oe=(e,t=1)=>e&&t>1?`${e}${t}`:e||null,ke=e=>e.slice(0,xe);function Ae(e,t,n){return{kind:`message`,label:``,time:Ee(t),n:null,id:n||null,excerpt:pe(fe(e),80)||`…`}}function je(e,t,n){return{kind:`point`,label:``,time:Ee(t),n:null,id:n||null,excerpt:me(Te(e),120)}}function Me(e,t,n,r=!1,i){let a=r?pe(Te(t),80):me(Te(t),120);return{kind:r?`decisions`:`decision`,label:``,time:Ee(n),n:e.replace(/\s+/g,``),id:i||null,excerpt:a}}function Ne(e){return e.excerpt?e.kind===`task`?`↳ ${e.label} ${e.excerpt} —`:`↳ Quote ${e.kind}${e.time?` ${e.time}`:``}${e.n?` #${e.n}`:``}${e.id?` ~${e.id}`:``} : ${e.excerpt} —`:``}function Pe(e){let t=Se.exec(e);if(t){let e=t[2];return(e===`decision`||e===`decisions`)==!!t[4]?{ref:{kind:e,label:``,time:Ee(t[3]),n:t[4]??null,id:t[5]??null,excerpt:t[6]},head:t[1],tail:t[7]}:null}let n=we.exec(e);return n?{ref:{kind:`task`,label:n[2],time:null,n:null,id:null,excerpt:n[3]},head:n[1],tail:n[4]}:null}var Fe=e=>Pe(e)?.ref??null,Ie=e=>Pe(e)!==null,p=e=>Te(e||``).toLowerCase();function Le(e,t){return e.kind===t.kind&&p(e.label)===p(t.label)&&p(e.n)===p(t.n)&&p(e.excerpt)===p(t.excerpt)&&(e.id&&t.id?e.id===t.id:!e.time||!t.time||e.time===t.time)}function Re(e){let t=[],n=0,r=String(e||``);for(let e of r.split(`
|
|
2
|
-
`)){let i=e.startsWith(`↳`)?Fe(e):null;i&&t.push({...i,start:n,end:Math.min(r.length,n+e.length+1)}),n+=e.length+1}return t}function ze(e){return e.includes(`↳`)?e.split(`
|
|
3
|
-
`).map(e=>e.startsWith(`↳`)&&Ie(e.replace(/\r$/,``))?`\\${e}`:e).join(`
|
|
4
|
-
`):e}var Be=RegExp(`^↳ (?:quote (?:message|point|decisions?)|${Ce.join(`|`).toLowerCase()}) .*? —(?:\\s+|$)`);function Ve(e){let t=Be.exec(e)||ye.exec(e);return t?{ref:t[0].replace(/\s+/g,``),words:e.slice(t[0].length)}:{ref:``,words:e}}function He(e,t,n){let r=Ve(e),i=Ve(t);return!r.ref||!i.ref?n(e,t):r.ref===i.ref&&(r.words||i.words?n(r.words,i.words):!0)}var Ue=/^>(?:\s|$)(.*)$/;function We(e){let t=[];for(let n of String(e||``).split(`
|
|
5
|
-
`)){let e=n.startsWith(`↳`)?Fe(n):null;if(e){t.push({kind:`ref`,ref:e});continue}let r=Ue.exec(n),i=r?`quote`:`text`,a=r?r[1]:n,o=t.at(-1);o&&o.kind===i?o.text+=`\n${a}`:t.push({kind:i,text:a})}return t}function Ge(e){let t=String(e||``),n=t.indexOf(`~`);return n<0?{machine:``,local:t}:{machine:t.slice(0,n),local:t.slice(n+1)}}var Ke=e=>Ge(String(e||``)).machine,qe=`Name: use at least one letter or digit`,Je={ß:`ss`,æ:`ae`,œ:`oe`,ø:`o`,đ:`d`,ł:`l`,þ:`th`};function Ye(e){let t=String(e??``).normalize(`NFKD`).replace(/\p{M}+/gu,``).toLowerCase();return t=t.replace(/[\u00df\u00e6\u0153\u00f8\u0111\u0142\u00fe]/g,e=>Je[e]),t=t.replace(/[^a-z0-9_-]+/g,`-`).replace(/-{2,}/g,`-`).replace(/^[-_]+|[-_]+$/g,``),t?(/^\d/.test(t)&&(t=`a-${t}`),t.slice(0,32).replace(/[-_]+$/,``)):``}var Xe={Autopilot:`Autopilot`,"Copy message":`Copier le message`,"Edit description":`Modifier`,"Invalid description":`Description invalide`,"Archived tasks are read-only":`Les tâches archivées sont en lecture seule`,Handovers:`Reprises`,Reviewer:`Relecteur`,"Previous agent":`Agent précédent`,"Taken over by":`Repris par`,"Machine time zone unavailable; using UTC":`Fuseau de la machine indisponible ; utilisation d’UTC`,"Autopilot unavailable":`Autopilot indisponible`,"Automations unavailable":`Automations indisponibles`,"Session timers unavailable":`Minuteurs de session indisponibles`,"Invalid attempt choice":`Choix d’essai invalide`,"This attempt cannot be chosen":`Cet essai ne peut pas être sélectionné`,"Too many exceptions. Remove an old one first.":`Trop d’exceptions. Retire d’abord une ancienne.`,"All activity":`Toute l’activité`,"Needs you + finished":`Besoin de toi + terminé`,"Needs you":`Besoin de toi`,Muted:`Muet`,Custom:`Personnalisé`,"Nothing.":`Rien.`,"A task or a coordinator is waiting for you.":`Une tâche ou un coordinateur t’attend.`,"Also a finished task, or a coordinator that finished answering you.":`Aussi une tâche terminée, ou un coordinateur qui a fini de te répondre.`,"Also every intermediate message.":`Aussi chaque message intermédiaire.`,"Only the events checked under Customize.":`Seulement les événements cochés sous Personnaliser.`,Customize:`Personnaliser`,Finished:`Terminé`,"New message":`Nouveau message`,"Scheduled task":`Tâche planifiée`,"Mute for 1 hour":`Muet pendant 1 h`,"Mute for 8 hours":`Muet pendant 8 h`,"Notification settings":`Réglages des notifications`,Exception:`Exception`,Default:`Défaut`,Current:`Actuel`,"Task agents follow the Sub-agents switch of the default (or of their coordinator’s exception), never one by one.":`Les agents de tâche suivent l’interrupteur Sous-agents du défaut (ou de l’exception de leur coordinateur), jamais un par un.`,"Turn sub-agents on":`Activer les sous-agents`,"Turn sub-agents off":`Couper les sous-agents`,"Default (applies to everything)":`Par défaut (s’applique à tout)`,"Default level":`Niveau par défaut`,"Sub-agents":`Sous-agents`,"On: task agents (workers, reviewers, attempts) notify too, at the same level.":`Activé : les agents de tâche (agents, relecteurs, tentatives) notifient aussi, au même niveau.`,"Off: only coordinators, standalone agents and board events notify. Task agents stay silent.":`Coupé : seuls les coordinateurs, les agents indépendants et les événements du board notifient. Les agents de tâche restent muets.`,"Visible conversations stay silent on every device. Push resumes after about 30 seconds away. Inactive tabs expire automatically.":`Les conversations visibles restent muettes sur tous les appareils. Les notifications reprennent après environ 30 s d’absence. Les onglets inactifs expirent automatiquement.`,Exceptions:`Exceptions`,"No exceptions: everything follows the default. Add one for a coordinator or an agent, or use Notifications in its menu.":`Aucune exception : tout suit le défaut. Ajoute-en une pour un coordinateur ou un agent, ou passe par Notifications dans son menu.`,"On: the task agents of this board follow this exception.":`Activé : les agents de tâche de ce board suivent cette exception.`,"Off: only this coordinator. Its board’s task agents follow the default.":`Coupé : seulement ce coordinateur. Les agents de tâche de son board suivent le défaut.`,"Remove exception":`Retirer l’exception`,"Add an exception":`Ajouter une exception`,"No coordinator or agent conversation to add. Task agents follow the Sub-agents switch.":`Aucun coordinateur ni conversation d’agent à ajouter. Les agents de tâche suivent l’interrupteur Sous-agents.`,"Remove all exceptions":`Retirer toutes les exceptions`,"Not available in this browser":`Indisponible dans ce navigateur`,Blocked:`Bloquées`,Allowed:`Autorisées`,"Allowed, but this device is not registered yet":`Autorisées, mais cet appareil n’est pas encore inscrit`,"Not asked yet":`Pas encore demandé`,"This browser blocks notifications from wherdr. Allow them in the site settings of the browser (or in the system settings), then come back.":`Ce navigateur bloque les notifications de wherdr. Autorise-les dans les réglages du site du navigateur (ou dans les réglages système), puis reviens.`,"This only asks this browser or phone for permission to show notifications. What notifies is set above.":`Ceci demande seulement à ce navigateur ou ce téléphone la permission d’afficher des notifications. Ce qui notifie se règle plus haut.`,Permission:`Autorisation`,Allow:`Autoriser`,"Group by":`Grouper par`,State:`État`,"Herdr authentication and the wherdr SSH connection are checked separately.":`L’authentification Herdr et la connexion SSH de wherdr sont vérifiées séparément.`,"Connection status":`État de la connexion`,Disabled:`Désactivée`,Reachable:`Joignable`,"Authentication required":`Authentification requise`,"Connection failed":`Échec de la connexion`,"Check status":`Vérifier l’état`,"Retry connection":`Réessayer la connexion`,"Machine diagnostics require Herdr 0.9.2 or later. The wherdr connection still retries automatically.":`Le diagnostic des machines nécessite Herdr 0.9.2 ou plus. wherdr continue de réessayer la connexion automatiquement.`,"For SSH authentication, run this command in a terminal on the machine running wherdr, then retry the connection here.":`Pour l’authentification SSH, lance cette commande dans un terminal sur la machine qui exécute wherdr, puis réessaie la connexion ici.`,"unknown remote machine":`Machine distante inconnue`,"Machine status unavailable":`État de la machine indisponible`,"herdr-projects 1.2.1 or later is not available on {machine}":`herdr-projects 1.2.1 ou plus n’est pas disponible sur {machine}`,"Invalid approval":`Approbation invalide`,"Autopilot needs herdr-projects {min} or later on {machine} (it has {version}).":`Autopilot nécessite herdr-projects {min} ou plus sur {machine} (version installée : {version}).`,"herdr-projects gave an Autopilot status wherdr cannot read.":`herdr-projects a renvoyé un état Autopilot que wherdr ne sait pas lire.`,"An Autopilot goal is required (maximum 16000 characters).":`Un objectif Autopilot est obligatoire (16000 caractères au plus).`,"Invalid Autopilot setting.":`Réglage Autopilot invalide.`,"Invalid Autopilot action.":`Action Autopilot invalide.`,"This task cannot bypass approval checks":`Cette tâche ne peut pas ignorer les contrôles d’approbation`,"This failure needs the human first":`Cet échec nécessite d’abord ton intervention`,"Invalid task":`Tâche invalide`,"Nothing to send":`Rien à envoyer`,"This task has no agent to talk to":`Cette tâche n’a pas d’agent à qui parler`,"This task has no failed review to send back":`Cette tâche n’a pas de relecture échouée à renvoyer`,"This task does not wait for approval":`Cette tâche n’attend pas d’approbation`,"Task not found":`Tâche introuvable`,"This task cannot be started now":`Cette tâche ne peut pas être lancée maintenant`,"Only Start takes an agent":`Seul Lancer prend un agent`,"Invalid tasks to wait for":`Tâches à attendre invalides`,"This task does not wait for other tasks":`Cette tâche n’attend pas d’autres tâches`,"{agent} is not installed on {machine}":`{agent} n’est pas installé sur {machine}`,"This task has no agent at work to stop":`Cette tâche n’a pas d’agent au travail à arrêter`,"This task has nothing to retry":`Cette tâche n’a rien à réessayer`,"This task has nothing to finish as it is":`Cette tâche n’a rien à terminer telle quelle`,"This task is not archived":`Cette tâche n’est pas archivée`,"This task cannot be archived while an agent works on it":`Cette tâche ne peut pas être archivée pendant qu’un agent y travaille`,"Unknown action":`Action inconnue`,"A task needs a title":`Une tâche a besoin d’un titre`,"Invalid repo":`Dépôt invalide`,"Invalid agent":`Agent invalide`,"Invalid effort":`Effort invalide`,"Invalid coordinator":`Coordinateur invalide`,"herdr-projects did not add the repository to the board.":`herdr-projects n’a pas ajouté le dépôt au board.`,"The repository is on the board now, but the automation {name} that added it could not be removed: {why}":`Le dépôt est maintenant sur le board, mais l’automatisation {name} qui l’a ajouté n’a pas pu être supprimée : {why}`,"This folder does not exist on this machine.":`Ce dossier n’existe pas sur cette machine.`,"This folder is not a Git repository: a project coordinator needs one.":`Ce dossier n’est pas un dépôt Git : un coordinateur de projet en demande un.`,"Move up":`Monter`,"Move down":`Descendre`,"Reset order":`Réinitialiser l’ordre`,"Drag to reorder":`Glisser pour réordonner`,"Keep awake":`Garder éveillé`,"Extend by one hour":`Prolonger d’une heure`,"Sleep control is not available on this machine":`Contrôle de veille indisponible sur cette machine`,"Closed lid is only available on a Mac":`Capot fermé disponible uniquement sur Mac`,"Invalid keep-awake option":`option de veille invalide`,"Keep-awake command failed":`Commande de veille impossible`,"Nothing to extend: the machine is not being kept awake":`Aucun éveil en cours à prolonger`,"It is already past 8 pm on this machine: pick a duration":`Il est déjà plus de 20 h sur cette machine : choisis une durée`,"It is already past 8 pm on this machine":`Il est déjà plus de 20 h sur cette machine`,"Keep awake did not start; the previous state is kept":`Le maintien éveillé n’a pas démarré ; l’état précédent est conservé`,"Closed lid requires the power adapter":`Le capot fermé nécessite le secteur`,Update:`Mettre à jour`,"Codex update failed":`Échec de la mise à jour de Codex`,"Show Codex’s usage breakdown":`Voir le détail de l’utilisation Codex`,"Codex update already in progress":`Mise à jour de Codex déjà en cours`,"Codex is working or waiting for an answer: update it once it is done":`Codex travaille ou attend une réponse : mets-le à jour quand il a fini`,"Codex is not running in this pane":`Codex ne tourne pas dans ce panneau`,"Codex was not started from a shell: quitting it would close the pane":`Codex n’a pas été lancé depuis un shell : le quitter fermerait le panneau`,"Codex is showing a menu: answer it first":`Codex affiche un menu : réponds-y d’abord`,"The update did not finish in 10 minutes: see the terminal":`La mise à jour n’a pas fini en 10 minutes : regarde le terminal`,"No Codex update to install":`Aucune mise à jour de Codex à installer`,"This update cannot be run from wherdr: copy the command":`Cette mise à jour ne peut pas être lancée depuis wherdr : copie la commande`,"Codex updated itself and stopped":`Codex s’est mis à jour et s’est arrêté`,"Restart Codex before sending a message":`Relance Codex avant d’envoyer un message`,"Restart Codex":`Relancer Codex`,"Resume conversation":`Reprendre la conversation`,"Start fresh":`Démarrer une nouvelle conversation`,Dismiss:`Ignorer`,"Choose a conversation in Codex":`Choisis une conversation dans Codex`,"Use the restart buttons for this stopped agent.":`Utilise les boutons de relance de cet agent arrêté.`,"Restart Codex before sending a command.":`Relance Codex avant d’envoyer une commande.`,"Codex just stopped. Try again in a few seconds.":`Codex vient de s’arrêter. Réessaie dans quelques secondes.`,"The pane is not at an empty shell prompt. Check its terminal.":`Le panneau n’est pas sur une invite de shell vide. Vérifie son terminal.`,"Restart agent":`Redémarrer l’agent`,Restart:`Redémarrer`,"Restart anyway":`Redémarrer quand même`,"Restart to update":`Redémarrer pour mettre à jour`,Restarting:`Redémarrage`,"Restart failed":`Redémarrage échoué`,"the agent did not stop":`l’agent ne s’est pas arrêté`,"the agent did not restart":`l’agent n’a pas redémarré`,"restart already in progress":`redémarrage déjà en cours`,"agent not supported":`agent non pris en charge`,"agent not found":`agent introuvable`,"timed out waiting for agent startup":`délai dépassé en attendant le démarrage de l’agent`,Collapse:`Réduire`,"Too long: only the beginning is shown. The terminal shows the rest.":`Trop long : seul le début est affiché. Le terminal montre la suite.`,"What prevents sleep":`Ce qui empêche la veille`,"Normal sleep":`Veille normale`,"Power adapter":`Secteur`,Battery:`Batterie`,"Closed lid (power adapter only)":`Capot fermé (sur secteur uniquement)`,"1 hour":`1 heure`,"4 hours":`4 heures`,"Until tonight (8 pm)":`Jusqu’à ce soir (20 h)`,"Until turned off":`Jusqu’à désactivation`,"No app is preventing sleep.":`Aucune app ne bloque la veille.`,"wherdr · Keep awake":`wherdr · Garder éveillé`,Security:`Sécurité`,"wherdr is locked":`wherdr est verrouillé`,"Unlock with your passkey (Face ID, Touch ID, Windows Hello…) to reach your agents.":`Déverrouille avec ta clé d’accès (Face ID, Touch ID, Windows Hello…) pour accéder à tes agents.`,Unlock:`Déverrouiller`,"Unlock cancelled":`Déverrouillage annulé`,Device:`Appareil`,"Lock enabled on this device ✓":`Verrouillage activé sur cet appareil ✓`,"Registration cancelled":`Enregistrement annulé`,"This device is already registered":`Cet appareil est déjà enregistré`,"Optional: wherdr already answers only this computer and your tailnet. A passkey adds a lock on each device, with Face ID, Touch ID, Windows Hello…":`Facultatif : wherdr ne répond déjà qu’à cet ordinateur et à ton tailnet. Une passkey ajoute un verrou sur chaque appareil, avec Face ID, Touch ID, Windows Hello…`,"This browser does not support passkeys.":`Ce navigateur ne gère pas les clés d’accès.`,"Registered keys:":`Clés enregistrées :`,"Turn off lock":`Désactiver le verrouillage`,"Turn off the lock? The app will be open again to anyone who can reach this server.":`Désactiver le verrouillage ? L’app redeviendra accessible à toute personne qui peut joindre ce serveur.`,"Lock turned off":`Verrouillage désactivé`,"Separate worktree":`Worktree séparé`,"new branch, leaves the original folder untouched":`nouvelle branche, sans toucher au dossier d’origine`,Branch:`Branche`,"(optional)":`(optionnel)`,"Reveal in Finder":`Afficher dans le Finder`,Open:`Ouvrir`,"Copy path":`Copier le chemin`,Download:`Télécharger`,"File too large to download (50 MB max)":`Fichier trop lourd à télécharger (50 Mo max)`,"Not found on {machine}: {path}":`Introuvable sur {machine} : {path}`,"Only files in your home folder can be shown":`Seuls les fichiers de ton dossier personnel peuvent être affichés`,"{machine} is not a Mac":`{machine} n’est pas un Mac`,"Open in editor":`Ouvrir dans l’éditeur`,"Apps and scripts are not opened from wherdr: use Reveal in Finder":`wherdr n’ouvre pas les apps ni les scripts : utilise Afficher dans le Finder`,"Could not open on {machine}: {reason}":`Ouverture impossible sur {machine} : {reason}`,Reset:`Réinitialiser`,Save:`Enregistrer`,"Rename pane":`Renommer le pane`,"Pane name (empty = automatic name)":`Nom du pane (vide = nom automatique)`,Renamed:`Renommé`,"Automatic name restored":`Nom automatique rétabli`,Search:`Rechercher`,"Search the conversation":`Rechercher dans la conversation`,"Enter at least two characters.":`Saisis au moins deux caractères.`,"Searching…":`Recherche en cours…`,"Search unavailable":`Recherche indisponible`,"No results":`Aucun résultat`,"Results limited. Refine your search.":`Résultats limités. Affine ta recherche.`,"Clear search":`Effacer la recherche`,Esc:`Échap`,Results:`Résultats`,You:`Toi`,yesterday:`hier`,navigate:`naviguer`,open:`ouvrir`,close:`fermer`,"loading…":`chargement…`,"no results":`aucun résultat`,Today:`Aujourd’hui`,Yesterday:`Hier`,action:`action`,"Stop the agent":`Arrêter l’agent`,Send:`Envoyer`,"Stopping…":`Interruption…`,"Agent stopped":`Agent arrêté`,"The agent is still working.":`L’agent travaille encore.`,"Last known state":`Dernier état connu`,"Offline reading":`Lecture hors ligne`,"Image unavailable offline":`Image non disponible hors ligne`,Image:`Image`,"Previous image":`Image précédente`,"Next image":`Image suivante`,"Zoom in":`Zoomer`,"Zoom out":`Dézoomer`,"Fit to screen":`Ajuster à l’écran`,"Actual size":`Taille réelle`,"Terminal unavailable offline":`Terminal indisponible hors ligne`,"Sending unavailable offline":`Envoi indisponible hors ligne`,"Changes unavailable offline":`Modification indisponible hors ligne`,"Draft saved — sending unavailable offline":`Brouillon conservé — envoi indisponible hors ligne`,"connecting…":`connexion…`,"offline — reconnecting…":`hors ligne — reconnexion…`,"Herdr unavailable":`Herdr injoignable`,"The agent isn’t ready in this pane (stopped or still starting).":`L’agent n’est pas prêt dans ce pane (arrêté ou en cours de démarrage).`,"Your turn":`À toi`,Done:`Terminé`,Working:`Au travail`,Ready:`Prêt`,Unknown:`Inconnu`,Starting:`Démarrage`,Closed:`Fermé`,"your turn":`à toi`,working:`au travail`,ready:`prêts`,coordinator:`coordinateur`,Coordinator:`Coordinateur`,review:`revue`,Hide:`Masquer`,"Show terminals":`Afficher les terminaux`,"Compact list":`Liste compacte`,"Tasks: one line in Compact, two in Normal with current activity and relevant labels. Details stay in the task sheet. Follows you on every device.":`Tâches : une ligne en compact, deux en normal avec l’activité et les étiquettes utiles. Les détails restent dans la fiche de la tâche. Te suit sur tous tes appareils.`,"The Herdr server is not responding":`Le serveur Herdr ne répond pas`,"This pane has been closed.":`Ce pane a été fermé.`,Back:`Retour`,"Type a reply…":`Réponse libre…`,"Command…":`Commande…`,"This terminal is already open elsewhere.":`Ce terminal est déjà ouvert ailleurs.`,"Take control":`Prendre la main`,"Another client took control.":`Un autre client a pris la main.`,"Take back control":`Reprendre`,"Terminal unavailable":`Terminal indisponible`,Retry:`Réessayer`,"Try again":`Réessayer`,"No conversation for this agent yet.":`Pas encore de conversation pour cet agent.`,"Conversation unavailable for this agent.":`Conversation indisponible pour cet agent.`,"Conversation not up to date — reconnecting…":`Conversation non à jour — reconnexion…`,"View terminal":`Voir le terminal`,"Interactive menu":`Menu interactif`,"Search…":`Rechercher…`,"Search the menu":`Rechercher dans le menu`,"Menu open":`Menu ouvert`,"Load earlier messages":`Charger plus haut`,"Start of conversation":`Début de la conversation`,"No messages yet.":`Conversation vide pour l’instant.`,Command:`Commande`,Write:`Écriture`,Edit:`Modif`,Files:`Fichiers`,"Web search":`Recherche web`,Subagent:`Sous-agent`,Tasks:`Tâches`,Tool:`Outil`,actions:`actions`,Advisor:`Conseiller`,"Background job done":`Tâche de fond terminée`,"Agent message":`Message d’un agent`,Process:`Processus`,"Background task":`Tâche en arrière-plan`,"Show all":`Tout afficher`,"Show list":`Afficher la liste`,"Collapse list":`Réduire la liste`,Continue:`Continuer`,"Sort ready":`Trier les prêts`,"Herdr order":`Ordre de Herdr`,"Recent activity":`Activité récente`,"Open terminal":`Ouvrir le terminal`,Queued:`En attente`,"Clear and send":`Vider et envoyer`,"agent stopped":`agent arrêté`,"agent starting":`démarrage de l’agent`,"Queued · ":`En attente · `,"Sent · read by the agent":`Envoyé · lu par l’agent`,Running:`En cours d’exécution`,"No output yet":`Pas encore de sortie`,"Removed from the queue":`Message retiré de la file`,"Already read by the agent":`Message déjà lu par l’agent`,"The agent’s input field is not empty":`Le champ de saisie de l’agent n’est pas vide`,"Agent is not ready":`L’agent n’est pas au repos`,"Agent input changed":`La saisie de l’agent a changé`,"Agent input field not found":`Champ de saisie de l’agent introuvable`,"Agent input not cleared: check its terminal":`Champ de l’agent pas vidé : vérifie son terminal`,"This agent can’t cancel queued messages":`Annulation impossible pour cet agent`,"Already cancelling":`Annulation déjà en cours`,"after you answer the question":`après ta réponse à la question`,"sending…":`envoi…`,"Photo is uploading…":`Photo en cours d’envoi…`,Remove:`Retirer`,"Photo upload failed":`Photo non envoyée`,"Drop to attach":`Déposer pour joindre`,"The file path is sent to the terminal":`Le chemin du fichier part dans le terminal`,"Images, PDFs, text and code files":`Images, PDF, fichiers texte et code`,"Images, text and code files":`Images, fichiers texte et code`,"Attach a file…":`Joindre un fichier…`,"File upload failed":`Fichier non envoyé`,"File is uploading…":`Fichier en cours d’envoi…`,"File (PDF, text, code)":`Fichier (PDF, texte, code)`,"File (text, code)":`Fichier (texte, code)`,"Archives cannot be read by the agent: extract the files first":`L’agent ne lit pas les archives : décompresse d’abord`,"Videos cannot be read by the agent":`L’agent ne lit pas les vidéos`,"Audio files cannot be read by the agent":`L’agent ne lit pas les fichiers audio`,"Office documents cannot be read by the agent: export to PDF or text first":`L’agent ne lit pas les documents Office : exporte d’abord en PDF ou en texte`,"Programs and binary files cannot be read by the agent":`L’agent ne lit pas les programmes ni les fichiers binaires`,"Binary files cannot be read by the agent":`L’agent ne lit pas les fichiers binaires`,"This agent cannot read PDFs: only Claude Code can":`Cet agent ne lit pas les PDF : seul Claude Code les lit`,"File too large for the agent":`Fichier trop gros pour l’agent`,"File too large (30 MB max)":`Fichier trop gros (30 Mo max)`,"Images go through the photo upload":`Les images passent par l’envoi de photos`,"Invalid file name":`Nom de fichier invalide`,"Clipboard unavailable here — paste into the message field.":`Presse-papiers inaccessible ici — colle dans le champ de message.`,"No image in the clipboard":`Pas d’image dans le presse-papiers`,"Paste denied":`Collage refusé`,"Paste failed":`Collage impossible`,"Terminal not connected — image not pasted":`Terminal non connecté — image non collée`,"Summarize context":`Résumer le contexte`,"New conversation":`Nouvelle conversation`,"Plan mode":`Mode plan`,"Priority service tier":`Niveau de service prioritaire`,"Context usage":`Occupation du contexte`,"Plan usage":`Consommation du forfait`,"Change model":`Changer de modèle`,"Code review":`Revue de code`,"Session status":`État de la session`,"View diff":`Voir le diff`,"Interrupt agent":`Interrompre l’agent`,"Commands that open a menu (model…) can then be controlled in the Terminal tab.":`Les commandes qui ouvrent un menu (modèle…) se pilotent ensuite dans l’onglet Terminal.`,"Nothing displayed — check the Terminal tab.":`Rien d’affiché — regarde l’onglet Terminal.`,Settings:`Réglages`,"You are notified when an agent needs your input or finishes.":`Tu es prévenu quand un agent attend ta réponse ou a terminé.`,"Notify for":`Notifier pour`,"On iPhone, add the app to your Home Screen (Share → Add to Home Screen) to receive notifications.":`Sur iPhone, ajoute d’abord l’app à l’écran d’accueil (Partager → Sur l’écran d’accueil) pour recevoir les notifications.`,"Enable notifications to know when an agent needs your input.":`Active les notifications pour être prévenu quand un agent attend ta réponse.`,"Close this terminal":`Fermer ce terminal`,"Pane closed":`Pane fermé`,"New terminal":`Nouveau terminal`,"New agent":`Nouvel agent`,Terminal:`Terminal`,"Command to run":`Commande à lancer`,"First message":`Premier message`,"E.g. npm run dev":`Ex. : npm run dev`,"E.g. Summarize the project TODOs":`Ex. : Fais le point sur les TODO du projet`,Launch:`Lancer`,"Starting…":`Démarrage…`,"No subfolders.":`Aucun sous-dossier.`,"Add the app to your Home Screen (Share → Add to Home Screen), then open it from the icon.":`Ajoute d’abord l’app à l’écran d’accueil (Partager → Sur l’écran d’accueil), puis ouvre-la depuis l’icône.`,"Notifications are unavailable in this browser.":`Notifications non disponibles dans ce navigateur.`,"Notifications denied — enable them in system settings.":`Notifications refusées — réactive-les dans Réglages.`,"Web Push is not configured on the server":`Web Push non configuré sur le serveur`,"Notifications enabled ✓":`Notifications activées ✓`,Failed:`Échec`,"Notification sent":`Notification envoyée`,"No device accepted the notification":`Aucun appareil n’a accepté la notification`,Agents:`Agents`,Menu:`Menu`,"No agents yet.":`Aucun agent pour l’instant.`,"Start one here, or from":`Lance-en un ici, ou depuis`,"in a terminal.":`dans un terminal.`,New:`Nouveau`,Options:`Options`,Conversation:`Conversation`,Keys:`Touches`,"Type in terminal":`Taper dans le terminal`,"Photo, file, paste, commands":`Photo, fichier, collage, commandes`,"Message to agent…":`Message à l’agent…`,"Choose an agent from the list":`Choisis un agent dans la liste`,"or start a new one.":`ou lances-en un nouveau.`,Close:`Fermer`,Type:`Type`,Folder:`Dossier`,"Resume the last conversation":`Reprendre la dernière conversation`,"for this agent in this folder":`de cet agent dans ce dossier`,Name:`Nom`,Cancel:`Annuler`,"Choose this folder":`Choisir ce dossier`,Language:`Langue`,English:`English`,"The interface language is saved on this device.":`La langue de l’interface est enregistrée sur cet appareil.`,"Offered agents":`Agents proposés`,"Agents offered wherever an agent is chosen. Terminal is always available.":`Agents proposés partout où l’on choisit un agent. Terminal toujours disponible.`,"No agents installed on online machines.":`Aucun agent installé sur les machines en ligne.`,"Choices follow you on every device.":`Ces choix te suivent sur tous tes appareils.`,Notifications:`Notifications`,Application:`Application`,Phone:`Téléphone`,"Show terminal spaces in the list, filed under Ready.":`Montrer les spaces de terminal dans la liste, rangés dans Prêts.`,"Show counters":`Afficher les compteurs`,"Show agent counters on the home screen.":`Afficher les compteurs d’agents sur l’accueil.`,"Show quotas":`Afficher les quotas`,"Show Claude and Codex quotas on the home screen.":`Afficher les quotas Claude et Codex sur l’accueil.`,"Terminal text size":`Taille du texte du terminal`,"Terminal rendering":`Rendu du terminal`,Clipboard:`Presse-papiers`,"Agent copies":`Copies des agents`,"Text an agent copies in the terminal (OSC 52) goes to this device’s clipboard. Never read from it. Saved on this device.":`Le texte qu’un agent copie dans le terminal (OSC 52) arrive dans le presse-papiers de cet appareil. Jamais lu. Enregistré sur cet appareil.`,"The agent copied text":`L’agent a copié du texte`,"The agent copied text — tap to copy":`L’agent a copié du texte — touche pour copier`,"Rendering is saved on this device.":`Le rendu est enregistré sur cet appareil.`,Typewriter:`Machine à écrire`,Desktop:`Ordinateur`,Normal:`Normale`,Wide:`Large`,"Full width":`Pleine largeur`,"Content width":`Largeur du contenu`,Appearance:`Apparence`,"Home screen":`Accueil`,"Reorder automatically":`Réorganiser automatiquement`,Unread:`Non lus`,Read:`Lus`,"In Ready, show unread agents before read ones. Follows you on every device.":`Dans Prêts, placer les non lus avant les lus. Te suit sur tous tes appareils.`,Text:`Texte`,Remaining:`Restant`,Used:`Utilisé`,Quotas:`Quotas`,"Used quotas":`Quotas utilisés`,"Loading…":`Chargement…`,"What is left in each window, like Codex.":`Ce qu’il reste de chaque fenêtre, comme Codex.`,"What has been used, like Claude.":`Ce qui est consommé, comme Claude.`,"The color always flags a nearly exhausted quota. Follows you on every device.":`La couleur signale toujours un quota presque épuisé. Te suit sur tous tes appareils.`,"Command copied: paste it into a terminal on the server, in the wherdr folder.":`Commande copiée : colle-la dans un terminal du serveur, dans le dossier de wherdr.`,"Then restart wherdr.":`Puis relance wherdr.`,"Release notes":`Notes`,"Stop wherdr first, then run this command.":`Arrête d’abord wherdr, puis lance cette commande.`,"wherdr update":`Mise à jour de wherdr`,"Updating…":`Mise à jour…`,"Reloading…":`Rechargement…`,"Update failed":`Échec de la mise à jour`,"Going back to the previous version…":`Retour à la version précédente…`,"Restarting wherdr":`Redémarrage de wherdr`,"Checking the new version":`Vérification de la nouvelle version`,"The app reloads by itself on the new version. Agents keep running.":`L’app se recharge d’elle-même sur la nouvelle version. Les agents continuent de tourner.`,"wherdr did not come back in 5 minutes. See ~/wherdr/update.log on the server.":`wherdr n’est pas revenu en 5 minutes. Regarde ~/wherdr/update.log sur le serveur.`,"This installation cannot update itself: run the update command":`Cette installation ne peut pas se mettre à jour seule : lance la commande de mise à jour`,"An update is already in progress":`Une mise à jour est déjà en cours`,"No newer version to install":`Aucune version plus récente à installer`,"The updater is missing from this installation: run the update command":`Le programme de mise à jour manque dans cette installation : lance la commande de mise à jour`,"Hide until the next version":`Masquer jusqu’à la version suivante`,"This is the latest version.":`C’est la dernière version.`,About:`À propos`,"Settings sections":`Sections des réglages`,"Conversation, terminal, settings and other content. Saved on this device.":`Conversation, terminal, réglages et autres contenus. Réglage propre à cet appareil.`,"760 px column · terminal fitted to width.":`Colonne de 760 px · terminal ajusté.`,"Up to 1100 px · terminal fitted to width.":`Jusqu’à 1100 px · terminal ajusté.`,"The whole width, terminal included.":`Toute la largeur, terminal compris.`,"Default pane view":`Vue par défaut du volet`,"What an agent pane opens on. A pane you switched to Terminal stays there. Follows you on every device.":`Ce sur quoi s’ouvre le volet d’un agent. Un volet passé au Terminal y reste. Te suit sur tous tes appareils.`,"Read the transcript first.":`Lire la transcription d’abord.`,"Type straight into the pane.":`Écrire directement dans le volet.`,"Encrypted text":`Texte chiffré`,"Writing advances in glyphs, then the text decrypts behind it.":`L’écriture avance en glyphes, puis le texte se déchiffre derrière.`,Off:`Désactivée`,Fast:`Rapide`,Medium:`Moyenne`,Slow:`Lente`,"Original speed · 0.5 to 2 s.":`Vitesse d’origine · 0,5 à 2 s.`,"Twice as slow · 1 to 4 s.":`Deux fois plus lente · 1 à 4 s.`,"Three times as slow · 1.5 to 6 s.":`Trois fois plus lente · 1,5 à 6 s.`,"The reply appears at once.":`La réponse s’affiche d’un coup.`,"Only new replies are animated; history appears at once. Tap a reply while it types to show it in full. Follows you on every device.":`Seules les nouvelles réponses s’écrivent ainsi ; l’historique s’affiche d’un coup. Touche une réponse en cours pour l’afficher entièrement. Te suit sur tous tes appareils.`,"Off: the system asks for reduced motion.":`Désactivée : le système demande de réduire les animations.`,"Active rendering: WebGL":`Rendu actif : WebGL`,"Active rendering: HTML":`Rendu actif : HTML`,"Active rendering: HTML (WebGL unavailable)":`Rendu actif : HTML (WebGL indisponible)`,"Decrease text size":`Réduire le texte`,"Increase text size":`Agrandir le texte`,"Herdr connection closed without a response":`connexion Herdr fermée sans réponse`,"Image too large (20 MB max)":`image trop lourde (20 Mo max)`,"Empty message":`message vide`,"Invalid pane":`pane invalide`,"Pane not found":`pane introuvable`,"The question has changed — check the current screen.":`La question a changé entre-temps — regarde l’écran à jour.`,"Settings are no longer open.":`Les réglages ne sont plus ouverts.`,"Settings tab change already in progress.":`Un changement d’onglet est déjà en cours.`,"Could not switch settings tabs. Open the terminal and try again.":`Impossible de changer d’onglet. Ouvre le terminal et réessaie.`,"Settings have changed.":`Les réglages ont changé.`,"Use the terminal to focus the settings tabs.":`Utilise le terminal pour revenir aux onglets des réglages.`,"The screen has changed — check the current screen.":`L’écran a changé entre-temps — regarde l’écran à jour.`,"Write your answer before sending it.":`Écris ta réponse avant de l’envoyer.`,"An answer is already being sent.":`Une réponse est déjà en cours d’envoi.`,"omp’s answer field did not open — check the current screen.":`Le champ de réponse d’omp ne s’est pas ouvert — regarde l’écran à jour.`,"omp’s answer field could not be cleared — check the current screen.":`Le champ de réponse d’omp ne se vide pas — regarde l’écran à jour.`,"omp’s answer field closed — answer not submitted, check the current screen.":`Le champ de réponse d’omp s’est refermé — réponse non validée, regarde l’écran à jour.`,"Claude’s answer field could not be reached — check the current screen.":`Impossible d’atteindre le champ de réponse de Claude — regarde l’écran à jour.`,"Claude’s answer field could not be cleared — check the current screen.":`Le champ de réponse de Claude ne se vide pas — regarde l’écran à jour.`,"Claude’s answer field closed — answer not submitted, check the current screen.":`Le champ de réponse de Claude s’est refermé — réponse non validée, regarde l’écran à jour.`,"Claude kept the answer in its field — answer not submitted, check the current screen.":`Claude a gardé la réponse dans son champ — réponse non validée, regarde l’écran à jour.`,"Your answer…":`Ta réponse…`,Questions:`Questions`,"Web Push is not configured":`Web Push non configuré`,"Invalid subscription":`abonnement invalide`,Rename:`Renommer`,"Take control of this terminal":`Prendre la main sur ce terminal`,Reconnect:`Reconnecter`,"Photo or screenshot":`Photo ou capture d’écran`,Changes:`Changements`,"View changes":`Voir les changements`,"Refresh changes":`Rafraîchir les changements`,Refresh:`Rafraîchir`,"Reading changes…":`Lecture des changements…`,"This folder is not a Git repository.":`Ce dossier n’est pas un dépôt Git.`,"Send review":`Envoyer la relecture`,Discard:`Abandonner`,"review comment":`remarque`,"review comments":`remarques`,"Comment on line":`Commenter la ligne`,"old line":`ancienne ligne`,"old lines":`anciennes lignes`,"no longer in diff":`absent du diff`,Line:`Ligne`,Lines:`Lignes`,"Selection:":`Sélection :`,Comment:`Commenter`,"Please review these points:":`Merci de revoir ces points :`,"Write a review comment…":`Écrire une remarque…`,"Delete comment":`Supprimer la remarque`,"Edit comment":`Modifier la remarque`,"Confirm delete":`Confirmer la suppression`,"Discard this text?":`Abandonner ce texte ?`,"to save":`pour enregistrer`,"to cancel":`pour annuler`,"The code of this block changed. Check this comment before sending.":`Le code de ce bloc a changé. Vérifie cette remarque avant de l’envoyer.`,"code changed since this comment":`code modifié depuis la remarque`,"No longer in the diff. Check this comment before sending.":`Absent du diff. Vérifie cette remarque avant de l’envoyer.`,"To comment, hover a line and click +. Drag from the + to comment a block of lines.":`Pour commenter, survole une ligne et clique sur +. Glisse depuis le + pour commenter un bloc de lignes.`,"To comment, tap a line number, then another line for a block.":`Pour commenter, touche un numéro de ligne, puis une autre ligne pour un bloc.`,"Tap another line of this hunk to extend the block.":`Touche une autre ligne de cette section pour étendre le bloc.`,"Shift+Arrow extends the block within this hunk.":`Maj+Flèche étend le bloc dans cette section du diff.`,"Arrow keys move between lines. Shift+Arrow selects a block of lines. Enter writes a comment.":`Les flèches passent d’une ligne à l’autre. Maj+Flèche sélectionne un bloc de lignes. Entrée écrit une remarque.`,"Adds to your message draft. You send it yourself.":`Ajout au brouillon du message. Tu l’envoies toi-même.`,"Working tree":`Dossier de travail`,"No working tree changes.":`Aucun changement dans le dossier de travail.`,"File list or diff limited to keep this view responsive.":`Liste ou diff limité pour garder la vue rapide.`,"Also show unpushed commits":`Voir aussi les commits non poussés`,Commits:`Commits`,"No committed changes to show.":`Aucun changement commité à afficher.`,"No upstream or base branch available for comparison.":`Aucun amont ou branche de base disponible pour comparer.`,Untracked:`Non suivi`,Commit:`Commit`,"Browse files":`Parcourir les fichiers`,"Back to folder":`Retour au dossier`,"Reading files…":`Lecture des fichiers…`,"Empty folder.":`Dossier vide.`,"Show hidden files":`Afficher les fichiers cachés`,"Markdown view":`Affichage Markdown`,Rendered:`Mis en forme`,Source:`Source`,"This link leads outside the folder.":`Ce lien mène hors du dossier.`,"Permission denied":`Accès refusé`,"The folder took too long to read":`Le dossier a mis trop de temps à se lire`,"macOS blocks access to this folder. On the Mac: System Settings › General › Sharing › Remote Login ⓘ › “Allow full disk access for remote users”.":`macOS bloque l’accès à ce dossier. Sur le Mac : Réglages Système › Général › Partage › Session à distance ⓘ › « Autoriser l’accès complet au disque pour les utilisateurs distants ».`,"macOS blocks access to this folder. Allow the app that runs wherdr in System Settings › Privacy & Security › Full Disk Access.":`macOS bloque l’accès à ce dossier. Autorise l’app qui fait tourner wherdr dans Réglages Système › Confidentialité et sécurité › Accès complet au disque.`,"File truncated to keep this view responsive.":`Fichier tronqué pour garder la vue rapide.`,"Image too large to preview.":`Image trop lourde pour l’aperçu.`,"Loading PDF…":`Chargement du PDF…`,"Could not preview this PDF. Use Open to view it.":`Impossible d’afficher ce PDF. Utilise Ouvrir pour le consulter.`,"This video cannot be played here. Use Open or Download.":`Cette vidéo ne peut pas être lue ici. Utilise Ouvrir ou Télécharger.`,Page:`Page`,"PDF too large to preview (50 MB max).":`PDF trop lourd pour l’aperçu (50 Mo max).`,"File not found":`Fichier introuvable`,"Outside the project folder":`Hors du dossier du projet`,"Not a file":`Pas un fichier`,"Not a video":`Pas une vidéo`,"Request closed":`Requête fermée`,"The file shrank while being read":`Le fichier a rétréci pendant sa lecture`,Added:`Ajouté`,Modified:`Modifié`,Deleted:`Supprimé`,From:`Depuis`,"Binary file":`Fichier binaire`,Binary:`Binaire`,"Diff truncated":`Diff tronqué`,"Diff not loaded (size limit)":`Diff non chargé (limite de taille)`,"Generated file or dependency lockfile":`Fichier généré ou verrouillage de dépendances`,"Paste copied image":`Coller l’image copiée`,"Send a test notification":`Envoyer une notification de test`,"Enable notifications":`Activer les notifications`,"Reload app":`Recharger l’app`,"Enable passkey lock":`Activer le verrouillage par clé d’accès`,"Add this device":`Ajouter cet appareil`,"Lock now":`Verrouiller maintenant`,"Lock all devices":`Verrouiller tous les appareils`,"Lock all":`Tout verrouiller`,"Lock every device? Each one, this one included, will need its passkey again. The keys are kept.":`Verrouiller tous les appareils ? Chacun, celui-ci compris, devra repasser par sa clé d’accès. Les clés sont conservées.`,"Ask for the passkey again after":`Redemander la clé d’accès après`,"1 day":`1 jour`,"1 year":`1 an`,"Invalid duration":`Durée invalide`,"Counted from the last passkey unlock, used or not, for every device. Never in the middle of use: at the next opening of the app.":`Compté depuis le dernier déverrouillage par clé d’accès, utilisée ou non, pour tous les appareils. Jamais en pleine utilisation : à la prochaine ouverture de l’app.`,"The passkey will be asked again the next time the app opens.":`La clé d’accès sera redemandée à la prochaine ouverture de l’app.`,Parent:`Parent`,Confirm:`Confirmer`,"Close pane":`Fermer le pane`,"Turn off":`Désactiver`,Worktrees:`Worktrees`,"Worktree not found":`Worktree introuvable`,"No worktrees.":`Aucun worktree.`,"folder missing":`dossier disparu`,closed:`fermé`,Delete:`Supprimer`,"Force delete":`Forcer la suppression`,"Delete this worktree":`Supprimer ce worktree`,"Deleting a worktree removes its folder; the Git branch is kept.":`Supprimer un worktree efface son dossier ; la branche Git est gardée.`,Preview:`Aperçu`,Replay:`Rejouer`,"Mark as read":`Marquer comme lu`,"Mark as unread":`Marquer comme non lu`,Commands:`Commandes`,Resets:`Réinitialisation`,left:`restant`,Week:`Semaine`,reset:`réinitialisé`,"new window":`fenêtre neuve`,"just now":`à l’instant`,"Remaining quotas":`Quotas restants`,Install:`Installer`,"Copy command":`Copier la commande`,"this machine":`cette machine`,"They will show after the next exchange with a Claude.":`Ils apparaîtront après le prochain échange avec un Claude.`,updated:`mis à jour`,used:`utilisé`,Agent:`Agent`,Previous:`Précédent`,Next:`Suivant`,"Conversation compacted":`Conversation compactée`,"Conversation cleared":`Conversation effacée`,Interrupted:`Interrompu`,"App is locked":`app verrouillée`,"Origin refused":`origine refusée`,"Not found":`introuvable`,"Waiting for your reply — details in the Terminal tab":`En attente de ta réponse — détail dans l’onglet Terminal`,Copy:`Copier`,Reply:`Répondre`,"Reply to this passage":`Répondre à ce passage`,"Show original message":`Voir le message d’origine`,"Original message not found (further up the conversation?)":`Message d’origine introuvable (plus haut dans la conversation ?)`,"Copy reply":`Copier la réponse`,"No output":`Aucune sortie`,Copied:`Copié`,"Copy pane ID":`Copier l’ID du pane`,"Copy failed":`Copie impossible`,"Copy ID":`Copier l’identifiant`,Quoted:`Citée`,Discuss:`Discuter`,Yes:`Oui`,No:`Non`,"OK to all":`Ok tout`,Decisions:`Décisions`,"Quoted questions":`Citations`,"Remove quote":`Retirer la citation`,"⌘+click to open":`⌘+clic pour ouvrir`,"Ctrl+click to open":`Ctrl+clic pour ouvrir`,Enter:`Entrée`,send:`envoyer`,suggestion:`suggestion`,"Use suggestion":`Utiliser la suggestion`,"new line":`nouvelle ligne`,"Image not found":`image introuvable`,"Invalid JSON":`JSON invalide`,"Request too large":`requête trop grosse`,Model:`Modèle`,"Unknown model":`Modèle inconnu`,"Unknown effort":`Effort inconnu`,"Reading effort levels…":`Lecture des efforts…`,"Picks the level each turn":`Choisit le niveau à chaque tour`,"Change effort":`Changer d’effort`,"Default (recommended)":`Par défaut (recommandé)`,Effort:`Effort`,"Effort level unavailable for this model":`Niveau d’effort indisponible pour ce modèle`,"Reading models…":`Lecture des modèles…`,"Reload list":`Relire la liste`,"For this session only":`Pour cette session seulement`,"For this start only":`Pour ce lancement seulement`,"Program’s default":`Défaut du programme`,"Model’s default":`Défaut du modèle`,"Models could not be read: Start uses the program alone.":`Modèles illisibles : le lancement utilise le programme seul.`,"The agent is working — change the model once it’s done.":`L’agent travaille — change de modèle quand il a fini.`,"The agent is waiting for an answer — reply first.":`L’agent attend une réponse — réponds-lui d’abord.`,"Model change already in progress":`Changement de modèle déjà en cours`,"The /model menu did not show up":`Le menu /model ne s’est pas affiché`,"omp’s model selector did not show up":`Le sélecteur de modèles d’omp ne s’est pas affiché`,"The terminal is too narrow for omp’s model selector — close wherdr’s terminal or widen the pane, then try again.":`Le terminal est trop étroit pour le sélecteur de modèles d’omp — ferme le terminal de wherdr ou élargis le panneau, puis réessaie.`,"Model not found in omp’s selector: {model}":`Modèle introuvable dans le sélecteur d’omp : {model}`,"The model selector did not follow — nothing was changed.":`Le sélecteur de modèles n’a pas suivi — rien n’a été changé.`,"The model selector changed — try again.":`Le sélecteur de modèles a changé — réessaie.`,"The /model menu changed — try again.":`Le menu /model a changé — réessaie.`,"“This session only” option not found — nothing was changed.":`Validation « cette session seulement » introuvable — rien n’a été changé.`,"Unexpected /model menu — nothing was changed.":`Menu /model inattendu — rien n’a été changé.`,"Unexpected effort menu — nothing was changed.":`Choix de l’effort inattendu — rien n’a été changé.`,"Not a Claude, Codex or omp agent":`pas un agent Claude, Codex ou omp`,"View image":`Voir l’image`,"Change theme":`Changer de thème`,"Hide themes":`Masquer les thèmes`,Theme:`Thème`,"Follow Herdr":`Suivre Herdr`,"config.toml not found":`config.toml introuvable`,default:`par défaut`,light:`clair`,"The theme follows you on every device.":`Le thème te suit sur tous tes appareils.`,"Message field border on focus":`Bordure du champ au focus`,"Border only":`Bord seul`,"A second color glides slowly around the border.":`Une seconde couleur glisse lentement autour du bord.`,Background:`Fond`,"Dotted grid with light packets, like wherdr.dev.":`Grille à points parcourue de paquets lumineux, comme wherdr.dev.`,"Flat line grid, like herdr.dev.":`Grille de lignes plates, comme herdr.dev.`,"Animated packets":`Paquets animés`,"Small glowing squares running along the wherdr grid.":`Petits carrés lumineux qui parcourent la grille wherdr.`,"Opens in Herdr":`S’ouvre dans Herdr`,"In the margins of the conversation. Still when the system asks for reduced motion. Follows you on every device.":`Dans les marges de la conversation. Immobile quand le système demande moins d’animations. Te suit sur tous tes appareils.`,Halo:`Halo`,"The same, with a faint glow around the field.":`Pareil, avec une légère lueur autour du champ.`,None:`Aucune`,"Plain 1 px border, no animation.":`Bord simple de 1 px, sans animation.`,"Also on omp’s running actions (border only). Frozen when the system asks for reduced motion. Follows you on every device.":`Aussi sur les actions en cours d’omp (bord seul). Figée si le système demande moins d’animations. Te suit sur tous tes appareils.`,"Plugin actions":`Actions des plugins`,Run:`Exécuter`,All:`Toutes`,"Open the board":`Ouvrir le board`,Machine:`Machine`,"This machine":`Cette machine`,LOCAL:`LOCAL`,online:`en ligne`,"reconnecting…":`reconnexion…`,offline:`hors ligne`,"No agents on this machine.":`Aucun agent sur cette machine.`,"No known agents.":`Aucun agent connu.`,"unknown machine":`machine inconnue`,"Rename machine":`Renommer la machine`,"Machine name":`Nom de la machine`,"Machine renamed":`Machine renommée`,"Herdr sessions":`Sessions Herdr`,"Session shown on this device":`Session affichée sur cet appareil`,running:`en cours`,stopped:`arrêtée`,"No sessions found.":`Aucune session trouvée.`,"Session unavailable: back to the default session":`Session indisponible : retour à la session par défaut`,Tab:`Onglet`,Tabs:`Onglets`,"This tab is unavailable.":`Cet onglet est indisponible.`,"Active pane in Herdr":`Pane actif dans Herdr`,"A pane is zoomed in Herdr":`Un pane est agrandi dans Herdr`,"Tab overview":`Plan de l’onglet`,"Side by side":`Côte à côte`,"Open alone":`Ouvrir seul`,Space:`Espace`,"New tab":`Nouvel onglet`,"New space":`Nouvel espace`,"in the same space":`dans le même espace`,"This space":`Cet espace`,"Swap with the pane on the left":`Échanger avec le pane de gauche`,"Swap with the pane on the right":`Échanger avec le pane de droite`,"Swap with the pane above":`Échanger avec le pane du dessus`,"Swap with the pane below":`Échanger avec le pane du dessous`,"Split right":`Diviser à droite`,"Split down":`Diviser en bas`,"Move to…":`Déplacer vers…`,Board:`Tableau`,Todo:`À faire`,"Nothing here":`Rien ici`,"Drag to move the pane":`Glisser pour déplacer le pane`,Swap:`Échanger`,"Place left":`Placer à gauche`,"Place right":`Placer à droite`,"Place above":`Placer au-dessus`,"Place below":`Placer en dessous`,Resize:`Redimensionner`,"Rename failed. The name was not changed.":`Échec du renommage. Le nom n’a pas été modifié.`,"Rename tab":`Renommer l’onglet`,"Rename space":`Renommer l’espace`,"Close tab":`Fermer l’onglet`,"Close space":`Fermer l’espace`,"Tab name":`Nom de l’onglet`,"Space name":`Nom de l’espace`,"Tab options":`Options de l’onglet`,"Pane options":`Options du pane`,"Tab created":`Onglet créé`,"Tab closed":`Onglet fermé`,"Space closed":`Espace fermé`,"Pane moved":`Pane déplacé`,"Start in a new pane":`Lancer dans un nouveau pane`,"Start in a new tab":`Lancer dans un nouvel onglet`,"New pane":`Nouveau pane`,"Ticket panel width":`Largeur du panneau du ticket`,"List width":`Largeur de la liste`,"Drag to resize · double-click: default width":`Glisser pour élargir · double-clic : largeur par défaut`,"Pull request":`Pull request`,"{machine} is unreachable: {reason}":`{machine} injoignable : {reason}`,"{machine} is unreachable":`{machine} injoignable`,"Unknown agent: {kind}":`Agent inconnu : {kind}`,"An agent is already running in this pane":`Un agent tourne déjà dans ce pane`,"No worktree in an existing pane":`Pas de worktree dans un pane existant`,"{kind} is not installed on {machine}":`{kind} non installé sur {machine}`,"The folder must be under {home}":`Le dossier doit être sous {home}`,"Folder not found: {path}":`Dossier introuvable : {path}`,"Not a Git repository: {path}":`Pas un dépôt Git : {path}`,"Invalid branch name":`Nom de branche invalide`,"Outside {home}":`Hors de {home}`,"Folder unreadable: {path}":`Dossier illisible : {path}`,"Empty file":`Fichier vide`,"Unknown machine: {machine}":`Machine inconnue : {machine}`,"Machine unreachable":`Machine injoignable`,"Herdr server unreachable ({reason})":`Serveur Herdr injoignable ({reason})`,"Missing model":`Modèle manquant`,"Model not found in /model: {model}":`Modèle introuvable dans /model : {model}`,"Claude’s effort slider could not be read — closed, nothing was changed.":`Curseur d’effort de Claude illisible — refermé, rien n’a été changé.`,"Unexpected effort slider — nothing was changed.":`Curseur d’effort inattendu — rien n’a été changé.`,"The effort slider did not follow — nothing was changed.":`Le curseur d’effort n’a pas suivi — rien n’a été changé.`,"The effort slider stayed open — nothing was changed.":`Le curseur d’effort est resté ouvert — rien n’a été changé.`,"omp’s thinking level is not on screen — nothing was changed.":`Le niveau de réflexion d’omp n’est pas à l’écran — rien n’a été changé.`,"omp did not change its thinking level — nothing was changed.":`omp n’a pas changé son niveau de réflexion — rien n’a été changé.`,"omp’s thinking level stopped following — check it in the terminal.":`Le niveau de réflexion d’omp n’a plus suivi — vérifie-le dans le terminal.`,"herdr not found":`herdr introuvable`,"timed out":`délai dépassé`,"Copy to {machine} failed: {reason}":`Copie sur {machine} impossible : {reason}`,"Herdr server not responding":`Serveur Herdr muet`,"SSH connection closed (code {code})":`Connexion SSH fermée (code {code})`,"SSH connection failed (timed out)":`Connexion SSH impossible (délai dépassé)`,"Remote SSH shell must support POSIX commands. On Windows, set OpenSSH DefaultShell to Git Bash (docs/machines.md, “Windows remote machines”).":`Le shell SSH distant doit accepter les commandes POSIX. Sous Windows, configurez OpenSSH DefaultShell avec Git Bash (docs/machines.md, « Windows remote machines »).`,"Remote Herdr must provide remote-api-bridge (Herdr 0.9.3 or later).":`Herdr distant doit fournir remote-api-bridge (Herdr 0.9.3 ou ultérieur).`,"Probe failed (code {code})":`Sonde échouée (code {code})`,"{reason} on {machine}":`{reason} sur {machine}`,"Herdr server stopped on {machine} (session {session})":`Serveur Herdr arrêté sur {machine} (session {session})`,"Herdr server stopped on {machine}":`Serveur Herdr arrêté sur {machine}`,"Herdr socket forwarding failed: {reason}":`Transfert du socket Herdr impossible : {reason}`,"SSH connection closed":`Connexion SSH fermée`,"SSH control connection lost":`Connexion SSH de contrôle perdue`,"SSH sessions refused":`Sessions SSH refusées`,"profile changed":`profil modifié`,"Session list unavailable":`Liste des sessions indisponible`,"Invalid session":`Session invalide`,"Session missing or stopped":`Session absente ou arrêtée`,"Empty machine name":`Nom de machine vide`,"Rename failed":`Renommage impossible`,"herdr-projects is already installed":`herdr-projects est déjà installé`,"herdr-projects is already {version} or later":`herdr-projects est déjà en {version} ou plus`,"Herdr folder is read-only on {machine}":`Dossier Herdr en lecture seule sur {machine}`,"Install failed (code {code})":`Installation impossible (code {code})`,"Message not found":`Message introuvable`,"starting…":`démarrage…`,"Install script not found":`Script d’installation introuvable`,"Home folder is read-only here: copy the command and paste it into a terminal on {machine}":`Dossier personnel en lecture seule ici : copie la commande et colle-la dans un terminal de {machine}`,"Install failed on {machine}: {reason}":`Installation impossible sur {machine} : {reason}`,"Invalid action":`Action invalide`,"Action not found on this machine":`Action introuvable sur cette machine`,"Action not available here":`Action non disponible ici`,"Invalid bootstrap token (see the server logs)":`Jeton d’amorçage invalide (voir les journaux du serveur)`,"Challenge expired, try again":`Défi expiré, recommence`,"Unlock first":`Déverrouille d’abord`,"Key rejected":`Clé refusée`,"Key unknown on this server":`Clé inconnue sur ce serveur`,"Unlock rejected":`Déverrouillage refusé`,"Host not allowed":`Hôte refusé`,"{count} tasks":`{count} tâches`,"The menu changed in the meantime — check the current screen.":`Le menu a changé entre-temps — regarde l’écran à jour.`,"This entry can’t be chosen here — check the terminal.":`Cette entrée ne se choisit pas — regarde le terminal.`,"The cursor doesn’t move — finish in the terminal.":`Le curseur ne bouge pas — termine dans le terminal.`,"Invalid operation":`Opération invalide`,"Invalid key":`Touche invalide`,"Enter doesn’t confirm from here — use the buttons.":`Entrée ne se valide pas d’ici — utilise les boutons.`,"Invalid message":`Message invalide`,"No agent in this pane":`Pas d’agent dans ce pane`,"This agent’s folder is unknown":`Dossier de cet agent inconnu`,"Name: use at least one letter or digit":`Nom : mets au moins une lettre ou un chiffre`,"Uncommitted changes in this worktree":`Modifications non commitées dans ce worktree`,"This pane’s folder is unknown":`Dossier de ce pane inconnu`,"Invalid machine order":`Ordre des machines invalide`,"Invalid settings":`Réglages invalides`,"Invalid repository":`Dépôt invalide`,"herdr-projects gave settings wherdr cannot read.":`herdr-projects a renvoyé des réglages que wherdr ne peut pas lire.`,"Invalid machine name (40 characters max)":`Nom de machine invalide (40 caractères maximum)`,"Invalid quiet setting":`Réglage de silence invalide`,"Notifications are not enabled on this device":`Notifications non activées sur cet appareil`,"Invalid path":`Chemin invalide`,"done must be true or false":`done doit valoir true ou false`,"keys and dismissed are required":`keys et dismissed sont requis`,"empty name":`nom vide`,"invalid direction":`direction invalide`,"invalid destination":`destination invalide`,"tab on another machine":`onglet d’une autre machine`,"pane on another machine":`pane d’une autre machine`,"space on another machine":`espace d’une autre machine`,"invalid split":`split invalide`,"invalid ratio":`ratio invalide`,"no pane on that side":`aucun pane de ce côté`,"a pane is zoomed in this tab":`un pane est agrandi dans cet onglet`,"Not sent":`Non envoyé`,"will be sent when the menu closes":`partira quand le menu sera fermé`,"A menu is still open in the agent’s terminal. Your messages wait for it to close.":`Un menu est resté ouvert dans le terminal de l’agent. Vos messages attendent qu’il se ferme.`,"Close menu":`Fermer le menu`,"Send anyway":`Envoyer quand même`,"No menu to close":`Aucun menu à fermer`,"The menu is still open. Close it in the terminal.":`Le menu est toujours ouvert. Fermez-le dans le terminal.`,"Not sent — the agent’s input contains text":`Non envoyé — le champ de l’agent contient du texte`,"Not sent — the agent’s input field was not found on its screen":`Non envoyé — champ de saisie de l’agent introuvable à l’écran`,"Not sent — it was taken out of the agent’s queue before being read":`Non envoyé — retiré de la file de l’agent avant d’être lu`,"Not sent — still not in the conversation after an hour":`Non envoyé — toujours absent de la conversation après une heure`,"The agent’s input contains text":`Le champ de l’agent contient du texte`,"The agent’s input stays in shell mode (!)":`Le champ de l’agent reste en mode shell (!)`,"The message did not show in the agent’s input":`Le message n’est pas apparu dans le champ de l’agent`,"The agent did not take the message":`L’agent n’a pas pris le message`,"Another writer keeps typing into the agent’s input":`Un autre programme écrit sans arrêt dans le champ de l’agent`,"message already being sent":`message déjà en cours d’envoi`,"same pane":`même pane`,"pane in another tab":`pane d’un autre onglet`},Ze=`herdrLanguage`;function Qe(){try{let e=localStorage.getItem(Ze);if(e===`fr`||e===`en`)return e;for(let e of navigator.languages??[navigator.language]){let t=e?.toLowerCase().slice(0,2);if(t===`fr`||t===`en`)return t}return`en`}catch{return`en`}}var m=Qe(),$e=Object.keys(Xe).filter(e=>/\{\w+\}/.test(e)).map(e=>{let t=[],n=e.split(/(\{\w+\})/).map(e=>{let n=/^\{(\w+)\}$/.exec(e);return n?(t.push(n[1]),`([\\s\\S]+?)`):e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}).join(``);return{key:e,names:t,re:RegExp(`^${n}$`),fixed:e.replace(/\{\w+\}/g,``).length}}).sort((e,t)=>t.fixed-e.fixed);function et(e){if(Xe[e])return Xe[e];for(let{key:t,names:n,re:r}of $e){let i=r.exec(e);if(!i)continue;let a=Object.fromEntries(n.map((e,t)=>[e,et(i[t+1])??i[t+1]]));return Xe[t].replace(/\{(\w+)\}/g,(e,t)=>a[t]??e)}}function h(e){return m===`fr`?et(e)??e:e}function tt(e,t){return m===`fr`?t:e}function nt(e){try{localStorage.setItem(Ze,e)}catch{}}var rt=e=>(e||``).replace(/^[^\p{L}\p{N}~/]+/u,``).trim(),it=new Set([`sh`,`bash`,`zsh`,`fish`,`dash`,`ksh`,`tcsh`,`csh`,`nu`,`pwsh`,`login`,`tmux`,`screen`]),at=new Set([`claude`,`claude code`,`codex`,`gemini`,`gemini cli`,`opencode`,`kimi`,`agent`]),ot=e=>(e||``).replace(/\\/g,`/`).replace(/\/+$/,``).split(`/`).pop()||``;function st(e){let t=rt(e.title).replace(/\s*\|\s*\S+$/,``).trim();if(!t||/^\S+@\S+:/.test(t))return``;let n=t.toLocaleLowerCase(),r=ot(n.split(/\s+/)[0]).replace(/^-/,``);if(it.has(r)&&!/\s/.test(n)||/^(?:~|\/)/.test(t)&&!/\s/.test(t))return``;let i=ot(e.cwd).toLocaleLowerCase();return i&&(n===i||n===`${i}/`)||e.agent&&at.has(n)||e.agent&&n===e.agent.toLocaleLowerCase()?``:t}function ct(e){let t=(e.name||``).toLocaleLowerCase();if(!/^sw-coordinator(?:-|$)/.test(t))return``;let n=rt(e.tabLabel);return/(?:^|\s)coordinator$/i.test(n)?n:/^sw-coordinator(?:-\d+)?$/.test(t)?`Coordinator`:/^sw-coordinator-machine(?:-\d+)?$/.test(t)?`Machine coordinator`:`${t.replace(/^sw-coordinator-/,``).replace(/-\d+$/,``)} coordinator`}function lt(e,t){if(e.label)return e.label;let n=ct(e);if(n)return n;let r=e.displayAgent?.trim();return e.agent&&r&&!at.has(r.toLocaleLowerCase())&&r.toLocaleLowerCase()!==e.agent.toLocaleLowerCase()?r:st(e)||(e.agent?e.name&&e.name!==e.agent?e.name:ut(e.agent):e.command?e.command:ot(e.cwd)||(e.cwd?`/`:`Shell`))}function ut(e){return e===`claude`?`Claude`:e===`codex`?`Codex`:e===`opencode`?`OpenCode`:e===`gemini`?`Gemini CLI`:e===`kimi`?`Kimi`:e?e[0].toUpperCase()+e.slice(1):`Shell`}var dt=[`claude`,`codex`,`omp`],ft=e=>dt.includes(e||``),pt={claude:`Claude`,codex:`Codex`,gemini:`Gemini CLI`,opencode:`OpenCode`,kimi:`Kimi`,qodercli:`Qoder CLI`,mastracode:`Mastra Code`,copilot:`Copilot`,qwen:`Qwen Code`,pi:`Pi`,omp:`omp`},mt=e=>e&&pt[e]||(e?e[0].toUpperCase()+e.slice(1):`Shell`),ht=e=>(e||``).replace(/^\/(?:home|Users)\/[^/]+/,`~`)||`~`,gt=e=>`${e}`,_t=e=>ft(e?.agent);function vt(e){return lt(e,F.value.workspaces.find(t=>t.id===e.workspace)?.label)}function yt(e,t){let n=e.workspaces.find(e=>e.id===t.workspace);return n?n.label:t.workspace}var g=()=>m===`en`?`en-GB`:`fr-FR`;function bt(e){return new Date(e).toLocaleTimeString(g(),{hour:`2-digit`,minute:`2-digit`})}function xt(e){return new Date(e).toLocaleString(g(),{weekday:`long`,day:`numeric`,month:`long`,year:`numeric`,hour:`2-digit`,minute:`2-digit`})}function St(e){let t=new Date(e),n=new Date,r=new Date;return r.setDate(n.getDate()-1),t.toDateString()===n.toDateString()?h(`Today`):t.toDateString()===r.toDateString()?h(`Yesterday`):t.toLocaleDateString(g(),{weekday:`long`,day:`numeric`,month:`long`})}function Ct(e,t=Date.now()){let n=new Date(e);if(Number.isNaN(n.getTime()))return``;let r=Math.floor((t-n.getTime())/6e4);if(r>=0&&r<1)return h(`just now`);if(r>=0&&r<60)return tt(`${r} min ago`,`il y a ${r} min`);let i=e=>new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime(),a=Math.round((i(new Date(t))-i(n))/864e5);return a===0?bt(e):a===1?`${h(`yesterday`)} ${bt(e)}`:a>1&&a<7?`${n.toLocaleDateString(g(),{weekday:`short`})} ${bt(e)}`:n.toLocaleDateString(g(),{day:`numeric`,month:`short`,...n.getFullYear()===new Date(t).getFullYear()?{}:{year:`numeric`}})}function wt(e){if(e<60)return`${e} s`;let t=Math.floor(e/60),n=e%60;if(t<60)return n?`${t} min ${n} s`:`${t} min`;let r=Math.floor(t/60),i=t%60;return i?`${r} h ${i} min`:`${r} h`}var Tt=()=>{navigator.vibrate&&navigator.vibrate(8)},Et=/iPad|iPhone|iPod/.test(navigator.userAgent)||navigator.platform===`MacIntel`&&navigator.maxTouchPoints>1,Dt=matchMedia(`(pointer: coarse)`).matches,Ot=matchMedia(`(display-mode: standalone)`).matches||navigator.standalone===!0;function kt(e){let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}function At(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t)}function jt(e,t=Date.now()){return!!e&&(e.until===null||t<e.until)}function Mt(e,t=8){let n=new Date(e);return n.setHours(t,0,0,0),n.getTime()<=e.getTime()&&n.setDate(n.getDate()+1),n.getTime()}function Nt(e,t=new Date){return e===`hour`?t.getTime()+36e5:e===`morning`?Mt(t):null}function Pt(e){return kt((e+`=`.repeat((4-e.length%4)%4)).replace(/-/g,`+`).replace(/_/g,`/`))}async function Ft(){try{return!(`serviceWorker`in navigator)||!(`Notification`in window)||Notification.permission!==`granted`?!1:!!await(await navigator.serviceWorker.ready).pushManager.getSubscription()}catch{return!1}}var It=i(null);async function Lt(){It.value=await Ft()}async function Rt(e=m){if(!(`serviceWorker`in navigator)||!(`Notification`in window)||Notification.permission!==`granted`)return;let t=await(await navigator.serviceWorker.ready).pushManager.getSubscription();t&&await Z(`/api/push/subscribe`,{...t.toJSON(),lang:e,sessions:L.value})}var zt=`pushEndpoint`;function Bt(){try{return localStorage.getItem(zt)||void 0}catch{return}}async function Vt(){if(!(`serviceWorker`in navigator)||!(`PushManager`in window)||!(`Notification`in window))return X(h(Et&&!Ot?`Add the app to your Home Screen (Share → Add to Home Screen), then open it from the icon.`:`Notifications are unavailable in this browser.`),!0);try{if(await Notification.requestPermission()!==`granted`)return X(h(`Notifications denied — enable them in system settings.`),!0);if(await Cs(),!V.value.push||!V.value.push.key)return X(h(`Web Push is not configured on the server`),!0);let e=await navigator.serviceWorker.ready,t=Pt(V.value.push.key),n=await e.pushManager.getSubscription(),r=n?.endpoint||Bt();n&&await n.unsubscribe().catch(()=>{}),n=await e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:t}),await Z(`/api/push/subscribe`,{...n.toJSON(),previous:r,lang:m,sessions:L.value});try{localStorage.setItem(zt,n.endpoint)}catch{}X(h(`Notifications enabled ✓`))}catch(e){X(`${h(`Failed`)} : ${e.message}`,!0)}}async function Ht(){try{let e=await Z(`/api/push/test`,{});X(h(e.sent?`Notification sent`:`No device accepted the notification`),!e.sent)}catch(e){X(e.message,!0)}}var Ut=i({global:null,device:null}),_=i(Date.now());c(()=>{_.value=Date.now()},3e4);var Wt=e(()=>{let{global:e,device:t}=Ut.value;return jt(t,_.value)?{scope:`device`,quiet:t}:jt(e,_.value)?{scope:`all`,quiet:e}:null});async function Gt(){try{return`serviceWorker`in navigator&&(await(await navigator.serviceWorker.ready).pushManager.getSubscription())?.endpoint||``}catch{return``}}async function Kt(){try{Ut.value=await Z(`/api/push/quiet`,{endpoint:await Gt()}),_.value=Date.now()}catch{}}async function qt(e,t,n=null){Ut.value=await Z(`/api/push/quiet`,{endpoint:await Gt(),scope:e,on:t,until:n}),_.value=Date.now()}function Jt(e){return e&&e.screen&&e.screen.kind!==`other`&&e.status!==`working`?e.screen:null}var Yt={enter:[`Entrée`,`Enter`],esc:[`Échap`,`Esc`],tab:[`Tab`,`Tab`],space:[`Espace`,`Space`],left:[`←`,`←`],right:[`→`,`→`]},Xt={"trust all":[`Tout approuver`,`Trust all`],review:[`Revoir`,`Review`],close:[`Fermer`,`Close`],skip:[`Passer`,`Skip`],continue:[`Continuer`,`Continue`],back:[`Retour`,`Back`],"go back":[`Retour`,`Go back`],confirm:[`Confirmer`,`Confirm`],cancel:[`Annuler`,`Cancel`],save:[`Enregistrer`,`Save`],exit:[`Quitter`,`Exit`],quit:[`Quitter`,`Quit`],select:[`Choisir`,`Select`],apply:[`Appliquer`,`Apply`],dismiss:[`Ignorer`,`Dismiss`],"show all projects":[`Tous les projets`,`All projects`],"only show current branch":[`Branche courante seulement`,`Current branch only`],"only show current repo":[`Projet courant seulement`,`Current project only`],"show all branches":[`Toutes les branches`,`All branches`],"only show current worktree":[`Worktree courant seulement`,`Current worktree only`],"show all worktrees":[`Tous les worktrees`,`All worktrees`],preview:[`Aperçu`,`Preview`],"set as default":[`Définir par défaut`,`Set as default`],"use this session only":[`Cette session seulement`,`This session only`],resume:[`Reprendre`,`Resume`],clear:[`Effacer`,`Clear`],"← switch":[`Onglet précédent`,`Previous tab`],"→ switch":[`Onglet suivant`,`Next tab`]},v=(e,t)=>e[+!!t];function Zt(e,t=m===`en`){if(Yt[e])return v(Yt[e],t);let n=e.match(/^ctrl\+(\w)$/);return n?`Ctrl+${n[1].toUpperCase()}`:e}function Qt(e,t=m===`en`){return e.title?`${v([`Menu`,`Menu`],t)} · ${e.title}`:v([`Menu ouvert`,`Menu open`],t)}function $t(e,t=m===`en`){let n=Xt[e.label.toLowerCase()];return n?v(n,t):e.label[0].toUpperCase()+e.label.slice(1)}function en(e,t=m===`en`){return`${$t(e,t)} (${Zt(e.key,t)})`}function tn(e,t=m===`en`){let n={hooks:[`Hooks à approuver`,`Hooks to review`],trust:[`Confiance du dossier demandée`,`Folder trust requested`],login:[`Connexion demandée`,`Sign-in required`],update:[`Mise à jour proposée`,`Update available`]}[e.kind];return n?v(n,t):e.title}function nn(e,t=m===`en`){let n={hooks:[`Des hooks (commandes lancées automatiquement à certains moments : avant un outil, au démarrage…) sont nouveaux ou ont changé : ils ne tournent qu’une fois approuvés.`,`Hooks (commands run automatically at set moments: before a tool, at startup…) are new or changed: they only run once you trust them.`],trust:[`L’agent demande s’il peut lire, modifier et exécuter les fichiers de ce dossier.`,`The agent asks whether it may read, edit and run the files in this folder.`],login:[`L’agent n’est pas connecté. La connexion s’ouvre sur la machine de l’agent : termine-la dans le terminal.`,`The agent is not signed in. Sign-in opens on the agent’s machine: finish it in the terminal.`],update:[`Une nouvelle version de l’agent est disponible.`,`A new version of the agent is available.`]}[e];return n?v(n,t):null}var rn=`(min-width: 700px) and (min-device-width: 700px) and (min-device-height: 700px) and (pointer: coarse)`,an=`(min-width: 900px), (min-width: 700px) and (min-height: 700px), ${rn}`,on=`(max-width: 899px) and (max-height: 699px)`,sn=`(max-width: 699px), ${on} and (max-device-width: 699px), ${on} and (max-device-height: 699px), ${on} and (pointer: fine), ${on} and (pointer: none)`,cn=`(min-width: 700px) and (min-height: 700px), ${rn}`;`${rn}`;var ln=1023,un=`(max-width: ${ln}px) and (min-width: 700px) and (min-height: 700px), (max-width: ${ln}px) and (min-width: 700px) and (min-device-width: 700px) and (min-device-height: 700px) and (pointer: coarse)`;function dn(e){return e.desk?e.slim?e.drawerOpen?`drawer`:`rail`:e.collapsed?`rail`:`docked`:`phone`}function fn(e){return e.metaKey||e.ctrlKey||e.altKey?!0:[`ArrowUp`,`ArrowDown`,`ArrowLeft`,`ArrowRight`,`Escape`,`Tab`].includes(e.key)}function pn(e){return!e.touch||e.desk&&e.tablet&&e.hardwareKeyboard&&!e.softKeyboard}var mn=2e3,y=e=>JSON.stringify(e).length*2;function hn(e){let t=e.slice(-160),n=t.map(y),r=n.reduce((e,t)=>e+t,0),i=0;for(;i<t.length&&r>225280;)r-=n[i++];return{items:i?t.slice(i):t,bytes:r}}function gn(e,t,n){let r=e.slice();if(t?.ok){let e=new Set(t.panes.map(e=>e.id)),n=new Set([``,...(t.machines||[]).filter(e=>e.status===`online`).map(e=>e.key)]);r=r.filter(t=>e.has(t.id)||!n.has(Ge(t.id).machine))}r=r.sort((e,t)=>t.used-e.used).slice(0,12);let i=n+r.reduce((e,t)=>e+t.bytes,0);for(;r.length&&i>4194304;)i-=r.pop().bytes;let a=new Set(r.map(e=>e.id));return{keep:r,drop:e.filter(e=>!a.has(e.id)).map(e=>e.id)}}var _n=`wherdr-offline`,vn=null;function yn(){return vn||(vn=new Promise((e,t)=>{let n=indexedDB.open(_n,2),r=setTimeout(()=>t(Error(`IndexedDB unavailable`)),3e3);n.onupgradeneeded=e=>{let t=n.result;if(t.createObjectStore(`kv`),t.createObjectStore(`chats`),e.oldVersion===1&&t.objectStoreNames.contains(`snapshot`)){let e=n.transaction,r=e.objectStore(`snapshot`).get(`current`);r.onsuccess=()=>{let n=r.result,i=e.objectStore(`kv`);n?.home?.state&&(i.put({state:n.home.state,at:n.home.at},`home`),n.home.quotas&&i.put(n.home.quotas,`quotas`));let a=[];for(let t of Array.isArray(n?.chats)?n.chats:[])typeof t?.id==`string`&&Array.isArray(t.items)&&(e.objectStore(`chats`).put({id:t.id,items:t.items,at:t.at},t.id),a.push({id:t.id,used:t.used||t.at||0,bytes:y(t.items)}));i.put(a,`index`),t.deleteObjectStore(`snapshot`)}}},n.onsuccess=()=>{clearTimeout(r),e(n.result)},n.onerror=()=>{clearTimeout(r),t(n.error)},n.onblocked=()=>{clearTimeout(r),t(Error(`IndexedDB blocked`))}}),vn.catch(e=>{throw vn=null,e}))}function b(e,t){return yn().then(n=>new Promise((r,i)=>{let a=n.transaction(e).objectStore(e).get(t);a.onsuccess=()=>r(a.result),a.onerror=()=>i(a.error)})).catch(()=>void 0)}function bn(e,t,n,r=Date.now()){let i=e.filter(e=>typeof e?.id==`string`&&!t.has(e.id));return i=i.map(e=>n.has(e.id)?{...e,used:n.get(e.id)}:e),[...[...t].map(([e,t])=>({id:e,used:n.get(e)||r,bytes:t})),...i]}var xn=()=>({chats:new Map,used:new Map}),x=xn(),S=null,C=Promise.resolve(),w=0,T=0;function E(){S||=setTimeout(Sn,mn)}function Sn(){S&&=(clearTimeout(S),null);let e=x;return x=xn(),!e.home&&!e.quotas&&!e.board&&!e.chats.size&&!e.used.size&&!e.prune||(C=C.then(()=>Cn(e)).catch(()=>{})),C}async function Cn(e){try{let t=await yn();e.home&&(w=y(e.home)),e.board&&(T=y(e.board));let n=new Map([...e.chats].map(([e,t])=>{let n=hn(t.items);return[e,{chat:{...t,items:n.items},bytes:n.bytes}]}));await new Promise((r,i)=>{let a=t.transaction([`kv`,`chats`],`readwrite`),o=a.objectStore(`kv`),s=a.objectStore(`chats`);e.home&&o.put(e.home,`home`),e.quotas&&o.put(e.quotas,`quotas`),e.board&&o.put(e.board,`board`);let c=o.get(`index`),l=w?null:o.get(`home`),u=T?null:o.get(`board`),d=s.getAllKeys();d.onsuccess=()=>{let t=new Set(d.result.map(String)),r=bn((Array.isArray(c.result)?c.result:[]).filter(e=>t.has(e?.id)),new Map([...n].map(([e,t])=>[e,t.bytes])),e.used);l?.result&&(w=y(l.result)),u?.result&&(T=y(u.result));let{keep:i}=gn(r,e.prune,w+T),a=new Set(i.map(e=>e.id));for(let[e,t]of n)a.has(e)&&s.put(t.chat,e);for(let e of d.result)a.has(String(e))||s.delete(e);o.put(i,`index`)},a.oncomplete=()=>r(),a.onerror=()=>i(a.error),a.onabort=()=>i(a.error)})}catch{}}typeof document<`u`&&(document.addEventListener(`visibilitychange`,()=>{document.visibilityState===`hidden`&&Sn()}),window.addEventListener(`pagehide`,()=>{Sn()}));async function wn(){let[e,t]=await Promise.all([x.home?Promise.resolve(x.home):b(`kv`,`home`),x.quotas?Promise.resolve(x.quotas):b(`kv`,`quotas`)]);return!e?.state||!Array.isArray(e.state.panes)||!Array.isArray(e.state.workspaces)?null:{state:e.state,quotas:t||null,at:e.at}}async function Tn(){return x.quotas||await b(`kv`,`quotas`)||null}async function En(e){let t=x.chats.get(e)||await b(`chats`,e);return t&&Array.isArray(t.items)&&Number.isFinite(t.at)?t:null}async function Dn(){let e=x.board||await b(`kv`,`board`);return e&&Array.isArray(e.board?.machines)&&Number.isFinite(e.at)?e:null}function On(e,t){x.home={state:e,at:Date.now()},t&&(x.quotas=t),x.prune=e,E()}function kn(e){x.quotas=e,E()}function An(e){x.board={board:e,at:Date.now()},E()}function jn(e,t){x.chats.set(e,{id:e,items:t,at:Date.now()}),x.used.set(e,Date.now()),E()}function Mn(e){x.used.set(e,Date.now()),E()}async function Nn(){return S&&=(clearTimeout(S),null),x=xn(),w=0,T=0,C=C.then(async()=>{try{let e=await yn();await new Promise((t,n)=>{let r=e.transaction([`kv`,`chats`],`readwrite`);r.objectStore(`kv`).clear(),r.objectStore(`chats`).clear(),r.oncomplete=()=>t(),r.onerror=()=>n(r.error)})}catch{}}),C}var Pn=[1,7,30,90,365],Fn=864e5,In=432e5,Ln=`wherdr-offline-access`,Rn=Math.max(...Pn)*Fn+In;function D(e,t=Date.now()){return!!(e&&(!e.enabled||e.expiresAt>t&&e.expiresAt<=t+Rn&&(e.deadline===void 0||e.deadline>t)))}function zn(e,t=Date.now()){if(!e.enabled)return{enabled:!1,expiresAt:0};if(!e.expiresAt)return{enabled:!0,expiresAt:0};let n=t-(e.now??t);return{enabled:!0,expiresAt:e.expiresAt+n,...e.deadline?{deadline:e.deadline+n}:{}}}function Bn(){try{let e=JSON.parse(localStorage.getItem(`wherdr-offline-access`)||`null`);return e&&typeof e.enabled==`boolean`&&Number.isFinite(e.expiresAt)?e:null}catch{return null}}function Vn(e){try{e?localStorage.setItem(Ln,JSON.stringify(e)):localStorage.removeItem(Ln)}catch{}}function Hn(e){return e===`html`?`html`:`webgl`}function Un(e,t){return e===`html`?`html`:t?`webgl`:`html-fallback`}function Wn(e,t,n){if(!e||!e.ok)return t;if(t.ready===!1)return null;if(!n||!t.ok)return t;let r=new Set([``,...(t.machines||[]).filter(e=>e.status===`online`).map(e=>e.key)]),i=new Set(t.panes.map(e=>Ke(e.id))),a=e=>{let t=Ke(e);return t!==``&&!r.has(t)&&!i.has(t)},o=e.panes.filter(e=>a(e.id));if(!o.length)return t;let s=new Set(o.map(e=>Ke(e.id))),c=new Set((t.machines||[]).map(e=>e.key)),l=(e.machines||[]).filter(e=>s.has(e.key)&&!c.has(e.key)).map(e=>({...e,status:`connecting`})),u=t.machines?[]:(e.machines||[]).filter(e=>e.key===``);return{...t,workspaces:[...t.workspaces,...e.workspaces.filter(e=>a(e.id))],tabs:[...t.tabs||[],...(e.tabs||[]).filter(e=>a(e.id))],panes:[...t.panes,...o],machines:[...u,...t.machines||[],...l]}}var O=(e,t)=>t>0?Math.round(e/t*1e4)/100:0;function Gn(e){let{area:t}=e;return Kn(e).map(({pane:e,rect:n})=>({pane:e,left:O(n.x-t.x,t.width),top:O(n.y-t.y,t.height),width:O(n.width,t.width),height:O(n.height,t.height)}))}function Kn(e){return e.panes}function qn(e,t,n){let r=Kn(e).map(e=>e.pane),i=r.indexOf(t);return i<0?null:r[i+n]??null}function Jn(e,t){if(e.layout&&e.layout.panes.length)return e.layout;let n=Math.max(1,t.length);return{tab:e.id,workspace:e.workspace,zoomed:!1,focused:t[0]??null,area:{x:0,y:0,width:120,height:40*n},panes:t.map((e,t)=>({pane:e,rect:{x:0,y:t*40,width:120,height:40}}))}}function Yn(e,t,n,r){let i=e.panes.findIndex(e=>e.pane===t);if(i<0)return e;let a=e.panes[i].rect,[o,s]=n===`right`?[{...a,width:Math.ceil(a.width/2)},{...a,x:a.x+Math.ceil(a.width/2),width:Math.floor(a.width/2)}]:[{...a,height:Math.ceil(a.height/2)},{...a,y:a.y+Math.ceil(a.height/2),height:Math.floor(a.height/2)}],c=[...e.panes];return c.splice(i,1,{pane:t,rect:o},{pane:r,rect:s}),{...e,zoomed:!1,panes:c}}var Xn=[`left`,`right`,`up`,`down`];function Zn(e,t,n){let r=e.panes.find(e=>e.pane===t)?.rect;if(!r)return null;let i=(e,t,n,r)=>Math.min(t,r)-Math.max(e,n),a=null;for(let{pane:o,rect:s}of e.panes){if(o===t)continue;let e=n===`left`||n===`right`,c=n===`left`?s.x+s.width===r.x:n===`right`?r.x+r.width===s.x:n===`up`?s.y+s.height===r.y:r.y+r.height===s.y,l=e?i(r.y,r.y+r.height,s.y,s.y+s.height):i(r.x,r.x+r.width,s.x,s.x+s.width);if(!c||l<=0)continue;let u=e?s.y:s.x;(!a||l>a.len||l===a.len&&u<a.at)&&(a={pane:o,len:l,at:u})}return a?.pane??null}function Qn(e,t){return e.zoomed?[]:Xn.filter(n=>Zn(e,t,n))}function $n(e,t,n){let r=e.panes.find(e=>e.pane===t)?.rect,i=e.panes.find(e=>e.pane===n)?.rect;return!r||!i||t===n?e:{...e,panes:e.panes.map(e=>e.pane===t?{pane:n,rect:r}:e.pane===n?{pane:t,rect:i}:e)}}function er(e){if(!e.splits)return null;let t=new Map(e.splits.map(e=>[e.path,e])),n=(e,r)=>{let i=t.get(e);if(!i)return r.length===1?{pane:r[0].pane}:null;let a=i.direction===`right`,o=a?i.rect.x+i.rect.width*i.ratio:i.rect.y+i.rect.height*i.ratio,s=e=>a?e.x+e.width/2:e.y+e.height/2,c=n(`${e}0`,r.filter(e=>s(e.rect)<o)),l=n(`${e}1`,r.filter(e=>s(e.rect)>=o));return c&&l?{direction:i.direction,ratio:i.ratio,first:c,second:l}:null};return n(``,e.panes)}function tr(e,t){let n=[],r=[],i=(e,t,a)=>{if(`pane`in e){n.push({pane:e.pane,rect:t});return}r.push({path:a,direction:e.direction,ratio:e.ratio,rect:t});let o=e.direction===`right`,s=Math.round((o?t.width:t.height)*e.ratio);i(e.first,o?{...t,width:s}:{...t,height:s},`${a}0`),i(e.second,o?{...t,x:t.x+s,width:t.width-s}:{...t,y:t.y+s,height:t.height-s},`${a}1`)};return i(t,e.area,``),{...e,panes:n,splits:r}}var nr=e=>`pane`in e?e.pane:`${e.direction}(${nr(e.first)},${nr(e.second)})`;function rr(e,t,n,r=.28){if(e.width<=0||e.height<=0)return null;let i=(t-e.left)/e.width,a=(n-e.top)/e.height;if(i<0||i>1||a<0||a>1)return null;let[o,s]=[[`left`,i],[`right`,1-i],[`up`,a],[`down`,1-a]].reduce((e,t)=>t[1]<e[1]?t:e);return s<r?o:`center`}function ir(e,t,n,r){if(e.zoomed||t===n)return null;let i=e.panes.map(e=>e.pane);if(!i.includes(t)||!i.includes(n))return null;if(r===`center`)return $n(e,t,n);let a=er(e);if(!a)return null;let o=e=>{if(`pane`in e)return e.pane===t?null:e;let n=o(e.first),r=o(e.second);return n&&r?{...e,first:n,second:r}:n||r},s=e=>{if(`pane`in e){if(e.pane!==n)return e;let i={pane:t},a=r===`left`||r===`up`;return{direction:r===`left`||r===`right`?`right`:`down`,ratio:.5,first:a?i:e,second:a?e:i}}return{...e,first:s(e.first),second:s(e.second)}},c=o(a);if(!c)return null;let l=s(c);return nr(l)===nr(a)?null:tr(e,l)}function ar(e){if(e.zoomed||!e.splits||!er(e))return[];let{area:t}=e;return e.splits.map(e=>{let n=e.direction===`right`,[r,i,a]=n?[e.rect.x-t.x,e.rect.width,t.width]:[e.rect.y-t.y,e.rect.height,t.height],[o,s,c]=n?[e.rect.y-t.y,e.rect.height,t.height]:[e.rect.x-t.x,e.rect.width,t.width];return{path:e.path,direction:e.direction,ratio:e.ratio,at:O(r+Math.round(i*e.ratio),a),from:O(o,c),span:O(s,c),start:O(r,a),size:O(i,a)}})}function or(e,t,n,r=8){let i=t.size/100*(t.direction===`right`?e.area.width:e.area.height),a=Math.min(.45,Math.max(.05,i>0?r/i:.5)),o=t.size>0?(n-t.start)/t.size:t.ratio;return Math.round(Math.min(1-a,Math.max(a,o))*1e3)/1e3}function sr(e,t,n){let r=er(e);if(!r)return e;let i=(e,r)=>`pane`in e?e:r===t?{...e,ratio:n}:{...e,first:i(e.first,`${r}0`),second:i(e.second,`${r}1`)};return tr(e,i(r,``))}var cr=(e,t)=>e.number-t.number;function lr(e){if(e.tabs)return e.tabs;let t=new Map;for(let n of e.panes)t.has(n.tab)||t.set(n.tab,{id:n.tab,...n.machine?{machine:n.machine}:{},workspace:n.workspace,label:n.tabLabel||``,number:t.size+1,layout:null});return[...t.values()]}function ur(e,t){let n=t.filter(t=>t.tab===e.id),r=new Set(n.map(e=>e.id)),i=e.layout,a=i&&i.panes.length===r.size&&i.panes.every(e=>r.has(e.pane)),o=Jn({...e,layout:a?i:null},n.map(e=>e.id)),s=new Map(n.map(e=>[e.id,e]));return{tab:e,layout:o,panes:Kn(o).map(e=>s.get(e.pane))}}function dr(e,t){let n=e=>t===void 0||(e.machine||``)===t,r=lr(e).filter(n);return e.workspaces.filter(n).sort(cr).map(t=>({workspace:t,tabs:r.filter(e=>e.workspace===t.id).sort(cr).map(t=>ur(t,e.panes))})).filter(e=>e.tabs.some(e=>e.panes.length))}function fr(e,t){let n=lr(e).find(e=>e.id===t);return n?ur(n,e.panes):null}var pr={blocked:0,working:1,done:2,idle:3,unknown:4},mr=e=>e.agent?pr[e.status||`unknown`]??4:9;function hr(e){let t=null;for(let n of e)(!t||mr(n)<mr(t))&&(t=n);return t}function gr(e,t){return dr(e,t).map(e=>{let t=e.tabs.filter(e=>e.panes.length),n=t.flatMap(e=>e.panes),r=hr(n);if(t.length===1&&n.length===1)return{kind:`pane`,key:r.id,pane:r,lead:r};let i=e=>n.filter(t=>t.agent&&t.status===e).length;return{kind:`space`,key:e.workspace.id,workspace:e.workspace,tabs:t,panes:n,lead:r,leadTab:t.find(e=>e.panes.includes(r)),sum:{blocked:i(`blocked`),working:i(`working`),done:i(`done`),agents:n.filter(e=>e.agent).length}}})}function _r(e){return e.agent&&e.status===`blocked`?`blocked`:e.agent&&e.status===`working`?`working`:`ready`}var vr=e=>_r(e.lead);function yr(e,t){if(!t)return[e];let n=e.filter(e=>(e.kind===`space`?e.panes:[e.pane]).some(e=>e.agent&&e.status===`done`));return[n,e.filter(e=>!n.includes(e))].filter(e=>e.length)}var br=[`herdr`,`recent`,`name`];function xr(e,t,n){if(t===`herdr`)return e;let r=e=>Math.max(-1,...(e.kind===`space`?e.panes:[e.pane]).map(e=>e.stateSeq??-1)),i=new Map(e.map(e=>[e,t===`recent`?r(e):n(e)]));return[...e].sort((e,n)=>t===`recent`?i.get(n)-i.get(e):i.get(e).localeCompare(i.get(n),void 0,{sensitivity:`base`,numeric:!0}))}function Sr(e,t,n,r){let i=e.filter(e=>e.panes.length),a=t[n];if(a&&i.some(e=>e.tab.id===a))return a;if(r&&i.some(e=>e.tab.id===r))return r;let o=hr(i.flatMap(e=>e.panes));return o&&i.find(e=>e.panes.includes(o))?.tab.id||i[0]?.tab.id||null}function Cr(e,t){let n=e.workspaces.find(e=>e.id===t);return n&&dr(e,n.machine||``).find(e=>e.workspace.id===t)?.tabs.filter(e=>e.panes.length)||[]}function wr(e,t){let n=e.panes.find(e=>e.tab===t)?.workspace??e.tabs?.find(e=>e.id===t)?.workspace;if(!n)return null;let r=Cr(e,n),i=r.findIndex(e=>e.tab.id===t);return i<0?null:(r[i-1]??r[i+1])?.tab.id??null}var Tr=(e,t)=>t.length===1?{pane:t[0].id}:{tab:e};function Er(e,t,n){if(!n)return null;let r=`pane`in n?e.panes.find(e=>e.id===n.pane):void 0,i=`tab`in n?n.tab:r?.tab,a=r?.workspace??e.panes.find(e=>e.tab===i)?.workspace;if(`workspace`in t)return a===t.workspace?`home`:null;let o=t=>{let n=wr(e,t);return n?Tr(n,e.panes.filter(e=>e.tab===n)):`home`};if(`tab`in t)return i===t.tab?o(t.tab):null;let s=e.panes.find(e=>e.id===t.pane);if(!s||i!==s.tab||r&&r.id!==s.id)return null;let c=(fr(e,s.tab)?.panes||[]).filter(e=>e.id!==s.id);return c.length?`tab`in n&&c.length>1?null:Tr(s.tab,c):o(s.tab)}function Dr(e,t,n,r){let i={...e,[t]:n};if(!r)return i;let a=new Set(r);return Object.fromEntries(Object.entries(i).filter(([e])=>a.has(e)))}function Or(e,t,n){let r=e.filter(e=>e!==t),i=n===null?-1:r.indexOf(n);return i<0?[...r,t]:[...r.slice(0,i),t,...r.slice(i)]}function kr(e,t,n,r){let i=t.indexOf(n);if(i<0||!e.includes(n))return null;let a=t.filter(e=>e!==n),o=Math.max(0,Math.min(a.length,r>i?r-1:r));if(!a.length)return null;let s;if(o<a.length)s=a[o];else{let t=e.filter(e=>e!==n);s=t[t.indexOf(a[a.length-1])+1]??null}return Or(e,n,s).every((t,n)=>t===e[n])?null:{before:s}}function Ar(e,t,n){let r=e.find(e=>e.id===t);if(!r)return e;let i=r.machine||``,a=e.filter(e=>(e.machine||``)===i).sort((e,t)=>e.number-t.number).map(e=>e.id),o=new Map(Or(a,t,n).map((e,t)=>[e,t+1]));return e.map(e=>o.has(e.id)?{...e,number:o.get(e.id)}:e)}function jr(e){return e.kind===`space`?e.tabs.map(e=>{let t=hr(e.panes);return t?.agent?t.status||`unknown`:`shell`}):[]}function Mr(e){let t;try{t=JSON.parse(e||`{}`)}catch{return{}}if(!t||typeof t!=`object`||Array.isArray(t))return{};let n={};for(let[e,r]of Object.entries(t))(e===``||/^[0-9a-f]{4,32}$/.test(e))&&typeof r==`string`&&/^[\w.-]{1,64}$/.test(r)&&(n[e]=r);return n}var Nr=e=>JSON.stringify(e);function Pr(e,t){if(!e.machines)return e;let n=[];for(let r of e.machines.filter(e=>e.baseKey===void 0)){let i=t[r.key];n.push(e.machines.find(e=>e.baseKey===r.key&&e.session===i)||r)}let r=new Set(n.map(e=>e.key)),i=n.find(e=>e.local);return{...e,ok:i?i.status===`online`&&(i.baseKey!==void 0||e.ok):e.ok,version:i?.version||e.version,session:i?.session||e.session,machines:n,workspaces:e.workspaces.filter(e=>r.has(e.machine||``)),tabs:e.tabs?.filter(e=>r.has(e.machine||``)),panes:e.panes.filter(e=>r.has(e.machine||``))}}var Fr=2e3,Ir={fast:1,medium:2,slow:3},Lr={fast:20,medium:40,slow:70},Rr={fast:300,medium:450,slow:650};function zr(e,t=`fast`){return t===`off`?0:Math.round(Math.min(Fr,Math.max(500,400+e*3.5))*Ir[t])}function Br(e,t,n){if(n===`off`||e<=0)return{written:e,decrypted:e,done:!0};let r=zr(e,n),i=Math.min(e,Math.floor(Math.max(0,t)/r*e)),a=Math.min(e,Lr[n]),o=Math.max(0,i-a),s=Math.min(1,Math.max(0,t-r)/Rr[n]);return{written:i,decrypted:Math.min(e,o+Math.floor((e-o)*s)),done:t>=r+Rr[n]}}function Vr(e,t=8){let n=[],r=/\s*\S+\s*/g,i;for(;i=r.exec(e);){let e=i.index+i[0].length;for(let r=i.index+t;r<e-2;r+=t)n.push(r);n.push(e)}return(!n.length||n[n.length-1]!==e.length)&&n.push(e.length),n}function Hr(e,t,n){if(!e.length)return 0;if(t>=n)return e[e.length-1];let r=Math.floor(Math.max(0,t)/n*e.length);return r<=0?0:e[Math.min(r,e.length)-1]}function Ur(e,{atomic:t=()=>!1,keep:n=()=>!1}={}){let r=[],i=[],a=0,o=``,s=e=>{for(let c of Array.from(e.childNodes))if(c.nodeType===3){let e=c.nodeValue||``;if(!e.trim())continue;r.push({node:c,full:e,start:a}),a+=e.length,o+=e}else if(c.nodeType===1){let e={node:c,start:a,text:!1,keep:n(c)};i.push(e),t(c)||s(c),e.text=a>e.start}};return s(e),{texts:r,elems:i,total:a,stops:Vr(o),shown:-1,written:-1}}function Wr(e,t,n=!1,r=t){if(t===e.shown&&r===e.written)return;e.shown=t,e.written=r;for(let n of e.texts){let e=n.full.slice(0,Math.max(0,t-n.start));n.node.nodeValue!==e&&(n.node.nodeValue=e)}let i=n&&r<e.total?r+1:r;for(let t of e.elems){let n=!t.keep&&r<e.total&&(t.text?t.start>=i:t.start>r);!!t.node.hidden!==n&&(t.node.hidden=n)}}var Gr=`#%@&$*+=-/\\|<>01{}[]~^:;_!?`;function Kr(e,t,n,r){return{speed:e===`off`||e===`fast`||e===`medium`||e===`slow`?e:n===`off`||r===`0`?`off`:n===`plain`||n===`terminal`?`fast`:`medium`,encrypted:t===`0`?!1:t===`1`||n!==`plain`}}var qr=(e,t)=>t?`off`:e,Jr=(e,t,n)=>qr(e,n)!==`off`&&t;function Yr(e,t,n){if(n<=t)return[];let r=[];for(let i of e.texts){if(i.start>=n)break;let e=Math.max(0,t-i.start),a=Math.min(i.full.length,n-i.start);a>e&&r.push({node:i.node,text:i.full.slice(e,a)})}return r}function Xr(e,t=Math.random){return Array.from(e,e=>/\s/.test(e)?e:Gr[Math.floor(t()*27)])}function Zr(e){Wr(e,e.total)}var Qr=e=>`${e.ts||``}|${e.text.length}|${e.text.slice(0,64)}`;function $r(e,t,n){let r=null;for(let n of t)e.has(n)||(e.add(n),r=n);return n?r:null}function ei(e){try{let t=JSON.parse(e||`[]`);return Array.isArray(t)?[...new Set(t.filter(e=>typeof e==`string`&&e!==`shell`))]:[]}catch{return[]}}function ti(e,t){let n=new Set(t);return[...new Set(e.filter(e=>e!==`shell`&&!n.has(e))),`shell`]}function ni(e,t,n=``){return t.includes(e)?e:!e&&t.includes(n)?n:t[0]||`shell`}function ri(e,t,n){let r=new Set(t),i=e.agent?.kind||``,a=!e.agent||!e.agents.length||e.agents.includes(i);return[{id:null,label:e.agent?.value||n,isDefault:!0,usable:a,hidden:!!i&&r.has(i)},...[...new Set(e.agents)].filter(e=>e!==i&&!r.has(e)).map(e=>({id:e,label:e,isDefault:!1,usable:!0,hidden:!1}))]}var ii=[`normal`,`wide`,`full`];function ai(e){return ii.includes(e)?e:`normal`}function oi(e,t){return ai(e??t)}var si=`#!/bin/sh
|
|
6
|
-
# wherdr: installs Claude Code's invisible status line (quotas + account
|
|
7
|
-
# fingerprint) for the current user. Self-contained (the status line is included
|
|
8
|
-
# below): wherdr runs it as is on a machine ("Install" button) or
|
|
9
|
-
# hands it out to paste ("Copy command"). Safe to run again:
|
|
10
|
-
# - writes the status line to ~/.claude/wherdr-statusline.sh (update);
|
|
11
|
-
# - no \`statusLine\` in ~/.claude/settings.json: adds ours;
|
|
12
|
-
# - another \`statusLine\` (command): chains it behind ours, its
|
|
13
|
-
# output stays the same; backup copy settings.json.bak-wherdr.
|
|
14
|
-
# Quotas show up after the next exchange with a Claude.
|
|
15
|
-
set -e
|
|
16
|
-
dir="\${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
|
|
17
|
-
mkdir -p "$dir"
|
|
18
|
-
# ---- status line (prints nothing) ----
|
|
19
|
-
cat > "$dir/wherdr-statusline.sh.tmp" <<'WHERDR_STATUSLINE'
|
|
20
|
-
#!/bin/sh
|
|
21
|
-
# wherdr: Claude Code's invisible status line (prints nothing). It only keeps
|
|
22
|
-
# the account quotas (rate_limits, which Claude Code passes to its
|
|
23
|
-
# status line after each exchange) for the wherdr home screen, and an account
|
|
24
|
-
# fingerprint (truncated hash of its ID, never the ID or the email)
|
|
25
|
-
# to tell apart machines that do not use the same account.
|
|
26
|
-
# Installed by install-claude-statusline.sh (wherdr repository, README, "Quotas
|
|
27
|
-
# on the home screen"). Existing status line: passed as an argument, it receives the
|
|
28
|
-
# same data and its output is kept (sh wherdr-statusline.sh 'cmd').
|
|
29
|
-
d=$(cat)
|
|
30
|
-
case "$d" in
|
|
31
|
-
*'"rate_limits"'*)
|
|
32
|
-
dir="$HOME/.cache/herdr-web"
|
|
33
|
-
mkdir -p "$dir"
|
|
34
|
-
# Bind the fingerprint and timestamp to the payload in one atomic rename.
|
|
35
|
-
# No fingerprint TTL: a login change must affect the very next reading.
|
|
36
|
-
printf '%s' "$d" | python3 -c '
|
|
37
|
-
import hashlib, json, os, sys, tempfile, time
|
|
38
|
-
from pathlib import Path
|
|
39
|
-
cache = Path(sys.argv[1])
|
|
40
|
-
config = Path(os.environ.get("CLAUDE_CONFIG_DIR", os.environ["HOME"])) / ".claude.json"
|
|
41
|
-
try:
|
|
42
|
-
account_id = json.loads(config.read_text()).get("oauthAccount", {}).get("accountUuid")
|
|
43
|
-
except (OSError, ValueError, AttributeError):
|
|
44
|
-
account_id = None
|
|
45
|
-
account = hashlib.sha256(("wherdr:" + account_id).encode()).hexdigest()[:16] if isinstance(account_id, str) and account_id else None
|
|
46
|
-
status = json.load(sys.stdin)
|
|
47
|
-
status["_wherdr"] = {"version": 1, "account": account, "at": int(time.time() * 1000)}
|
|
48
|
-
def atomic(name, text):
|
|
49
|
-
fd, temp = tempfile.mkstemp(prefix=name + ".", dir=cache)
|
|
50
|
-
try:
|
|
51
|
-
with os.fdopen(fd, "w") as f:
|
|
52
|
-
f.write(text)
|
|
53
|
-
os.replace(temp, cache / name)
|
|
54
|
-
finally:
|
|
55
|
-
if os.path.exists(temp):
|
|
56
|
-
os.unlink(temp)
|
|
57
|
-
# Compatibility for older readers; new readers use only the embedded account.
|
|
58
|
-
if account:
|
|
59
|
-
atomic("claude-account", account + "\\n")
|
|
60
|
-
else:
|
|
61
|
-
(cache / "claude-account").unlink(missing_ok=True)
|
|
62
|
-
atomic("claude-status.json", json.dumps(status))
|
|
63
|
-
' "$dir" ;;
|
|
64
|
-
esac
|
|
65
|
-
if [ -n "$1" ]; then printf '%s' "$d" | sh -c "$1"; exit $?; fi
|
|
66
|
-
exit 0
|
|
67
|
-
WHERDR_STATUSLINE
|
|
68
|
-
chmod 755 "$dir/wherdr-statusline.sh.tmp"
|
|
69
|
-
mv "$dir/wherdr-statusline.sh.tmp" "$dir/wherdr-statusline.sh"
|
|
70
|
-
echo "status line written: $dir/wherdr-statusline.sh"
|
|
71
|
-
# ---- settings.json ----
|
|
72
|
-
[ -f "$dir/settings.json" ] || echo '{}' > "$dir/settings.json"
|
|
73
|
-
cp "$dir/settings.json" "$dir/settings.json.bak-wherdr"
|
|
74
|
-
python3 - "$dir/settings.json" "$dir/wherdr-statusline.sh" <<'WHERDR_PY'
|
|
75
|
-
import json, shlex, sys
|
|
76
|
-
path, script = sys.argv[1], sys.argv[2]
|
|
77
|
-
d = json.load(open(path))
|
|
78
|
-
ours = 'sh ' + shlex.quote(script)
|
|
79
|
-
cur = d.get('statusLine')
|
|
80
|
-
if isinstance(cur, dict) and 'wherdr-statusline.sh' in str(cur.get('command', '')):
|
|
81
|
-
print('already installed:', cur['command'])
|
|
82
|
-
sys.exit(0)
|
|
83
|
-
if cur is None:
|
|
84
|
-
d['statusLine'] = {'type': 'command', 'command': ours}
|
|
85
|
-
print('status line added:', ours)
|
|
86
|
-
elif isinstance(cur, dict) and cur.get('type') == 'command' and cur.get('command'):
|
|
87
|
-
d['statusLine'] = {**cur, 'command': ours + ' ' + shlex.quote(cur['command'])}
|
|
88
|
-
print('existing status line chained:', d['statusLine']['command'])
|
|
89
|
-
else:
|
|
90
|
-
print('unknown statusLine, nothing changed:', json.dumps(cur), file=sys.stderr)
|
|
91
|
-
sys.exit(1)
|
|
92
|
-
with open(path, 'w') as f:
|
|
93
|
-
json.dump(d, f, indent=2, ensure_ascii=False)
|
|
94
|
-
f.write('\\n')
|
|
95
|
-
WHERDR_PY
|
|
96
|
-
`;function ci(e,t=[]){if(!e)return[];let n=[];return e.claude&&!t.includes(`claude`)&&!((e.claudeAccounts?.length||0)>1)&&n.push({key:`claude`,agent:`claude`,q:e.claude}),e.codex&&!t.includes(`codex`)&&!((e.codexAccounts?.length||0)>1)&&n.push({key:`codex`,agent:`codex`,q:e.codex}),n}function li(e,t,n=[]){if(!e)return[];let r=[];for(let i of[`claude`,`codex`]){let a=i===`claude`?e.claudeAccounts:e.codexAccounts;if(n.includes(i)||(a?.length||0)<2)continue;let o=a.find(e=>e.machines.some(e=>e.key===t));if(!o)continue;let{machines:s,...c}=o;r.push({key:`${i}:${t}`,agent:i,q:c})}return r}function ui(e,t){return[`claude`,`codex`].flatMap(n=>[...e,...t].filter(e=>e.agent===n))}function di(e,t){return e?.claudeSetup?.find(e=>e.key===t)||null}function fi(e,t,n,r=[]){if(!n||r.includes(`claude`))return null;let i=di(e,t);return i&&(i.state===`missing`||i.state===`outdated`)&&!i.dismissed?i:null}var pi=`sh <<'WHERDR_INSTALL'\n${si.trimEnd()}\nWHERDR_INSTALL\n`;function mi(e,t){return e.resetsAt&&e.resetsAt<=t?100:Math.round(100-e.used)}function hi(e){return e===`used`?`used`:`left`}function gi(e,t,n){let r=mi(e,t);return n===`used`?100-r:r}var _i=(e,t)=>{let n=mi(e,t);return n<=15?`hi`:n<=40?`mid`:`lo`},vi=36e5;function yi(e,t,n){if(!e.resetsAt)return``;if(e.resetsAt<=t)return null;let r=new Date(e.resetsAt),i=r.toLocaleTimeString(n,{hour:`2-digit`,minute:`2-digit`});return e.resetsAt-t<864e5?i:`${r.toLocaleDateString(n,{weekday:`short`})} ${i}`}function bi(e,t){return t.flatMap(t=>{let n=t.online?di(e,t.key):null;return!t.kinds.includes(`claude`)&&(!n||n.state===`missing`)?[]:[{key:t.key,name:t.name,online:t.online,setup:n}]})}function xi(e){return e!==`0`}function Si(e){return e===`state`?`state`:`machine`}function Ci(e,t){let n=e.coordinators.map(e=>({row:e.row,level:e.level}));for(let r of e.projects){r.coordinator&&n.push({row:r.coordinator,repo:r.repo,level:`project`}),r.space&&(r.space.lead.agent||t)&&n.push({row:r.space,repo:r.repo});for(let e of r.members)(e.row.lead.agent||t)&&n.push({row:e.row,repo:r.repo,member:e})}return n.push(...e.others.filter(e=>e.lead.agent||t).map(e=>({row:e}))),n}function wi(e,t){let n=e=>e.baseKey??e.key,r=e.filter(e=>t===null||t.includes(n(e)));return t&&r.sort((e,r)=>t.indexOf(n(e))-t.indexOf(n(r))),{online:r.filter(e=>e.status===`online`),away:r.filter(e=>e.status!==`online`)}}var Ti=`compactListV2`,Ei=`compactList`;function Di(e){return e===`1`}function Oi(e){let t=e.tabs??0,n=e.panes??0;return{dots:t>1,panes:t<=1&&n>1?n:null}}function ki(e){return e.status===`blocked`&&!!(e.preview||e.detail||e.choices)}var Ai=(e,t)=>t-e>=400;function ji(e=1e3){let t=!1,n=0,r=null;return{shown:()=>t,mount(){n++,!t&&!r&&(r=setTimeout(()=>{t=!0,r=null},e))},unmount(){--n>0||(n=0,t=!1,r&&clearTimeout(r),r=null)}}}function Mi(e){let t=e.chat&&(e.live||e.desk&&e.cell);return{selector:t&&e.desk?e.cell?`cell`:`header`:null,term:t&&!e.desk}}function Ni(e){return(e.live||!!(e.desk&&e.cell))&&(!e.desk||e.mode!==`term`)}function Pi(e){return e.chat&&e.viewMode!==`term`?`chat`:`term`}function Fi(e){return e.desk?e.defaultMode:`chat`}function Ii(e){return e.desk&&e.live&&e.available&&e.mode===`term`}function Li(e){return{row:e>1,headerAdd:e===1}}function Ri(e,t){return e===t?`chat`:t}function zi(e){return!e.altKey||!(e.ctrlKey||e.metaKey)||e.shiftKey?0:{ArrowLeft:-1,ArrowUp:-1,ArrowRight:1,ArrowDown:1}[e.key]??0}function Bi(e){return!e.desk||e.coarse}var Vi=[`lines`,`native`],Hi=`native`,Ui=`quoteMode`,Wi=[`quoteModeComputer`,`quoteModePhone`,`quoteTokensComputer`,`quoteTokensPhone`];function Gi(e){let t=e.getItem(Ui);if(Vi.includes(t))return t;for(let t of Wi)e.removeItem(t);return e.setItem(Ui,Hi),Hi}function Ki(e,t){let n=new Map,r=0;function i(e){let t=n.get(e);if(t)return n.delete(e),r-=t.weight,t.value}return{get(e){let t=n.get(e);if(t)return n.delete(e),n.set(e,t),t.value},set(a,o,s){if(i(a),!(s>t))for(n.set(a,{value:o,weight:s}),r+=s;n.size>e||r>t;)i(n.keys().next().value)},delete:i,stats:()=>({entries:n.size,weight:r}),clear(){n.clear(),r=0}}}function qi(e=8){let t=[];return n=>{let r=[];for(let e=t.length-1;e>=0;e--){let i=t[e];i===n?t.splice(e,1):n.length>i.length&&n.startsWith(i)&&r.push(...t.splice(e,1))}return t.push(n),t.length>e&&t.shift(),r}}var k=e=>e.replace(/\s+/g,` `).trim(),Ji=/\?[\s"'»”’)\]*_~]*$/,Yi=/\?\s*["'»”’][\s"'»”’)\]*_~]*$/,Xi=/(?<=[.!?…]["'»”’)\]*_~]*)\s+(?=[^?!:;»\p{Ll}])/gu,Zi=/^[\s"'«“‘(*_~]*(?:yes|yep|no|nope|because|oui|non|si|parce\s+qu|car)(?![\p{L}\p{N}])/iu,Qi=e=>e.match(/[\p{L}\p{N}]+/gu)?.length||0,$i=e=>Ji.test(e)&&!Yi.test(e)&&Qi(e)>0;function ea(e){if(!e.includes(`?`))return[];let t=[],n=0,r=r=>{let i=e.slice(n,r),a=n+i.length-i.trimStart().length,o=n+i.trimEnd().length;o>a&&t.push({start:a,end:o,q:$i(e.slice(a,o))})};for(let t of e.matchAll(Xi))r(t.index),n=t.index+t[0].length;r(e.length);let i=[];for(let n=0;n<t.length;n++){if(!t[n].q)continue;let r=n;for(;r+1<t.length&&t[r+1].q;)r++;let a=t[n].start,o=t[r].end,s=t[r+1],c=k(e.slice(a,o));s&&(Zi.test(e.slice(s.start,s.end))||n===r&&Qi(c)<2)||i.push({text:c,start:a,end:o}),n=r}return i}var ta=Re,na=(e,t)=>Re(e).find(e=>Le(e,t))||null,A=(e,t)=>na(e,t)!==null;function ra(e,t){let n=Ne(t);if(!n||A(e,t))return null;let r=String(e||``).replace(/\s+$/,``);return`${r}${r?Ie(r.slice(r.lastIndexOf(`
|
|
97
|
-
`)+1))?`
|
|
98
|
-
|
|
99
|
-
`:`
|
|
100
|
-
`:``}${n}\n`}function ia(e,t){return(e.slice(0,t.start)+e.slice(t.end)).replace(/^\n+/,``)}var aa=RegExp(`^(?:${[`(?:shall|should|can|could|may|will|would|do|does|did|is|are|was|were|have|has|am|must)\\s+(?:i|we|you|it|this|that|these|those|there|they|he|she|the|your|my|our|everything|anything|all)(?![\\p{L}\\p{N}'’])`,`(?:want me to|ok(?:ay)? (?:to|if|for|with)|sounds? good|good to go|go ahead|proceed|ready (?:to|for)|agreed|makes? sense|all good)(?![\\p{L}\\p{N}])`,`est-ce(?![\\p{L}\\p{N}])`,`(?:je|tu|vous|nous|ça)\\s`,`on\\s+(?!(?:the|a|an|this|that|these|those|my|your|our|its|top|main|all|both|each|every)(?![\\p{L}\\p{N}]))`,`(?:j|c)['’]\\p{L}`,`(?:ok|d['’]accord) pour(?![\\p{L}\\p{N}])`,`\\p{L}+-(?:t-)?(?:je|tu|il|elle|on|nous|vous|ils|elles)(?![\\p{L}\\p{N}])`].map(e=>`(?:${e})`).join(`|`)})`,`iu`),oa=/,\s*(?:ok|okay|right|agreed|d['’]accord|ça te va|ça vous va|c['’]est bon|non)\s*\?[\s"'»”’)\]*_~]*$/iu,sa=/^(?:and|so|then|also|but|now|et|donc|alors|sinon|mais|du coup)[,\s]+/iu,ca=/(?<![\p{L}\p{N}])(?:or|ou|ou bien|plutôt|either|versus|vs)(?![\p{L}\p{N}])/iu,la=/(?<![\p{L}\p{N}])(?:what|which|who|whom|whose|where|when|why|how|quel|quels|quelle|quelles|quoi|comment|combien|pourquoi|lequel|laquelle|lesquels|lesquelles)(?![\p{L}\p{N}])/iu,ua=/(?<![\p{L}\p{N}])(?:où|quand|qui)\s*\?/iu,da=/(?<![\p{L}\p{N}])(?:not|never|ne|pas|jamais)(?![\p{L}\p{N}])|n['’]t(?![\p{L}\p{N}])|(?<![\p{L}\p{N}])n['’]\p{L}/iu;function fa(e){let t=k(e);return $i(t)&&(ca.test(t)||la.test(t)||ua.test(t))}function pa(e){let t=k(e);return(t.match(/\?/g)||[]).length!==1||!$i(t)||ca.test(t)||la.test(t)||ua.test(t)||da.test(t)?!1:oa.test(t)?!0:[t,t.slice(t.lastIndexOf(`: `)+1)].some(e=>{let t=e.replace(/^[\s"'«“‘(*_~]+/,``);for(let e=sa.exec(t);e;e=sa.exec(t))t=t.slice(e[0].length);return aa.test(t)})}var ma={yes:/^(?:yes|oui)\.?$/i,no:/^(?:no|non)\.?$/i},ha=e=>{let t=e.trim();return ma.yes.test(t)?`yes`:ma.no.test(t)?`no`:null};function ga(e,t){let n=Re(e),r=n.findIndex(e=>Le(e,t));return r<0?null:{start:n[r].end,end:n[r+1]?.start??e.length}}function _a(e,t){let n=ga(e,t);return n?e.slice(n.start,n.end).trim():null}function va(e,t){let n=String(e||``),r=ga(n,t);if(!r)return n.length;let i=n.slice(r.start,r.end).replace(/\s+$/,``);return i.trim()?r.start+i.length:r.start}function ya(e,t,n){let r=ra(e,t)??String(e||``),i=ga(r,t);if(!i)return null;let a=r.slice(i.start,i.end).trim();if(a===n||a&&!ha(a))return null;let o=r.slice(0,i.start);return`${o}${o.endsWith(`
|
|
101
|
-
`)?``:`
|
|
102
|
-
`}${n}\n${r.slice(i.end)}`}var ba=/^(?:#|n[°º]|no\.?|num(?:[ée]ro)?\.?|id|q)$/i,xa=/^(?:[#qd]|n[°º])?\s*\d{1,3}[.)]?$/i,Sa=/question|d[ée]cision|choix|choice|to decide|à décider|à trancher/i,Ca=/avis|recomm|suggestion|proposition|proposal|opinion|my take|my pick|conseil|advice/i;function wa(e,t){let n=e.map(k),r=t.map(e=>e.map(k));if(n.length<2||!r.length||r.some(e=>e.length<n.length))return null;let i=e=>r.map(t=>t[e]),a=e=>e.replace(/[.)]$/,``),o=n.findIndex((e,t)=>ba.test(e)&&i(t).every(e=>xa.test(e))&&new Set(i(t).map(e=>a(e).toLowerCase())).size===r.length);if(o<0)return null;let s=n.map((e,t)=>t).filter(e=>e!==o),c=s.filter(e=>Ca.test(n[e])),l=s.find(e=>Sa.test(n[e])&&!c.includes(e));return l??=s.find(e=>i(e).every($i)),l===void 0&&c.length&&(l=s.find(e=>!c.includes(e))),l===void 0||i(l).some(e=>!Qi(e))?null:r.map(e=>({n:a(e[o]),text:e[l]}))}function Ta(e){let t=[];for(let n of e){let e=t.at(-1),r=e?/^(\D*)(\d+)$/.exec(e.at(-1)):null,i=/^(\D*)(\d+)$/.exec(n);e&&r&&i&&r[1]===i[1]&&Number(i[2])===Number(r[2])+1?e.push(n):t.push([n])}return t.map(e=>e.length>1?`${e[0]}-${e.at(-1)}`:e[0]).join(`,`)}var Ea=e=>({n:Ta(e.map(e=>e.n)),text:e.map(e=>e.text).join(` · `)}),Da=(e,t,n)=>Me(e.n,e.text,t,!1,Oe(n,e.table)),Oa=(e,t,n,r=1)=>Me(e.n,e.text,t,!0,Oe(n,r)),ka=/^ok\s+(?:to\s+all|tout|pour\s+tout)\s*[.!]?$/i;function Aa(e,t,n){let r=na(e,t);if(!r)return ya(e,t,n)??e;let i=ga(e,t),a=ka.test(e.slice(i.start,i.end).trim())?i.end:r.end;return(e.slice(0,r.start)+e.slice(a)).replace(/^\n+/,``)}var ja=(e,t,n,r)=>A(e,Da(t,n,r))||!!(t.all&&A(e,Oa(t.all,n,r,t.table)));function Ma(e,t,n,r){let i=e.questions.filter(e=>!A(t,je(e.text,n,r))).length+e.rows.filter(e=>!ja(t,e,n,r)).length;return e.questions.length+e.rows.length===1&&String(t||``).split(`
|
|
103
|
-
`).some(e=>e.trim()&&!Ie(e))?0:i}var Na=/^(UL|OL|PRE|DIV|BLOCKQUOTE|TABLE)$/;function Pa(e){let t=[],n=``,r=``,i=(e,a)=>{for(let o of e.childNodes)if(o.nodeType===3){let e=o.data;t.push({node:o,start:n.length}),n+=e,r+=a?e.replace(/[?!.…]/g,`x`):e}else if(o.nodeType===1){let e=o.tagName;if(Na.test(e))return!1;if(e===`BR`)n+=`
|
|
104
|
-
`,r+=`
|
|
105
|
-
`;else if(!i(o,a||e===`CODE`||e===`KBD`))return!1}return!0};return i(e,!1),{parts:t,raw:n,masked:r}}var Fa=[`icon`,`text`,`list`],Ia=e=>Fa.includes(e||``)?e:`icon`,La=3,Ra=e=>Qi(e)>=La&&!/[::]$/.test(e.trim());function za(e,t){let n=new Map;for(let r of e.querySelectorAll(`p, li`)){if(r.closest(`pre, code, .code-block, blockquote, table`)||r.tagName===`LI`&&r.querySelector(`:scope > p`))continue;let{parts:e,raw:i,masked:a}=Pa(r),o=i.trimEnd().length,s=ea(a);if(!s.length&&Ra(i)){let e=k(i),n=document.createElement(`button`);n.type=`button`,n.className=`q-point`,n.dataset.q=e,n.dataset.l=t.discuss,n.dataset.lq=t.quoted,n.setAttribute(`aria-label`,`${t.discuss}: ${e}`),r.classList.add(`q-pt`),r.insertBefore(n,[...r.children].find(e=>Na.test(e.tagName))||null)}for(let{start:a,end:c}of s.reverse()){let s=e.findLast(e=>e.start<c);if(!s)continue;let l=k(i.slice(a,c)),u=document.createElement(`button`);u.type=`button`,u.className=c<o?`q-reply q-mid`:`q-reply`,u.dataset.q=l,u.dataset.l=t.reply,u.dataset.lq=t.quoted,u.setAttribute(`aria-label`,`${t.reply}: ${l}`);let d=c-s.start;d<s.node.data.length&&s.node.splitText(d);let f=s.node;for(;f.parentNode&&f.parentNode!==r&&(!f.nextSibling||/^(A|CODE|KBD)$/.test(f.parentNode.tagName));)f=f.parentNode;if(f.parentNode.insertBefore(u,f.nextSibling),pa(l)){u.dataset.c=`1`;for(let e of[`no`,`yes`]){let n=document.createElement(`button`);n.type=`button`,n.className=`q-ans q-${e}`,n.dataset.q=l,n.dataset.a=e,n.dataset.l=t[e],n.setAttribute(`aria-label`,`${t[e]}: ${l}`),n.setAttribute(`aria-pressed`,`false`),u.after(n)}}let ee=[];for(let t of e.filter(e=>e.start<c).reverse()){let e=t.node.data.length;if(t.start+e<=a)break;let n=Math.max(0,a-t.start),r=Math.min(e,c-t.start);if(r<=n)continue;r<e&&t.node.splitText(r);let i=n>0?t.node.splitText(n):t.node;if(!i.data.trim())continue;let o=document.createElement(`span`);o.className=`q-text`,i.replaceWith(o),o.appendChild(i),ee.push(o)}n.set(u,ee)}}Ba(e,t);let r=0;for(let t of e.querySelectorAll(`.q-reply`)){t.dataset.n=String(++r);for(let e of n.get(t)||[])e.dataset.n=t.dataset.n}}function Ba(e,t){let n=e=>[...e.children].filter(e=>/^T[DH]$/.test(e.tagName)).map(e=>e.textContent||``),r=0;for(let i of e.querySelectorAll(`table`)){if(i.closest(`pre, code, .code-block, blockquote`)||i.parentElement?.closest(`table`))continue;let e=i.querySelector(`:scope > thead > tr`),a=e?wa(n(e),[...i.querySelectorAll(`:scope > tbody > tr`)].map(n)):null;if(!a)continue;let o=(e,t,n,r)=>{let i=document.createElement(e);return i.className=t,Object.assign(i.dataset,n),e===`button`&&(i.type=`button`),r&&i.setAttribute(`aria-label`,r),i},s=o(`div`,`q-table`,{t:String(++r)},t.decisions);s.setAttribute(`role`,`group`);let c=o(`div`,`q-table-h`,{l:t.decisions});if(a.length>1){let e=Ea(a),n=o(`button`,`q-all`,{l:t.okAll,n:e.n,q:e.text},t.okAll);n.setAttribute(`aria-pressed`,`false`),c.append(n)}s.append(c);for(let e of a){let n=o(`div`,`q-trow`,{n:e.n,q:e.text});n.append(o(`span`,`q-tl`,{n:e.n,l:e.text}));for(let r of fa(e.text)?[]:[`yes`,`no`]){let i=o(`button`,`q-tans q-${r}`,{n:e.n,a:r,l:t[r]},`${e.n} · ${t[r]}: ${e.text}`);i.setAttribute(`aria-pressed`,`false`),n.append(i)}n.append(o(`button`,`q-tquote`,{n:e.n,l:t.reply,lq:t.quoted},`${t.reply}: ${e.n}. ${e.text}`)),s.append(n)}i.after(s)}}var Va=6e6,Ha=3e6,Ua=2e3,Wa=Ki(Ua,Va);function Ga(e,t){if(typeof document>`u`)return e;let n=`${t.reply}\u0000${t.discuss}\u0000${t.yes}\u0000${t.okAll}`,r=Wa.get(e);if(r&&r.labels===n)return r.out;let i=document.createElement(`template`);i.innerHTML=e,za(i.content,t);let a=i.innerHTML;return Wa.set(e,{labels:n,out:a},e.length+a.length),a}function Ka(e){let t=Wa.delete(e);Ya.delete(t?t.out:e)}var qa=e=>Number(e.closest(`.q-table`)?.dataset.t)||1;function Ja(e){let t=e.closest(`.q-table`)?.querySelector(`.q-all`);return{n:e.dataset.n||``,text:e.dataset.q||``,all:t?{n:t.dataset.n||``,text:t.dataset.q||``}:null,table:qa(e)}}var Ya=Ki(Ua,Ha);function Xa(e){let t=Ya.get(e);if(!t){if(t={questions:[],rows:[],points:0,pick:!1},typeof document<`u`&&e.includes(`class="q-`)){let n=document.createElement(`template`);n.innerHTML=e,t.questions=[...n.content.querySelectorAll(`.q-reply`)].map(e=>({n:e.dataset.n||``,text:e.dataset.q||``,closed:e.dataset.c===`1`})),t.rows=[...n.content.querySelectorAll(`.q-trow`)].map(Ja);let r=[...n.content.querySelectorAll(`.q-point`)];t.points=r.length,t.pick=r.length>1||r.some(e=>e.closest(`li`))}Ya.set(e,t,e.length)}return t}var Za=`notificationRules,theme,focusBorder,backdrop,backdropPackets,machineBar,machineBarOrder,machineBarHidden,machineGroups,compactListV2,homeGrouping,collapsedMachines,collapsedRepos,showShells,showCounters,showQuotas,quotaDisplay,autoReorderReady,readySort,hiddenAgents,typewriterSpeed,encryptedText,replyStyle,defaultViewMode,boardGrouping,boardDone,boardFolds,wherdr.files.hidden,wherdr.files.md`.split(`,`),Qa=16384,$a=new Set(Za),eo=e=>$a.has(e),to=`syncedSettingsPending`,no=`syncedSettingsMigrated`;function ro(e){let t=new Map;try{let n=JSON.parse(e||`{}`);if(n&&typeof n==`object`&&!Array.isArray(n))for(let[e,r]of Object.entries(n))eo(e)&&(r===null||typeof r==`string`)&&t.set(e,r)}catch{}return t}function io(e){let{local:t}=e,n=e.transport,r=e.delay??300,i=new Map,a=ro(t.get(to));function o(){a.size?t.set(to,JSON.stringify(Object.fromEntries(a))):t.remove(to)}let s=null,c=null,l=null;function u(e,n){n===null?t.remove(e):t.set(e,n)}function d(e,n){let r=n?Za:Object.keys(e).filter(eo);for(let n of r){if(a.has(n))continue;let r=e[n]??null;if(r!==t.get(n)){u(n,r);for(let e of i.get(n)||[])e(r)}}}async function f(){if(s&&=(clearTimeout(s),null),c&&await c.catch(()=>{}),!n||!a.size)return!0;let e=Object.fromEntries(a),t=(async()=>{try{let t=await n.post(e,!1);for(let[t,n]of Object.entries(e))a.get(t)===n&&a.delete(t);return o(),d(t,!0),!0}catch{return!1}})();c=t;try{return await t}finally{c===t&&(c=null)}}function ee(){s&&clearTimeout(s),s=setTimeout(()=>{s=null,f()},r)}return{setTransport(e){n=e},bind(e,t){return i.has(e)||i.set(e,new Set),i.get(e).add(t),()=>{i.get(e)?.delete(t)}},write(e,r){(r!==t.get(e)||a.has(e))&&(u(e,r),a.set(e,r),o(),n&&ee())},load(){return l||(l=(async()=>{if(!n)return;let e;if(t.get(`syncedSettingsMigrated`)!==`1`){let r={};for(let e of Za){let n=t.get(e);n!==null&&(r[e]=n)}e=Object.keys(r).length?await n.post(r,!0):await n.get(),t.set(no,`1`)}else e=await n.get();a.size?await f():d(e,!0)})().catch(()=>{}).finally(()=>{l=null}),l)},receive(e){d(e,!1)},flush:f,get pendingKeys(){return[...a.keys()]}}}var j=io({local:{get(e){try{return localStorage.getItem(e)}catch{return null}},set(e,t){try{localStorage.setItem(e,t)}catch{}},remove(e){try{localStorage.removeItem(e)}catch{}}}});function M(e,t,r,o={}){let c=()=>{try{return localStorage.getItem(e)}catch{return null}},l=i(t(c())),u=j.bind(e,e=>{l.value=t(e)});return a(l,n=>{let i=r(n);i!==r(t(c()))&&j.write(e,i)},{deep:o.deep}),s()&&n(u),l}var N={read:e=>t=>t===null?e:t!==`0`,write:e=>e?`1`:`0`},P={get(e){try{return localStorage.getItem(e)}catch{return null}},set(e,t){try{localStorage.setItem(e,t)}catch{}}},F=r({ok:!1,workspaces:[],panes:[]}),I=F.value,ao=r(I);function oo(){return Mr(P.get(`machineSessions`))}var L=i(oo());function so(e){L.value=e,P.set(`machineSessions`,Nr(e)),F.value=Pr(I,e)}async function co(e){return(await Z(`/api/sessions?machine=${encodeURIComponent(e)}`)).sessions}async function lo(e,t){let n=await Z(`/api/sessions`,{machine:e,name:t});so({...L.value,[e]:t}),J.value=n.session.key,Rt().catch(()=>{}),await Cs()}var uo=new Map;async function fo(){for(let[e,t]of Object.entries(L.value)){if(!t||I.machines?.some(n=>n.key===e&&n.session===t)||I.machines?.some(n=>n.baseKey===e&&n.session===t))continue;let n=Date.now();n-(uo.get(e)||0)<1e4||(uo.set(e,n),Z(`/api/sessions`,{machine:e,name:t}).catch(()=>{}))}}async function po(){for(let[e,t]of Object.entries(L.value))if(t&&!I.machines?.some(n=>n.key===e&&n.session===t))try{if(!(await co(e)).some(e=>e.name===t&&e.running)){let t={...L.value};delete t[e],so(t),Rt().catch(()=>{}),J.value&&!I.machines?.some(e=>e.key===J.value&&!e.baseKey)&&(J.value=e),X(h(`Session unavailable: back to the default session`))}}catch{}}var R=i(!1),mo=i(!1),z=i(null),ho=e(()=>z.value!==null),B=i(!1),V=i({kinds:[`claude`,`codex`],home:``,dirs:[],push:{enabled:!1,key:null,devices:0}}),go=i(``),_o=e(()=>`wherdr`),vo=i(null),yo=i(!0),bo=M(`showShells`,xi,N.write),xo=M(`showCounters`,N.read(!0),N.write),So=M(`showQuotas`,N.read(!0),N.write),Co=M(`homeGrouping`,Si,e=>e),wo=M(Ti,Di,N.write);try{localStorage.removeItem(Ei)}catch{}var To=M(`autoReorderReady`,N.read(!0),N.write),Eo=M(`readySort`,e=>br.includes(e||``)?e:`herdr`,e=>e),Do=M(`quotaDisplay`,hi,e=>e),Oo=M(`hiddenAgents`,ei,e=>JSON.stringify(e),{deep:!0}),ko=i(oi(P.get(`contentWidth`),P.get(`chatWidth`)));a(ko,e=>{P.set(`contentWidth`,e);try{localStorage.removeItem(`chatWidth`)}catch{}document.documentElement.dataset.contentWidth=e},{immediate:!0});var Ao=Kr(P.get(`typewriterSpeed`),P.get(`encryptedText`),P.get(`typewriterMode`),P.get(`typewriter`));P.set(`typewriterSpeed`,Ao.speed),P.set(`encryptedText`,Ao.encrypted?`1`:`0`);var jo=M(`typewriterSpeed`,e=>Kr(e,`0`,null,null).speed,e=>e),Mo=M(`encryptedText`,N.read(!0),N.write),H=i(!1);{let e=matchMedia(`(prefers-reduced-motion: reduce)`);H.value=e.matches,e.addEventListener(`change`,e=>{H.value=e.matches})}var No=e(()=>qr(jo.value,H.value)),Po=e(()=>No.value!==`off`),Fo=e(()=>Jr(jo.value,Mo.value,H.value));function Io(){try{return Gi(localStorage)}catch{return Hi}}var Lo=i(Io());a(Lo,e=>P.set(Ui,e));var Ro=M(`replyStyle`,Ia,e=>e),zo=i(null),Bo=i(Number(P.get(`fontSize`))||12);a(Bo,e=>P.set(`fontSize`,String(e)));var U=i(Hn(P.get(`terminalRenderer`)));a(U,e=>P.set(`terminalRenderer`,e));var Vo=i(P.get(`agentClipboard`)!==`0`);a(Vo,e=>P.set(`agentClipboard`,e?`1`:`0`));var Ho=i(null),W=i(null);function Uo(e){Ho.value=e,e!==`html`&&(W.value=e===`webgl`)}function Wo(){if(U.value===`html`){Ho.value=`html`;return}if(W.value===null)try{let e=document.createElement(`canvas`).getContext(`webgl2`);W.value=!!e,e?.getExtension(`WEBGL_lose_context`)?.loseContext()}catch{W.value=!1}Ho.value=Un(U.value,W.value===!0)}window.addEventListener(`storage`,e=>{e.key===`terminalRenderer`&&(U.value=Hn(e.newValue),Wo())});function Go(){try{let e=JSON.parse(P.get(`viewModes`)||`{}`);return e&&typeof e==`object`?e:{}}catch{return{}}}var G=t(Go()),Ko=M(`defaultViewMode`,e=>e===`term`?`term`:`chat`,e=>e),qo=e=>G[e]===`term`||G[e]===`chat`?G[e]:Fi({desk:Zo.value,defaultMode:Ko.value});function Jo(e,t){G[e]=t,P.set(`viewModes`,JSON.stringify(G))}function Yo(e){if(!e.ok)return;let t=new Set(I.panes.map(e=>e.id)),n=new Set([``,...(I.machines||[]).filter(e=>e.status===`online`).map(e=>e.key)]),r=!1;for(let e of Object.keys(G))!t.has(e)&&n.has(Ge(e).machine)&&(delete G[e],r=!0);r&&P.set(`viewModes`,JSON.stringify(G))}a(F,Yo);var Xo=i(P.get(`lastKind`)||``);a(Xo,e=>P.set(`lastKind`,e));var Zo=i(!1),Qo=i(!1),$o=i(!1),es=i(!1),ts=i(!1);{let e=matchMedia(cn);es.value=e.matches,e.addEventListener(`change`,()=>{es.value=e.matches}),window.addEventListener(`keydown`,e=>{fn(e)&&(ts.value=!0)},!0);let t=()=>{ts.value=!1};window.addEventListener(`pointerdown`,e=>{e.pointerType===`touch`&&t()},!0),window.addEventListener(`touchstart`,t,{capture:!0,passive:!0}),window.addEventListener(`focusout`,e=>{e.target?.closest?.(`.prompt`)&&t()},!0)}{let e=matchMedia(an),t=matchMedia(un),n=()=>{Zo.value=e.matches,Qo.value=e.matches&&t.matches};n(),e.addEventListener(`change`,n),t.addEventListener(`change`,n)}var ns=i(!1);{let e=matchMedia(`(pointer: coarse)`);ns.value=e.matches,e.addEventListener(`change`,()=>{ns.value=e.matches})}var rs=e(()=>Bi({desk:Zo.value,coarse:ns.value})),is=e(()=>F.value.panes.find(e=>e.id===vo.value)),K=e(()=>F.value.machines||[]),as=e(()=>K.value.length>1||!!K.value[0]?.baseKey),q=e=>K.value.find(t=>t.key===(e||``)),os=e=>q(e)?.os||(e?void 0:V.value.os),ss=e=>!!(e?.cwd&&os(e.machine)===`Darwin`),cs=e(()=>as.value?(V.value.machines||[]).filter(e=>K.value.some(t=>t.key===e.key)):null),ls=e=>e.local||q(e.key)?.status===`online`&&!!e.home,us=e=>e.local?`online`:q(e.key)?.status||`offline`,ds=e=>{let t=q(e);return t?t.label||h(`This machine`):``},fs=e=>{let t=e?q(e.machine):void 0;return!!(t&&t.status!==`online`)};function ps(e){try{let t=JSON.parse(e||`[]`);return Array.isArray(t)?t.map(String):[]}catch{return[]}}var ms=M(`collapsedMachines`,ps,e=>JSON.stringify(e),{deep:!0}),hs=M(`collapsedRepos`,ps,e=>JSON.stringify(e.slice(-200)),{deep:!0}),J=i(P.get(`lastMachine`)||``);a(J,e=>P.set(`lastMachine`,e));var Y=null;function gs(e){Y=e}function _s(){Y?.clear()}var vs=6e3;function X(e,t=!1,n,r){Y&&(Y.clear(),Y.add({title:e,description:n||void 0,color:t?`error`:`neutral`,class:t?`hw-toast-error`:void 0,icon:t?`i-lucide-circle-alert`:void 0,duration:r?vs:(t?4200:2600)+(n?2400:0),close:!1,...r?{orientation:`horizontal`,actions:[{label:r.label,icon:r.icon,color:`neutral`,variant:`outline`,size:`xs`,class:`hw-toast-action`,onClick:()=>r.run()}]}:{}}))}function ys(e,t,n){Y&&(Y.clear(),Y.add({title:e,color:`neutral`,duration:1e4,close:!1,orientation:`horizontal`,actions:[{label:t,color:`primary`,variant:`solid`,onClick:n}]}))}var bs=class extends Error{code;status;constructor(e,t,n){super(e),this.status=t,this.code=n}};async function Z(e,t,n){let r=t===void 0?{signal:n}:{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t),signal:n},i=await fetch(e,r),a=await i.json().catch(()=>(n?.throwIfAborted(),{}));i.status===401&&a.code===`locked`&&!e.startsWith(`/api/auth/`)&&Bs();let o=a.code===`agent_not_ready`?`The agent isn’t ready in this pane (stopped or still starting).`:null;if(!i.ok&&a.code===`projects_failed`&&a.error)throw new bs(String(a.error),i.status,a.code);if(!i.ok)throw new bs(h(o||a.error||`HTTP ${i.status}`),i.status,a.code);return a}j.setTransport({get:async()=>(await Z(`/api/settings`)).settings,post:async(e,t)=>(await Z(`/api/settings`,{settings:e,migrate:t})).settings});async function xs(e,t){let n=await fetch(e);if(!n.ok){let e=await n.json().catch(()=>({}));throw n.status===401&&e.code===`locked`&&Bs(),new bs(h(e.error||`HTTP ${n.status}`),n.status,e.code)}let r=URL.createObjectURL(await n.blob()),i=document.createElement(`a`);i.href=r,i.download=t,document.body.appendChild(i),i.click(),i.remove(),setTimeout(()=>URL.revokeObjectURL(r),6e4)}async function Ss(e){try{let t=await Z(`/api/reveal`,{pane_id:e.id,path:e.cwd,mode:`open`});X(tt(`Opened in the editor on ${t.machine}`,`Ouvert dans l’éditeur sur ${t.machine}`))}catch(e){X(e.message,!0)}}async function Cs(){try{V.value=await Z(`/api/config`),V.value.hostLabel!==void 0&&(go.value=V.value.hostLabel)}catch{}}var Q=null,ws=0,Ts=!1,Es=0,Ds=3e4,$=null,Os,ks,As=()=>`${location.protocol===`https:`?`wss`:`ws`}://${location.host}`;function js(e){if(!e){clearTimeout(ks),ks=void 0,mo.value=!1;return}mo.value||ks||(ks=setTimeout(()=>{ks=void 0,mo.value=!0},2500))}function Ms(e){for(let t of e.panes)(t.prompt&&t.prompt.options||Jt(t))&&t.status!==`working`&&(t.status=`blocked`);return e}function Ns(){if(clearTimeout(Os),B.value||Q&&Q.readyState<=1)return;let e=new WebSocket(`${As()}/ws/events`);Q=e,e.onopen=()=>{ws=0,R.value=!0,Ts&&(Es=Date.now()+Ds,ue()),Ts=!0,zs(),fo(),j.load()},e.onmessage=e=>{try{let t=JSON.parse(e.data);if(t?.type===`settings`){j.receive(t.settings||{});return}let n=Ms(t),r=Wn($?I:null,n,Date.now()<Es);if(!r)return;if(js(!1),!r.ok&&F.value.ok&&$){z.value=$;return}I=r,ao.value=I,F.value=Pr(r,L.value),fo(),$=Date.now(),z.value=null,r.ok&&D(Bn())&&On(F.value)}catch{}},e.onclose=()=>{Q===e&&(Q=null,R.value=!1,F.value.ok&&$&&(z.value=$),Bs(),!B.value&&(js(!0),Os=setTimeout(Ns,Math.min(8e3,500*2**ws++))))}}function Ps(){ws=0,clearTimeout(Os),Ns()}var Fs=Date.now(),Is=0,Ls=!1;function Rs(){Fs=Date.now(),(!Ls||Fs-Is>=1e3)&&zs()}function zs(){Is=Date.now();let e=yo.value&&document.hasFocus()&&Date.now()-Fs<12e4;Ls=e,Q&&Q.readyState===1&&Q.send(JSON.stringify({type:`viewing`,pane:vo.value,visible:e}))}a(vo,zs),a(F,e=>{let t=e.panes.filter(e=>e.status===`blocked`||e.status===`done`).length,n=navigator;try{t&&n.setAppBadge?n.setAppBadge(t).catch(()=>{}):n.clearAppBadge&&n.clearAppBadge().catch(()=>{})}catch{}});async function Bs({resume:e=!1}={}){try{let t=await Z(e?`/api/auth/status?resume=1`:`/api/auth/status`);if(t.enabled&&!t.unlocked)return Ks();let n=zn(t);Vn(n),e&&Hs(n)}catch{}}var Vs=!1;function Hs(e){Vs||!e.deadline||e.deadline-Date.now()>216e5||(Vs=!0,X(h(`The passkey will be asked again the next time the app opens.`)))}var Us=!1,Ws;function Gs(){Us||(Us=!0,B.value=!1,Ns(),Ws||=c(po,3e4),Cs(),Rt().catch(()=>{}))}function Ks(){B.value=!0,F.value={ok:!1,workspaces:[],panes:[]},I=F.value,ao.value=I,z.value=null,Vn(null),Nn();let e=Q;if(Q=null,e){e.onclose=null;try{e.close()}catch{}}R.value=!1,clearTimeout(Os),js(!1),Us=!1}var qs=3e3;async function Js({resume:e=!1}={}){let t=Bn(),n=D(t)?wn():null;try{let n=e?await Z(`/api/auth/status?resume=1`,void 0,AbortSignal.timeout(qs)):await Z(`/api/auth/status`);if(n.hostLabel!==void 0&&(go.value=n.hostLabel),n.enabled&&!n.unlocked)return Ks();t=zn(n),Vn(t),e&&Hs(t)}catch{if(t?.enabled&&!D(t)&&!R.value)return Ks()}if(D(t)){let e=await(n||wn());e&&!R.value&&(I=e.state,ao.value=I,F.value=Pr(I,L.value),z.value=e.at)}Gs()}export{Do as $,sr as $n,ct as $r,Ii as $t,Co as A,Br as An,Lt as Ar,ra as At,q as B,gr as Bn,bt as Br,ja as Bt,Fo as C,ne as Ci,Zr as Cn,nn as Cr,Po as Ct,ts as D,ee as Di,Hr as Dn,Ft as Dr,M as Dt,Bo as E,f as Ei,Qr as En,It as Er,N as Et,$o as F,Dr as Fn,kt as Fr,ta as Ft,as as G,Zn as Gn,mt as Gr,Ma as Gt,ls as H,jr as Hn,Tt as Hr,Oa as Ht,co as I,kr as In,At as Ir,ia as It,ho as J,rr as Jn,ht as Jr,qi as Jt,mo as K,ar as Kn,gt as Kr,Ga as Kt,Cs as L,Ar as Ln,St as Lr,Xa as Lt,go as M,hr as Mn,qt as Mr,_a as Mt,Xo as N,wr as Nn,Ht as Nr,Ka as Nt,F as O,c as Oi,Xr as On,Wt as Or,Qa as Ot,J as P,yr as Pn,Nt as Pr,A as Pt,qo as Q,or as Qn,rt as Qr,Li as Qt,B as R,vr as Rn,xt as Rr,Ja as Rt,Zo as S,ue as Si,Yr as Sn,Zt as Sr,ys as St,R as T,ce as Ti,Ur as Tn,Vt as Tr,No as Tt,us as U,fr as Un,_t as Ur,ha as Ut,ds as V,Sr as Vn,Ct as Vr,qa as Vt,K as W,dr as Wn,Et as Wr,Aa as Wt,yo as X,qn as Xn,Dt as Xr,Pi as Xt,Ss as Y,er as Yn,Ot as Yr,zi as Yt,fs as Z,Gn as Zn,yt as Zr,Ni as Zt,Ns as _,He as _i,ui as _n,dn as _r,Js as _t,V as a,qe as ai,ji as an,Pn as ar,Uo as at,is as b,ge as bi,ti as bn,en as br,U as bt,z as c,Ye as ci,vi as cn,En as cr,zs as ct,_s as d,ke as di,fi as dn,jn as dr,rs as dt,lt as ei,Ri as en,Yn as er,Lo as et,ns as f,Ae as fi,li as fn,kn as fr,xo as ft,Bs as g,We as gi,yi as gn,pn as gr,Qo as gt,wo as h,Pe as hi,gi as hn,sn as hr,bo as ht,Z as i,tt as ii,ki as in,Bn as ir,Ro as it,zo as j,Er as jn,Kt as jr,va as jt,Oo as k,zr as kn,_ as kr,ya as kt,ss as l,Ie as li,pi as ln,Tn as lr,Jo as lt,hs as m,Ne as mi,ci as mn,an as mr,So as mt,Vo as n,nt as ni,Ai as nn,$n as nr,H as nt,To as o,Ke as oi,Ci as on,Nn as or,Ps as ot,ms as p,je as pi,_i as pn,Mn as pr,Ks as pt,Rs as q,ir as qn,vt as qr,Ki as qt,ao as r,h as ri,Oi as rn,D as rr,Wo as rt,_o as s,Ge as si,wi as sn,Dn as sr,xs as st,bs as t,m as ti,Mi as tn,Qn as tr,Eo as tt,lo as u,De as ui,bi as un,An as ur,gs as ut,ko as v,ze as vi,ni as vn,Jt as vr,es as vt,Mo as w,te as wi,$r as wn,tn as wr,jo as wt,Ko as x,de as xi,Wr as xn,$t as xr,X as xt,vo as y,ve as yi,ri as yn,Qt as yr,Ho as yt,cs as z,xr as zn,wt as zr,Da as zt};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"id":"1d193254-809f-48d8-bf27-3640edb58f54","timestamp":1793023814837,"prerendered":[]}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|