@kernel.chat/kbot 3.99.31 → 3.99.33

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 (58) hide show
  1. package/README.md +1 -1
  2. package/dist/agents/security-agent.d.ts +31 -0
  3. package/dist/agents/security-agent.js +180 -0
  4. package/dist/agents/security-rules.d.ts +35 -0
  5. package/dist/agents/security-rules.js +206 -0
  6. package/dist/agents/specialists.d.ts +6 -0
  7. package/dist/agents/specialists.js +45 -0
  8. package/dist/architect.js +5 -0
  9. package/dist/auth.js +1 -1
  10. package/dist/channels/matrix.d.ts +4 -0
  11. package/dist/channels/matrix.js +28 -0
  12. package/dist/channels/office.d.ts +78 -0
  13. package/dist/channels/office.js +169 -0
  14. package/dist/channels/registry.d.ts +8 -0
  15. package/dist/channels/registry.js +38 -0
  16. package/dist/channels/signal.d.ts +4 -0
  17. package/dist/channels/signal.js +29 -0
  18. package/dist/channels/slack.d.ts +4 -0
  19. package/dist/channels/slack.js +97 -0
  20. package/dist/channels/teams.d.ts +4 -0
  21. package/dist/channels/teams.js +29 -0
  22. package/dist/channels/telegram.d.ts +4 -0
  23. package/dist/channels/telegram.js +28 -0
  24. package/dist/channels/types.d.ts +50 -0
  25. package/dist/channels/types.js +13 -0
  26. package/dist/channels/whatsapp.d.ts +4 -0
  27. package/dist/channels/whatsapp.js +28 -0
  28. package/dist/computer-use-coordinator.d.ts +44 -0
  29. package/dist/computer-use-coordinator.js +0 -0
  30. package/dist/file-library.d.ts +76 -0
  31. package/dist/file-library.js +269 -0
  32. package/dist/managed-agents-anthropic.d.ts +90 -0
  33. package/dist/managed-agents-anthropic.js +123 -0
  34. package/dist/plugins-integrity.d.ts +72 -0
  35. package/dist/plugins-integrity.js +153 -0
  36. package/dist/plugins.d.ts +13 -2
  37. package/dist/plugins.js +87 -10
  38. package/dist/tools/anthropic-managed-agents-tools.d.ts +22 -0
  39. package/dist/tools/anthropic-managed-agents-tools.js +191 -0
  40. package/dist/tools/channel-tools.d.ts +4 -0
  41. package/dist/tools/channel-tools.js +80 -0
  42. package/dist/tools/computer-coordinator-tools.d.ts +13 -0
  43. package/dist/tools/computer-coordinator-tools.js +104 -0
  44. package/dist/tools/computer.js +463 -299
  45. package/dist/tools/file-library-tools.d.ts +12 -0
  46. package/dist/tools/file-library-tools.js +191 -0
  47. package/dist/tools/image-thoughtful.d.ts +31 -0
  48. package/dist/tools/image-thoughtful.js +233 -0
  49. package/dist/tools/index.js +1 -0
  50. package/dist/tools/security-agent-tools.d.ts +34 -0
  51. package/dist/tools/security-agent-tools.js +30 -0
  52. package/dist/tools/swarm-2026-04.d.ts +2 -0
  53. package/dist/tools/swarm-2026-04.js +91 -0
  54. package/dist/tools/workspace-agent-tools.d.ts +19 -0
  55. package/dist/tools/workspace-agent-tools.js +191 -0
  56. package/dist/workspace-agents.d.ts +132 -0
  57. package/dist/workspace-agents.js +379 -0
  58. package/package.json +1 -1
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Plugin integrity verification — fail-closed SHA-256 manifest checking.
3
+ *
4
+ * Ports OpenClaw's `plugins.json5` integrity-pinned plugin model. Plugins must
5
+ * be declared in a manifest with a SHA-256 hash; the loader verifies the file
6
+ * on disk against the manifest entry and refuses to load on drift.
7
+ *
8
+ * Manifest format here is plain JSON. If we add a JSON5 dep later (e.g.
9
+ * `json5`), swap `JSON.parse` for `JSON5.parse` and accept `.json5` files.
10
+ */
11
+ import { createHash } from 'node:crypto';
12
+ import { readFile, stat } from 'node:fs/promises';
13
+ import { resolve, isAbsolute } from 'node:path';
14
+ export class IntegrityError extends Error {
15
+ failed;
16
+ constructor(failed) {
17
+ const names = failed.map((f) => `${f.name} (${f.reason})`).join(', ');
18
+ super(`Plugin integrity check failed: ${names}`);
19
+ this.name = 'IntegrityError';
20
+ this.failed = failed;
21
+ }
22
+ }
23
+ const INTEGRITY_PREFIX = 'sha256-';
24
+ function isManifestEntry(v) {
25
+ if (!v || typeof v !== 'object')
26
+ return false;
27
+ const e = v;
28
+ return (typeof e.name === 'string' &&
29
+ typeof e.version === 'string' &&
30
+ typeof e.path === 'string' &&
31
+ typeof e.integrity === 'string' &&
32
+ e.integrity.startsWith(INTEGRITY_PREFIX));
33
+ }
34
+ function isManifest(v) {
35
+ if (!v || typeof v !== 'object')
36
+ return false;
37
+ const m = v;
38
+ if (m.schemaVersion !== 1)
39
+ return false;
40
+ if (!Array.isArray(m.plugins))
41
+ return false;
42
+ return m.plugins.every(isManifestEntry);
43
+ }
44
+ /**
45
+ * Load and validate a manifest from disk. Throws on missing file, invalid
46
+ * JSON, or schema violation.
47
+ */
48
+ export async function loadManifest(path) {
49
+ let raw;
50
+ try {
51
+ raw = await readFile(path, 'utf8');
52
+ }
53
+ catch (err) {
54
+ throw new Error(`Failed to read manifest at ${path}: ${err.message}`);
55
+ }
56
+ let parsed;
57
+ try {
58
+ parsed = JSON.parse(raw);
59
+ }
60
+ catch (err) {
61
+ throw new Error(`Manifest is not valid JSON: ${err.message}`);
62
+ }
63
+ if (!isManifest(parsed)) {
64
+ throw new Error(`Manifest at ${path} is malformed: expected { schemaVersion: 1, plugins: [{name, version, path, integrity: "sha256-..."}] }`);
65
+ }
66
+ return parsed;
67
+ }
68
+ /**
69
+ * Compute SHA-256 of a file and return it formatted as `sha256-<base64>`.
70
+ */
71
+ async function computeIntegrity(filePath) {
72
+ const buf = await readFile(filePath);
73
+ const digest = createHash('sha256').update(buf).digest('base64');
74
+ return `${INTEGRITY_PREFIX}${digest}`;
75
+ }
76
+ /**
77
+ * Verify a single plugin file against its manifest entry.
78
+ *
79
+ * - Missing file → `{ ok: false, reason: "plugin file missing" }`
80
+ * - Hash mismatch → `{ ok: false, reason: "integrity drift" }`
81
+ * - Match → `{ ok: true }`
82
+ */
83
+ export async function verifyPlugin(filePath, manifestEntry) {
84
+ try {
85
+ const s = await stat(filePath);
86
+ if (!s.isFile()) {
87
+ return {
88
+ ok: false,
89
+ reason: 'plugin file missing',
90
+ expected: manifestEntry.integrity,
91
+ actual: '',
92
+ };
93
+ }
94
+ }
95
+ catch {
96
+ return {
97
+ ok: false,
98
+ reason: 'plugin file missing',
99
+ expected: manifestEntry.integrity,
100
+ actual: '',
101
+ };
102
+ }
103
+ const actual = await computeIntegrity(filePath);
104
+ if (actual !== manifestEntry.integrity) {
105
+ return {
106
+ ok: false,
107
+ reason: 'integrity drift',
108
+ expected: manifestEntry.integrity,
109
+ actual,
110
+ };
111
+ }
112
+ return { ok: true };
113
+ }
114
+ /**
115
+ * Verify every plugin in a manifest against the corresponding files under
116
+ * `pluginsDir`. Resolves entry paths relative to `pluginsDir` unless
117
+ * absolute.
118
+ *
119
+ * Always returns a result; never throws on drift. Callers should pass the
120
+ * result to `enforce()` to fail closed.
121
+ */
122
+ export async function verifyAllPlugins(manifestPath, pluginsDir) {
123
+ const manifest = await loadManifest(manifestPath);
124
+ const verified = [];
125
+ const failed = [];
126
+ for (const entry of manifest.plugins) {
127
+ const filePath = isAbsolute(entry.path) ? entry.path : resolve(pluginsDir, entry.path);
128
+ const result = await verifyPlugin(filePath, entry);
129
+ if (result.ok) {
130
+ verified.push(entry.name);
131
+ }
132
+ else {
133
+ failed.push({
134
+ name: entry.name,
135
+ reason: result.reason,
136
+ expected: result.expected,
137
+ actual: result.actual,
138
+ });
139
+ }
140
+ }
141
+ return { verified, failed };
142
+ }
143
+ /**
144
+ * Fail-closed gate. Throws `IntegrityError` if any plugin failed verification.
145
+ * No-op when all plugins are verified. Loaders should call this unless
146
+ * integrity checking has been explicitly disabled (e.g. dev override).
147
+ */
148
+ export function enforce(result) {
149
+ if (result.failed.length > 0) {
150
+ throw new IntegrityError(result.failed);
151
+ }
152
+ }
153
+ //# sourceMappingURL=plugins-integrity.js.map
package/dist/plugins.d.ts CHANGED
@@ -1,3 +1,14 @@
1
+ export interface LoadPluginsOptions {
2
+ /** Override the plugin directory (used by tests). Defaults to ~/.kbot/plugins. */
3
+ pluginsDir?: string;
4
+ /** Override the integrity manifest path. Defaults to ~/.kbot/plugins.json. */
5
+ manifestPath?: string;
6
+ /**
7
+ * Override the integrity-disabled flag. Defaults to reading
8
+ * `process.env.KBOT_PLUGIN_INTEGRITY === 'off'`.
9
+ */
10
+ integrityDisabled?: boolean;
11
+ }
1
12
  export interface PluginDefinition {
2
13
  name: string;
3
14
  description: string;
@@ -18,9 +29,9 @@ export interface PluginManifest {
18
29
  error?: string;
19
30
  }
20
31
  /** Ensure the plugins directory exists */
21
- export declare function ensurePluginsDir(): string;
32
+ export declare function ensurePluginsDir(dir?: string): string;
22
33
  /** Load all plugins from ~/.kbot/plugins/ */
23
- export declare function loadPlugins(verbose?: boolean): Promise<PluginManifest[]>;
34
+ export declare function loadPlugins(verbose?: boolean, opts?: LoadPluginsOptions): Promise<PluginManifest[]>;
24
35
  /** List loaded plugins */
25
36
  export declare function getLoadedPlugins(): PluginManifest[];
26
37
  /** Format plugin list for display */
package/dist/plugins.js CHANGED
@@ -14,23 +14,82 @@ import { existsSync, readdirSync, mkdirSync, writeFileSync, statSync } from 'nod
14
14
  import { join } from 'node:path';
15
15
  import { homedir } from 'node:os';
16
16
  import { pathToFileURL } from 'node:url';
17
+ import chalk from 'chalk';
17
18
  import { registerTool } from './tools/index.js';
19
+ import { IntegrityError, verifyAllPlugins, enforce, } from './plugins-integrity.js';
18
20
  const PLUGINS_DIR = join(homedir(), '.kbot', 'plugins');
19
21
  const PLUGIN_EXTENSIONS = ['.js', '.mjs'];
22
+ /**
23
+ * Default integrity manifest path. Override with KBOT_PLUGIN_MANIFEST env var
24
+ * or the `manifestPath` option to `loadPlugins`.
25
+ */
26
+ const DEFAULT_MANIFEST_PATH = join(homedir(), '.kbot', 'plugins.json');
20
27
  const loadedPlugins = [];
21
28
  /** Ensure the plugins directory exists */
22
- export function ensurePluginsDir() {
23
- if (!existsSync(PLUGINS_DIR)) {
24
- mkdirSync(PLUGINS_DIR, { recursive: true });
29
+ export function ensurePluginsDir(dir = PLUGINS_DIR) {
30
+ if (!existsSync(dir)) {
31
+ mkdirSync(dir, { recursive: true });
32
+ }
33
+ return dir;
34
+ }
35
+ /**
36
+ * Run the integrity manifest gate before discovery.
37
+ *
38
+ * Behaviour:
39
+ * - If KBOT_PLUGIN_INTEGRITY=off (or `opts.integrityDisabled === true`):
40
+ * emit a yellow warning and return `null` (verification skipped, all
41
+ * discovered plugins will load).
42
+ * - If the manifest file does not exist: emit a yellow info note and
43
+ * return `null` (back-compat — manifest is optional today).
44
+ * - If the manifest exists and verifies: return the `VerifyAllResult` so
45
+ * the caller can restrict loads to `result.verified`.
46
+ * - If the manifest exists and any plugin fails: throw `IntegrityError`
47
+ * (kbot refuses to start).
48
+ */
49
+ async function runIntegrityGate(manifestPath, pluginsDir, integrityDisabled) {
50
+ if (integrityDisabled) {
51
+ console.error(chalk.yellow(` ⚠ Plugin integrity verification is DISABLED (KBOT_PLUGIN_INTEGRITY=off). ` +
52
+ `Plugins under ${pluginsDir} will load without hash checking.`));
53
+ return null;
54
+ }
55
+ if (!existsSync(manifestPath)) {
56
+ console.error(chalk.yellow(` ⚠ no plugin manifest at ${manifestPath} — plugins are unverified. ` +
57
+ `Create one to pin plugins by SHA-256 (see PLUGINS_INTEGRITY.md).`));
58
+ return null;
59
+ }
60
+ // verifyAllPlugins resolves manifest entry paths against pluginsDir, so the
61
+ // file layout is: <pluginsDir>/<entry.path> matches the hash in the manifest.
62
+ try {
63
+ const result = await verifyAllPlugins(manifestPath, pluginsDir);
64
+ if (result.failed.length > 0) {
65
+ const lines = result.failed
66
+ .map((f) => ` - ${f.name}: ${f.reason}`)
67
+ .join('\n');
68
+ console.error(chalk.red(` ✗ Plugin integrity check failed for ${result.failed.length} plugin(s):\n${lines}\n` +
69
+ ` Manifest: ${manifestPath}\n` +
70
+ ` To refresh hashes, recompute SHA-256 for each plugin file and update the manifest. ` +
71
+ `Set KBOT_PLUGIN_INTEGRITY=off ONLY for local dev; never in production.`));
72
+ enforce(result); // throws IntegrityError
73
+ }
74
+ return result;
75
+ }
76
+ catch (err) {
77
+ if (err instanceof IntegrityError)
78
+ throw err;
79
+ // loadManifest threw (malformed JSON, schema violation, etc.) — fail closed.
80
+ console.error(chalk.red(` ✗ Failed to load plugin integrity manifest at ${manifestPath}: ${err.message}`));
81
+ throw err;
25
82
  }
26
- return PLUGINS_DIR;
27
83
  }
28
84
  /** Load all plugins from ~/.kbot/plugins/ */
29
- export async function loadPlugins(verbose = false) {
30
- ensurePluginsDir();
85
+ export async function loadPlugins(verbose = false, opts = {}) {
86
+ const pluginsDir = opts.pluginsDir ?? PLUGINS_DIR;
87
+ const manifestPath = opts.manifestPath ?? process.env.KBOT_PLUGIN_MANIFEST ?? DEFAULT_MANIFEST_PATH;
88
+ const integrityDisabled = opts.integrityDisabled ?? process.env.KBOT_PLUGIN_INTEGRITY === 'off';
89
+ ensurePluginsDir(pluginsDir);
31
90
  // Security: reject plugins if directory is world/group-writable
32
91
  try {
33
- const dirStat = statSync(PLUGINS_DIR);
92
+ const dirStat = statSync(pluginsDir);
34
93
  if ((dirStat.mode & 0o022) !== 0) {
35
94
  if (verbose)
36
95
  console.error(' ⚠ Plugin directory is writable by others — skipping plugins for security');
@@ -40,13 +99,31 @@ export async function loadPlugins(verbose = false) {
40
99
  catch {
41
100
  return [];
42
101
  }
43
- const files = readdirSync(PLUGINS_DIR).filter(f => PLUGIN_EXTENSIONS.some(ext => f.endsWith(ext)));
102
+ // Integrity gate runs BEFORE any file is imported. Throws IntegrityError
103
+ // on drift unless KBOT_PLUGIN_INTEGRITY=off.
104
+ const integrity = await runIntegrityGate(manifestPath, pluginsDir, integrityDisabled);
105
+ // When a manifest verified successfully, restrict loads to verified names.
106
+ // When the manifest is missing or integrity is disabled, allow every file.
107
+ const verifiedNames = integrity
108
+ ? new Set(integrity.verified)
109
+ : null;
110
+ const files = readdirSync(pluginsDir).filter(f => PLUGIN_EXTENSIONS.some(ext => f.endsWith(ext)));
44
111
  if (files.length === 0)
45
112
  return [];
46
113
  for (const file of files) {
114
+ const pluginName = file.replace(/\.[^.]+$/, '');
115
+ // When manifest verification ran, only load plugins whose name appears in
116
+ // the verified set. Files not declared in the manifest are silently
117
+ // skipped (they did not pass — and could not have passed — verification).
118
+ if (verifiedNames && !verifiedNames.has(pluginName)) {
119
+ if (verbose) {
120
+ console.error(chalk.yellow(` ⚠ Skipping ${file} — not declared in plugin manifest`));
121
+ }
122
+ continue;
123
+ }
47
124
  // Security: reject plugin files that are group/world-writable
48
125
  try {
49
- const fileStat = statSync(join(PLUGINS_DIR, file));
126
+ const fileStat = statSync(join(pluginsDir, file));
50
127
  if ((fileStat.mode & 0o022) !== 0) {
51
128
  loadedPlugins.push({
52
129
  name: file.replace(/\.[^.]+$/, ''),
@@ -61,7 +138,7 @@ export async function loadPlugins(verbose = false) {
61
138
  catch {
62
139
  continue;
63
140
  }
64
- const filePath = join(PLUGINS_DIR, file);
141
+ const filePath = join(pluginsDir, file);
65
142
  const manifest = {
66
143
  name: file.replace(/\.[^.]+$/, ''),
67
144
  file,
@@ -0,0 +1,22 @@
1
+ /**
2
+ * kbot tool definitions wrapping the Anthropic Managed Agents client.
3
+ *
4
+ * Six tools mirror the client surface: create / turn / list / close /
5
+ * memory_read / memory_write. Each uses the canonical ToolDefinition shape
6
+ * from ./index.js.
7
+ *
8
+ * Wiring into the global tool registry happens elsewhere (tools/index.ts).
9
+ * This file only exports the definitions so workspace-agents.ts can pick
10
+ * them up when ANTHROPIC_API_KEY is set.
11
+ *
12
+ * SPEC: best-effort, refine when official docs published.
13
+ */
14
+ import type { ToolDefinition } from './index.js';
15
+ export declare const anthropicManagedAgentCreate: ToolDefinition;
16
+ export declare const anthropicManagedAgentTurn: ToolDefinition;
17
+ export declare const anthropicManagedAgentList: ToolDefinition;
18
+ export declare const anthropicManagedAgentClose: ToolDefinition;
19
+ export declare const anthropicManagedAgentMemoryRead: ToolDefinition;
20
+ export declare const anthropicManagedAgentMemoryWrite: ToolDefinition;
21
+ export declare const anthropicManagedAgentTools: ToolDefinition[];
22
+ //# sourceMappingURL=anthropic-managed-agents-tools.d.ts.map
@@ -0,0 +1,191 @@
1
+ /**
2
+ * kbot tool definitions wrapping the Anthropic Managed Agents client.
3
+ *
4
+ * Six tools mirror the client surface: create / turn / list / close /
5
+ * memory_read / memory_write. Each uses the canonical ToolDefinition shape
6
+ * from ./index.js.
7
+ *
8
+ * Wiring into the global tool registry happens elsewhere (tools/index.ts).
9
+ * This file only exports the definitions so workspace-agents.ts can pick
10
+ * them up when ANTHROPIC_API_KEY is set.
11
+ *
12
+ * SPEC: best-effort, refine when official docs published.
13
+ */
14
+ import { AnthropicManagedAgentsClient } from '../managed-agents-anthropic.js';
15
+ // ─────────────────────────────────────────────────────────────────────────
16
+ // Helpers
17
+ // ─────────────────────────────────────────────────────────────────────────
18
+ function getClient() {
19
+ // Construct fresh per call so callers can rotate API keys without
20
+ // restarting the process. The constructor cost is trivial (just a string
21
+ // copy and a fetch reference).
22
+ return new AnthropicManagedAgentsClient();
23
+ }
24
+ function asString(v) {
25
+ return typeof v === 'string' ? v : undefined;
26
+ }
27
+ function asStringArray(v) {
28
+ if (!Array.isArray(v))
29
+ return undefined;
30
+ const out = [];
31
+ for (const item of v) {
32
+ if (typeof item === 'string')
33
+ out.push(item);
34
+ }
35
+ return out;
36
+ }
37
+ async function safeRun(fn) {
38
+ try {
39
+ const result = await fn();
40
+ return JSON.stringify(result, null, 2);
41
+ }
42
+ catch (err) {
43
+ const message = err instanceof Error ? err.message : String(err);
44
+ return `Error: ${message}`;
45
+ }
46
+ }
47
+ // ─────────────────────────────────────────────────────────────────────────
48
+ // Tools
49
+ // ─────────────────────────────────────────────────────────────────────────
50
+ export const anthropicManagedAgentCreate = {
51
+ name: 'anthropic_managed_agent_create',
52
+ description: 'Create a hosted Anthropic Managed Agent session. Returns session_id. Requires ANTHROPIC_API_KEY. Sends anthropic-beta: managed-agents-2026-04-01.',
53
+ tier: 'pro',
54
+ parameters: {
55
+ mission: {
56
+ type: 'string',
57
+ description: 'The agent\'s long-horizon goal / mission statement.',
58
+ required: true,
59
+ },
60
+ allowed_tools: {
61
+ type: 'array',
62
+ description: 'Optional list of tool names the hosted agent may invoke.',
63
+ items: { type: 'string' },
64
+ },
65
+ model: {
66
+ type: 'string',
67
+ description: 'Optional model override (e.g., "claude-sonnet-4-7").',
68
+ },
69
+ },
70
+ async execute(args) {
71
+ return safeRun(async () => {
72
+ const mission = asString(args.mission) ?? '';
73
+ const allowedTools = asStringArray(args.allowed_tools);
74
+ const model = asString(args.model);
75
+ return getClient().createSession({ mission, allowedTools, model });
76
+ });
77
+ },
78
+ };
79
+ export const anthropicManagedAgentTurn = {
80
+ name: 'anthropic_managed_agent_turn',
81
+ description: 'Send a turn (user input) to an Anthropic Managed Agent session. Returns the agent output and any tool calls.',
82
+ tier: 'pro',
83
+ parameters: {
84
+ session_id: {
85
+ type: 'string',
86
+ description: 'Session id returned by anthropic_managed_agent_create.',
87
+ required: true,
88
+ },
89
+ input: {
90
+ type: 'string',
91
+ description: 'The user-side input for this turn.',
92
+ required: true,
93
+ },
94
+ },
95
+ async execute(args) {
96
+ return safeRun(async () => {
97
+ const sessionId = asString(args.session_id) ?? '';
98
+ const input = asString(args.input) ?? '';
99
+ return getClient().sendTurn({ sessionId, input });
100
+ });
101
+ },
102
+ };
103
+ export const anthropicManagedAgentList = {
104
+ name: 'anthropic_managed_agent_list',
105
+ description: 'List all hosted Anthropic Managed Agent sessions for the configured API key.',
106
+ tier: 'pro',
107
+ parameters: {},
108
+ async execute() {
109
+ return safeRun(async () => getClient().listSessions());
110
+ },
111
+ };
112
+ export const anthropicManagedAgentClose = {
113
+ name: 'anthropic_managed_agent_close',
114
+ description: 'Close (DELETE) a hosted Anthropic Managed Agent session.',
115
+ tier: 'pro',
116
+ parameters: {
117
+ session_id: {
118
+ type: 'string',
119
+ description: 'Session id to close.',
120
+ required: true,
121
+ },
122
+ },
123
+ async execute(args) {
124
+ return safeRun(async () => {
125
+ const sessionId = asString(args.session_id) ?? '';
126
+ return getClient().closeSession({ sessionId });
127
+ });
128
+ },
129
+ };
130
+ export const anthropicManagedAgentMemoryRead = {
131
+ name: 'anthropic_managed_agent_memory_read',
132
+ description: 'Read a memory value from a hosted Anthropic Managed Agent session. Pass key to read a single entry; omit key for the full memory.',
133
+ tier: 'pro',
134
+ parameters: {
135
+ session_id: {
136
+ type: 'string',
137
+ description: 'Session id.',
138
+ required: true,
139
+ },
140
+ key: {
141
+ type: 'string',
142
+ description: 'Optional memory key. If omitted, returns the full memory.',
143
+ },
144
+ },
145
+ async execute(args) {
146
+ return safeRun(async () => {
147
+ const sessionId = asString(args.session_id) ?? '';
148
+ const key = asString(args.key);
149
+ return getClient().memoryRead({ sessionId, key });
150
+ });
151
+ },
152
+ };
153
+ export const anthropicManagedAgentMemoryWrite = {
154
+ name: 'anthropic_managed_agent_memory_write',
155
+ description: 'Write a memory value to a hosted Anthropic Managed Agent session.',
156
+ tier: 'pro',
157
+ parameters: {
158
+ session_id: {
159
+ type: 'string',
160
+ description: 'Session id.',
161
+ required: true,
162
+ },
163
+ key: {
164
+ type: 'string',
165
+ description: 'Memory key to write.',
166
+ required: true,
167
+ },
168
+ value: {
169
+ type: 'string',
170
+ description: 'Value to store. Strings are stored as-is; if the value is a JSON string it is forwarded verbatim.',
171
+ required: true,
172
+ },
173
+ },
174
+ async execute(args) {
175
+ return safeRun(async () => {
176
+ const sessionId = asString(args.session_id) ?? '';
177
+ const key = asString(args.key) ?? '';
178
+ const value = args.value;
179
+ return getClient().memoryWrite({ sessionId, key, value });
180
+ });
181
+ },
182
+ };
183
+ export const anthropicManagedAgentTools = [
184
+ anthropicManagedAgentCreate,
185
+ anthropicManagedAgentTurn,
186
+ anthropicManagedAgentList,
187
+ anthropicManagedAgentClose,
188
+ anthropicManagedAgentMemoryRead,
189
+ anthropicManagedAgentMemoryWrite,
190
+ ];
191
+ //# sourceMappingURL=anthropic-managed-agents-tools.js.map
@@ -0,0 +1,4 @@
1
+ import type { ToolDefinition } from './index.js';
2
+ export declare const channelSendTool: ToolDefinition;
3
+ export declare const channelReceiveTool: ToolDefinition;
4
+ //# sourceMappingURL=channel-tools.d.ts.map
@@ -0,0 +1,80 @@
1
+ // kbot tool definitions for the unified channel adapter family.
2
+ //
3
+ // These tools are NOT auto-registered. Whoever wires them in (cli.ts,
4
+ // a plugin, or an agent prompt) should call `registerTool(channelSendTool)`
5
+ // and `registerTool(channelReceiveTool)`. Keeping registration external
6
+ // preserves the CURATION_PLAN.md target of 52 core tools.
7
+ import { getChannel } from '../channels/registry.js';
8
+ export const channelSendTool = {
9
+ name: 'channel_send',
10
+ description: 'Send a message through a unified channel adapter (slack, whatsapp, telegram, signal, matrix, teams). Slack is fully implemented; others are stubs and will throw until implemented.',
11
+ tier: 'pro',
12
+ parameters: {
13
+ channel_type: {
14
+ type: 'string',
15
+ description: 'Adapter name: slack | whatsapp | telegram | signal | matrix | teams',
16
+ required: true,
17
+ },
18
+ channel: {
19
+ type: 'string',
20
+ description: 'Target channel/chat/room id understood by the adapter',
21
+ required: true,
22
+ },
23
+ text: {
24
+ type: 'string',
25
+ description: 'Plain-text message body',
26
+ required: true,
27
+ },
28
+ blocks: {
29
+ type: 'array',
30
+ description: 'Optional rich content (Slack blocks, etc.)',
31
+ required: false,
32
+ },
33
+ },
34
+ async execute(args) {
35
+ const adapter = getChannel(String(args.channel_type));
36
+ const result = await adapter.send({
37
+ channel: String(args.channel),
38
+ text: String(args.text),
39
+ blocks: args.blocks,
40
+ });
41
+ return JSON.stringify({ ok: true, adapter: adapter.name, ...result });
42
+ },
43
+ };
44
+ export const channelReceiveTool = {
45
+ name: 'channel_receive',
46
+ description: 'Fetch recent messages from a unified channel adapter. Returns a JSON array of {id, from, text, ts}.',
47
+ tier: 'pro',
48
+ parameters: {
49
+ channel_type: {
50
+ type: 'string',
51
+ description: 'Adapter name: slack | whatsapp | telegram | signal | matrix | teams',
52
+ required: true,
53
+ },
54
+ channel: {
55
+ type: 'string',
56
+ description: 'Source channel/chat/room id',
57
+ required: true,
58
+ },
59
+ oldest: {
60
+ type: 'number',
61
+ description: 'Unix epoch ms; only return messages newer than this',
62
+ required: false,
63
+ },
64
+ limit: {
65
+ type: 'number',
66
+ description: 'Maximum messages to return',
67
+ required: false,
68
+ },
69
+ },
70
+ async execute(args) {
71
+ const adapter = getChannel(String(args.channel_type));
72
+ const messages = await adapter.receive({
73
+ channel: String(args.channel),
74
+ oldest: args.oldest === undefined ? undefined : Number(args.oldest),
75
+ limit: args.limit === undefined ? undefined : Number(args.limit),
76
+ });
77
+ return JSON.stringify({ ok: true, adapter: adapter.name, messages });
78
+ },
79
+ };
80
+ //# sourceMappingURL=channel-tools.js.map
@@ -0,0 +1,13 @@
1
+ export interface ToolDef {
2
+ name: string;
3
+ description: string;
4
+ inputSchema: Record<string, unknown>;
5
+ handler: (args: Record<string, unknown>) => Promise<unknown> | unknown;
6
+ }
7
+ export declare const computerCoordinatorRegister: ToolDef;
8
+ export declare const computerCoordinatorClaim: ToolDef;
9
+ export declare const computerCoordinatorRelease: ToolDef;
10
+ export declare const computerCoordinatorStatus: ToolDef;
11
+ export declare const computerCoordinatorUnregister: ToolDef;
12
+ export declare const computerCoordinatorTools: ToolDef[];
13
+ //# sourceMappingURL=computer-coordinator-tools.d.ts.map