requestshield 0.1.2 → 0.1.3
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/README.md +75 -181
- package/package.json +13 -11
- package/skills/requestshield/SKILL.md +302 -39
- package/skills/requestshield/assets/AGENTS.codex.md +62 -0
- package/skills/requestshield/references/backend-java-core.md +128 -0
- package/skills/requestshield/references/backend-spring-boot.md +145 -0
- package/skills/requestshield/references/browser-manual.md +210 -0
- package/skills/requestshield/references/browser-seamless.md +164 -0
- package/skills/requestshield/references/cli.md +182 -0
- package/skills/requestshield/references/integration-planning.md +389 -0
- package/skills/requestshield/references/troubleshooting.md +118 -0
- package/src/agent-detector.mjs +74 -0
- package/src/args.mjs +23 -66
- package/src/cli.mjs +2 -13
- package/src/commands/agent-setup.mjs +109 -15
- package/src/main.mjs +24 -24
- package/src/commands/update-check.mjs +0 -139
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
import readline from "node:readline/promises";
|
|
4
|
-
import { spawn } from "node:child_process";
|
|
5
|
-
import { stdin, stdout } from "node:process";
|
|
6
|
-
import { CliError } from "../errors.mjs";
|
|
7
|
-
|
|
8
|
-
const DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @param {{ currentVersion: string, packageName: string, log: (message: string) => void, fetchImpl?: typeof fetch, confirm?: () => Promise<boolean>, install?: (packageName: string, version: string) => Promise<void> }} options
|
|
12
|
-
*/
|
|
13
|
-
export async function checkForUpdate(options) {
|
|
14
|
-
const latestVersion = await fetchLatestVersion(
|
|
15
|
-
options.packageName,
|
|
16
|
-
options.fetchImpl ?? fetch,
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
options.log(`Current version: ${options.currentVersion}`);
|
|
20
|
-
options.log(`Latest version: ${latestVersion}`);
|
|
21
|
-
|
|
22
|
-
if (compareVersions(latestVersion, options.currentVersion) <= 0) {
|
|
23
|
-
options.log("RequestShield is already up to date.");
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const accepted = await (options.confirm ?? confirmUpdate)(latestVersion);
|
|
28
|
-
if (!accepted) {
|
|
29
|
-
options.log("Update cancelled.");
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
options.log(`Updating RequestShield to ${latestVersion}...`);
|
|
34
|
-
await (options.install ?? installWithNpm)(options.packageName, latestVersion);
|
|
35
|
-
options.log(`RequestShield ${latestVersion} was installed successfully.`);
|
|
36
|
-
options.log("Open a new terminal before running RequestShield again.");
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** @param {string} packageName @param {typeof fetch} fetchImpl */
|
|
40
|
-
async function fetchLatestVersion(packageName, fetchImpl) {
|
|
41
|
-
const url = `${DEFAULT_REGISTRY}/${encodeURIComponent(packageName)}/latest`;
|
|
42
|
-
let response;
|
|
43
|
-
try {
|
|
44
|
-
response = await fetchImpl(url, { signal: AbortSignal.timeout(15_000) });
|
|
45
|
-
} catch (error) {
|
|
46
|
-
throw new CliError(`Could not check the latest RequestShield version: ${messageOf(error)}`, {
|
|
47
|
-
code: "UPDATE_CHECK_FAILED",
|
|
48
|
-
exitCode: 7,
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (!response.ok) {
|
|
53
|
-
throw new CliError(`Could not check the latest RequestShield version: HTTP ${response.status}`, {
|
|
54
|
-
code: "UPDATE_CHECK_FAILED",
|
|
55
|
-
exitCode: 7,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const body = await response.json();
|
|
60
|
-
const version = body && typeof body === "object" ? Reflect.get(body, "version") : undefined;
|
|
61
|
-
if (typeof version !== "string" || !parseVersion(version)) {
|
|
62
|
-
throw new CliError("The npm registry returned an invalid RequestShield version", {
|
|
63
|
-
code: "INVALID_UPDATE_RESPONSE",
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
return version;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** @param {string} latestVersion */
|
|
70
|
-
async function confirmUpdate(latestVersion) {
|
|
71
|
-
if (!stdin.isTTY || !stdout.isTTY) {
|
|
72
|
-
throw new CliError(`RequestShield ${latestVersion} is available, but confirmation requires an interactive terminal`, {
|
|
73
|
-
code: "UPDATE_CONFIRMATION_REQUIRED",
|
|
74
|
-
exitCode: 2,
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
const prompt = readline.createInterface({ input: stdin, output: stdout });
|
|
78
|
-
try {
|
|
79
|
-
const answer = await prompt.question(`Update to RequestShield ${latestVersion}? (y/N): `);
|
|
80
|
-
return answer.trim().toLowerCase() === "y";
|
|
81
|
-
} finally {
|
|
82
|
-
prompt.close();
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/** @param {string} packageName @param {string} version */
|
|
87
|
-
async function installWithNpm(packageName, version) {
|
|
88
|
-
await new Promise((resolve, reject) => {
|
|
89
|
-
const child = spawn("npm", ["install", "--global", `${packageName}@${version}`], {
|
|
90
|
-
shell: process.platform === "win32",
|
|
91
|
-
stdio: "inherit",
|
|
92
|
-
windowsHide: true,
|
|
93
|
-
});
|
|
94
|
-
child.once("error", (error) => {
|
|
95
|
-
reject(new CliError(`Could not start npm: ${error.message}`, {
|
|
96
|
-
code: "UPDATE_FAILED",
|
|
97
|
-
exitCode: 1,
|
|
98
|
-
}));
|
|
99
|
-
});
|
|
100
|
-
child.once("exit", (code) => {
|
|
101
|
-
if (code === 0) resolve(undefined);
|
|
102
|
-
else reject(new CliError(`npm update failed with exit code ${code ?? "unknown"}`, {
|
|
103
|
-
code: "UPDATE_FAILED",
|
|
104
|
-
exitCode: 1,
|
|
105
|
-
}));
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/** @param {string} left @param {string} right */
|
|
111
|
-
function compareVersions(left, right) {
|
|
112
|
-
const a = parseVersion(left);
|
|
113
|
-
const b = parseVersion(right);
|
|
114
|
-
if (!a || !b) throw new CliError("RequestShield has an invalid semantic version");
|
|
115
|
-
for (let index = 0; index < 3; index++) {
|
|
116
|
-
if (a.numbers[index] !== b.numbers[index]) return a.numbers[index] - b.numbers[index];
|
|
117
|
-
}
|
|
118
|
-
if (a.prerelease === b.prerelease) return 0;
|
|
119
|
-
if (a.prerelease === undefined) return 1;
|
|
120
|
-
if (b.prerelease === undefined) return -1;
|
|
121
|
-
return a.prerelease.localeCompare(b.prerelease, "en", { numeric: true });
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/** @param {string} value */
|
|
125
|
-
function parseVersion(value) {
|
|
126
|
-
const match = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(value);
|
|
127
|
-
if (!match) return undefined;
|
|
128
|
-
return {
|
|
129
|
-
numbers: [Number(match[1]), Number(match[2]), Number(match[3])],
|
|
130
|
-
prerelease: match[4],
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/** @param {unknown} error */
|
|
135
|
-
function messageOf(error) {
|
|
136
|
-
return error instanceof Error ? error.message : String(error);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export { compareVersions };
|