shadok-ai 0.1.149 → 0.1.151
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/package.json +1 -1
- package/public/index.html +39 -0
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -2883,6 +2883,45 @@
|
|
|
2883
2883
|
await loadVault(); renderSecrets();
|
|
2884
2884
|
$("secretKey").focus();
|
|
2885
2885
|
});
|
|
2886
|
+
// Parse un bloc collé façon .env → [{name, value}]. Gère `export KEY=VALUE`,
|
|
2887
|
+
// les guillemets simples/doubles englobants, les commentaires (#) et les
|
|
2888
|
+
// lignes vides. Une ligne sans nom d'env valide avant `=` est ignorée — donc
|
|
2889
|
+
// un collage sans aucune paire valide (ex. un simple nom) laisse le collage
|
|
2890
|
+
// normal remplir le champ NAME.
|
|
2891
|
+
function parseEnvSecrets(text) {
|
|
2892
|
+
const out = [];
|
|
2893
|
+
for (const raw of String(text).split(/\r?\n/)) {
|
|
2894
|
+
let line = raw.trim();
|
|
2895
|
+
if (!line || line.startsWith("#")) continue;
|
|
2896
|
+
if (line.startsWith("export ")) line = line.slice(7).trim();
|
|
2897
|
+
const eq = line.indexOf("=");
|
|
2898
|
+
if (eq <= 0) continue;
|
|
2899
|
+
const name = line.slice(0, eq).trim();
|
|
2900
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) continue;
|
|
2901
|
+
let value = line.slice(eq + 1).trim();
|
|
2902
|
+
const q = value[0];
|
|
2903
|
+
if (value.length >= 2 && (q === '"' || q === "'") && value[value.length - 1] === q) {
|
|
2904
|
+
value = value.slice(1, -1);
|
|
2905
|
+
}
|
|
2906
|
+
out.push({ name, value });
|
|
2907
|
+
}
|
|
2908
|
+
return out;
|
|
2909
|
+
}
|
|
2910
|
+
// Coller une liste .env dans le champ NAME ajoute tous les secrets d'un coup.
|
|
2911
|
+
$("secretKey").addEventListener("paste", async (e) => {
|
|
2912
|
+
const text = (e.clipboardData || window.clipboardData).getData("text");
|
|
2913
|
+
const pairs = parseEnvSecrets(text);
|
|
2914
|
+
if (!pairs.length) return; // rien de parsable → collage normal (remplit NAME)
|
|
2915
|
+
e.preventDefault();
|
|
2916
|
+
// Séquentiel : chaque PUT fait un read-modify-write de secrets.json côté
|
|
2917
|
+
// serveur ; les awaits évitent une course sur le fichier.
|
|
2918
|
+
for (const { name, value } of pairs) {
|
|
2919
|
+
await fetch("/secrets", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name, value }) });
|
|
2920
|
+
}
|
|
2921
|
+
$("secretKey").value = ""; $("secretVal").value = "";
|
|
2922
|
+
await loadVault(); renderSecrets();
|
|
2923
|
+
$("secretKey").focus();
|
|
2924
|
+
});
|
|
2886
2925
|
// ── Profiles panel (global agent roles/guardrails/secret refs) ──────────
|
|
2887
2926
|
let profileCache = []; // profiles from the server
|
|
2888
2927
|
let editSecretRefs = []; // secret NAMES the profile being edited injects
|