pipcode 2.1.3 → 2.1.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pipcode",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "PipCode — architecture, security and quality rules for your AI coding assistants (MCP server).",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -3,22 +3,25 @@
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
+ import { PRO_UPGRADE_URL } from "../core/constants.js";
6
8
 
7
9
  const MAX_TRIES = 3;
8
10
 
9
11
  /** @typedef {{ ask: (q: string) => Promise<string> }} AskPrompt */
10
12
  /** @typedef {{ licenseKey: string, email: string }} AuthResult */
11
13
 
12
- /** @param {AskPrompt} p @param {import("./auth-interactive.js").SharedConfig} [existingConfig] @returns {Promise<AuthResult>} */
13
- export async function collectAuthSimple(p, existingConfig = {}) {
14
+ /** @param {AskPrompt} p @param {import("./auth-interactive.js").SharedConfig} [existingConfig] @param {boolean} [links] @returns {Promise<AuthResult>} */
15
+ export async function collectAuthSimple(p, existingConfig = {}, links = supportsLinks()) {
14
16
  const { existingLicense, existingEmail } = existingLicenseInfo(existingConfig);
15
17
  const keep = { licenseKey: existingLicense, email: existingEmail };
16
18
  console.log("\n Votre licence PipCode");
17
19
  if (existingLicense) {
18
20
  console.log(" Une licence est déjà enregistrée" + (existingEmail ? " (" + existingEmail + ")" : "") + " : Entrée pour la conserver, ou collez une autre clé.");
19
21
  } else {
20
- console.log(" Collez votre clé de licence (reçue par e-mail après l'achat),");
22
+ console.log(` Collez votre ${link("clé de licence", PRO_UPGRADE_URL, links)} (reçue par e-mail après l'achat),`);
21
23
  console.log(" ou appuyez sur Entrée pour l'essai gratuit de 5 jours.");
24
+ if (!links) console.log(` Pas encore de licence ? Achat : ${PRO_UPGRADE_URL}`);
22
25
  }
23
26
  for (let i = 0; i < MAX_TRIES; i++) {
24
27
  const key = (await p.ask("\n Clé : ")).trim();
@@ -0,0 +1,25 @@
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