multicorn-shield 1.0.0 → 1.2.0

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.
@@ -2970,7 +2970,7 @@ var require_compile = __commonJS({
2970
2970
  const schOrFunc = root.refs[ref];
2971
2971
  if (schOrFunc)
2972
2972
  return schOrFunc;
2973
- let _sch = resolve.call(this, root, ref);
2973
+ let _sch = resolve2.call(this, root, ref);
2974
2974
  if (_sch === void 0) {
2975
2975
  const schema = (_a2 = root.localRefs) === null || _a2 === void 0 ? void 0 : _a2[ref];
2976
2976
  const { schemaId } = this.opts;
@@ -2997,7 +2997,7 @@ var require_compile = __commonJS({
2997
2997
  function sameSchemaEnv(s1, s2) {
2998
2998
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
2999
2999
  }
3000
- function resolve(root, ref) {
3000
+ function resolve2(root, ref) {
3001
3001
  let sch;
3002
3002
  while (typeof (sch = this.refs[ref]) == "string")
3003
3003
  ref = sch;
@@ -3569,7 +3569,7 @@ var require_fast_uri = __commonJS({
3569
3569
  }
3570
3570
  return uri;
3571
3571
  }
3572
- function resolve(baseURI, relativeURI, options) {
3572
+ function resolve2(baseURI, relativeURI, options) {
3573
3573
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3574
3574
  const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
3575
3575
  schemelessOptions.skipEscape = true;
@@ -3796,7 +3796,7 @@ var require_fast_uri = __commonJS({
3796
3796
  var fastUri = {
3797
3797
  SCHEMES,
3798
3798
  normalize,
3799
- resolve,
3799
+ resolve: resolve2,
3800
3800
  resolveComponent,
3801
3801
  equal,
3802
3802
  serialize,
@@ -20675,7 +20675,7 @@ var Protocol = class {
20675
20675
  return;
20676
20676
  }
20677
20677
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
20678
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
20678
+ await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
20679
20679
  options?.signal?.throwIfAborted();
20680
20680
  }
20681
20681
  } catch (error2) {
@@ -20692,7 +20692,7 @@ var Protocol = class {
20692
20692
  */
20693
20693
  request(request, resultSchema, options) {
20694
20694
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
20695
- return new Promise((resolve, reject) => {
20695
+ return new Promise((resolve2, reject) => {
20696
20696
  const earlyReject = (error2) => {
20697
20697
  reject(error2);
20698
20698
  };
@@ -20770,7 +20770,7 @@ var Protocol = class {
20770
20770
  if (!parseResult.success) {
20771
20771
  reject(parseResult.error);
20772
20772
  } else {
20773
- resolve(parseResult.data);
20773
+ resolve2(parseResult.data);
20774
20774
  }
20775
20775
  } catch (error2) {
20776
20776
  reject(error2);
@@ -21031,12 +21031,12 @@ var Protocol = class {
21031
21031
  }
21032
21032
  } catch {
21033
21033
  }
21034
- return new Promise((resolve, reject) => {
21034
+ return new Promise((resolve2, reject) => {
21035
21035
  if (signal.aborted) {
21036
21036
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
21037
21037
  return;
21038
21038
  }
21039
- const timeoutId = setTimeout(resolve, interval);
21039
+ const timeoutId = setTimeout(resolve2, interval);
21040
21040
  signal.addEventListener("abort", () => {
21041
21041
  clearTimeout(timeoutId);
21042
21042
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -21890,12 +21890,12 @@ var StdioServerTransport = class {
21890
21890
  this.onclose?.();
21891
21891
  }
21892
21892
  send(message) {
21893
- return new Promise((resolve) => {
21893
+ return new Promise((resolve2) => {
21894
21894
  const json2 = serializeMessage(message);
21895
21895
  if (this._stdout.write(json2)) {
21896
- resolve();
21896
+ resolve2();
21897
21897
  } else {
21898
- this._stdout.once("drain", resolve);
21898
+ this._stdout.once("drain", resolve2);
21899
21899
  }
21900
21900
  });
21901
21901
  }
@@ -22214,7 +22214,7 @@ function detectScopeHints() {
22214
22214
  return [];
22215
22215
  }
22216
22216
  function sleep(ms) {
22217
- return new Promise((resolve) => setTimeout(resolve, ms));
22217
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
22218
22218
  }
22219
22219
  function isApiSuccessResponse(value) {
22220
22220
  if (typeof value !== "object" || value === null) return false;
@@ -22259,6 +22259,69 @@ function getClaudeDesktopConfigPath() {
22259
22259
  );
22260
22260
  }
22261
22261
  }
22262
+ var INIT_WIZARD_PLATFORM_REGISTRY = [
22263
+ { slug: "openclaw", displayName: "OpenClaw", section: "native", detectable: true },
22264
+ { slug: "claude-code", displayName: "Claude Code", section: "native", detectable: true },
22265
+ { slug: "windsurf", displayName: "Windsurf", section: "native", detectable: true },
22266
+ { slug: "cline", displayName: "Cline", section: "native", detectable: false },
22267
+ { slug: "gemini-cli", displayName: "Gemini CLI", section: "native", detectable: false },
22268
+ {
22269
+ slug: "cursor",
22270
+ displayName: "Cursor",
22271
+ section: "hosted",
22272
+ prereqUrl: "https://www.cursor.com/downloads",
22273
+ detectable: true
22274
+ },
22275
+ {
22276
+ slug: "claude-desktop",
22277
+ displayName: "Claude Desktop",
22278
+ section: "hosted",
22279
+ prereqUrl: "https://claude.ai/download",
22280
+ detectable: false
22281
+ },
22282
+ {
22283
+ slug: "github-copilot",
22284
+ displayName: "GitHub Copilot",
22285
+ section: "hosted",
22286
+ prereqUrl: "https://docs.github.com/en/copilot/get-started",
22287
+ detectable: false
22288
+ },
22289
+ {
22290
+ slug: "kilo-code",
22291
+ displayName: "Kilo Code",
22292
+ section: "hosted",
22293
+ prereqUrl: "https://kilocode.ai/docs/getting-started",
22294
+ detectable: false
22295
+ },
22296
+ {
22297
+ slug: "continue-dev",
22298
+ displayName: "Continue",
22299
+ section: "hosted",
22300
+ prereqUrl: "https://docs.continue.dev/ide-extensions/install",
22301
+ detectable: false
22302
+ },
22303
+ {
22304
+ slug: "goose",
22305
+ displayName: "Goose",
22306
+ section: "hosted",
22307
+ prereqUrl: "https://goose-docs.ai/docs/quickstart/",
22308
+ detectable: false
22309
+ },
22310
+ { slug: "other-mcp", displayName: "Local MCP / Other", section: "hosted", detectable: false }
22311
+ ];
22312
+ (() => {
22313
+ const itemsFor = (section) => INIT_WIZARD_PLATFORM_REGISTRY.filter((e) => e.section === section).map((e) => ({
22314
+ platform: e.slug,
22315
+ label: e.displayName
22316
+ }));
22317
+ return [
22318
+ { title: "Recommended (native plugin)", items: itemsFor("native") },
22319
+ { title: "Hosted proxy (MCP only)", items: itemsFor("hosted") }
22320
+ ];
22321
+ })();
22322
+ Object.fromEntries(
22323
+ INIT_WIZARD_PLATFORM_REGISTRY.map((e, i) => [i + 1, e.slug])
22324
+ );
22262
22325
 
22263
22326
  // src/extension/config-reader.ts
22264
22327
  var EXTENSION_BACKUP_FILENAME = "extension-backup.json";
@@ -22359,7 +22422,7 @@ async function writeExtensionBackup(claudeDesktopConfigPath, mcpServers) {
22359
22422
 
22360
22423
  // package.json
22361
22424
  var package_default = {
22362
- version: "1.0.0"};
22425
+ version: "1.2.0"};
22363
22426
 
22364
22427
  // src/package-meta.ts
22365
22428
  var PACKAGE_VERSION = package_default.version;
@@ -23138,7 +23201,7 @@ function createActionLogger(config2) {
23138
23201
  };
23139
23202
  }
23140
23203
  function sleep2(ms) {
23141
- return new Promise((resolve) => setTimeout(resolve, ms));
23204
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
23142
23205
  }
23143
23206
 
23144
23207
  // src/proxy/interceptor.ts
@@ -23716,8 +23779,8 @@ async function runShieldExtension() {
23716
23779
  const dashboardUrl = deriveDashboardUrl(baseUrl);
23717
23780
  let resolveReady;
23718
23781
  let rejectReady;
23719
- const readyPromise = new Promise((resolve, reject) => {
23720
- resolveReady = resolve;
23782
+ const readyPromise = new Promise((resolve2, reject) => {
23783
+ resolveReady = resolve2;
23721
23784
  rejectReady = reject;
23722
23785
  });
23723
23786
  const toolRegistry = /* @__PURE__ */ new Map();
@@ -23968,10 +24031,10 @@ async function runShieldExtension() {
23968
24031
  await Promise.all(proxySessions.map((s) => s.close().catch(() => void 0)));
23969
24032
  await server.close();
23970
24033
  };
23971
- const stdinEnded = new Promise((resolve) => {
24034
+ const stdinEnded = new Promise((resolve2) => {
23972
24035
  process.stdin.resume();
23973
24036
  process.stdin.once("end", () => {
23974
- resolve();
24037
+ resolve2();
23975
24038
  });
23976
24039
  });
23977
24040
  const onSignal = () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multicorn-shield",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "The control layer for AI agents: permissions, consent, spending limits, and audit logging.",
5
5
  "license": "MIT",
6
6
  "author": "Multicorn AI Pty Ltd",
@@ -53,21 +53,58 @@ function readStdin() {
53
53
  * @param {Record<string, unknown>} obj
54
54
  * @returns {string}
55
55
  */
56
- function resolveClineAgentName(obj) {
56
+ function cwdUnderWorkspacePath(cwdResolved, workspacePath) {
57
+ const w = path.resolve(workspacePath);
58
+ if (cwdResolved === w) return true;
59
+ const prefix = w.endsWith(path.sep) ? w : w + path.sep;
60
+ return cwdResolved.startsWith(prefix);
61
+ }
62
+
63
+ function pickAgentNameForPlatform(obj, platform, cwd) {
57
64
  const agents = obj.agents;
58
- if (Array.isArray(agents)) {
59
- for (const entry of agents) {
60
- if (
61
- entry &&
62
- typeof entry === "object" &&
63
- /** @type {{ platform?: string; name?: string }} */ (entry).platform === "cline" &&
64
- typeof (/** @type {{ platform?: string; name?: string }} */ (entry).name) === "string"
65
- ) {
66
- return /** @type {{ name: string }} */ (entry).name;
67
- }
65
+ if (!Array.isArray(agents)) {
66
+ return typeof obj.agentName === "string" ? obj.agentName : "";
67
+ }
68
+ const matches = [];
69
+ for (const entry of agents) {
70
+ if (
71
+ entry &&
72
+ typeof entry === "object" &&
73
+ /** @type {{ platform?: string; name?: string; workspacePath?: string }} */ (entry)
74
+ .platform === platform &&
75
+ typeof (/** @type {{ platform?: string; name?: string }} */ (entry).name) === "string"
76
+ ) {
77
+ matches.push(/** @type {{ name: string; workspacePath?: string }} */ (entry));
68
78
  }
69
79
  }
70
- return typeof obj.agentName === "string" ? obj.agentName : "";
80
+ if (matches.length === 0) {
81
+ return typeof obj.agentName === "string" ? obj.agentName : "";
82
+ }
83
+ const withWs = matches.filter(
84
+ (m) => typeof m.workspacePath === "string" && m.workspacePath.length > 0,
85
+ );
86
+ if (withWs.length === 0) {
87
+ return matches[0].name;
88
+ }
89
+ const resolvedCwd = path.resolve(cwd);
90
+ let best = null;
91
+ let bestLen = -1;
92
+ for (const m of withWs) {
93
+ if (!cwdUnderWorkspacePath(resolvedCwd, m.workspacePath)) continue;
94
+ const len = path.resolve(m.workspacePath).length;
95
+ if (len > bestLen) {
96
+ bestLen = len;
97
+ best = m;
98
+ }
99
+ }
100
+ if (best !== null) {
101
+ return best.name;
102
+ }
103
+ return matches[0].name;
104
+ }
105
+
106
+ function resolveClineAgentName(obj) {
107
+ return pickAgentNameForPlatform(obj, "cline", process.cwd());
71
108
  }
72
109
 
73
110
  /**
@@ -56,21 +56,58 @@ function readStdin() {
56
56
  });
57
57
  }
58
58
 
59
- function resolveGeminiCliAgentName(obj) {
59
+ function cwdUnderWorkspacePath(cwdResolved, workspacePath) {
60
+ const w = path.resolve(workspacePath);
61
+ if (cwdResolved === w) return true;
62
+ const prefix = w.endsWith(path.sep) ? w : w + path.sep;
63
+ return cwdResolved.startsWith(prefix);
64
+ }
65
+
66
+ function pickAgentNameForPlatform(obj, platform, cwd) {
60
67
  const agents = obj.agents;
61
- if (Array.isArray(agents)) {
62
- for (const entry of agents) {
63
- if (
64
- entry &&
65
- typeof entry === "object" &&
66
- /** @type {{ platform?: string; name?: string }} */ (entry).platform === "gemini-cli" &&
67
- typeof (/** @type {{ platform?: string; name?: string }} */ (entry).name) === "string"
68
- ) {
69
- return /** @type {{ name: string }} */ (entry).name;
70
- }
68
+ if (!Array.isArray(agents)) {
69
+ return typeof obj.agentName === "string" ? obj.agentName : "";
70
+ }
71
+ const matches = [];
72
+ for (const entry of agents) {
73
+ if (
74
+ entry &&
75
+ typeof entry === "object" &&
76
+ /** @type {{ platform?: string; name?: string; workspacePath?: string }} */ (entry)
77
+ .platform === platform &&
78
+ typeof (/** @type {{ platform?: string; name?: string }} */ (entry).name) === "string"
79
+ ) {
80
+ matches.push(/** @type {{ name: string; workspacePath?: string }} */ (entry));
71
81
  }
72
82
  }
73
- return typeof obj.agentName === "string" ? obj.agentName : "";
83
+ if (matches.length === 0) {
84
+ return typeof obj.agentName === "string" ? obj.agentName : "";
85
+ }
86
+ const withWs = matches.filter(
87
+ (m) => typeof m.workspacePath === "string" && m.workspacePath.length > 0,
88
+ );
89
+ if (withWs.length === 0) {
90
+ return matches[0].name;
91
+ }
92
+ const resolvedCwd = path.resolve(cwd);
93
+ let best = null;
94
+ let bestLen = -1;
95
+ for (const m of withWs) {
96
+ if (!cwdUnderWorkspacePath(resolvedCwd, m.workspacePath)) continue;
97
+ const len = path.resolve(m.workspacePath).length;
98
+ if (len > bestLen) {
99
+ bestLen = len;
100
+ best = m;
101
+ }
102
+ }
103
+ if (best !== null) {
104
+ return best.name;
105
+ }
106
+ return matches[0].name;
107
+ }
108
+
109
+ function resolveGeminiCliAgentName(obj) {
110
+ return pickAgentNameForPlatform(obj, "gemini-cli", process.cwd());
74
111
  }
75
112
 
76
113
  function loadConfig() {
@@ -37,25 +37,73 @@ function readStdin() {
37
37
  }
38
38
 
39
39
  // Duplicated in pre-action.cjs. CJS hooks cannot import shared TypeScript modules.
40
+ /**
41
+ * @param {string} cwdResolved
42
+ * @param {string} workspacePath
43
+ * @returns {boolean}
44
+ */
45
+ function cwdUnderWorkspacePath(cwdResolved, workspacePath) {
46
+ const w = path.resolve(workspacePath);
47
+ if (cwdResolved === w) return true;
48
+ const prefix = w.endsWith(path.sep) ? w : w + path.sep;
49
+ return cwdResolved.startsWith(prefix);
50
+ }
51
+
40
52
  /**
41
53
  * @param {Record<string, unknown>} obj
54
+ * @param {string} platform
55
+ * @param {string} cwd
42
56
  * @returns {string}
43
57
  */
44
- function resolveWindsurfAgentName(obj) {
58
+ function pickAgentNameForPlatform(obj, platform, cwd) {
45
59
  const agents = obj.agents;
46
- if (Array.isArray(agents)) {
47
- for (const entry of agents) {
48
- if (
49
- entry &&
50
- typeof entry === "object" &&
51
- /** @type {{ platform?: string; name?: string }} */ (entry).platform === "windsurf" &&
52
- typeof (/** @type {{ platform?: string; name?: string }} */ (entry).name) === "string"
53
- ) {
54
- return /** @type {{ name: string }} */ (entry).name;
55
- }
60
+ if (!Array.isArray(agents)) {
61
+ return typeof obj.agentName === "string" ? obj.agentName : "";
62
+ }
63
+ const matches = [];
64
+ for (const entry of agents) {
65
+ if (
66
+ entry &&
67
+ typeof entry === "object" &&
68
+ /** @type {{ platform?: string; name?: string; workspacePath?: string }} */ (entry)
69
+ .platform === platform &&
70
+ typeof (/** @type {{ platform?: string; name?: string }} */ (entry).name) === "string"
71
+ ) {
72
+ matches.push(/** @type {{ name: string; workspacePath?: string }} */ (entry));
56
73
  }
57
74
  }
58
- return typeof obj.agentName === "string" ? obj.agentName : "";
75
+ if (matches.length === 0) {
76
+ return typeof obj.agentName === "string" ? obj.agentName : "";
77
+ }
78
+ const withWs = matches.filter(
79
+ (m) => typeof m.workspacePath === "string" && m.workspacePath.length > 0,
80
+ );
81
+ if (withWs.length === 0) {
82
+ return matches[0].name;
83
+ }
84
+ const resolvedCwd = path.resolve(cwd);
85
+ let best = null;
86
+ let bestLen = -1;
87
+ for (const m of withWs) {
88
+ if (!cwdUnderWorkspacePath(resolvedCwd, m.workspacePath)) continue;
89
+ const len = path.resolve(m.workspacePath).length;
90
+ if (len > bestLen) {
91
+ bestLen = len;
92
+ best = m;
93
+ }
94
+ }
95
+ if (best !== null) {
96
+ return best.name;
97
+ }
98
+ return matches[0].name;
99
+ }
100
+
101
+ /**
102
+ * @param {Record<string, unknown>} obj
103
+ * @returns {string}
104
+ */
105
+ function resolveWindsurfAgentName(obj) {
106
+ return pickAgentNameForPlatform(obj, "windsurf", process.cwd());
59
107
  }
60
108
 
61
109
  /**
@@ -41,25 +41,73 @@ function readStdin() {
41
41
  }
42
42
 
43
43
  // Duplicated in post-action.cjs. CJS hooks cannot import shared TypeScript modules.
44
+ /**
45
+ * @param {string} cwdResolved
46
+ * @param {string} workspacePath
47
+ * @returns {boolean}
48
+ */
49
+ function cwdUnderWorkspacePath(cwdResolved, workspacePath) {
50
+ const w = path.resolve(workspacePath);
51
+ if (cwdResolved === w) return true;
52
+ const prefix = w.endsWith(path.sep) ? w : w + path.sep;
53
+ return cwdResolved.startsWith(prefix);
54
+ }
55
+
44
56
  /**
45
57
  * @param {Record<string, unknown>} obj
58
+ * @param {string} platform
59
+ * @param {string} cwd
46
60
  * @returns {string}
47
61
  */
48
- function resolveWindsurfAgentName(obj) {
62
+ function pickAgentNameForPlatform(obj, platform, cwd) {
49
63
  const agents = obj.agents;
50
- if (Array.isArray(agents)) {
51
- for (const entry of agents) {
52
- if (
53
- entry &&
54
- typeof entry === "object" &&
55
- /** @type {{ platform?: string; name?: string }} */ (entry).platform === "windsurf" &&
56
- typeof (/** @type {{ platform?: string; name?: string }} */ (entry).name) === "string"
57
- ) {
58
- return /** @type {{ name: string }} */ (entry).name;
59
- }
64
+ if (!Array.isArray(agents)) {
65
+ return typeof obj.agentName === "string" ? obj.agentName : "";
66
+ }
67
+ const matches = [];
68
+ for (const entry of agents) {
69
+ if (
70
+ entry &&
71
+ typeof entry === "object" &&
72
+ /** @type {{ platform?: string; name?: string; workspacePath?: string }} */ (entry)
73
+ .platform === platform &&
74
+ typeof (/** @type {{ platform?: string; name?: string }} */ (entry).name) === "string"
75
+ ) {
76
+ matches.push(/** @type {{ name: string; workspacePath?: string }} */ (entry));
60
77
  }
61
78
  }
62
- return typeof obj.agentName === "string" ? obj.agentName : "";
79
+ if (matches.length === 0) {
80
+ return typeof obj.agentName === "string" ? obj.agentName : "";
81
+ }
82
+ const withWs = matches.filter(
83
+ (m) => typeof m.workspacePath === "string" && m.workspacePath.length > 0,
84
+ );
85
+ if (withWs.length === 0) {
86
+ return matches[0].name;
87
+ }
88
+ const resolvedCwd = path.resolve(cwd);
89
+ let best = null;
90
+ let bestLen = -1;
91
+ for (const m of withWs) {
92
+ if (!cwdUnderWorkspacePath(resolvedCwd, m.workspacePath)) continue;
93
+ const len = path.resolve(m.workspacePath).length;
94
+ if (len > bestLen) {
95
+ bestLen = len;
96
+ best = m;
97
+ }
98
+ }
99
+ if (best !== null) {
100
+ return best.name;
101
+ }
102
+ return matches[0].name;
103
+ }
104
+
105
+ /**
106
+ * @param {Record<string, unknown>} obj
107
+ * @returns {string}
108
+ */
109
+ function resolveWindsurfAgentName(obj) {
110
+ return pickAgentNameForPlatform(obj, "windsurf", process.cwd());
63
111
  }
64
112
 
65
113
  /**