@alfe.ai/openclaw-google 0.0.15 → 0.0.17

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/dist/plugin.cjs CHANGED
@@ -102,7 +102,7 @@ function runGwsCommand(args, configDir) {
102
102
  resolve({
103
103
  stdout,
104
104
  stderr,
105
- exitCode: error?.code ?? (error ? 1 : 0)
105
+ exitCode: typeof error?.code === "number" ? error.code : error ? 1 : 0
106
106
  });
107
107
  });
108
108
  });
@@ -183,7 +183,11 @@ const plugin = {
183
183
  const log = api.logger;
184
184
  for (const tool of googleTools) api.registerTool(tool);
185
185
  log.info(`Registered ${googleTools.length.toString()} Google tools: ${googleTools.map((t) => t.name).join(", ")}`);
186
- if (!globalThis.__googlePluginActivated) {
186
+ const startGoogleService = () => {
187
+ if (globalThis.__googlePluginActivated === true) {
188
+ log.debug("Google plugin already activated — skipping duplicate");
189
+ return;
190
+ }
187
191
  globalThis.__googlePluginActivated = true;
188
192
  log.info("Alfe Google Workspace plugin activating...");
189
193
  try {
@@ -202,7 +206,22 @@ const plugin = {
202
206
  log.warn("Google tools will fail — no API config available");
203
207
  }
204
208
  log.info("Alfe Google Workspace plugin activated");
205
- }
209
+ };
210
+ const stopGoogleService = () => {
211
+ globalThis.__googlePluginActivated = false;
212
+ client = null;
213
+ cachedAccounts = [];
214
+ log.info("Alfe Google Workspace plugin stopped");
215
+ };
216
+ if (api.registerService) api.registerService({
217
+ id: "alfe-google-workspace",
218
+ start: () => {
219
+ startGoogleService();
220
+ },
221
+ stop: () => {
222
+ stopGoogleService();
223
+ }
224
+ });
206
225
  },
207
226
  deactivate(api) {
208
227
  globalThis.__googlePluginActivated = false;
package/dist/plugin.d.cts CHANGED
@@ -8,11 +8,22 @@ interface Logger {
8
8
  error(msg: string, ...args: unknown[]): void;
9
9
  debug(msg: string, ...args: unknown[]): void;
10
10
  }
11
+ interface PluginServiceContext {
12
+ config?: Record<string, unknown>;
13
+ workspaceDir?: string;
14
+ stateDir?: string;
15
+ logger?: Logger;
16
+ }
11
17
  interface OpenClawPluginApi {
12
18
  logger: Logger;
13
19
  registrationMode?: "full" | "setup-only" | "setup-runtime" | "cli-metadata";
14
20
  registerTool(tool: ToolDef): void;
15
21
  registerGatewayMethod(name: string, handler: (...args: unknown[]) => Promise<unknown>): void;
22
+ registerService?(service: {
23
+ id: string;
24
+ start: (ctx: PluginServiceContext) => void | Promise<void>;
25
+ stop?: (ctx: PluginServiceContext) => void | Promise<void>;
26
+ }): void;
16
27
  on(event: string, handler: (...args: unknown[]) => void | Promise<void>, options?: {
17
28
  priority?: number;
18
29
  }): void;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.cts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;;AAiCmE,UAZzD,MAAA,CAiBO;EAAA,IAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;MAIH,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;OAC0B,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;OAA4B,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;;AAAO,UAfjE,iBAAA,CAoRT;EAAA,MAAA,EAnRS,MAmRT;kBAvCe,CAAA,EAAA,MAAA,GAAA,YAAA,GAAA,eAAA,GAAA,cAAA;cAiCE,CAAA,IAAA,EA3QG,OA2QH,CAAA,EAAA,IAAA;EAAiB,qBAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,CAAA,GAAA,IAAA,EAAA,OAAA,EAAA,EAAA,GA1QoC,OA0QpC,CAAA,OAAA,CAAA,CAAA,EAAA,IAAA;4DAzQyB;;;;UAKlD,OAAA;;;;cAII;wCAC0B,4BAA4B;;;;;;;;cAwN9D;;;;;gBAMU;kBAiCE"}
1
+ {"version":3,"file":"plugin.d.cts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;;UAqBU,MAAA,CAeA;MAEW,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;MACkD,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;OAGtD,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;OAAgC,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;;UAdvC,oBAAA,CAeuC;QAEW,CAAA,EAhBjD,MAgBiD,CAAA,MAAA,EAAA,OAAA,CAAA;EAAO,YAAA,CAAA,EAAA,MAAA;EAKzD,QAAA,CAAA,EAAO,MAAA;EAAA,MAAA,CAAA,EAlBN,MAkBM;;UAfP,iBAAA,CAoB8B;QAA4B,EAnB1D,MAmB0D;EAAO,gBAAA,CAAA,EAAA,MAAA,GAAA,YAAA,GAAA,eAAA,GAAA,cAAA;EAwNrE,YA+DL,CAAA,IAAA,EAxSoB,OAwSpB,CAAA,EAAA,IAAA;EAAA,qBAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,CAAA,GAAA,IAAA,EAAA,OAAA,EAAA,EAAA,GAvSsE,OAuStE,CAAA,OAAA,CAAA,CAAA,EAAA,IAAA;iBAzDe,EAAA,OAAA,EAAA;IAmDE,EAAA,EAAA,MAAA;IAAiB,KAAA,EAAA,CAAA,GAAA,EA9RlB,oBA8RkB,EAAA,GAAA,IAAA,GA9Rc,OA8Rd,CAAA,IAAA,CAAA;iBA7RlB,gCAAgC;;4DAEW;;;;UAKlD,OAAA;;;;cAII;wCAC0B,4BAA4B;;;;;;;;cAwN9D;;;;;gBAMU;kBAmDE"}
package/dist/plugin.d.ts CHANGED
@@ -8,11 +8,22 @@ interface Logger {
8
8
  error(msg: string, ...args: unknown[]): void;
9
9
  debug(msg: string, ...args: unknown[]): void;
10
10
  }
11
+ interface PluginServiceContext {
12
+ config?: Record<string, unknown>;
13
+ workspaceDir?: string;
14
+ stateDir?: string;
15
+ logger?: Logger;
16
+ }
11
17
  interface OpenClawPluginApi {
12
18
  logger: Logger;
13
19
  registrationMode?: "full" | "setup-only" | "setup-runtime" | "cli-metadata";
14
20
  registerTool(tool: ToolDef): void;
15
21
  registerGatewayMethod(name: string, handler: (...args: unknown[]) => Promise<unknown>): void;
22
+ registerService?(service: {
23
+ id: string;
24
+ start: (ctx: PluginServiceContext) => void | Promise<void>;
25
+ stop?: (ctx: PluginServiceContext) => void | Promise<void>;
26
+ }): void;
16
27
  on(event: string, handler: (...args: unknown[]) => void | Promise<void>, options?: {
17
28
  priority?: number;
18
29
  }): void;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;;AAiCmE,UAZzD,MAAA,CAiBO;EAAA,IAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;MAIH,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;OAC0B,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;OAA4B,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;;AAAO,UAfjE,iBAAA,CAoRT;EAAA,MAAA,EAnRS,MAmRT;kBAvCe,CAAA,EAAA,MAAA,GAAA,YAAA,GAAA,eAAA,GAAA,cAAA;cAiCE,CAAA,IAAA,EA3QG,OA2QH,CAAA,EAAA,IAAA;EAAiB,qBAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,CAAA,GAAA,IAAA,EAAA,OAAA,EAAA,EAAA,GA1QoC,OA0QpC,CAAA,OAAA,CAAA,CAAA,EAAA,IAAA;4DAzQyB;;;;UAKlD,OAAA;;;;cAII;wCAC0B,4BAA4B;;;;;;;;cAwN9D;;;;;gBAMU;kBAiCE"}
1
+ {"version":3,"file":"plugin.d.ts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;;UAqBU,MAAA,CAeA;MAEW,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;MACkD,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;OAGtD,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;OAAgC,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;;UAdvC,oBAAA,CAeuC;QAEW,CAAA,EAhBjD,MAgBiD,CAAA,MAAA,EAAA,OAAA,CAAA;EAAO,YAAA,CAAA,EAAA,MAAA;EAKzD,QAAA,CAAA,EAAO,MAAA;EAAA,MAAA,CAAA,EAlBN,MAkBM;;UAfP,iBAAA,CAoB8B;QAA4B,EAnB1D,MAmB0D;EAAO,gBAAA,CAAA,EAAA,MAAA,GAAA,YAAA,GAAA,eAAA,GAAA,cAAA;EAwNrE,YA+DL,CAAA,IAAA,EAxSoB,OAwSpB,CAAA,EAAA,IAAA;EAAA,qBAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,CAAA,GAAA,IAAA,EAAA,OAAA,EAAA,EAAA,GAvSsE,OAuStE,CAAA,OAAA,CAAA,CAAA,EAAA,IAAA;iBAzDe,EAAA,OAAA,EAAA;IAmDE,EAAA,EAAA,MAAA;IAAiB,KAAA,EAAA,CAAA,GAAA,EA9RlB,oBA8RkB,EAAA,GAAA,IAAA,GA9Rc,OA8Rd,CAAA,IAAA,CAAA;iBA7RlB,gCAAgC;;4DAEW;;;;UAKlD,OAAA;;;;cAII;wCAC0B,4BAA4B;;;;;;;;cAwN9D;;;;;gBAMU;kBAmDE"}
package/dist/plugin.js CHANGED
@@ -103,7 +103,7 @@ function runGwsCommand(args, configDir) {
103
103
  resolve({
104
104
  stdout,
105
105
  stderr,
106
- exitCode: error?.code ?? (error ? 1 : 0)
106
+ exitCode: typeof error?.code === "number" ? error.code : error ? 1 : 0
107
107
  });
108
108
  });
109
109
  });
@@ -184,7 +184,11 @@ const plugin = {
184
184
  const log = api.logger;
185
185
  for (const tool of googleTools) api.registerTool(tool);
186
186
  log.info(`Registered ${googleTools.length.toString()} Google tools: ${googleTools.map((t) => t.name).join(", ")}`);
187
- if (!globalThis.__googlePluginActivated) {
187
+ const startGoogleService = () => {
188
+ if (globalThis.__googlePluginActivated === true) {
189
+ log.debug("Google plugin already activated — skipping duplicate");
190
+ return;
191
+ }
188
192
  globalThis.__googlePluginActivated = true;
189
193
  log.info("Alfe Google Workspace plugin activating...");
190
194
  try {
@@ -203,7 +207,22 @@ const plugin = {
203
207
  log.warn("Google tools will fail — no API config available");
204
208
  }
205
209
  log.info("Alfe Google Workspace plugin activated");
206
- }
210
+ };
211
+ const stopGoogleService = () => {
212
+ globalThis.__googlePluginActivated = false;
213
+ client = null;
214
+ cachedAccounts = [];
215
+ log.info("Alfe Google Workspace plugin stopped");
216
+ };
217
+ if (api.registerService) api.registerService({
218
+ id: "alfe-google-workspace",
219
+ start: () => {
220
+ startGoogleService();
221
+ },
222
+ stop: () => {
223
+ stopGoogleService();
224
+ }
225
+ });
207
226
  },
208
227
  deactivate(api) {
209
228
  globalThis.__googlePluginActivated = false;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["/**\n * @alfe/openclaw-google — OpenClaw native plugin\n *\n * Registers Google Workspace account management tools with OpenClaw.\n * Provides multi-account awareness so the agent can:\n * - List connected Google accounts\n * - Run gws CLI commands targeting a specific account\n * - Set the default account\n * - Disconnect an account\n */\n\nimport { Type, type TSchema } from \"@sinclair/typebox\";\nimport { resolveConfig } from \"@alfe.ai/config\";\nimport { AgentApiClient } from \"@alfe.ai/agent-api-client\";\nimport { execFile } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { createRequire } from 'node:module';\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json') as { version: string };\n\ninterface Logger {\n info(msg: string, ...args: unknown[]): void;\n warn(msg: string, ...args: unknown[]): void;\n error(msg: string, ...args: unknown[]): void;\n debug(msg: string, ...args: unknown[]): void;\n}\n\ninterface OpenClawPluginApi {\n logger: Logger;\n registrationMode?: \"full\" | \"setup-only\" | \"setup-runtime\" | \"cli-metadata\";\n registerTool(tool: ToolDef): void;\n registerGatewayMethod(name: string, handler: (...args: unknown[]) => Promise<unknown>): void;\n on(event: string, handler: (...args: unknown[]) => void | Promise<void>, options?: { priority?: number }): void;\n}\n\n// ── Tool types ───────────────────────────────────────────────\n\ninterface ToolDef {\n name: string;\n description: string;\n label: string;\n parameters: TSchema;\n execute: (toolCallId: string, params: Record<string, unknown>) => Promise<{\n content: { type: \"text\"; text: string }[];\n details: unknown;\n }>;\n}\n\nfunction ok(data: unknown) {\n return { content: [{ type: \"text\" as const, text: JSON.stringify(data) }], details: data };\n}\n\nfunction errResult(message: string) {\n return { content: [{ type: \"text\" as const, text: JSON.stringify({ error: message }) }], details: { error: message } };\n}\n\nfunction defineTool(def: {\n name: string;\n description: string;\n parameters: TSchema;\n handler: (params: Record<string, unknown>) => Promise<unknown>;\n}): ToolDef {\n return {\n name: def.name,\n description: def.description,\n label: def.name,\n parameters: def.parameters,\n execute: async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n const result = await def.handler(params);\n return ok(result);\n } catch (e: unknown) {\n return errResult(e instanceof Error ? e.message : \"Unknown error\");\n }\n },\n };\n}\n\n// ── Account config dir resolution ───────────────────────────\n\ninterface GoogleAccountInfo {\n email: string;\n isDefault: boolean;\n displayName?: string;\n configDir: string;\n}\n\nfunction sanitizeEmail(email: string): string {\n return email.replace(/@/g, \"-\").replace(/\\./g, \"-\");\n}\n\nfunction resolveConfigDir(email: string, isDefault: boolean): string {\n const dirName = isDefault ? \"gws\" : `gws-${sanitizeEmail(email)}`;\n return join(homedir(), \".config\", dirName);\n}\n\n// ── State ───────────────────────────────────────────────────\n\nlet client: AgentApiClient | null = null;\nlet cachedAccounts: GoogleAccountInfo[] = [];\n\nfunction getClient(): AgentApiClient {\n if (!client) throw new Error(\"Google plugin not initialized — no API client\");\n return client;\n}\n\nasync function refreshAccountCache(): Promise<GoogleAccountInfo[]> {\n const creds = await getClient().getGoogleCredentials();\n const accounts = creds.accounts ?? [{\n email: creds.email,\n isDefault: true,\n displayName: undefined,\n }];\n\n cachedAccounts = accounts.map((a, i) => ({\n email: a.email,\n isDefault: i === 0 ? true : a.isDefault,\n displayName: a.displayName,\n configDir: resolveConfigDir(a.email, i === 0 ? true : a.isDefault),\n }));\n\n return cachedAccounts;\n}\n\nfunction findAccount(email?: string): GoogleAccountInfo {\n if (!email) {\n const def = cachedAccounts.find((a) => a.isDefault);\n if (!def) {\n if (cachedAccounts.length === 0) throw new Error(\"No Google accounts connected\");\n return cachedAccounts[0];\n }\n return def;\n }\n\n const account = cachedAccounts.find((a) => a.email === email);\n if (!account) {\n throw new Error(\n `Google account \"${email}\" not found. Available: ${cachedAccounts.map((a) => a.email).join(\", \")}`,\n );\n }\n return account;\n}\n\n// ── gws command execution ───────────────────────────────────\n\nfunction runGwsCommand(args: string[], configDir: string): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n return new Promise((resolve) => {\n const env = { ...process.env, GOOGLE_WORKSPACE_CLI_CONFIG_DIR: configDir };\n execFile(\"gws\", args, { env, timeout: 60_000, maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {\n resolve({\n stdout,\n stderr,\n exitCode: error?.code ?? (error ? 1 : 0),\n });\n });\n });\n}\n\n// ── Tool definitions ─────────────────────────────────────────\n\nconst googleTools: ToolDef[] = [\n defineTool({\n name: \"google_list_accounts\",\n description:\n \"List all connected Google Workspace accounts. Shows email, display name, \" +\n \"whether it's the default account, and the gws CLI config directory path. \" +\n \"Use this to resolve which account to target (e.g., 'Kevin\\\\'s emails' → kevin@alfe.ai).\",\n parameters: Type.Object({}),\n handler: async () => {\n const accounts = await refreshAccountCache();\n return {\n accounts: accounts.map((a) => ({\n email: a.email,\n displayName: a.displayName,\n isDefault: a.isDefault,\n configDir: a.configDir,\n })),\n count: accounts.length,\n };\n },\n }),\n\n defineTool({\n name: \"google_run_command\",\n description:\n \"Run a gws (Google Workspace CLI) command targeting a specific account. \" +\n \"Automatically sets GOOGLE_WORKSPACE_CLI_CONFIG_DIR for the target account. \" +\n \"If no email is specified, uses the default account. \" +\n \"Example: google_run_command({ command: 'gmail list', email: 'kevin@alfe.ai' })\",\n parameters: Type.Object({\n command: Type.String({\n description: \"The gws CLI command and arguments (e.g., 'gmail list', 'calendar agenda', 'drive list')\",\n }),\n email: Type.Optional(\n Type.String({\n description: \"Email of the Google account to use. Omit to use the default account.\",\n }),\n ),\n }),\n handler: async (params) => {\n const { command, email } = params as { command: string; email?: string };\n const account = findAccount(email);\n\n const args = command.split(/\\s+/).filter(Boolean);\n if (args.length === 0) throw new Error(\"Command cannot be empty\");\n\n const result = await runGwsCommand(args, account.configDir);\n\n return {\n account: account.email,\n command: `gws ${command}`,\n ...result,\n };\n },\n }),\n\n defineTool({\n name: \"google_set_default_account\",\n description:\n \"Set a specific Google account as the default. The default account is \" +\n \"used when no email is specified in google_run_command.\",\n parameters: Type.Object({\n email: Type.String({ description: \"Email of the Google account to set as default\" }),\n }),\n handler: async (params) => {\n const { email } = params as { email: string };\n const result = await getClient().setDefaultGoogleAccount(email);\n await refreshAccountCache();\n return {\n message: `${email} is now the default Google account`,\n accounts: result.accounts,\n };\n },\n }),\n\n defineTool({\n name: \"google_disconnect_account\",\n description:\n \"Disconnect a specific Google account from this agent. \" +\n \"Revokes the OAuth token and removes the account. \" +\n \"If this was the default account, the next account is promoted.\",\n parameters: Type.Object({\n email: Type.String({ description: \"Email of the Google account to disconnect\" }),\n }),\n handler: async (params) => {\n const { email } = params as { email: string };\n const result = await getClient().disconnectGoogleAccount(email);\n await refreshAccountCache();\n return {\n message: `${email} has been disconnected`,\n remainingAccounts: result.accounts,\n };\n },\n }),\n];\n\n// ── Plugin definition ────────────────────────────────────────\n\nconst plugin = {\n id: \"@alfe.ai/openclaw-google\",\n name: \"Alfe Google Workspace Plugin\",\n description: \"Multi-account Google Workspace management — list accounts, run gws commands, manage defaults\",\n version: pkg.version,\n\n activate(api: OpenClawPluginApi) {\n const log = api.logger;\n\n\n for (const tool of googleTools) {\n api.registerTool(tool);\n }\n log.info(`Registered ${googleTools.length.toString()} Google tools: ${googleTools.map((t) => t.name).join(\", \")}`);\n\n if (!(globalThis as Record<string, unknown>).__googlePluginActivated) {\n (globalThis as Record<string, unknown>).__googlePluginActivated = true;\n log.info(\"Alfe Google Workspace plugin activating...\");\n\n try {\n const config = resolveConfig();\n client = new AgentApiClient({ apiKey: config.apiKey, apiUrl: config.apiUrl });\n\n refreshAccountCache()\n .then((accounts) => {\n log.info(`Cached ${accounts.length.toString()} Google account(s): ${accounts.map((a) => a.email).join(\", \")}`);\n })\n .catch((err: unknown) => {\n log.warn(`Failed to pre-cache Google accounts: ${err instanceof Error ? err.message : \"unknown\"}`);\n });\n } catch (err: unknown) {\n log.error(`Failed to resolve config: ${err instanceof Error ? err.message : \"unknown\"}`);\n log.warn(\"Google tools will fail — no API config available\");\n }\n\n log.info(\"Alfe Google Workspace plugin activated\");\n }\n },\n\n deactivate(api: OpenClawPluginApi) {\n (globalThis as Record<string, unknown>).__googlePluginActivated = false;\n client = null;\n cachedAccounts = [];\n api.logger.info(\"Alfe Google Workspace plugin deactivated\");\n },\n};\n\nexport default plugin;\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["/**\n * @alfe/openclaw-google — OpenClaw native plugin\n *\n * Registers Google Workspace account management tools with OpenClaw.\n * Provides multi-account awareness so the agent can:\n * - List connected Google accounts\n * - Run gws CLI commands targeting a specific account\n * - Set the default account\n * - Disconnect an account\n */\n\nimport { Type, type TSchema } from \"@sinclair/typebox\";\nimport { resolveConfig } from \"@alfe.ai/config\";\nimport { AgentApiClient } from \"@alfe.ai/agent-api-client\";\nimport { execFile } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { createRequire } from 'node:module';\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json') as { version: string };\n\ninterface Logger {\n info(msg: string, ...args: unknown[]): void;\n warn(msg: string, ...args: unknown[]): void;\n error(msg: string, ...args: unknown[]): void;\n debug(msg: string, ...args: unknown[]): void;\n}\n\ninterface PluginServiceContext {\n config?: Record<string, unknown>;\n workspaceDir?: string;\n stateDir?: string;\n logger?: Logger;\n}\n\ninterface OpenClawPluginApi {\n logger: Logger;\n registrationMode?: \"full\" | \"setup-only\" | \"setup-runtime\" | \"cli-metadata\";\n registerTool(tool: ToolDef): void;\n registerGatewayMethod(name: string, handler: (...args: unknown[]) => Promise<unknown>): void;\n registerService?(service: {\n id: string;\n start: (ctx: PluginServiceContext) => void | Promise<void>;\n stop?: (ctx: PluginServiceContext) => void | Promise<void>;\n }): void;\n on(event: string, handler: (...args: unknown[]) => void | Promise<void>, options?: { priority?: number }): void;\n}\n\n// ── Tool types ───────────────────────────────────────────────\n\ninterface ToolDef {\n name: string;\n description: string;\n label: string;\n parameters: TSchema;\n execute: (toolCallId: string, params: Record<string, unknown>) => Promise<{\n content: { type: \"text\"; text: string }[];\n details: unknown;\n }>;\n}\n\nfunction ok(data: unknown) {\n return { content: [{ type: \"text\" as const, text: JSON.stringify(data) }], details: data };\n}\n\nfunction errResult(message: string) {\n return { content: [{ type: \"text\" as const, text: JSON.stringify({ error: message }) }], details: { error: message } };\n}\n\nfunction defineTool(def: {\n name: string;\n description: string;\n parameters: TSchema;\n handler: (params: Record<string, unknown>) => Promise<unknown>;\n}): ToolDef {\n return {\n name: def.name,\n description: def.description,\n label: def.name,\n parameters: def.parameters,\n execute: async (_toolCallId: string, params: Record<string, unknown>) => {\n try {\n const result = await def.handler(params);\n return ok(result);\n } catch (e: unknown) {\n return errResult(e instanceof Error ? e.message : \"Unknown error\");\n }\n },\n };\n}\n\n// ── Account config dir resolution ───────────────────────────\n\ninterface GoogleAccountInfo {\n email: string;\n isDefault: boolean;\n displayName?: string;\n configDir: string;\n}\n\nfunction sanitizeEmail(email: string): string {\n return email.replace(/@/g, \"-\").replace(/\\./g, \"-\");\n}\n\nfunction resolveConfigDir(email: string, isDefault: boolean): string {\n const dirName = isDefault ? \"gws\" : `gws-${sanitizeEmail(email)}`;\n return join(homedir(), \".config\", dirName);\n}\n\n// ── State ───────────────────────────────────────────────────\n\nlet client: AgentApiClient | null = null;\nlet cachedAccounts: GoogleAccountInfo[] = [];\n\nfunction getClient(): AgentApiClient {\n if (!client) throw new Error(\"Google plugin not initialized — no API client\");\n return client;\n}\n\nasync function refreshAccountCache(): Promise<GoogleAccountInfo[]> {\n const creds = await getClient().getGoogleCredentials();\n const accounts = creds.accounts ?? [{\n email: creds.email,\n isDefault: true,\n displayName: undefined,\n }];\n\n cachedAccounts = accounts.map((a, i) => ({\n email: a.email,\n isDefault: i === 0 ? true : a.isDefault,\n displayName: a.displayName,\n configDir: resolveConfigDir(a.email, i === 0 ? true : a.isDefault),\n }));\n\n return cachedAccounts;\n}\n\nfunction findAccount(email?: string): GoogleAccountInfo {\n if (!email) {\n const def = cachedAccounts.find((a) => a.isDefault);\n if (!def) {\n if (cachedAccounts.length === 0) throw new Error(\"No Google accounts connected\");\n return cachedAccounts[0];\n }\n return def;\n }\n\n const account = cachedAccounts.find((a) => a.email === email);\n if (!account) {\n throw new Error(\n `Google account \"${email}\" not found. Available: ${cachedAccounts.map((a) => a.email).join(\", \")}`,\n );\n }\n return account;\n}\n\n// ── gws command execution ───────────────────────────────────\n\nfunction runGwsCommand(args: string[], configDir: string): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n return new Promise((resolve) => {\n const env = { ...process.env, GOOGLE_WORKSPACE_CLI_CONFIG_DIR: configDir };\n execFile(\"gws\", args, { env, timeout: 60_000, maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {\n resolve({\n stdout,\n stderr,\n exitCode: typeof error?.code === 'number' ? error.code : error ? 1 : 0,\n });\n });\n });\n}\n\n// ── Tool definitions ─────────────────────────────────────────\n\nconst googleTools: ToolDef[] = [\n defineTool({\n name: \"google_list_accounts\",\n description:\n \"List all connected Google Workspace accounts. Shows email, display name, \" +\n \"whether it's the default account, and the gws CLI config directory path. \" +\n \"Use this to resolve which account to target (e.g., 'Kevin\\\\'s emails' → kevin@alfe.ai).\",\n parameters: Type.Object({}),\n handler: async () => {\n const accounts = await refreshAccountCache();\n return {\n accounts: accounts.map((a) => ({\n email: a.email,\n displayName: a.displayName,\n isDefault: a.isDefault,\n configDir: a.configDir,\n })),\n count: accounts.length,\n };\n },\n }),\n\n defineTool({\n name: \"google_run_command\",\n description:\n \"Run a gws (Google Workspace CLI) command targeting a specific account. \" +\n \"Automatically sets GOOGLE_WORKSPACE_CLI_CONFIG_DIR for the target account. \" +\n \"If no email is specified, uses the default account. \" +\n \"Example: google_run_command({ command: 'gmail list', email: 'kevin@alfe.ai' })\",\n parameters: Type.Object({\n command: Type.String({\n description: \"The gws CLI command and arguments (e.g., 'gmail list', 'calendar agenda', 'drive list')\",\n }),\n email: Type.Optional(\n Type.String({\n description: \"Email of the Google account to use. Omit to use the default account.\",\n }),\n ),\n }),\n handler: async (params) => {\n const { command, email } = params as { command: string; email?: string };\n const account = findAccount(email);\n\n const args = command.split(/\\s+/).filter(Boolean);\n if (args.length === 0) throw new Error(\"Command cannot be empty\");\n\n const result = await runGwsCommand(args, account.configDir);\n\n return {\n account: account.email,\n command: `gws ${command}`,\n ...result,\n };\n },\n }),\n\n defineTool({\n name: \"google_set_default_account\",\n description:\n \"Set a specific Google account as the default. The default account is \" +\n \"used when no email is specified in google_run_command.\",\n parameters: Type.Object({\n email: Type.String({ description: \"Email of the Google account to set as default\" }),\n }),\n handler: async (params) => {\n const { email } = params as { email: string };\n const result = await getClient().setDefaultGoogleAccount(email);\n await refreshAccountCache();\n return {\n message: `${email} is now the default Google account`,\n accounts: result.accounts,\n };\n },\n }),\n\n defineTool({\n name: \"google_disconnect_account\",\n description:\n \"Disconnect a specific Google account from this agent. \" +\n \"Revokes the OAuth token and removes the account. \" +\n \"If this was the default account, the next account is promoted.\",\n parameters: Type.Object({\n email: Type.String({ description: \"Email of the Google account to disconnect\" }),\n }),\n handler: async (params) => {\n const { email } = params as { email: string };\n const result = await getClient().disconnectGoogleAccount(email);\n await refreshAccountCache();\n return {\n message: `${email} has been disconnected`,\n remainingAccounts: result.accounts,\n };\n },\n }),\n];\n\n// ── Plugin definition ────────────────────────────────────────\n\nconst plugin = {\n id: \"@alfe.ai/openclaw-google\",\n name: \"Alfe Google Workspace Plugin\",\n description: \"Multi-account Google Workspace management — list accounts, run gws commands, manage defaults\",\n version: pkg.version,\n\n activate(api: OpenClawPluginApi) {\n const log = api.logger;\n\n for (const tool of googleTools) {\n api.registerTool(tool);\n }\n log.info(`Registered ${googleTools.length.toString()} Google tools: ${googleTools.map((t) => t.name).join(\", \")}`);\n\n const startGoogleService = () => {\n if ((globalThis as Record<string, unknown>).__googlePluginActivated === true) {\n log.debug(\"Google plugin already activated — skipping duplicate\");\n return;\n }\n (globalThis as Record<string, unknown>).__googlePluginActivated = true;\n log.info(\"Alfe Google Workspace plugin activating...\");\n\n try {\n const config = resolveConfig();\n client = new AgentApiClient({ apiKey: config.apiKey, apiUrl: config.apiUrl });\n\n refreshAccountCache()\n .then((accounts) => {\n log.info(`Cached ${accounts.length.toString()} Google account(s): ${accounts.map((a) => a.email).join(\", \")}`);\n })\n .catch((err: unknown) => {\n log.warn(`Failed to pre-cache Google accounts: ${err instanceof Error ? err.message : \"unknown\"}`);\n });\n } catch (err: unknown) {\n log.error(`Failed to resolve config: ${err instanceof Error ? err.message : \"unknown\"}`);\n log.warn(\"Google tools will fail — no API config available\");\n }\n\n log.info(\"Alfe Google Workspace plugin activated\");\n };\n\n const stopGoogleService = () => {\n (globalThis as Record<string, unknown>).__googlePluginActivated = false;\n client = null;\n cachedAccounts = [];\n log.info(\"Alfe Google Workspace plugin stopped\");\n };\n\n if (api.registerService) {\n api.registerService({\n id: \"alfe-google-workspace\",\n start: () => { startGoogleService(); },\n stop: () => { stopGoogleService(); },\n });\n }\n },\n\n deactivate(api: OpenClawPluginApi) {\n (globalThis as Record<string, unknown>).__googlePluginActivated = false;\n client = null;\n cachedAccounts = [];\n api.logger.info(\"Alfe Google Workspace plugin deactivated\");\n },\n};\n\nexport default plugin;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/openclaw-google",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "OpenClaw Google Workspace plugin — multi-account management and gws CLI integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,7 +28,7 @@
28
28
  ],
29
29
  "dependencies": {
30
30
  "@sinclair/typebox": "^0.34.48",
31
- "@alfe.ai/agent-api-client": "0.1.2",
31
+ "@alfe.ai/agent-api-client": "0.1.3",
32
32
  "@alfe.ai/config": "0.0.8"
33
33
  },
34
34
  "scripts": {