multicorn-shield 0.1.7 → 0.1.8

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.
@@ -476,7 +476,7 @@ var handler = async (event) => {
476
476
  const capitalizedService = mapping.service.charAt(0).toUpperCase() + mapping.service.slice(1);
477
477
  const dashboardUrl = deriveDashboardUrl(config.baseUrl);
478
478
  event.messages.push(
479
- `Permission denied: ${capitalizedService} ${mapping.permissionLevel} access is not allowed. Check pending approvals at ${dashboardUrl}/approvals`
479
+ `Permission denied: ${capitalizedService} ${mapping.permissionLevel} access is not allowed. Check pending approvals at ${dashboardUrl}/approvals `
480
480
  );
481
481
  void logAction(
482
482
  {
@@ -495,53 +495,20 @@ var pluginLogger = null;
495
495
  var pluginConfig;
496
496
  var connectionLogged = false;
497
497
  var SCOPE_REFRESH_INTERVAL_MS = 6e4;
498
+ var cachedMulticornConfig = null;
499
+ function loadMulticornConfig() {
500
+ try {
501
+ const configPath = path.join(os.homedir(), ".multicorn", "config.json");
502
+ const raw = fs.readFileSync(configPath, "utf-8");
503
+ return JSON.parse(raw);
504
+ } catch {
505
+ return null;
506
+ }
507
+ }
498
508
  function readConfig() {
499
509
  const pc = pluginConfig ?? {};
500
- let resolvedApiKey = asString(pc["apiKey"]) ?? process.env["MULTICORN_API_KEY"] ?? "";
501
- let resolvedBaseUrl = asString(pc["baseUrl"]) ?? process.env["MULTICORN_BASE_URL"] ?? "";
502
- if (!resolvedApiKey) {
503
- try {
504
- const multicornConfigPath = path.join(os.homedir(), ".multicorn", "config.json");
505
- const multicornConfigContent = fs.readFileSync(multicornConfigPath, "utf-8");
506
- const multicornConfig = JSON.parse(multicornConfigContent);
507
- if (multicornConfig && typeof multicornConfig.apiKey === "string" && multicornConfig.apiKey.length > 0) {
508
- resolvedApiKey = multicornConfig.apiKey;
509
- if (!resolvedBaseUrl) {
510
- resolvedBaseUrl = multicornConfig.baseUrl ?? "https://api.multicorn.ai";
511
- }
512
- }
513
- } catch {
514
- }
515
- }
516
- if (!resolvedApiKey) {
517
- try {
518
- const configPath = path.join(os.homedir(), ".openclaw", "openclaw.json");
519
- const configContent = fs.readFileSync(configPath, "utf-8");
520
- const config = JSON.parse(configContent);
521
- const hooks = config["hooks"];
522
- const internal = hooks?.["internal"];
523
- const entries = internal?.["entries"];
524
- const shieldEntry = entries?.["multicorn-shield"];
525
- const env = shieldEntry?.env;
526
- if (env) {
527
- const hookApiKey = asString(env["MULTICORN_API_KEY"]);
528
- const hookBaseUrl = asString(env["MULTICORN_BASE_URL"]);
529
- if (hookApiKey) {
530
- resolvedApiKey = hookApiKey;
531
- resolvedBaseUrl = resolvedBaseUrl || (hookBaseUrl ?? "https://api.multicorn.ai");
532
- pluginLogger?.warn(
533
- "Multicorn Shield: Reading config from hooks.internal.entries. For cleaner setup, set MULTICORN_API_KEY as a system environment variable."
534
- );
535
- } else if (hookBaseUrl) {
536
- resolvedBaseUrl = resolvedBaseUrl || hookBaseUrl;
537
- }
538
- }
539
- } catch {
540
- }
541
- }
542
- if (!resolvedBaseUrl) {
543
- resolvedBaseUrl = "https://api.multicorn.ai";
544
- }
510
+ const resolvedApiKey = asString(process.env["MULTICORN_API_KEY"]) ?? asString(cachedMulticornConfig?.apiKey) ?? "";
511
+ const resolvedBaseUrl = asString(process.env["MULTICORN_BASE_URL"]) ?? asString(cachedMulticornConfig?.baseUrl) ?? "https://api.multicorn.ai";
545
512
  const agentName = asString(pc["agentName"]) ?? process.env["MULTICORN_AGENT_NAME"] ?? null;
546
513
  const failModeRaw = asString(pc["failMode"]) ?? process.env["MULTICORN_FAIL_MODE"] ?? "open";
547
514
  const failMode = failModeRaw === "closed" ? "closed" : "open";
@@ -718,7 +685,9 @@ function buildApprovalDescription(agentName, permissionLevel, service, toolName,
718
685
  async function beforeToolCall(event, ctx) {
719
686
  const config = readConfig();
720
687
  if (config.apiKey.length === 0) {
721
- pluginLogger?.warn("MULTICORN_API_KEY is not set. Skipping permission checks.");
688
+ pluginLogger?.warn(
689
+ "Multicorn Shield: No API key found. Run 'npx multicorn-proxy init' or set MULTICORN_API_KEY."
690
+ );
722
691
  return void 0;
723
692
  }
724
693
  const agentName = resolveAgentName(ctx.sessionKey ?? "", config.agentName);
@@ -816,7 +785,7 @@ async function beforeToolCall(event, ctx) {
816
785
  }
817
786
  const capitalizedService = mapping.service.charAt(0).toUpperCase() + mapping.service.slice(1);
818
787
  const dashboardUrl = deriveDashboardUrl(config.baseUrl);
819
- const reason = `${capitalizedService} ${mapping.permissionLevel} access is not allowed. Check pending approvals at ${dashboardUrl}/approvals`;
788
+ const reason = `${capitalizedService} ${mapping.permissionLevel} access is not allowed. Check pending approvals at ${dashboardUrl}/approvals `;
820
789
  return { block: true, blockReason: reason };
821
790
  }
822
791
  function afterToolCall(event, ctx) {
@@ -849,13 +818,14 @@ var plugin = {
849
818
  register(api) {
850
819
  pluginLogger = api.logger;
851
820
  pluginConfig = api.pluginConfig;
821
+ cachedMulticornConfig = loadMulticornConfig();
852
822
  api.on("before_tool_call", beforeToolCall, { priority: 10 });
853
823
  api.on("after_tool_call", afterToolCall);
854
824
  api.logger.info("Multicorn Shield plugin registered.");
855
825
  const config = readConfig();
856
826
  if (config.apiKey.length === 0) {
857
827
  api.logger.error(
858
- "Multicorn Shield: No API key found. Run `npx multicorn-proxy init` to set up your API key, or set MULTICORN_API_KEY in your OpenClaw config (~/.openclaw/openclaw.json \u2192 plugins.entries.multicorn-shield.env.MULTICORN_API_KEY). Get a key from your Multicorn dashboard (Settings \u2192 API Keys)."
828
+ "Multicorn Shield: No API key found. Run 'npx multicorn-proxy init' or set MULTICORN_API_KEY."
859
829
  );
860
830
  } else {
861
831
  api.logger.info(`Multicorn Shield connecting to ${config.baseUrl}`);
@@ -874,6 +844,7 @@ function resetState() {
874
844
  lastScopeRefresh = 0;
875
845
  pluginLogger = null;
876
846
  pluginConfig = void 0;
847
+ cachedMulticornConfig = null;
877
848
  connectionLogged = false;
878
849
  }
879
850
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multicorn-shield",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "The control layer for AI agents: permissions, consent, spending limits, and audit logging.",
5
5
  "license": "MIT",
6
6
  "type": "module",