pipcode 2.1.4 → 2.1.6
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/src/cli/auth-simple.js +4 -5
- package/src/cli/claude-desktop.js +35 -0
- package/src/cli/ide-paths.js +2 -1
- package/src/cli/term-link.js +0 -25
package/package.json
CHANGED
package/src/cli/auth-simple.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
|
|
4
4
|
import { existingLicenseInfo } from "./auth-interactive.js";
|
|
5
5
|
import { KEY_RE } from "./setup-args.js";
|
|
6
|
-
import { link, supportsLinks } from "./term-link.js";
|
|
7
6
|
import { PRO_UPGRADE_URL } from "../core/constants.js";
|
|
8
7
|
|
|
9
8
|
const MAX_TRIES = 3;
|
|
@@ -11,17 +10,17 @@ const MAX_TRIES = 3;
|
|
|
11
10
|
/** @typedef {{ ask: (q: string) => Promise<string> }} AskPrompt */
|
|
12
11
|
/** @typedef {{ licenseKey: string, email: string }} AuthResult */
|
|
13
12
|
|
|
14
|
-
/** @param {AskPrompt} p @param {import("./auth-interactive.js").SharedConfig} [existingConfig] @
|
|
15
|
-
export async function collectAuthSimple(p, existingConfig = {}
|
|
13
|
+
/** @param {AskPrompt} p @param {import("./auth-interactive.js").SharedConfig} [existingConfig] @returns {Promise<AuthResult>} */
|
|
14
|
+
export async function collectAuthSimple(p, existingConfig = {}) {
|
|
16
15
|
const { existingLicense, existingEmail } = existingLicenseInfo(existingConfig);
|
|
17
16
|
const keep = { licenseKey: existingLicense, email: existingEmail };
|
|
18
17
|
console.log("\n Votre licence PipCode");
|
|
19
18
|
if (existingLicense) {
|
|
20
19
|
console.log(" Une licence est déjà enregistrée" + (existingEmail ? " (" + existingEmail + ")" : "") + " : Entrée pour la conserver, ou collez une autre clé.");
|
|
21
20
|
} else {
|
|
22
|
-
console.log(
|
|
21
|
+
console.log(" Collez votre clé de licence (reçue par e-mail après l'achat),");
|
|
23
22
|
console.log(" ou appuyez sur Entrée pour l'essai gratuit de 5 jours.");
|
|
24
|
-
|
|
23
|
+
console.log(` Pas encore de licence ? ${PRO_UPGRADE_URL}`);
|
|
25
24
|
}
|
|
26
25
|
for (let i = 0; i < MAX_TRIES; i++) {
|
|
27
26
|
const key = (await p.ask("\n Clé : ")).trim();
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/cli/claude-desktop.js — Config de Claude Desktop. Installé depuis le Microsoft Store (MSIX), Windows isole sa config dans
|
|
2
|
+
// %LOCALAPPDATA%\Packages\Claude_<id>\LocalCache\Roaming\Claude : l'ancien %APPDATA%\Claude n'existe pas et l'app n'y lit rien.
|
|
3
|
+
// On vise le dossier réellement utilisé. Zero Trust : racine bornée sous home, nom du paquet validé (aucune traversée de chemin).
|
|
4
|
+
|
|
5
|
+
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { boundRoot } from "../fs/config-path.js";
|
|
8
|
+
|
|
9
|
+
const FILE = "claude_desktop_config.json";
|
|
10
|
+
const STORE_ID = /^Claude_[a-z0-9]+$/i;
|
|
11
|
+
|
|
12
|
+
/** @param {Record<string, string | undefined>} env @param {string} home @returns {string | null} */
|
|
13
|
+
function storeDir(env, home) {
|
|
14
|
+
const pkgs = path.join(boundRoot(env.LOCALAPPDATA, home, path.join(home, "AppData", "Local")), "Packages");
|
|
15
|
+
try {
|
|
16
|
+
const name = readdirSync(pkgs).find((n) => STORE_ID.test(n));
|
|
17
|
+
const dir = name ? path.join(pkgs, name, "LocalCache", "Roaming", "Claude") : "";
|
|
18
|
+
return dir && existsSync(dir) ? dir : null;
|
|
19
|
+
} catch { return null; } // pas de dossier Packages : aucune installation Store (cas normal hors Windows)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** @param {string} f @returns {number} */
|
|
23
|
+
const mtime = (f) => { try { return statSync(f).mtimeMs; } catch { return 0; } }; // fichier absent : jamais « plus récent »
|
|
24
|
+
|
|
25
|
+
// Chemin de la config : Store (MSIX) si présent, sauf si la config classique a été modifiée plus récemment (les deux coexistent).
|
|
26
|
+
/** @param {string} osName @param {Record<string, string | undefined>} env @param {string} home @param {string} configRoot @returns {string} */
|
|
27
|
+
export function claudeDesktopPath(osName, env, home, configRoot) {
|
|
28
|
+
const classic = path.join(configRoot, "Claude", FILE);
|
|
29
|
+
if (osName !== "windows") return classic;
|
|
30
|
+
const dir = storeDir(env, home);
|
|
31
|
+
if (!dir) return classic;
|
|
32
|
+
const store = path.join(dir, FILE);
|
|
33
|
+
return existsSync(classic) && mtime(classic) > mtime(store) ? classic : store;
|
|
34
|
+
}
|
|
35
|
+
// MODULE_COMPLETE
|
package/src/cli/ide-paths.js
CHANGED
|
@@ -11,6 +11,7 @@ import { detectOS } from "./detect-os.js";
|
|
|
11
11
|
import { ideConfigRoot } from "./ide-roots.js";
|
|
12
12
|
import { coreIdeEntries, uiIdeEntries } from "./ide-entries.js";
|
|
13
13
|
import { jetbrainsCandidates } from "./jetbrains.js";
|
|
14
|
+
import { claudeDesktopPath } from "./claude-desktop.js";
|
|
14
15
|
|
|
15
16
|
/** @typedef {{ id: string, name: string, path: string, parentExists: boolean, configExists: boolean, schema?: "mcpServers" | "servers" | "context_servers" | "toml" }} IdeConfigEntry */
|
|
16
17
|
|
|
@@ -24,7 +25,7 @@ export function ideConfigPaths(osName = detectOS(), env = process.env, home = os
|
|
|
24
25
|
const { configRoot, codeUser } = ideConfigRoot(osName, env || {}, home);
|
|
25
26
|
/** @type {Array<{ id: string, name: string, path: string, schema?: "mcpServers" | "servers" | "context_servers" | "toml" }>} */
|
|
26
27
|
const entries = [
|
|
27
|
-
...coreIdeEntries(home, configRoot),
|
|
28
|
+
...coreIdeEntries(home, configRoot).map((e) => (e.id === "claude-desktop" ? { ...e, path: claudeDesktopPath(osName, env || {}, home, configRoot) } : e)),
|
|
28
29
|
...uiIdeEntries(osName, codeUser, home, configRoot),
|
|
29
30
|
...jetbrainsCandidates(osName, env || {}, home, configRoot),
|
|
30
31
|
];
|
package/src/cli/term-link.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// src/cli/term-link.js — Lien cliquable dans le terminal (séquence OSC 8) quand le terminal le gère ; sinon le texte seul et l'appelant
|
|
2
|
-
// affiche l'adresse en clair. Zero Trust : seule une URL https sans caractère de contrôle devient un lien (jamais d'injection de séquence).
|
|
3
|
-
|
|
4
|
-
const OSC = "\u001b]8;;";
|
|
5
|
-
const ST = "\u001b\\";
|
|
6
|
-
const KNOWN_TERMS = /^(vscode|iTerm\.app|WezTerm|Hyper|ghostty)$/i;
|
|
7
|
-
|
|
8
|
-
/** @param {NodeJS.ProcessEnv} [env] @param {boolean} [isTTY] @returns {boolean} */
|
|
9
|
-
export function supportsLinks(env = process.env, isTTY = Boolean(process.stdout.isTTY)) {
|
|
10
|
-
if (!isTTY) return false;
|
|
11
|
-
return Boolean(env.WT_SESSION || env.KITTY_WINDOW_ID || env.WEZTERM_EXECUTABLE || env.FORCE_HYPERLINK === "1"
|
|
12
|
-
|| KNOWN_TERMS.test(env.TERM_PROGRAM || "") || Number(env.VTE_VERSION) >= 5000);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** @param {string} url @returns {boolean} */
|
|
16
|
-
export function isSafeUrl(url) {
|
|
17
|
-
if (/[\u0000-\u001f\u007f]/.test(url)) return false;
|
|
18
|
-
try { return new URL(url).protocol === "https:"; } catch { return false; }
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** @param {string} text @param {string} url @param {boolean} [enabled] @returns {string} */
|
|
22
|
-
export function link(text, url, enabled = supportsLinks()) {
|
|
23
|
-
return enabled && isSafeUrl(url) ? `${OSC}${url}${ST}${text}${OSC}${ST}` : text;
|
|
24
|
-
}
|
|
25
|
-
// MODULE_COMPLETE
|