@alfe.ai/openclaw-teams 0.0.37 → 0.0.38
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/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/plugin.cjs +10 -40
- package/dist/plugin.d.cts +42 -16
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.ts +42 -16
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +7 -37
- package/dist/plugin.js.map +1 -1
- package/dist/plugin2.d.cts +2 -0
- package/dist/plugin2.d.ts +2 -0
- package/package.json +4 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import plugin from "./plugin.cjs";
|
|
1
|
+
import { t as plugin } from "./plugin.cjs";
|
|
2
2
|
export { plugin as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import plugin from "./plugin.js";
|
|
1
|
+
import { t as plugin } from "./plugin.js";
|
|
2
2
|
export { plugin as default };
|
package/dist/plugin.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
let _sinclair_typebox = require("@sinclair/typebox");
|
|
2
2
|
let _alfe_ai_config = require("@alfe.ai/config");
|
|
3
3
|
let _alfe_ai_agent_api_client = require("@alfe.ai/agent-api-client");
|
|
4
|
+
let _alfe_ai_openclaw_plugin_kit = require("@alfe.ai/openclaw-plugin-kit");
|
|
4
5
|
//#region src/plugin.ts
|
|
5
6
|
/**
|
|
6
7
|
* @alfe/openclaw-teams — OpenClaw native plugin
|
|
@@ -14,46 +15,14 @@ let _alfe_ai_agent_api_client = require("@alfe.ai/agent-api-client");
|
|
|
14
15
|
* - teams_list_channels — list Teams channels the bot has access to
|
|
15
16
|
*/
|
|
16
17
|
const pkg = (0, require("node:module").createRequire)(require("url").pathToFileURL(__filename).href)("../package.json");
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
content: [{
|
|
20
|
-
type: "text",
|
|
21
|
-
text: JSON.stringify(data)
|
|
22
|
-
}],
|
|
23
|
-
details: data
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
function errResult(message) {
|
|
27
|
-
return {
|
|
28
|
-
content: [{
|
|
29
|
-
type: "text",
|
|
30
|
-
text: JSON.stringify({ error: message })
|
|
31
|
-
}],
|
|
32
|
-
details: { error: message }
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
function defineTool(def) {
|
|
36
|
-
return {
|
|
37
|
-
name: def.name,
|
|
38
|
-
description: def.description,
|
|
39
|
-
label: def.name,
|
|
40
|
-
parameters: def.parameters,
|
|
41
|
-
execute: async (_toolCallId, params) => {
|
|
42
|
-
try {
|
|
43
|
-
return ok(await def.handler(params));
|
|
44
|
-
} catch (e) {
|
|
45
|
-
return errResult(e.message);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
}
|
|
18
|
+
const TEAMS_ACTIVATION_KEY = (0, _alfe_ai_openclaw_plugin_kit.getActivationKey)("teams");
|
|
50
19
|
let client = null;
|
|
51
20
|
function getClient() {
|
|
52
21
|
if (!client) throw new Error("Teams plugin not initialized — no API client");
|
|
53
22
|
return client;
|
|
54
23
|
}
|
|
55
24
|
const teamsTools = [
|
|
56
|
-
defineTool({
|
|
25
|
+
(0, _alfe_ai_openclaw_plugin_kit.defineTool)({
|
|
57
26
|
name: "teams_send_message",
|
|
58
27
|
description: "Send a text message to a Microsoft Teams conversation. You need the conversationId from an inbound Teams message or from teams_list_channels.",
|
|
59
28
|
parameters: _sinclair_typebox.Type.Object({
|
|
@@ -68,7 +37,7 @@ const teamsTools = [
|
|
|
68
37
|
});
|
|
69
38
|
}
|
|
70
39
|
}),
|
|
71
|
-
defineTool({
|
|
40
|
+
(0, _alfe_ai_openclaw_plugin_kit.defineTool)({
|
|
72
41
|
name: "teams_send_card",
|
|
73
42
|
description: "Send an Adaptive Card to a Microsoft Teams conversation. Adaptive Cards support rich formatting, inputs, and actions. Pass a valid Adaptive Card JSON object.",
|
|
74
43
|
parameters: _sinclair_typebox.Type.Object({
|
|
@@ -86,7 +55,7 @@ const teamsTools = [
|
|
|
86
55
|
});
|
|
87
56
|
}
|
|
88
57
|
}),
|
|
89
|
-
defineTool({
|
|
58
|
+
(0, _alfe_ai_openclaw_plugin_kit.defineTool)({
|
|
90
59
|
name: "teams_list_channels",
|
|
91
60
|
description: "List Microsoft Teams channels and conversations that the bot has access to. Returns channel IDs that can be used with teams_send_message and teams_send_card.",
|
|
92
61
|
parameters: _sinclair_typebox.Type.Object({}),
|
|
@@ -105,8 +74,7 @@ const plugin = {
|
|
|
105
74
|
const log = api.logger;
|
|
106
75
|
for (const tool of teamsTools) api.registerTool(tool);
|
|
107
76
|
log.info(`Registered ${String(teamsTools.length)} Teams tools: ${teamsTools.map((t) => t.name).join(", ")}`);
|
|
108
|
-
|
|
109
|
-
globalThis.__teamsPluginActivated = true;
|
|
77
|
+
(0, _alfe_ai_openclaw_plugin_kit.guardedStart)(TEAMS_ACTIVATION_KEY, log, () => {
|
|
110
78
|
log.info("Alfe Teams plugin activating...");
|
|
111
79
|
try {
|
|
112
80
|
const config = (0, _alfe_ai_config.resolveConfig)();
|
|
@@ -117,13 +85,15 @@ const plugin = {
|
|
|
117
85
|
} catch (err) {
|
|
118
86
|
log.error(`Failed to resolve config: ${err instanceof Error ? err.message : String(err)}`);
|
|
119
87
|
log.warn("Teams tools will fail — no API config available");
|
|
88
|
+
(0, _alfe_ai_openclaw_plugin_kit.resetActivation)(TEAMS_ACTIVATION_KEY);
|
|
89
|
+
return;
|
|
120
90
|
}
|
|
121
91
|
log.info("Alfe Teams plugin activated");
|
|
122
|
-
}
|
|
92
|
+
});
|
|
123
93
|
},
|
|
124
94
|
deactivate(api) {
|
|
125
|
-
globalThis.__teamsPluginActivated = false;
|
|
126
95
|
client = null;
|
|
96
|
+
(0, _alfe_ai_openclaw_plugin_kit.resetActivation)(TEAMS_ACTIVATION_KEY);
|
|
127
97
|
api.logger.info("Alfe Teams plugin deactivated");
|
|
128
98
|
}
|
|
129
99
|
};
|
package/dist/plugin.d.cts
CHANGED
|
@@ -1,7 +1,46 @@
|
|
|
1
1
|
import { TSchema } from "@sinclair/typebox";
|
|
2
2
|
|
|
3
|
-
//#region
|
|
3
|
+
//#region ../openclaw-plugin-kit/dist/index.d.ts
|
|
4
4
|
|
|
5
|
+
//# sourceMappingURL=types.d.ts.map
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/tools.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* Tool-definition helpers — the `defineTool` / `ok` / `errResult` trio that
|
|
10
|
+
* was copy-pasted across 8 plugins (identity, google, teams, mobile,
|
|
11
|
+
* whatsapp, voice, chat a2a-tools, base openclaw).
|
|
12
|
+
*
|
|
13
|
+
* Error handling is standardized on the openclaw-google variant — the only
|
|
14
|
+
* copy that survived non-`Error` throws (`e instanceof Error ? e.message :
|
|
15
|
+
* "Unknown error"`). The other copies did `(e as Error).message`, which
|
|
16
|
+
* crashes the tool executor when a handler throws a string/object.
|
|
17
|
+
*/
|
|
18
|
+
/** Shape returned to OpenClaw from a tool `execute`. */
|
|
19
|
+
interface ToolResult {
|
|
20
|
+
content: {
|
|
21
|
+
type: "text";
|
|
22
|
+
text: string;
|
|
23
|
+
}[];
|
|
24
|
+
details: unknown;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* An OpenClaw tool definition.
|
|
28
|
+
*
|
|
29
|
+
* `parameters` is generic because the fleet is split between TypeBox
|
|
30
|
+
* `TSchema` schemas (identity/google/teams/mobile/whatsapp) and plain
|
|
31
|
+
* JSON-Schema objects (chat a2a-tools). Instantiate with whichever schema
|
|
32
|
+
* type the plugin uses — the kit itself has no schema dependency.
|
|
33
|
+
*/
|
|
34
|
+
interface ToolDef<TParameters = unknown> {
|
|
35
|
+
name: string;
|
|
36
|
+
description: string;
|
|
37
|
+
label: string;
|
|
38
|
+
parameters: TParameters;
|
|
39
|
+
execute: (toolCallId: string, params: Record<string, unknown>) => Promise<ToolResult>;
|
|
40
|
+
}
|
|
41
|
+
/** Wrap a successful handler result in the OpenClaw tool-result envelope. */
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/plugin.d.ts
|
|
5
44
|
interface Logger {
|
|
6
45
|
info(msg: string, ...args: unknown[]): void;
|
|
7
46
|
warn(msg: string, ...args: unknown[]): void;
|
|
@@ -11,25 +50,12 @@ interface Logger {
|
|
|
11
50
|
interface OpenClawPluginApi {
|
|
12
51
|
logger: Logger;
|
|
13
52
|
registrationMode?: "full" | "setup-only" | "setup-runtime" | "cli-metadata";
|
|
14
|
-
registerTool(tool: ToolDef): void;
|
|
53
|
+
registerTool(tool: ToolDef<TSchema>): void;
|
|
15
54
|
registerGatewayMethod(name: string, handler: (...args: unknown[]) => Promise<unknown>): void;
|
|
16
55
|
on(event: string, handler: (...args: unknown[]) => void | Promise<void>, options?: {
|
|
17
56
|
priority?: number;
|
|
18
57
|
}): void;
|
|
19
58
|
}
|
|
20
|
-
interface ToolDef {
|
|
21
|
-
name: string;
|
|
22
|
-
description: string;
|
|
23
|
-
label: string;
|
|
24
|
-
parameters: TSchema;
|
|
25
|
-
execute: (toolCallId: string, params: Record<string, unknown>) => Promise<{
|
|
26
|
-
content: {
|
|
27
|
-
type: "text";
|
|
28
|
-
text: string;
|
|
29
|
-
}[];
|
|
30
|
-
details: unknown;
|
|
31
|
-
}>;
|
|
32
|
-
}
|
|
33
59
|
declare const plugin: {
|
|
34
60
|
id: string;
|
|
35
61
|
name: string;
|
|
@@ -39,5 +65,5 @@ declare const plugin: {
|
|
|
39
65
|
deactivate(api: OpenClawPluginApi): void;
|
|
40
66
|
};
|
|
41
67
|
//#endregion
|
|
42
|
-
export { plugin as
|
|
68
|
+
export { plugin as t };
|
|
43
69
|
//# sourceMappingURL=plugin.d.cts.map
|
package/dist/plugin.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.cts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"plugin.d.cts","names":["KitLogger","ToolResult","ToolDef","TParameters","Record","Promise","ok","errResult","defineTool","IpcResponse","IpcClient","ConnectToDaemonOptions","connectToDaemon","ResolveOpenClawSdkOptions","resolveOpenClawSdk","T","getActivationKey","isActivated","resetActivation","guardedStart","ScheduleRefreshOptions","RefreshHandle","scheduleRefresh"],"sources":["../../openclaw-plugin-kit/dist/index.d.ts","../src/plugin.ts"],"sourcesContent":["//#region src/types.d.ts\n/**\n * Minimal logger contract shared by every helper in the kit.\n *\n * Deliberately the *narrowest* shape in the fleet: some plugins declare\n * variadic loggers (`info(msg: string, ...args: unknown[])`), others\n * single-arg (`info(msg: string)`). Both are assignable to this. The kit\n * only ever calls with a single string.\n */\ninterface KitLogger {\n info(msg: string): void;\n warn(msg: string): void;\n error(msg: string): void;\n debug(msg: string): void;\n}\n//# sourceMappingURL=types.d.ts.map\n//#endregion\n//#region src/tools.d.ts\n/**\n * Tool-definition helpers — the `defineTool` / `ok` / `errResult` trio that\n * was copy-pasted across 8 plugins (identity, google, teams, mobile,\n * whatsapp, voice, chat a2a-tools, base openclaw).\n *\n * Error handling is standardized on the openclaw-google variant — the only\n * copy that survived non-`Error` throws (`e instanceof Error ? e.message :\n * \"Unknown error\"`). The other copies did `(e as Error).message`, which\n * crashes the tool executor when a handler throws a string/object.\n */\n/** Shape returned to OpenClaw from a tool `execute`. */\ninterface ToolResult {\n content: {\n type: \"text\";\n text: string;\n }[];\n details: unknown;\n}\n/**\n * An OpenClaw tool definition.\n *\n * `parameters` is generic because the fleet is split between TypeBox\n * `TSchema` schemas (identity/google/teams/mobile/whatsapp) and plain\n * JSON-Schema objects (chat a2a-tools). Instantiate with whichever schema\n * type the plugin uses — the kit itself has no schema dependency.\n */\ninterface ToolDef<TParameters = unknown> {\n name: string;\n description: string;\n label: string;\n parameters: TParameters;\n execute: (toolCallId: string, params: Record<string, unknown>) => Promise<ToolResult>;\n}\n/** Wrap a successful handler result in the OpenClaw tool-result envelope. */\ndeclare function ok(data: unknown): ToolResult;\n/** Wrap an error message in the OpenClaw tool-result envelope. */\ndeclare function errResult(message: string): ToolResult;\n/**\n * Define an OpenClaw tool from a plain async handler. Handler throws (of\n * any type — `Error` or not) are converted to `errResult` envelopes so the\n * LLM sees a structured error instead of the tool executor crashing.\n */\ndeclare function defineTool<TParameters>(def: {\n name: string;\n description: string;\n parameters: TParameters;\n handler: (params: Record<string, unknown>) => Promise<unknown>;\n}): ToolDef<TParameters>;\n//# sourceMappingURL=tools.d.ts.map\n//#endregion\n//#region src/daemon.d.ts\n/** Response envelope for daemon IPC requests. */\ninterface IpcResponse {\n ok: boolean;\n error?: {\n message?: string;\n };\n [key: string]: unknown;\n}\n/** The subset of `@alfe.ai/openclaw`'s IPCClient the kit relies on. */\ninterface IpcClient {\n on(event: string, handler: (...args: unknown[]) => void): void;\n request(method: string, params: Record<string, unknown>): Promise<IpcResponse>;\n start(): void;\n stop(): void;\n}\ninterface ConnectToDaemonOptions {\n /** Plugin package name sent with `capability.register` (e.g. `@alfe.ai/openclaw-sync`). */\n pluginId: string;\n /** Capabilities to register on every (re)connect. Constants stay per-plugin. */\n capabilities?: readonly string[];\n /**\n * Optional handler for daemon → plugin messages. Only invoked with\n * object payloads — the kit does the message-shape checking.\n */\n onMessage?: (msg: Record<string, unknown>) => void;\n /** Log line when the daemon isn't available (plugin runs standalone). */\n standaloneNote?: string;\n}\n/**\n * Attempt to connect to the Alfe daemon IPC socket. Returns `null` (after\n * an info log) when `@alfe.ai/openclaw` isn't installed — plugins degrade\n * gracefully to standalone mode.\n */\ndeclare function connectToDaemon(socketPath: string, log: KitLogger, options: ConnectToDaemonOptions): Promise<IpcClient | null>;\n//# sourceMappingURL=daemon.d.ts.map\n//#endregion\n//#region src/sdk.d.ts\ninterface ResolveOpenClawSdkOptions {\n /** Module specifier resolved from OpenClaw's context. */\n specifier?: string;\n /** Named export to extract from the resolved module. */\n exportName?: string;\n /** Warn line emitted when the SDK can't be resolved. */\n unresolvableNote?: string;\n}\n/**\n * Resolve a named export from the running OpenClaw process's SDK.\n *\n * Defaults target `dispatchInboundDirectDmWithRuntime` from\n * `openclaw/plugin-sdk/channel-inbound` — the export both existing\n * consumers (chat, google-chat) need. Returns `null` (after a warn log)\n * when unresolvable; callers degrade gracefully.\n */\ndeclare function resolveOpenClawSdk<T = unknown>(log: KitLogger, options?: ResolveOpenClawSdkOptions): T | null;\n//# sourceMappingURL=sdk.d.ts.map\n\n//#endregion\n//#region src/activation.d.ts\n/**\n * Canonical activation-flag key for a plugin: `__alfe<Name>PluginActivated`.\n *\n * Accepts a short name (`\"google\"`, `\"google-chat\"`) or a full package name\n * (`\"@alfe.ai/openclaw-teams\"`); scope + `openclaw-` prefix are stripped\n * and the remainder PascalCased:\n *\n * getActivationKey(\"google\") → \"__alfeGooglePluginActivated\"\n * getActivationKey(\"google-chat\") → \"__alfeGoogleChatPluginActivated\"\n * getActivationKey(\"@alfe.ai/openclaw-teams\") → \"__alfeTeamsPluginActivated\"\n */\ndeclare function getActivationKey(name: string): string;\n/** True when the activation flag for `key` is currently set. */\ndeclare function isActivated(key: string): boolean;\n/**\n * Clear the activation flag so a later start can run again.\n *\n * Call this LAST in stop/deactivate paths — after side effects are stopped\n * (see the ordering rule in the module doc). Also exported for soft-failure\n * paths inside a `guardedStart` fn that want to log at a custom level and\n * return normally instead of throwing.\n */\ndeclare function resetActivation(key: string): void;\n/**\n * Run a service start exactly once per activation cycle.\n *\n * - If the flag is already set, logs at debug and returns `false` (skipped).\n * - Otherwise sets the flag and runs `fn`.\n * - If `fn` throws synchronously OR returns a promise that rejects, the\n * flag is RESET (so a later activate can retry) and the error is logged.\n * Errors are not rethrown — matching fleet behavior where a failed start\n * must never crash the host's plugin loader.\n *\n * Returns `true` when the start was initiated (even if an async portion\n * later fails), `false` when skipped or when `fn` threw synchronously.\n *\n * Note: cleaning up partial side effects on failure is `fn`'s job (throw\n * only after tearing down what was started); the kit only guarantees the\n * flag reset happens after `fn` has failed — i.e. after `fn`'s own cleanup.\n */\ndeclare function guardedStart(key: string, log: KitLogger, fn: () => void | Promise<void>): boolean;\n//# sourceMappingURL=activation.d.ts.map\n//#endregion\n//#region src/refresh.d.ts\ninterface ScheduleRefreshOptions {\n /** Cadence between successful refreshes (per-provider token lifetime — stays in the consuming package). */\n intervalMs: number;\n /** Delay before retrying after a failed refresh. */\n retryMs: number;\n /** Run one refresh immediately instead of waiting a full interval first. Default false. */\n immediate?: boolean;\n}\ninterface RefreshHandle {\n /** Cancel the schedule. Safe to call multiple times. */\n stop(): void;\n}\n/**\n * Run `refreshFn` every `intervalMs`; on failure, log a warning and retry\n * after `retryMs`. Timers are unref'd so the schedule never keeps the\n * process alive.\n */\ndeclare function scheduleRefresh(refreshFn: () => Promise<void>, options: ScheduleRefreshOptions, log: KitLogger): RefreshHandle;\n//# sourceMappingURL=refresh.d.ts.map\n\n//#endregion\nexport { type ConnectToDaemonOptions, type IpcClient, type IpcResponse, type KitLogger, type RefreshHandle, type ResolveOpenClawSdkOptions, type ScheduleRefreshOptions, type ToolDef, type ToolResult, connectToDaemon, defineTool, errResult, getActivationKey, guardedStart, isActivated, ok, resetActivation, resolveOpenClawSdk, scheduleRefresh };\n//# sourceMappingURL=index.d.ts.map"],"mappings":";;;;AC0BgB;;;;;;;;AAYmD;;;;;;UDTzDC,UAAAA;;;;;;;;;;;;;;;UAeAC;;;;cAIIC;wCAC0BC,4BAA4BC,QAAQJ;;;;;UCvBlE,MAAA;EAAA,IAAA,CAAA,GAAA,EAAM,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAON,IAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAiB,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAAA,KAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;OACjB,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;;UADA,iBAAA,CAGW;QACkD,EAH7D,MAG6D;kBACX,CAAA,EAAA,MAAA,GAAA,YAAA,GAAA,eAAA,GAAA,cAAA;EAAO,YAAA,CAAA,IAAA,EAF9C,OAE8C,CAFtC,OAEsC,CAAA,CAAA,EAAA,IAAA;EAsE7D,qBA2CL,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,CAAA,GAAA,IAAA,EAAA,OAAA,EAAA,EAAA,GAlHsE,OAkHtE,CAAA,OAAA,CAAA,CAAA,EAAA,IAAA;EAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,OAAA,EAAA,CAAA,GAAA,IAAA,EAAA,OAAA,EAAA,EAAA,GAAA,IAAA,GAjH2D,OAiH3D,CAAA,IAAA,CAAA,EAAA,QAAA,EAAA;IArCe,QAAA,CAAA,EAAA,MAAA;MA+BE,IAAA;;cArCZ;;;;;gBAMU;kBA+BE"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,7 +1,46 @@
|
|
|
1
1
|
import { TSchema } from "@sinclair/typebox";
|
|
2
2
|
|
|
3
|
-
//#region
|
|
3
|
+
//#region ../openclaw-plugin-kit/dist/index.d.ts
|
|
4
4
|
|
|
5
|
+
//# sourceMappingURL=types.d.ts.map
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/tools.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* Tool-definition helpers — the `defineTool` / `ok` / `errResult` trio that
|
|
10
|
+
* was copy-pasted across 8 plugins (identity, google, teams, mobile,
|
|
11
|
+
* whatsapp, voice, chat a2a-tools, base openclaw).
|
|
12
|
+
*
|
|
13
|
+
* Error handling is standardized on the openclaw-google variant — the only
|
|
14
|
+
* copy that survived non-`Error` throws (`e instanceof Error ? e.message :
|
|
15
|
+
* "Unknown error"`). The other copies did `(e as Error).message`, which
|
|
16
|
+
* crashes the tool executor when a handler throws a string/object.
|
|
17
|
+
*/
|
|
18
|
+
/** Shape returned to OpenClaw from a tool `execute`. */
|
|
19
|
+
interface ToolResult {
|
|
20
|
+
content: {
|
|
21
|
+
type: "text";
|
|
22
|
+
text: string;
|
|
23
|
+
}[];
|
|
24
|
+
details: unknown;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* An OpenClaw tool definition.
|
|
28
|
+
*
|
|
29
|
+
* `parameters` is generic because the fleet is split between TypeBox
|
|
30
|
+
* `TSchema` schemas (identity/google/teams/mobile/whatsapp) and plain
|
|
31
|
+
* JSON-Schema objects (chat a2a-tools). Instantiate with whichever schema
|
|
32
|
+
* type the plugin uses — the kit itself has no schema dependency.
|
|
33
|
+
*/
|
|
34
|
+
interface ToolDef<TParameters = unknown> {
|
|
35
|
+
name: string;
|
|
36
|
+
description: string;
|
|
37
|
+
label: string;
|
|
38
|
+
parameters: TParameters;
|
|
39
|
+
execute: (toolCallId: string, params: Record<string, unknown>) => Promise<ToolResult>;
|
|
40
|
+
}
|
|
41
|
+
/** Wrap a successful handler result in the OpenClaw tool-result envelope. */
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/plugin.d.ts
|
|
5
44
|
interface Logger {
|
|
6
45
|
info(msg: string, ...args: unknown[]): void;
|
|
7
46
|
warn(msg: string, ...args: unknown[]): void;
|
|
@@ -11,25 +50,12 @@ interface Logger {
|
|
|
11
50
|
interface OpenClawPluginApi {
|
|
12
51
|
logger: Logger;
|
|
13
52
|
registrationMode?: "full" | "setup-only" | "setup-runtime" | "cli-metadata";
|
|
14
|
-
registerTool(tool: ToolDef): void;
|
|
53
|
+
registerTool(tool: ToolDef<TSchema>): void;
|
|
15
54
|
registerGatewayMethod(name: string, handler: (...args: unknown[]) => Promise<unknown>): void;
|
|
16
55
|
on(event: string, handler: (...args: unknown[]) => void | Promise<void>, options?: {
|
|
17
56
|
priority?: number;
|
|
18
57
|
}): void;
|
|
19
58
|
}
|
|
20
|
-
interface ToolDef {
|
|
21
|
-
name: string;
|
|
22
|
-
description: string;
|
|
23
|
-
label: string;
|
|
24
|
-
parameters: TSchema;
|
|
25
|
-
execute: (toolCallId: string, params: Record<string, unknown>) => Promise<{
|
|
26
|
-
content: {
|
|
27
|
-
type: "text";
|
|
28
|
-
text: string;
|
|
29
|
-
}[];
|
|
30
|
-
details: unknown;
|
|
31
|
-
}>;
|
|
32
|
-
}
|
|
33
59
|
declare const plugin: {
|
|
34
60
|
id: string;
|
|
35
61
|
name: string;
|
|
@@ -39,5 +65,5 @@ declare const plugin: {
|
|
|
39
65
|
deactivate(api: OpenClawPluginApi): void;
|
|
40
66
|
};
|
|
41
67
|
//#endregion
|
|
42
|
-
export { plugin as
|
|
68
|
+
export { plugin as t };
|
|
43
69
|
//# sourceMappingURL=plugin.d.ts.map
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","names":["KitLogger","ToolResult","ToolDef","TParameters","Record","Promise","ok","errResult","defineTool","IpcResponse","IpcClient","ConnectToDaemonOptions","connectToDaemon","ResolveOpenClawSdkOptions","resolveOpenClawSdk","T","getActivationKey","isActivated","resetActivation","guardedStart","ScheduleRefreshOptions","RefreshHandle","scheduleRefresh"],"sources":["../../openclaw-plugin-kit/dist/index.d.ts","../src/plugin.ts"],"sourcesContent":["//#region src/types.d.ts\n/**\n * Minimal logger contract shared by every helper in the kit.\n *\n * Deliberately the *narrowest* shape in the fleet: some plugins declare\n * variadic loggers (`info(msg: string, ...args: unknown[])`), others\n * single-arg (`info(msg: string)`). Both are assignable to this. The kit\n * only ever calls with a single string.\n */\ninterface KitLogger {\n info(msg: string): void;\n warn(msg: string): void;\n error(msg: string): void;\n debug(msg: string): void;\n}\n//# sourceMappingURL=types.d.ts.map\n//#endregion\n//#region src/tools.d.ts\n/**\n * Tool-definition helpers — the `defineTool` / `ok` / `errResult` trio that\n * was copy-pasted across 8 plugins (identity, google, teams, mobile,\n * whatsapp, voice, chat a2a-tools, base openclaw).\n *\n * Error handling is standardized on the openclaw-google variant — the only\n * copy that survived non-`Error` throws (`e instanceof Error ? e.message :\n * \"Unknown error\"`). The other copies did `(e as Error).message`, which\n * crashes the tool executor when a handler throws a string/object.\n */\n/** Shape returned to OpenClaw from a tool `execute`. */\ninterface ToolResult {\n content: {\n type: \"text\";\n text: string;\n }[];\n details: unknown;\n}\n/**\n * An OpenClaw tool definition.\n *\n * `parameters` is generic because the fleet is split between TypeBox\n * `TSchema` schemas (identity/google/teams/mobile/whatsapp) and plain\n * JSON-Schema objects (chat a2a-tools). Instantiate with whichever schema\n * type the plugin uses — the kit itself has no schema dependency.\n */\ninterface ToolDef<TParameters = unknown> {\n name: string;\n description: string;\n label: string;\n parameters: TParameters;\n execute: (toolCallId: string, params: Record<string, unknown>) => Promise<ToolResult>;\n}\n/** Wrap a successful handler result in the OpenClaw tool-result envelope. */\ndeclare function ok(data: unknown): ToolResult;\n/** Wrap an error message in the OpenClaw tool-result envelope. */\ndeclare function errResult(message: string): ToolResult;\n/**\n * Define an OpenClaw tool from a plain async handler. Handler throws (of\n * any type — `Error` or not) are converted to `errResult` envelopes so the\n * LLM sees a structured error instead of the tool executor crashing.\n */\ndeclare function defineTool<TParameters>(def: {\n name: string;\n description: string;\n parameters: TParameters;\n handler: (params: Record<string, unknown>) => Promise<unknown>;\n}): ToolDef<TParameters>;\n//# sourceMappingURL=tools.d.ts.map\n//#endregion\n//#region src/daemon.d.ts\n/** Response envelope for daemon IPC requests. */\ninterface IpcResponse {\n ok: boolean;\n error?: {\n message?: string;\n };\n [key: string]: unknown;\n}\n/** The subset of `@alfe.ai/openclaw`'s IPCClient the kit relies on. */\ninterface IpcClient {\n on(event: string, handler: (...args: unknown[]) => void): void;\n request(method: string, params: Record<string, unknown>): Promise<IpcResponse>;\n start(): void;\n stop(): void;\n}\ninterface ConnectToDaemonOptions {\n /** Plugin package name sent with `capability.register` (e.g. `@alfe.ai/openclaw-sync`). */\n pluginId: string;\n /** Capabilities to register on every (re)connect. Constants stay per-plugin. */\n capabilities?: readonly string[];\n /**\n * Optional handler for daemon → plugin messages. Only invoked with\n * object payloads — the kit does the message-shape checking.\n */\n onMessage?: (msg: Record<string, unknown>) => void;\n /** Log line when the daemon isn't available (plugin runs standalone). */\n standaloneNote?: string;\n}\n/**\n * Attempt to connect to the Alfe daemon IPC socket. Returns `null` (after\n * an info log) when `@alfe.ai/openclaw` isn't installed — plugins degrade\n * gracefully to standalone mode.\n */\ndeclare function connectToDaemon(socketPath: string, log: KitLogger, options: ConnectToDaemonOptions): Promise<IpcClient | null>;\n//# sourceMappingURL=daemon.d.ts.map\n//#endregion\n//#region src/sdk.d.ts\ninterface ResolveOpenClawSdkOptions {\n /** Module specifier resolved from OpenClaw's context. */\n specifier?: string;\n /** Named export to extract from the resolved module. */\n exportName?: string;\n /** Warn line emitted when the SDK can't be resolved. */\n unresolvableNote?: string;\n}\n/**\n * Resolve a named export from the running OpenClaw process's SDK.\n *\n * Defaults target `dispatchInboundDirectDmWithRuntime` from\n * `openclaw/plugin-sdk/channel-inbound` — the export both existing\n * consumers (chat, google-chat) need. Returns `null` (after a warn log)\n * when unresolvable; callers degrade gracefully.\n */\ndeclare function resolveOpenClawSdk<T = unknown>(log: KitLogger, options?: ResolveOpenClawSdkOptions): T | null;\n//# sourceMappingURL=sdk.d.ts.map\n\n//#endregion\n//#region src/activation.d.ts\n/**\n * Canonical activation-flag key for a plugin: `__alfe<Name>PluginActivated`.\n *\n * Accepts a short name (`\"google\"`, `\"google-chat\"`) or a full package name\n * (`\"@alfe.ai/openclaw-teams\"`); scope + `openclaw-` prefix are stripped\n * and the remainder PascalCased:\n *\n * getActivationKey(\"google\") → \"__alfeGooglePluginActivated\"\n * getActivationKey(\"google-chat\") → \"__alfeGoogleChatPluginActivated\"\n * getActivationKey(\"@alfe.ai/openclaw-teams\") → \"__alfeTeamsPluginActivated\"\n */\ndeclare function getActivationKey(name: string): string;\n/** True when the activation flag for `key` is currently set. */\ndeclare function isActivated(key: string): boolean;\n/**\n * Clear the activation flag so a later start can run again.\n *\n * Call this LAST in stop/deactivate paths — after side effects are stopped\n * (see the ordering rule in the module doc). Also exported for soft-failure\n * paths inside a `guardedStart` fn that want to log at a custom level and\n * return normally instead of throwing.\n */\ndeclare function resetActivation(key: string): void;\n/**\n * Run a service start exactly once per activation cycle.\n *\n * - If the flag is already set, logs at debug and returns `false` (skipped).\n * - Otherwise sets the flag and runs `fn`.\n * - If `fn` throws synchronously OR returns a promise that rejects, the\n * flag is RESET (so a later activate can retry) and the error is logged.\n * Errors are not rethrown — matching fleet behavior where a failed start\n * must never crash the host's plugin loader.\n *\n * Returns `true` when the start was initiated (even if an async portion\n * later fails), `false` when skipped or when `fn` threw synchronously.\n *\n * Note: cleaning up partial side effects on failure is `fn`'s job (throw\n * only after tearing down what was started); the kit only guarantees the\n * flag reset happens after `fn` has failed — i.e. after `fn`'s own cleanup.\n */\ndeclare function guardedStart(key: string, log: KitLogger, fn: () => void | Promise<void>): boolean;\n//# sourceMappingURL=activation.d.ts.map\n//#endregion\n//#region src/refresh.d.ts\ninterface ScheduleRefreshOptions {\n /** Cadence between successful refreshes (per-provider token lifetime — stays in the consuming package). */\n intervalMs: number;\n /** Delay before retrying after a failed refresh. */\n retryMs: number;\n /** Run one refresh immediately instead of waiting a full interval first. Default false. */\n immediate?: boolean;\n}\ninterface RefreshHandle {\n /** Cancel the schedule. Safe to call multiple times. */\n stop(): void;\n}\n/**\n * Run `refreshFn` every `intervalMs`; on failure, log a warning and retry\n * after `retryMs`. Timers are unref'd so the schedule never keeps the\n * process alive.\n */\ndeclare function scheduleRefresh(refreshFn: () => Promise<void>, options: ScheduleRefreshOptions, log: KitLogger): RefreshHandle;\n//# sourceMappingURL=refresh.d.ts.map\n\n//#endregion\nexport { type ConnectToDaemonOptions, type IpcClient, type IpcResponse, type KitLogger, type RefreshHandle, type ResolveOpenClawSdkOptions, type ScheduleRefreshOptions, type ToolDef, type ToolResult, connectToDaemon, defineTool, errResult, getActivationKey, guardedStart, isActivated, ok, resetActivation, resolveOpenClawSdk, scheduleRefresh };\n//# sourceMappingURL=index.d.ts.map"],"mappings":";;;;AC0BgB;;;;;;;;AAYmD;;;;;;UDTzDC,UAAAA;;;;;;;;;;;;;;;UAeAC;;;;cAIIC;wCAC0BC,4BAA4BC,QAAQJ;;;;;UCvBlE,MAAA;EAAA,IAAA,CAAA,GAAA,EAAM,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAON,IAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAiB,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAAA,KAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;OACjB,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;;UADA,iBAAA,CAGW;QACkD,EAH7D,MAG6D;kBACX,CAAA,EAAA,MAAA,GAAA,YAAA,GAAA,eAAA,GAAA,cAAA;EAAO,YAAA,CAAA,IAAA,EAF9C,OAE8C,CAFtC,OAEsC,CAAA,CAAA,EAAA,IAAA;EAsE7D,qBA2CL,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,CAAA,GAAA,IAAA,EAAA,OAAA,EAAA,EAAA,GAlHsE,OAkHtE,CAAA,OAAA,CAAA,CAAA,EAAA,IAAA;EAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,OAAA,EAAA,CAAA,GAAA,IAAA,EAAA,OAAA,EAAA,EAAA,GAAA,IAAA,GAjH2D,OAiH3D,CAAA,IAAA,CAAA,EAAA,QAAA,EAAA;IArCe,QAAA,CAAA,EAAA,MAAA;MA+BE,IAAA;;cArCZ;;;;;gBAMU;kBA+BE"}
|
package/dist/plugin.js
CHANGED
|
@@ -2,6 +2,7 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import { Type } from "@sinclair/typebox";
|
|
3
3
|
import { resolveConfig } from "@alfe.ai/config";
|
|
4
4
|
import { AgentApiClient, installToolErrorCapture } from "@alfe.ai/agent-api-client";
|
|
5
|
+
import { defineTool, getActivationKey, guardedStart, resetActivation } from "@alfe.ai/openclaw-plugin-kit";
|
|
5
6
|
//#region src/plugin.ts
|
|
6
7
|
/**
|
|
7
8
|
* @alfe/openclaw-teams — OpenClaw native plugin
|
|
@@ -15,39 +16,7 @@ import { AgentApiClient, installToolErrorCapture } from "@alfe.ai/agent-api-clie
|
|
|
15
16
|
* - teams_list_channels — list Teams channels the bot has access to
|
|
16
17
|
*/
|
|
17
18
|
const pkg = createRequire(import.meta.url)("../package.json");
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
content: [{
|
|
21
|
-
type: "text",
|
|
22
|
-
text: JSON.stringify(data)
|
|
23
|
-
}],
|
|
24
|
-
details: data
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
function errResult(message) {
|
|
28
|
-
return {
|
|
29
|
-
content: [{
|
|
30
|
-
type: "text",
|
|
31
|
-
text: JSON.stringify({ error: message })
|
|
32
|
-
}],
|
|
33
|
-
details: { error: message }
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
function defineTool(def) {
|
|
37
|
-
return {
|
|
38
|
-
name: def.name,
|
|
39
|
-
description: def.description,
|
|
40
|
-
label: def.name,
|
|
41
|
-
parameters: def.parameters,
|
|
42
|
-
execute: async (_toolCallId, params) => {
|
|
43
|
-
try {
|
|
44
|
-
return ok(await def.handler(params));
|
|
45
|
-
} catch (e) {
|
|
46
|
-
return errResult(e.message);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
}
|
|
19
|
+
const TEAMS_ACTIVATION_KEY = getActivationKey("teams");
|
|
51
20
|
let client = null;
|
|
52
21
|
function getClient() {
|
|
53
22
|
if (!client) throw new Error("Teams plugin not initialized — no API client");
|
|
@@ -106,8 +75,7 @@ const plugin = {
|
|
|
106
75
|
const log = api.logger;
|
|
107
76
|
for (const tool of teamsTools) api.registerTool(tool);
|
|
108
77
|
log.info(`Registered ${String(teamsTools.length)} Teams tools: ${teamsTools.map((t) => t.name).join(", ")}`);
|
|
109
|
-
|
|
110
|
-
globalThis.__teamsPluginActivated = true;
|
|
78
|
+
guardedStart(TEAMS_ACTIVATION_KEY, log, () => {
|
|
111
79
|
log.info("Alfe Teams plugin activating...");
|
|
112
80
|
try {
|
|
113
81
|
const config = resolveConfig();
|
|
@@ -118,13 +86,15 @@ const plugin = {
|
|
|
118
86
|
} catch (err) {
|
|
119
87
|
log.error(`Failed to resolve config: ${err instanceof Error ? err.message : String(err)}`);
|
|
120
88
|
log.warn("Teams tools will fail — no API config available");
|
|
89
|
+
resetActivation(TEAMS_ACTIVATION_KEY);
|
|
90
|
+
return;
|
|
121
91
|
}
|
|
122
92
|
log.info("Alfe Teams plugin activated");
|
|
123
|
-
}
|
|
93
|
+
});
|
|
124
94
|
},
|
|
125
95
|
deactivate(api) {
|
|
126
|
-
globalThis.__teamsPluginActivated = false;
|
|
127
96
|
client = null;
|
|
97
|
+
resetActivation(TEAMS_ACTIVATION_KEY);
|
|
128
98
|
api.logger.info("Alfe Teams plugin deactivated");
|
|
129
99
|
}
|
|
130
100
|
};
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["/**\n * @alfe/openclaw-teams — OpenClaw native plugin\n *\n * Registers Microsoft Teams tools with OpenClaw. Tools call the Alfe\n * agent API via @alfe.ai/agent-api-client.\n *\n * This plugin provides:\n * - teams_send_message — send a text message to a Teams conversation\n * - teams_send_card — send an adaptive card to a Teams conversation\n * - teams_list_channels — list Teams channels the bot has access to\n */\n\nimport { Type, type TSchema } from \"@sinclair/typebox\";\nimport { resolveConfig } from \"@alfe.ai/config\";\nimport { AgentApiClient, installToolErrorCapture } from \"@alfe.ai/agent-api-client\";\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// ──
|
|
1
|
+
{"version":3,"file":"plugin.js","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["/**\n * @alfe/openclaw-teams — OpenClaw native plugin\n *\n * Registers Microsoft Teams tools with OpenClaw. Tools call the Alfe\n * agent API via @alfe.ai/agent-api-client.\n *\n * This plugin provides:\n * - teams_send_message — send a text message to a Teams conversation\n * - teams_send_card — send an adaptive card to a Teams conversation\n * - teams_list_channels — list Teams channels the bot has access to\n */\n\nimport { Type, type TSchema } from \"@sinclair/typebox\";\nimport { resolveConfig } from \"@alfe.ai/config\";\nimport { AgentApiClient, installToolErrorCapture } from \"@alfe.ai/agent-api-client\";\nimport {\n defineTool,\n getActivationKey,\n guardedStart,\n resetActivation,\n type ToolDef,\n} from \"@alfe.ai/openclaw-plugin-kit\";\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<TSchema>): 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// ── Activation guard ─────────────────────────────────────────\n\nconst TEAMS_ACTIVATION_KEY = getActivationKey(\"teams\");\n\n// ── API client ───────────────────────────────────────────────\n\nlet client: AgentApiClient | null = null;\n\nfunction getClient(): AgentApiClient {\n if (!client) throw new Error(\"Teams plugin not initialized — no API client\");\n return client;\n}\n\n// ── Tool definitions ─────────────────────────────────────────\n\nconst teamsTools: ToolDef<TSchema>[] = [\n defineTool({\n name: \"teams_send_message\",\n description:\n \"Send a text message to a Microsoft Teams conversation. \" +\n \"You need the conversationId from an inbound Teams message or from teams_list_channels.\",\n parameters: Type.Object({\n conversationId: Type.String({ description: \"The Teams conversation ID to send the message to\" }),\n text: Type.String({ description: \"The message text to send\" }),\n }),\n handler: async (params) => {\n const { conversationId, text } = params as { conversationId: string; text: string };\n return getClient().sendTeamsMessage({ conversationId, text });\n },\n }),\n\n defineTool({\n name: \"teams_send_card\",\n description:\n \"Send an Adaptive Card to a Microsoft Teams conversation. \" +\n \"Adaptive Cards support rich formatting, inputs, and actions. \" +\n \"Pass a valid Adaptive Card JSON object.\",\n parameters: Type.Object({\n conversationId: Type.String({ description: \"The Teams conversation ID to send the card to\" }),\n adaptiveCard: Type.Object({}, {\n description: \"Adaptive Card JSON payload (see https://adaptivecards.io)\",\n additionalProperties: true,\n }),\n }),\n handler: async (params) => {\n const { conversationId, adaptiveCard } = params as {\n conversationId: string;\n adaptiveCard: Record<string, unknown>;\n };\n return getClient().sendTeamsMessage({ conversationId, adaptiveCard });\n },\n }),\n\n defineTool({\n name: \"teams_list_channels\",\n description:\n \"List Microsoft Teams channels and conversations that the bot has access to. \" +\n \"Returns channel IDs that can be used with teams_send_message and teams_send_card.\",\n parameters: Type.Object({}),\n handler: async () => {\n return getClient().listTeamsChannels();\n },\n }),\n];\n\n// ── Plugin definition ────────────────────────────────────────\n\nconst plugin = {\n id: \"@alfe.ai/openclaw-teams\",\n name: \"Alfe Teams Plugin\",\n description: \"Microsoft Teams integration — send messages and adaptive cards\",\n version: pkg.version,\n\n activate(api: OpenClawPluginApi) {\n // First thing, before any registerTool call: tool failures emit a\n // deterministic [ERROR] line the gateway's runtime-output monitor captures\n // to Sentry. See @alfe.ai/agent-api-client tool-error-capture.\n installToolErrorCapture(api, { plugin: \"openclaw-teams\" });\n const log = api.logger;\n\n\n for (const tool of teamsTools) {\n api.registerTool(tool);\n }\n log.info(`Registered ${String(teamsTools.length)} Teams tools: ${teamsTools.map((t) => t.name).join(\", \")}`);\n\n guardedStart(TEAMS_ACTIVATION_KEY, log, () => {\n log.info(\"Alfe Teams plugin activating...\");\n\n try {\n const config = resolveConfig();\n client = new AgentApiClient({ apiKey: config.apiKey, apiUrl: config.apiUrl });\n } catch (err) {\n log.error(`Failed to resolve config: ${err instanceof Error ? err.message : String(err)}`);\n log.warn(\"Teams tools will fail — no API config available\");\n // Reset so a later activate() can retry once config exists.\n resetActivation(TEAMS_ACTIVATION_KEY);\n return;\n }\n\n log.info(\"Alfe Teams plugin activated\");\n });\n },\n\n deactivate(api: OpenClawPluginApi) {\n // Stop side effects BEFORE resetting the activation flag.\n client = null;\n resetActivation(TEAMS_ACTIVATION_KEY);\n api.logger.info(\"Alfe Teams plugin deactivated\");\n },\n};\n\nexport default plugin;\n"],"mappings":";;;;;;;;;;;;;;;;;AAwBA,MAAM,MADU,cAAc,OAAO,KAAK,IAAI,CAC1B,kBAAkB;AAmBtC,MAAM,uBAAuB,iBAAiB,QAAQ;AAItD,IAAI,SAAgC;AAEpC,SAAS,YAA4B;AACnC,KAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,+CAA+C;AAC5E,QAAO;;AAKT,MAAM,aAAiC;CACrC,WAAW;EACT,MAAM;EACN,aACE;EAEF,YAAY,KAAK,OAAO;GACtB,gBAAgB,KAAK,OAAO,EAAE,aAAa,oDAAoD,CAAC;GAChG,MAAM,KAAK,OAAO,EAAE,aAAa,4BAA4B,CAAC;GAC/D,CAAC;EACF,SAAS,OAAO,WAAW;GACzB,MAAM,EAAE,gBAAgB,SAAS;AACjC,UAAO,WAAW,CAAC,iBAAiB;IAAE;IAAgB;IAAM,CAAC;;EAEhE,CAAC;CAEF,WAAW;EACT,MAAM;EACN,aACE;EAGF,YAAY,KAAK,OAAO;GACtB,gBAAgB,KAAK,OAAO,EAAE,aAAa,iDAAiD,CAAC;GAC7F,cAAc,KAAK,OAAO,EAAE,EAAE;IAC5B,aAAa;IACb,sBAAsB;IACvB,CAAC;GACH,CAAC;EACF,SAAS,OAAO,WAAW;GACzB,MAAM,EAAE,gBAAgB,iBAAiB;AAIzC,UAAO,WAAW,CAAC,iBAAiB;IAAE;IAAgB;IAAc,CAAC;;EAExE,CAAC;CAEF,WAAW;EACT,MAAM;EACN,aACE;EAEF,YAAY,KAAK,OAAO,EAAE,CAAC;EAC3B,SAAS,YAAY;AACnB,UAAO,WAAW,CAAC,mBAAmB;;EAEzC,CAAC;CACH;AAID,MAAM,SAAS;CACb,IAAI;CACJ,MAAM;CACN,aAAa;CACb,SAAS,IAAI;CAEb,SAAS,KAAwB;AAI/B,0BAAwB,KAAK,EAAE,QAAQ,kBAAkB,CAAC;EAC1D,MAAM,MAAM,IAAI;AAGhB,OAAK,MAAM,QAAQ,WACjB,KAAI,aAAa,KAAK;AAExB,MAAI,KAAK,cAAc,OAAO,WAAW,OAAO,CAAC,gBAAgB,WAAW,KAAK,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,GAAG;AAE5G,eAAa,sBAAsB,WAAW;AAC5C,OAAI,KAAK,kCAAkC;AAE3C,OAAI;IACF,MAAM,SAAS,eAAe;AAC9B,aAAS,IAAI,eAAe;KAAE,QAAQ,OAAO;KAAQ,QAAQ,OAAO;KAAQ,CAAC;YACtE,KAAK;AACZ,QAAI,MAAM,6BAA6B,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;AAC1F,QAAI,KAAK,kDAAkD;AAE3D,oBAAgB,qBAAqB;AACrC;;AAGF,OAAI,KAAK,8BAA8B;IACvC;;CAGJ,WAAW,KAAwB;AAEjC,WAAS;AACT,kBAAgB,qBAAqB;AACrC,MAAI,OAAO,KAAK,gCAAgC;;CAEnD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfe.ai/openclaw-teams",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.38",
|
|
4
4
|
"description": "OpenClaw Microsoft Teams plugin for Alfe — send messages and adaptive cards to Teams",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -28,8 +28,9 @@
|
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@sinclair/typebox": "^0.34.48",
|
|
31
|
-
"@alfe.ai/agent-api-client": "0.
|
|
32
|
-
"@alfe.ai/config": "0.
|
|
31
|
+
"@alfe.ai/agent-api-client": "0.14.0",
|
|
32
|
+
"@alfe.ai/config": "0.4.0",
|
|
33
|
+
"@alfe.ai/openclaw-plugin-kit": "0.1.0"
|
|
33
34
|
},
|
|
34
35
|
"homepage": "https://alfe.ai",
|
|
35
36
|
"author": "Alfe (https://alfe.ai)",
|