jd-skills 0.1.0 → 0.1.1
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/dist/_chunks/config.mjs +158 -2
- package/dist/_chunks/config2.mjs +2 -42
- package/dist/_chunks/jd-cookie.mjs +1 -1
- package/dist/_chunks/jd-cookie2.mjs +10 -7
- package/dist/cli.mjs +109 -61
- package/package.json +1 -1
package/dist/_chunks/config.mjs
CHANGED
|
@@ -1,2 +1,158 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
+
import { dirname, join } from "path";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
const JD_INTRANET_DEFAULTS = {
|
|
5
|
+
skillApiUrl: "https://mkt-skill-manager.jd.com/api/skill/public/sorted-list",
|
|
6
|
+
brokerUrl: "https://cbroker.jd.com",
|
|
7
|
+
sdkPackage: "@jd/jd-cookie-broker",
|
|
8
|
+
gitlabHosts: ["coding.jd.com"],
|
|
9
|
+
npmRegistry: "http://registry.m.jd.com"
|
|
10
|
+
};
|
|
11
|
+
const PROBE_CACHE_PATH = join(homedir(), ".jd-skills", "intranet-probe.json");
|
|
12
|
+
const PROBE_TTL_MS = 3600 * 1e3;
|
|
13
|
+
const PROBE_TIMEOUT_MS = 3e3;
|
|
14
|
+
let memoryProbe = null;
|
|
15
|
+
let inFlightProbe = null;
|
|
16
|
+
function readDiskProbe() {
|
|
17
|
+
try {
|
|
18
|
+
if (!existsSync(PROBE_CACHE_PATH)) return null;
|
|
19
|
+
const parsed = JSON.parse(readFileSync(PROBE_CACHE_PATH, "utf-8"));
|
|
20
|
+
if (typeof parsed.available !== "boolean" || typeof parsed.checkedAt !== "number") return null;
|
|
21
|
+
if (Date.now() - parsed.checkedAt > PROBE_TTL_MS) return null;
|
|
22
|
+
return parsed;
|
|
23
|
+
} catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function writeDiskProbe(available) {
|
|
28
|
+
try {
|
|
29
|
+
mkdirSync(dirname(PROBE_CACHE_PATH), { recursive: true });
|
|
30
|
+
writeFileSync(PROBE_CACHE_PATH, JSON.stringify({
|
|
31
|
+
available,
|
|
32
|
+
checkedAt: Date.now()
|
|
33
|
+
}, null, 2), { mode: 384 });
|
|
34
|
+
} catch {}
|
|
35
|
+
}
|
|
36
|
+
function setProbeResult(available) {
|
|
37
|
+
memoryProbe = available;
|
|
38
|
+
writeDiskProbe(available);
|
|
39
|
+
return available;
|
|
40
|
+
}
|
|
41
|
+
function getJdIntranetProbeSync() {
|
|
42
|
+
if (memoryProbe !== null) return memoryProbe;
|
|
43
|
+
const cached = readDiskProbe();
|
|
44
|
+
if (!cached) return null;
|
|
45
|
+
memoryProbe = cached.available;
|
|
46
|
+
return cached.available;
|
|
47
|
+
}
|
|
48
|
+
async function headReachable(url) {
|
|
49
|
+
try {
|
|
50
|
+
return (await fetch(url, {
|
|
51
|
+
method: "HEAD",
|
|
52
|
+
signal: AbortSignal.timeout(PROBE_TIMEOUT_MS)
|
|
53
|
+
})).status < 500;
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function probeJdIntranet(force = false) {
|
|
59
|
+
if (!force && memoryProbe !== null) return memoryProbe;
|
|
60
|
+
if (!force) {
|
|
61
|
+
const cached = readDiskProbe();
|
|
62
|
+
if (cached) {
|
|
63
|
+
memoryProbe = cached.available;
|
|
64
|
+
return cached.available;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (!force && inFlightProbe) return inFlightProbe;
|
|
68
|
+
inFlightProbe = (async () => {
|
|
69
|
+
return setProbeResult(await headReachable((process.env.JD_SKILL_API_URL ?? "").trim() || JD_INTRANET_DEFAULTS.skillApiUrl));
|
|
70
|
+
})();
|
|
71
|
+
try {
|
|
72
|
+
return await inFlightProbe;
|
|
73
|
+
} finally {
|
|
74
|
+
inFlightProbe = null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function isJdIntranetAvailable() {
|
|
78
|
+
return getJdIntranetProbeSync() === true;
|
|
79
|
+
}
|
|
80
|
+
async function resolveSkillApiUrl() {
|
|
81
|
+
const env = (process.env.JD_SKILL_API_URL ?? "").trim();
|
|
82
|
+
if (env) return env;
|
|
83
|
+
if (await probeJdIntranet()) return JD_INTRANET_DEFAULTS.skillApiUrl;
|
|
84
|
+
return "";
|
|
85
|
+
}
|
|
86
|
+
function resolveSkillApiUrlSync() {
|
|
87
|
+
const env = (process.env.JD_SKILL_API_URL ?? "").trim();
|
|
88
|
+
if (env) return env;
|
|
89
|
+
if (isJdIntranetAvailable()) return JD_INTRANET_DEFAULTS.skillApiUrl;
|
|
90
|
+
return "";
|
|
91
|
+
}
|
|
92
|
+
function resolveSdkPackageName() {
|
|
93
|
+
const env = (process.env.JD_BROKER_SDK_PACKAGE ?? "").trim();
|
|
94
|
+
if (env) return env;
|
|
95
|
+
if (isJdIntranetAvailable()) return JD_INTRANET_DEFAULTS.sdkPackage;
|
|
96
|
+
return "";
|
|
97
|
+
}
|
|
98
|
+
async function resolveSdkPackageNameAsync() {
|
|
99
|
+
const env = (process.env.JD_BROKER_SDK_PACKAGE ?? "").trim();
|
|
100
|
+
if (env) return env;
|
|
101
|
+
if (await probeJdIntranet()) return JD_INTRANET_DEFAULTS.sdkPackage;
|
|
102
|
+
return "";
|
|
103
|
+
}
|
|
104
|
+
function resolveBrokerUrlFromIntranet(fileBrokerUrl) {
|
|
105
|
+
const envUrl = (process.env.JD_BROKER_URL ?? "").trim();
|
|
106
|
+
if (envUrl) return envUrl.replace(/\/+$/, "");
|
|
107
|
+
if (fileBrokerUrl) return fileBrokerUrl;
|
|
108
|
+
if (isJdIntranetAvailable()) return JD_INTRANET_DEFAULTS.brokerUrl;
|
|
109
|
+
return "";
|
|
110
|
+
}
|
|
111
|
+
function resolveGitlabHosts() {
|
|
112
|
+
const fromEnv = (process.env.JD_GITLAB_HOSTS ?? "").split(",").map((h) => h.trim().toLowerCase()).filter((h) => h.length > 0).filter((h, i, arr) => arr.indexOf(h) === i);
|
|
113
|
+
if (fromEnv.length > 0) return fromEnv;
|
|
114
|
+
if (isJdIntranetAvailable()) return [...JD_INTRANET_DEFAULTS.gitlabHosts];
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
function resolveExpectedNpmRegistry() {
|
|
118
|
+
const env = (process.env.JD_NPM_REGISTRY ?? "").trim();
|
|
119
|
+
if (env) return env;
|
|
120
|
+
if (isJdIntranetAvailable()) return JD_INTRANET_DEFAULTS.npmRegistry;
|
|
121
|
+
return "";
|
|
122
|
+
}
|
|
123
|
+
const CONFIG_PATH = join(join(homedir(), ".jd-skills"), "config.json");
|
|
124
|
+
function readConfig() {
|
|
125
|
+
try {
|
|
126
|
+
if (!existsSync(CONFIG_PATH)) return {};
|
|
127
|
+
const raw = readFileSync(CONFIG_PATH, "utf-8");
|
|
128
|
+
const parsed = JSON.parse(raw);
|
|
129
|
+
if (typeof parsed !== "object" || parsed === null) return {};
|
|
130
|
+
return parsed;
|
|
131
|
+
} catch {
|
|
132
|
+
return {};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function writeConfig(config) {
|
|
136
|
+
mkdirSync(dirname(CONFIG_PATH), { recursive: true });
|
|
137
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 384 });
|
|
138
|
+
}
|
|
139
|
+
function getBrokerUrl() {
|
|
140
|
+
const fileConfig = readConfig();
|
|
141
|
+
return resolveBrokerUrlFromIntranet(fileConfig.brokerUrl && fileConfig.brokerUrl.trim().length > 0 ? fileConfig.brokerUrl.trim().replace(/\/+$/, "") : "");
|
|
142
|
+
}
|
|
143
|
+
function setBrokerUrl(url) {
|
|
144
|
+
const config = readConfig();
|
|
145
|
+
if (url && url.trim().length > 0) config.brokerUrl = url.trim().replace(/\/+$/, "");
|
|
146
|
+
else delete config.brokerUrl;
|
|
147
|
+
config.version = 1;
|
|
148
|
+
writeConfig(config);
|
|
149
|
+
}
|
|
150
|
+
function resetConfig() {
|
|
151
|
+
try {
|
|
152
|
+
if (existsSync(CONFIG_PATH)) writeFileSync(CONFIG_PATH, "{}", { mode: 384 });
|
|
153
|
+
} catch {}
|
|
154
|
+
}
|
|
155
|
+
function getConfig() {
|
|
156
|
+
return readConfig();
|
|
157
|
+
}
|
|
158
|
+
export { JD_INTRANET_DEFAULTS as a, resolveExpectedNpmRegistry as c, resolveSdkPackageNameAsync as d, resolveSkillApiUrl as f, setBrokerUrl as i, resolveGitlabHosts as l, getConfig as n, isJdIntranetAvailable as o, resolveSkillApiUrlSync as p, resetConfig as r, probeJdIntranet as s, getBrokerUrl as t, resolveSdkPackageName as u };
|
package/dist/_chunks/config2.mjs
CHANGED
|
@@ -1,42 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { homedir } from "os";
|
|
4
|
-
const CONFIG_PATH = join(join(homedir(), ".jd-skills"), "config.json");
|
|
5
|
-
function readConfig() {
|
|
6
|
-
try {
|
|
7
|
-
if (!existsSync(CONFIG_PATH)) return {};
|
|
8
|
-
const raw = readFileSync(CONFIG_PATH, "utf-8");
|
|
9
|
-
const parsed = JSON.parse(raw);
|
|
10
|
-
if (typeof parsed !== "object" || parsed === null) return {};
|
|
11
|
-
return parsed;
|
|
12
|
-
} catch {
|
|
13
|
-
return {};
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function writeConfig(config) {
|
|
17
|
-
mkdirSync(dirname(CONFIG_PATH), { recursive: true });
|
|
18
|
-
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 384 });
|
|
19
|
-
}
|
|
20
|
-
function getBrokerUrl() {
|
|
21
|
-
const envUrl = process.env.JD_BROKER_URL;
|
|
22
|
-
if (envUrl && envUrl.trim().length > 0) return envUrl.trim().replace(/\/+$/, "");
|
|
23
|
-
const fileConfig = readConfig();
|
|
24
|
-
if (fileConfig.brokerUrl && fileConfig.brokerUrl.trim().length > 0) return fileConfig.brokerUrl.trim().replace(/\/+$/, "");
|
|
25
|
-
return "";
|
|
26
|
-
}
|
|
27
|
-
function setBrokerUrl(url) {
|
|
28
|
-
const config = readConfig();
|
|
29
|
-
if (url && url.trim().length > 0) config.brokerUrl = url.trim().replace(/\/+$/, "");
|
|
30
|
-
else delete config.brokerUrl;
|
|
31
|
-
config.version = 1;
|
|
32
|
-
writeConfig(config);
|
|
33
|
-
}
|
|
34
|
-
function resetConfig() {
|
|
35
|
-
try {
|
|
36
|
-
if (existsSync(CONFIG_PATH)) writeFileSync(CONFIG_PATH, "{}", { mode: 384 });
|
|
37
|
-
} catch {}
|
|
38
|
-
}
|
|
39
|
-
function getConfig() {
|
|
40
|
-
return readConfig();
|
|
41
|
-
}
|
|
42
|
-
export { setBrokerUrl as i, getConfig as n, resetConfig as r, getBrokerUrl as t };
|
|
1
|
+
import { i as setBrokerUrl, n as getConfig, r as resetConfig, t as getBrokerUrl } from "./config.mjs";
|
|
2
|
+
export { getBrokerUrl };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "./
|
|
1
|
+
import "./config.mjs";
|
|
2
2
|
import { a as getSdkPackageName, c as isBrokerSdkAvailable, i as getJdSourcePromptState, n as getCookieStatus, o as installSdkHint, r as getJdCookie, s as isBrokerReachable, t as clearJdCookie } from "./jd-cookie2.mjs";
|
|
3
3
|
export { getJdCookie };
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { t as getBrokerUrl } from "./
|
|
1
|
+
import { d as resolveSdkPackageNameAsync, s as probeJdIntranet, t as getBrokerUrl, u as resolveSdkPackageName } from "./config.mjs";
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
3
3
|
import { dirname, join } from "path";
|
|
4
4
|
import { homedir } from "os";
|
|
5
5
|
const CACHE_PATH = join(join(homedir(), ".jd-skills"), "cookies.json");
|
|
6
6
|
const COOKIE_TTL_MS = 1440 * 60 * 1e3;
|
|
7
7
|
function getSdkPackageName() {
|
|
8
|
-
return (
|
|
8
|
+
return resolveSdkPackageName();
|
|
9
|
+
}
|
|
10
|
+
async function getSdkPackageNameResolved() {
|
|
11
|
+
return resolveSdkPackageNameAsync();
|
|
9
12
|
}
|
|
10
13
|
function installSdkHint() {
|
|
11
|
-
|
|
12
|
-
return `install ${pkg} from your private registry and set JD_BROKER_SDK_PACKAGE=${pkg.split("/")[0] + "/<sdk>"} in your env`;
|
|
14
|
+
return `install ${getSdkPackageName() || "@jd/jd-cookie-broker"} from your npm registry (on JD intranet: add registry = http://registry.m.jd.com to ~/.npmrc)`;
|
|
13
15
|
}
|
|
14
16
|
function readCache() {
|
|
15
17
|
try {
|
|
@@ -33,7 +35,7 @@ async function getJdCookie(opts) {
|
|
|
33
35
|
const cached = readCache();
|
|
34
36
|
if (cached && cached.expiresAt > Date.now()) return cached.cookie;
|
|
35
37
|
}
|
|
36
|
-
const sdkPackage =
|
|
38
|
+
const sdkPackage = await getSdkPackageNameResolved();
|
|
37
39
|
if (!sdkPackage) return null;
|
|
38
40
|
let loginFn = null;
|
|
39
41
|
try {
|
|
@@ -73,7 +75,7 @@ function getCookieStatus() {
|
|
|
73
75
|
};
|
|
74
76
|
}
|
|
75
77
|
async function isBrokerSdkAvailable() {
|
|
76
|
-
const sdkPackage =
|
|
78
|
+
const sdkPackage = await getSdkPackageNameResolved();
|
|
77
79
|
if (!sdkPackage) return false;
|
|
78
80
|
try {
|
|
79
81
|
return typeof (await import(
|
|
@@ -95,10 +97,11 @@ async function isBrokerReachable(brokerUrl) {
|
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
99
|
async function getJdSourcePromptState() {
|
|
100
|
+
if (!await probeJdIntranet()) return "unreachable";
|
|
98
101
|
if (!await isBrokerSdkAvailable()) return "sdk_missing";
|
|
99
102
|
const cookieStatus = getCookieStatus();
|
|
100
103
|
if (cookieStatus.loggedIn && cookieStatus.remainingMs && cookieStatus.remainingMs > 0) return "logged_in";
|
|
101
|
-
const { getBrokerUrl } = await import("./
|
|
104
|
+
const { getBrokerUrl } = await import("./config2.mjs");
|
|
102
105
|
return await isBrokerReachable(getBrokerUrl()) ? "auth_required" : "unreachable";
|
|
103
106
|
}
|
|
104
107
|
function clearJdCookie() {
|
package/dist/cli.mjs
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import { r as __toESM } from "./_chunks/rolldown-runtime.mjs";
|
|
3
3
|
import { l as pD, u as require_picocolors } from "./_chunks/libs/@clack/core.mjs";
|
|
4
4
|
import { a as Y, c as ve, i as Se, l as xe, n as M, o as be, r as Me, s as fe, t as Ie, u as ye } from "./_chunks/libs/@clack/prompts.mjs";
|
|
5
|
+
import { a as JD_INTRANET_DEFAULTS, c as resolveExpectedNpmRegistry, f as resolveSkillApiUrl, i as setBrokerUrl, l as resolveGitlabHosts, n as getConfig, o as isJdIntranetAvailable, p as resolveSkillApiUrlSync, r as resetConfig, s as probeJdIntranet, t as getBrokerUrl } from "./_chunks/config.mjs";
|
|
5
6
|
import "./_chunks/libs/@kwsites/file-exists.mjs";
|
|
6
7
|
import "./_chunks/libs/@kwsites/promise-deferred.mjs";
|
|
7
8
|
import { t as esm_default } from "./_chunks/libs/simple-git.mjs";
|
|
8
9
|
import { t as xdgConfig } from "./_chunks/libs/xdg-basedir.mjs";
|
|
9
10
|
import { t as require_dist } from "./_chunks/libs/@vercel/detect-agent.mjs";
|
|
10
|
-
import { i as
|
|
11
|
-
import { c as isBrokerSdkAvailable, i as getJdSourcePromptState, n as getCookieStatus, o as installSdkHint, r as getJdCookie, t as clearJdCookie } from "./_chunks/jd-cookie2.mjs";
|
|
11
|
+
import { a as getSdkPackageName, c as isBrokerSdkAvailable, i as getJdSourcePromptState, n as getCookieStatus, o as installSdkHint, r as getJdCookie, t as clearJdCookie } from "./_chunks/jd-cookie2.mjs";
|
|
12
12
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "fs";
|
|
13
13
|
import { execFile, execSync, spawn, spawnSync } from "child_process";
|
|
14
14
|
import { basename, dirname, isAbsolute, join, normalize, relative, resolve, sep } from "path";
|
|
@@ -25,7 +25,7 @@ import { createHash as createHash$1 } from "node:crypto";
|
|
|
25
25
|
import { gunzipSync, inflateRawSync } from "node:zlib";
|
|
26
26
|
var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
|
|
27
27
|
function getInternalGitlabHosts() {
|
|
28
|
-
return (
|
|
28
|
+
return resolveGitlabHosts();
|
|
29
29
|
}
|
|
30
30
|
function getOwnerRepo(parsed) {
|
|
31
31
|
if (parsed.type === "local") return null;
|
|
@@ -3046,7 +3046,7 @@ async function tryBlobInstall(ownerRepo, options = {}) {
|
|
|
3046
3046
|
tree
|
|
3047
3047
|
};
|
|
3048
3048
|
}
|
|
3049
|
-
var version$1 = "0.1.
|
|
3049
|
+
var version$1 = "0.1.1";
|
|
3050
3050
|
const isCancelled$1 = (value) => typeof value === "symbol";
|
|
3051
3051
|
async function isSourcePrivate(source) {
|
|
3052
3052
|
const ownerRepo = parseOwnerRepo(source);
|
|
@@ -4061,13 +4061,16 @@ async function runAdd(args, options = {}) {
|
|
|
4061
4061
|
if (error instanceof GitCloneError) {
|
|
4062
4062
|
M.error(import_picocolors.default.red("Failed to clone repository"));
|
|
4063
4063
|
for (const line of error.message.split("\n")) M.message(import_picocolors.default.dim(line));
|
|
4064
|
-
|
|
4065
|
-
const
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4064
|
+
try {
|
|
4065
|
+
const reparsed = parseSource(source);
|
|
4066
|
+
if (reparsed.type === "gitlab" && resolveGitlabHosts().length > 0) {
|
|
4067
|
+
const host = reparsed.url.match(/^https?:\/\/([^/]+)/)?.[1] ?? "<host>";
|
|
4068
|
+
M.message("");
|
|
4069
|
+
M.message(import_picocolors.default.yellow(`Hint: search results may use account names that don't match the GitLab group on ${host}.`));
|
|
4070
|
+
M.message(import_picocolors.default.yellow(`Try the full URL once you know the correct GitLab path:`));
|
|
4071
|
+
M.message(import_picocolors.default.yellow(` jd-skills add https://${host}/<group>/<repo>`));
|
|
4072
|
+
}
|
|
4073
|
+
} catch {}
|
|
4071
4074
|
} else M.error(error instanceof Error ? error.message : "Unknown error occurred");
|
|
4072
4075
|
showInstallTip();
|
|
4073
4076
|
Se(import_picocolors.default.red("Installation failed"));
|
|
@@ -4159,9 +4162,6 @@ function parseAddOptions(args) {
|
|
|
4159
4162
|
options
|
|
4160
4163
|
};
|
|
4161
4164
|
}
|
|
4162
|
-
function getApiUrl() {
|
|
4163
|
-
return (process.env.JD_SKILL_API_URL ?? "").trim();
|
|
4164
|
-
}
|
|
4165
4165
|
const REQUEST_TIMEOUT_MS = 5e3;
|
|
4166
4166
|
const DEFAULT_PAGE_SIZE = 24;
|
|
4167
4167
|
async function searchJdSkills(query, opts = {}) {
|
|
@@ -4172,7 +4172,7 @@ async function searchJdSkills(query, opts = {}) {
|
|
|
4172
4172
|
cookie = null;
|
|
4173
4173
|
}
|
|
4174
4174
|
let res;
|
|
4175
|
-
const apiUrl =
|
|
4175
|
+
const apiUrl = await resolveSkillApiUrl();
|
|
4176
4176
|
if (!apiUrl) return { kind: "unreachable" };
|
|
4177
4177
|
try {
|
|
4178
4178
|
res = await fetch(apiUrl, {
|
|
@@ -4260,6 +4260,7 @@ async function searchUpstreamSkills(query) {
|
|
|
4260
4260
|
}
|
|
4261
4261
|
}
|
|
4262
4262
|
async function searchSkillsAPI(query) {
|
|
4263
|
+
await probeJdIntranet();
|
|
4263
4264
|
const [upstream, jdResult] = await Promise.all([searchUpstreamSkills(query).catch(() => []), searchJdSkills(query).catch(() => ({ kind: "unreachable" }))]);
|
|
4264
4265
|
const jdSkills = jdResult && jdResult.kind === "results" ? jdResult.skills.map((s) => ({
|
|
4265
4266
|
name: sanitizeMetadata(s.nameEn || s.alias),
|
|
@@ -4280,13 +4281,14 @@ async function searchSkillsAPI(query) {
|
|
|
4280
4281
|
}
|
|
4281
4282
|
let _jdIssueLogged = null;
|
|
4282
4283
|
function surfaceJdSourceIssue(jdResult) {
|
|
4284
|
+
if (!isJdIntranetAvailable()) return;
|
|
4283
4285
|
if (!jdResult) return;
|
|
4284
4286
|
if (jdResult.kind === "results") return;
|
|
4287
|
+
if (jdResult.kind === "unreachable") return;
|
|
4285
4288
|
if (_jdIssueLogged && _jdIssueLogged !== jdIssueKind(jdResult)) {}
|
|
4286
4289
|
if (_jdIssueLogged === jdIssueKind(jdResult)) return;
|
|
4287
4290
|
_jdIssueLogged = jdIssueKind(jdResult);
|
|
4288
|
-
if (jdResult.kind === "
|
|
4289
|
-
else if (jdResult.kind === "auth_required") {
|
|
4291
|
+
if (jdResult.kind === "auth_required") {
|
|
4290
4292
|
if (!process.stdin.isTTY) process.stderr.write(`${YELLOW$1}┄${RESET$3} ${YELLOW$1}JD marketplace requires login.${RESET$3} ${DIM$3}Run ${TEXT$2}jd-skills login${RESET$3}${DIM$3} to authenticate.${RESET$3}\n`);
|
|
4291
4293
|
} else if (jdResult.kind === "error") process.stderr.write(`${RED}┄${RESET$3} ${RED}JD marketplace error: ${jdResult.message}${RESET$3}\n`);
|
|
4292
4294
|
}
|
|
@@ -4430,6 +4432,30 @@ function getOwnerRepoFromString(pkg) {
|
|
|
4430
4432
|
async function isRepoPublic(owner, repo) {
|
|
4431
4433
|
return await isRepoPrivate(owner, repo) === false;
|
|
4432
4434
|
}
|
|
4435
|
+
async function offerJdLoginPrompt(query) {
|
|
4436
|
+
if (!process.stdin.isTTY) return;
|
|
4437
|
+
if (!await probeJdIntranet()) return;
|
|
4438
|
+
if (await getJdSourcePromptState() !== "auth_required") return;
|
|
4439
|
+
console.log(`${YELLOW$1}┄${RESET$3} ${YELLOW$1}JD marketplace is reachable but you're not logged in.${RESET$3} ${DIM$3}Log in now to also see internal skills?${RESET$3}`);
|
|
4440
|
+
if (!await promptYesNo(" Log in? [Y/n]: ")) return;
|
|
4441
|
+
const { getJdCookie } = await import("./_chunks/jd-cookie.mjs");
|
|
4442
|
+
if (!!!await getJdCookie({ forceRefresh: true })) {
|
|
4443
|
+
console.log(`${DIM$3}Login cancelled or failed.${RESET$3} You can retry with: jd-skills login`);
|
|
4444
|
+
return;
|
|
4445
|
+
}
|
|
4446
|
+
console.log(`${TEXT$2}✓${RESET$3} Logged in.${query ? " Re-running search with JD results..." : ""}`);
|
|
4447
|
+
if (!query) return;
|
|
4448
|
+
const jdOnly = (await searchSkillsAPI(query)).filter((s) => s.origin === "jd");
|
|
4449
|
+
if (jdOnly.length > 0) {
|
|
4450
|
+
console.log();
|
|
4451
|
+
console.log(`${YELLOW$1}JD results:${RESET$3}`);
|
|
4452
|
+
for (const skill of jdOnly.slice(0, 6)) {
|
|
4453
|
+
const installs = formatInstalls(skill.installs);
|
|
4454
|
+
console.log(`${YELLOW$1}[jd]${RESET$3} ${TEXT$2}${skill.ownerErp}@${skill.name}${RESET$3}${installs ? ` ${CYAN$1}${installs}${RESET$3}` : ""}`);
|
|
4455
|
+
console.log(`${DIM$3}└ ★${skill.starScore?.toFixed(2) ?? "—"} ${skill.category1Name ?? ""}${RESET$3}`);
|
|
4456
|
+
}
|
|
4457
|
+
} else console.log(`${DIM$3}No JD results for "${query}".${RESET$3}`);
|
|
4458
|
+
}
|
|
4433
4459
|
async function runFind(args) {
|
|
4434
4460
|
const query = args.join(" ");
|
|
4435
4461
|
const isNonInteractive = !process.stdin.isTTY;
|
|
@@ -4445,6 +4471,7 @@ ${DIM$3} 2) npx jd-skills add <owner/repo@skill>${RESET$3}`;
|
|
|
4445
4471
|
});
|
|
4446
4472
|
if (results.length === 0) {
|
|
4447
4473
|
console.log(`${DIM$3}No skills found for "${query}"${RESET$3}`);
|
|
4474
|
+
await offerJdLoginPrompt(query);
|
|
4448
4475
|
return;
|
|
4449
4476
|
}
|
|
4450
4477
|
if (results.some((s) => s.origin === "jd")) console.log(`${DIM$3}Legend:${RESET$3} ${YELLOW$1}[jd]${RESET$3} ${DIM$3}= JD internal marketplace${RESET$3}`);
|
|
@@ -4463,27 +4490,7 @@ ${DIM$3} 2) npx jd-skills add <owner/repo@skill>${RESET$3}`;
|
|
|
4463
4490
|
}
|
|
4464
4491
|
console.log();
|
|
4465
4492
|
}
|
|
4466
|
-
|
|
4467
|
-
if (await getJdSourcePromptState() === "auth_required") {
|
|
4468
|
-
console.log(`${YELLOW$1}┄${RESET$3} ${YELLOW$1}JD marketplace is reachable but you're not logged in.${RESET$3} ${DIM$3}Log in now to also see internal skills?${RESET$3}`);
|
|
4469
|
-
if (await promptYesNo(" Log in? [Y/n]: ")) {
|
|
4470
|
-
const { getJdCookie } = await import("./_chunks/jd-cookie.mjs");
|
|
4471
|
-
if (!!await getJdCookie({ forceRefresh: true })) {
|
|
4472
|
-
console.log(`${TEXT$2}✓${RESET$3} Logged in. Re-running search with JD results...`);
|
|
4473
|
-
const jdOnly = (await searchSkillsAPI(query)).filter((s) => s.origin === "jd");
|
|
4474
|
-
if (jdOnly.length > 0) {
|
|
4475
|
-
console.log();
|
|
4476
|
-
console.log(`${YELLOW$1}JD results:${RESET$3}`);
|
|
4477
|
-
for (const skill of jdOnly.slice(0, 6)) {
|
|
4478
|
-
const installs = formatInstalls(skill.installs);
|
|
4479
|
-
console.log(`${YELLOW$1}[jd]${RESET$3} ${TEXT$2}${skill.ownerErp}@${skill.name}${RESET$3}${installs ? ` ${CYAN$1}${installs}${RESET$3}` : ""}`);
|
|
4480
|
-
console.log(`${DIM$3}└ ★${skill.starScore?.toFixed(2) ?? "—"} ${skill.category1Name ?? ""}${RESET$3}`);
|
|
4481
|
-
}
|
|
4482
|
-
} else console.log(`${DIM$3}No JD results for "${query}".${RESET$3}`);
|
|
4483
|
-
} else console.log(`${DIM$3}Login cancelled or failed.${RESET$3} You can retry with: jd-skills login`);
|
|
4484
|
-
}
|
|
4485
|
-
}
|
|
4486
|
-
}
|
|
4493
|
+
await offerJdLoginPrompt(query);
|
|
4487
4494
|
return;
|
|
4488
4495
|
}
|
|
4489
4496
|
if (isNonInteractive || await isRunningInAgent()) {
|
|
@@ -4492,6 +4499,7 @@ ${DIM$3} 2) npx jd-skills add <owner/repo@skill>${RESET$3}`;
|
|
|
4492
4499
|
console.log(`${DIM$3}Usage: npx jd-skills find <query>${RESET$3}`);
|
|
4493
4500
|
return;
|
|
4494
4501
|
}
|
|
4502
|
+
await offerJdLoginPrompt();
|
|
4495
4503
|
const selected = await runSearchPrompt();
|
|
4496
4504
|
track({
|
|
4497
4505
|
event: "find",
|
|
@@ -4539,7 +4547,7 @@ async function showJdDetailsAndInstall(selected) {
|
|
|
4539
4547
|
}
|
|
4540
4548
|
console.log();
|
|
4541
4549
|
const installCmd = `jd:${d.owner}/${selected.name}`;
|
|
4542
|
-
const apiUrl =
|
|
4550
|
+
const apiUrl = resolveSkillApiUrlSync();
|
|
4543
4551
|
const webUiUrl = apiUrl ? apiUrl.replace(/\/api\/.*$/, `/skill/${d.skillCode}`) : "";
|
|
4544
4552
|
console.log(`${DIM$3}To install (best-effort: account name may not match the GitLab group):${RESET$3}\n npx jd-skills add ${installCmd}`);
|
|
4545
4553
|
if (webUiUrl) console.log(`${DIM$3}Or open in browser:${RESET$3}\n ${webUiUrl}`);
|
|
@@ -6117,12 +6125,12 @@ const BOLD = "\x1B[1m";
|
|
|
6117
6125
|
const DIM = "\x1B[38;5;102m";
|
|
6118
6126
|
const TEXT = "\x1B[38;5;145m";
|
|
6119
6127
|
const LOGO_LINES = [
|
|
6120
|
-
"███████╗██╗ ██╗██╗██╗ ██╗ ███████╗",
|
|
6121
|
-
"██╔════╝██║ ██╔╝██║██║ ██║ ██╔════╝",
|
|
6122
|
-
"
|
|
6123
|
-
"
|
|
6124
|
-
"███████║██║ ██╗██║███████╗███████╗███████║",
|
|
6125
|
-
"╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚══════╝"
|
|
6128
|
+
" ██╗██████╗ ███████╗██╗ ██╗██╗██╗ ██╗ ███████╗",
|
|
6129
|
+
" ██║██╔══██╗ ██╔════╝██║ ██╔╝██║██║ ██║ ██╔════╝",
|
|
6130
|
+
" ██║██║ ██║█████╗███████╗█████╔╝ ██║██║ ██║ ███████╗",
|
|
6131
|
+
"██ ██║██║ ██║╚════╝╚════██║██╔═██╗ ██║██║ ██║ ╚════██║",
|
|
6132
|
+
"╚█████╔╝██████╔╝ ███████║██║ ██╗██║███████╗███████╗███████║",
|
|
6133
|
+
" ╚════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚══════╝"
|
|
6126
6134
|
];
|
|
6127
6135
|
const GRAYS = [
|
|
6128
6136
|
"\x1B[38;5;250m",
|
|
@@ -6406,21 +6414,53 @@ async function runDoctor() {
|
|
|
6406
6414
|
console.log(`${BOLD}jd-skills doctor${RESET}`);
|
|
6407
6415
|
console.log(`${DIM}JD marketplace setup diagnostic (read-only, no installs)${RESET}`);
|
|
6408
6416
|
console.log();
|
|
6417
|
+
if (!await probeJdIntranet()) {
|
|
6418
|
+
console.log(`${DIM}JD intranet not detected${RESET} — marketplace probe to ${JD_INTRANET_DEFAULTS.skillApiUrl} failed.`);
|
|
6419
|
+
console.log(`${DIM}Upstream skills (skills.sh) still work. Connect to JD VPN/network and re-run doctor, or set JD_SKILL_API_URL to override.${RESET}`);
|
|
6420
|
+
console.log();
|
|
6421
|
+
return;
|
|
6422
|
+
}
|
|
6409
6423
|
const checks = [];
|
|
6410
|
-
const
|
|
6411
|
-
const
|
|
6424
|
+
const skillApiUrl = await resolveSkillApiUrl();
|
|
6425
|
+
const sdkPackage = getSdkPackageName();
|
|
6426
|
+
const expectedRegistry = resolveExpectedNpmRegistry();
|
|
6412
6427
|
checks.push({
|
|
6413
|
-
label: "
|
|
6414
|
-
ok:
|
|
6415
|
-
detail:
|
|
6416
|
-
fix: registryOk ? void 0 : `Add this line to ~/.npmrc:\n registry = ${JD_BROKER_SDK_REGISTRY}\n Then re-run npx jd-skills.`
|
|
6428
|
+
label: "JD intranet detected",
|
|
6429
|
+
ok: true,
|
|
6430
|
+
detail: `marketplace reachable (auto: ${JD_INTRANET_DEFAULTS.skillApiUrl})`
|
|
6417
6431
|
});
|
|
6418
|
-
const sdkOk = await isBrokerSdkAvailable();
|
|
6419
6432
|
checks.push({
|
|
6420
|
-
label:
|
|
6433
|
+
label: "JD skill search API",
|
|
6434
|
+
ok: skillApiUrl.length > 0,
|
|
6435
|
+
detail: skillApiUrl || "unavailable after probe",
|
|
6436
|
+
fix: skillApiUrl.length > 0 ? void 0 : `Set JD_SKILL_API_URL only if the default marketplace URL is wrong for your environment.`
|
|
6437
|
+
});
|
|
6438
|
+
checks.push({
|
|
6439
|
+
label: "cookie-broker SDK package",
|
|
6440
|
+
ok: sdkPackage.length > 0,
|
|
6441
|
+
detail: sdkPackage || "not resolved (unexpected on intranet)",
|
|
6442
|
+
fix: sdkPackage.length > 0 ? void 0 : `Set JD_BROKER_SDK_PACKAGE only if you use a forked SDK name.`
|
|
6443
|
+
});
|
|
6444
|
+
const npmRegistry = await getNpmRegistry();
|
|
6445
|
+
if (expectedRegistry) {
|
|
6446
|
+
const registryOk = npmRegistry.replace(/\/+$/, "") === expectedRegistry.replace(/\/+$/, "");
|
|
6447
|
+
checks.push({
|
|
6448
|
+
label: "npm registry configured",
|
|
6449
|
+
ok: registryOk,
|
|
6450
|
+
detail: registryOk ? `registry = ${npmRegistry}` : `registry = ${npmRegistry} ${DIM}(expected ${expectedRegistry})${RESET}`,
|
|
6451
|
+
fix: registryOk ? void 0 : `Add this line to ~/.npmrc:\n registry = ${expectedRegistry}\n Or export JD_NPM_REGISTRY=${expectedRegistry} and re-run jd-skills doctor.`
|
|
6452
|
+
});
|
|
6453
|
+
} else checks.push({
|
|
6454
|
+
label: "npm registry (informational)",
|
|
6455
|
+
ok: true,
|
|
6456
|
+
detail: `registry = ${npmRegistry} ${DIM}(intranet default: ${JD_INTRANET_DEFAULTS.npmRegistry})${RESET}`
|
|
6457
|
+
});
|
|
6458
|
+
const sdkOk = sdkPackage.length > 0 ? await isBrokerSdkAvailable() : false;
|
|
6459
|
+
checks.push({
|
|
6460
|
+
label: sdkPackage ? `${sdkPackage} SDK loadable` : "cookie-broker SDK loadable",
|
|
6421
6461
|
ok: sdkOk,
|
|
6422
|
-
detail: sdkOk ? `dynamic import() succeeded` : `${
|
|
6423
|
-
fix: sdkOk ? void 0 :
|
|
6462
|
+
detail: sdkOk ? `dynamic import() succeeded` : sdkPackage ? `${sdkPackage} not found in this run's node_modules` : "skipped (SDK package not resolved)",
|
|
6463
|
+
fix: sdkOk ? void 0 : sdkPackage ? `${installSdkHint()}. After fixing ~/.npmrc, re-run npx jd-skills.` : `Unexpected on intranet — contact your platform team.`
|
|
6424
6464
|
});
|
|
6425
6465
|
const cookieStatus = getCookieStatus();
|
|
6426
6466
|
if (!sdkOk) checks.push({
|
|
@@ -6443,13 +6483,21 @@ async function runDoctor() {
|
|
|
6443
6483
|
fix: `Run jd-skills login to authenticate.`
|
|
6444
6484
|
});
|
|
6445
6485
|
const broker = getBrokerUrl();
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
fix: brokerOk ? void 0 : `Check your network. If you're outside JD's intranet, JD source is expected to be unreachable — jd-skills will still work for upstream skills.`
|
|
6486
|
+
if (!broker) checks.push({
|
|
6487
|
+
label: "SSO broker URL",
|
|
6488
|
+
ok: false,
|
|
6489
|
+
detail: "not resolved (unexpected on intranet)",
|
|
6490
|
+
fix: `Run jd-skills config set-broker <url> or set JD_BROKER_URL to override the default.`
|
|
6452
6491
|
});
|
|
6492
|
+
else {
|
|
6493
|
+
const brokerOk = await isUrlReachable(broker);
|
|
6494
|
+
checks.push({
|
|
6495
|
+
label: "SSO broker reachable",
|
|
6496
|
+
ok: brokerOk,
|
|
6497
|
+
detail: brokerOk ? `${broker} (auto-detected on intranet)` : `HEAD ${broker} → unreachable (network or DNS)`,
|
|
6498
|
+
fix: brokerOk ? void 0 : `Check VPN/network, or jd-skills config set-broker <url> if your broker host differs.`
|
|
6499
|
+
});
|
|
6500
|
+
}
|
|
6453
6501
|
let allOk = true;
|
|
6454
6502
|
for (const c of checks) {
|
|
6455
6503
|
const mark = c.ok ? `${TEXT}✓${RESET}` : `${TEXT}✗${RESET}`;
|