@kanvas/openclaw-plugin 0.1.11 → 0.1.13

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.
Files changed (2) hide show
  1. package/dist/index.js +53 -33
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10,6 +10,18 @@ import { registerOrdersTools } from "./tools/orders.js";
10
10
  import { registerSocialTools } from "./tools/social.js";
11
11
  import { toolResult } from "./tools/helpers.js";
12
12
  const DEFAULT_API_URL = "https://graphapi.kanvas.dev/graphql";
13
+ // OpenClaw v2026.4.5+ calls register() per-agent-context (main, subagents,
14
+ // cron lanes). Heavy objects (client, services) are created once and shared;
15
+ // tools & hooks must be registered on every api object.
16
+ let sharedClient = null;
17
+ let sharedConfig = null;
18
+ let sharedEnsureAuth = null;
19
+ let sharedCrm = null;
20
+ let sharedInventory = null;
21
+ let sharedOrders = null;
22
+ let sharedSocial = null;
23
+ let startupBannerShown = false;
24
+ let skipBannerShown = false;
13
25
  function resolveConfig(pluginConfig) {
14
26
  const cfg = pluginConfig ?? {};
15
27
  const apiUrl = cfg.apiUrl || process.env.KANVAS_API_URL || DEFAULT_API_URL;
@@ -67,38 +79,46 @@ export default {
67
79
  description: "Connects agents to Kanvas — your company's nervous system for CRM, inventory, orders, and messaging.",
68
80
  configSchema: { type: "object" },
69
81
  register(api) {
70
- // Guard: resolve config and log a warning instead of throwing if
71
- // credentials are missing. This prevents the gateway from entering
72
- // an infinite retry loop when the plugin is installed but not yet
73
- // configured, or when the gateway re-invokes register() multiple times.
74
- let config;
82
+ // Resolve plugin config. api.pluginConfig is set on the gateway init
83
+ // context but often undefined on agent contexts (Slack, subagents, cron).
84
+ // Fall back to extracting from the full app config (api.config), which
85
+ // is always available — matching the pattern used by budget-guard and
86
+ // lossless-claw.
87
+ const pluginCfg = api.pluginConfig
88
+ ?? api.config?.plugins?.entries?.kanvas?.config
89
+ ?? {};
90
+ let config = null;
75
91
  try {
76
- config = resolveConfig(api.pluginConfig);
92
+ config = resolveConfig(pluginCfg);
77
93
  }
78
94
  catch (err) {
79
- api.logger.info(`Kanvas plugin skipped: ${err.message}. Run "openclaw kanvas setup" to configure.`);
80
- // Still register the CLI so the user can run setup even without config
81
- api.registerCli((ctx) => {
82
- ctx.program
83
- .command("setup")
84
- .description("Interactive setup — configure Kanvas credentials and test the connection")
85
- .action(async () => {
86
- const { runSetup } = await import("./cli/setup.js");
87
- await runSetup();
88
- });
89
- }, { commands: ["setup"] });
90
- return;
95
+ // If shared state exists from a prior init, fall through to register
96
+ // tools. Otherwise this is genuinely unconfigured bail.
97
+ if (!sharedClient) {
98
+ if (!skipBannerShown) {
99
+ api.logger.info(`Kanvas plugin skipped: ${err.message}. Run "openclaw kanvas setup" to configure.`);
100
+ skipBannerShown = true;
101
+ }
102
+ return;
103
+ }
91
104
  }
92
- const client = new KanvasClient(config);
93
- const ensureAuth = createAuthGuard(client, config, api.logger);
94
- const crm = new CrmService(client);
95
- const inventory = new InventoryService(client);
96
- const orders = new OrdersService(client);
97
- const social = new SocialService(client);
98
- registerCrmTools(api, crm, ensureAuth);
99
- registerInventoryTools(api, inventory, ensureAuth);
100
- registerOrdersTools(api, orders, ensureAuth);
101
- registerSocialTools(api, social, ensureAuth);
105
+ // Create heavy objects once; reuse across agent contexts.
106
+ if (!sharedClient && config) {
107
+ sharedConfig = config;
108
+ sharedClient = new KanvasClient(config);
109
+ sharedEnsureAuth = createAuthGuard(sharedClient, config, api.logger);
110
+ sharedCrm = new CrmService(sharedClient);
111
+ sharedInventory = new InventoryService(sharedClient);
112
+ sharedOrders = new OrdersService(sharedClient);
113
+ sharedSocial = new SocialService(sharedClient);
114
+ }
115
+ // Tools and hooks must be registered on every api object — each one is
116
+ // a separate agent context (main, subagents, cron lanes).
117
+ const ensureAuth = sharedEnsureAuth;
118
+ registerCrmTools(api, sharedCrm, ensureAuth);
119
+ registerInventoryTools(api, sharedInventory, ensureAuth);
120
+ registerOrdersTools(api, sharedOrders, ensureAuth);
121
+ registerSocialTools(api, sharedSocial, ensureAuth);
102
122
  api.registerTool({
103
123
  name: "kanvas_test_connection",
104
124
  label: "Test Connection",
@@ -106,15 +126,12 @@ export default {
106
126
  parameters: Type.Object({}),
107
127
  async execute() {
108
128
  await ensureAuth();
109
- return toolResult(await client.testConnection());
129
+ return toolResult(await sharedClient.testConnection());
110
130
  },
111
131
  });
112
- // Inject Kanvas context into the agent's system prompt so it knows
113
- // what these tools are for and how to use them together.
114
132
  api.on("before_prompt_build", () => ({
115
133
  appendSystemContext: KANVAS_SYSTEM_CONTEXT,
116
134
  }));
117
- // Register `openclaw kanvas setup` CLI command for interactive configuration.
118
135
  api.registerCli((ctx) => {
119
136
  ctx.program
120
137
  .command("setup")
@@ -124,7 +141,10 @@ export default {
124
141
  await runSetup();
125
142
  });
126
143
  }, { commands: ["setup"] });
127
- api.logger.info("Kanvas plugin registered — 53 tools loaded");
144
+ if (!startupBannerShown) {
145
+ startupBannerShown = true;
146
+ api.logger.info("Kanvas plugin registered — 53 tools loaded");
147
+ }
128
148
  },
129
149
  };
130
150
  const KANVAS_SYSTEM_CONTEXT = `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanvas/openclaw-plugin",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Connects agents to Kanvas — your company's nervous system for CRM, inventory, orders, and messaging.",
5
5
  "license": "MIT",
6
6
  "repository": {