@sellable/install 0.1.582 → 0.1.583

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.
@@ -9,24 +9,56 @@ import {
9
9
  executeExternalSkillsBridgeOperation,
10
10
  } from "./fly-skills-bridge.mjs";
11
11
 
12
- export async function runFlySkillsBridgeExecCli() {
13
- try {
14
- if (process.argv.length !== 2)
12
+ export const FLY_SKILLS_EXEC_ARGUMENT_MAX_BYTES = 96 * 1024;
13
+ export const FLY_SKILLS_EXEC_ARGUMENT_MAX_COUNT = 8;
14
+
15
+ const BASE64URL_CHUNK = /^[A-Za-z0-9_-]+$/;
16
+ const FLY_SKILLS_EXEC_ENCODED_MAX_BYTES =
17
+ Math.ceil(SKILLS_REQUEST_MAX_BYTES / 3) * 4;
18
+
19
+ export function decodeFlySkillsExecArguments(args) {
20
+ if (!Array.isArray(args) || args.length === 0) {
21
+ throw new FlySkillsBridgeError("skills_request_rejected");
22
+ }
23
+ if (args.length > FLY_SKILLS_EXEC_ARGUMENT_MAX_COUNT) {
24
+ throw new FlySkillsBridgeError("skills_request_too_large");
25
+ }
26
+ let encoded = "";
27
+ for (const chunk of args) {
28
+ if (typeof chunk !== "string" || !BASE64URL_CHUNK.test(chunk)) {
15
29
  throw new FlySkillsBridgeError("skills_request_rejected");
16
- const chunks = [];
17
- let total = 0;
18
- for await (const chunk of process.stdin) {
19
- total += chunk.length;
20
- if (total > SKILLS_REQUEST_MAX_BYTES)
21
- throw new FlySkillsBridgeError("skills_request_too_large");
22
- chunks.push(chunk);
23
30
  }
24
- let request;
25
- try {
26
- request = JSON.parse(Buffer.concat(chunks).toString("utf8"));
27
- } catch {
28
- throw new FlySkillsBridgeError("skills_request_rejected");
31
+ if (Buffer.byteLength(chunk, "utf8") > FLY_SKILLS_EXEC_ARGUMENT_MAX_BYTES) {
32
+ throw new FlySkillsBridgeError("skills_request_too_large");
33
+ }
34
+ encoded += chunk;
35
+ if (encoded.length > FLY_SKILLS_EXEC_ENCODED_MAX_BYTES) {
36
+ throw new FlySkillsBridgeError("skills_request_too_large");
29
37
  }
38
+ }
39
+ let bytes;
40
+ try {
41
+ bytes = Buffer.from(encoded, "base64url");
42
+ } catch {
43
+ throw new FlySkillsBridgeError("skills_request_rejected");
44
+ }
45
+ if (bytes.toString("base64url") !== encoded) {
46
+ throw new FlySkillsBridgeError("skills_request_rejected");
47
+ }
48
+ if (bytes.byteLength > SKILLS_REQUEST_MAX_BYTES) {
49
+ throw new FlySkillsBridgeError("skills_request_too_large");
50
+ }
51
+ try {
52
+ const json = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
53
+ return JSON.parse(json);
54
+ } catch {
55
+ throw new FlySkillsBridgeError("skills_request_rejected");
56
+ }
57
+ }
58
+
59
+ export async function runFlySkillsBridgeExecCli() {
60
+ try {
61
+ const request = decodeFlySkillsExecArguments(process.argv.slice(2));
30
62
  const result = executeExternalSkillsBridgeOperation(request);
31
63
  process.stdout.write(`${JSON.stringify(result)}\n`);
32
64
  process.exitCode = result.ok ? 0 : 2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/install",
3
- "version": "0.1.582",
3
+ "version": "0.1.583",
4
4
  "type": "module",
5
5
  "description": "One-command installer for Sellable MCP in Claude Code, Codex, and Hermes",
6
6
  "bin": {