openbot 0.4.7 → 0.5.4

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 (130) hide show
  1. package/.claude/agents/runtime-security-reviewer.md +32 -0
  2. package/.claude/hooks/format.sh +18 -0
  3. package/.claude/hooks/protect-secrets.sh +23 -0
  4. package/.claude/settings.json +26 -0
  5. package/.claude/skills/deploy/SKILL.md +26 -0
  6. package/.claude/skills/new-plugin/SKILL.md +46 -0
  7. package/.dockerignore +9 -0
  8. package/.mcp.json +8 -0
  9. package/AGENTS.md +2 -2
  10. package/CLAUDE.md +50 -0
  11. package/Dockerfile +41 -0
  12. package/deploy/README.md +61 -0
  13. package/deploy/entrypoint.sh +6 -0
  14. package/deploy/fly.toml +36 -0
  15. package/dist/app/bootstrap.js +29 -0
  16. package/dist/app/cli.js +3 -1
  17. package/dist/app/cloud-mode.js +26 -0
  18. package/dist/app/config.js +61 -16
  19. package/dist/app/server.js +38 -6
  20. package/dist/plugins/approval/index.js +1 -1
  21. package/dist/plugins/bash/index.js +386 -164
  22. package/dist/plugins/memory/service.js +2 -5
  23. package/dist/plugins/openbot/context.js +17 -1
  24. package/dist/plugins/openbot/index.js +23 -8
  25. package/dist/plugins/openbot/model.js +59 -0
  26. package/dist/plugins/openbot/runtime.js +39 -56
  27. package/dist/plugins/openbot/system-prompt.js +43 -8
  28. package/dist/plugins/preview/index.js +267 -0
  29. package/dist/plugins/storage/index.js +3 -3
  30. package/dist/plugins/storage/service.js +58 -12
  31. package/dist/plugins/todo/index.js +131 -38
  32. package/dist/plugins/todo/service.js +93 -0
  33. package/dist/plugins/ui/index.js +8 -1
  34. package/dist/services/plugins/model-registry.js +101 -0
  35. package/dist/services/plugins/registry.js +6 -4
  36. package/dist/services/plugins/service.js +2 -6
  37. package/docs/agents.md +20 -2
  38. package/docs/architecture.md +1 -1
  39. package/docs/plugins.md +13 -3
  40. package/docs/templates/AGENT.example.md +1 -1
  41. package/package.json +5 -2
  42. package/pnpm-workspace.yaml +2 -0
  43. package/src/app/bootstrap.ts +43 -0
  44. package/src/app/cli.ts +3 -1
  45. package/src/app/cloud-mode.ts +41 -0
  46. package/src/app/config.ts +71 -19
  47. package/src/app/server.ts +45 -6
  48. package/src/app/types.ts +162 -31
  49. package/src/plugins/approval/index.ts +1 -1
  50. package/src/plugins/bash/index.ts +498 -185
  51. package/src/plugins/memory/service.ts +2 -5
  52. package/src/plugins/openbot/context.ts +17 -1
  53. package/src/plugins/openbot/index.ts +25 -10
  54. package/src/plugins/openbot/model.ts +76 -0
  55. package/src/plugins/openbot/runtime.ts +47 -69
  56. package/src/plugins/openbot/system-prompt.ts +43 -8
  57. package/src/plugins/preview/index.ts +323 -0
  58. package/src/plugins/storage/index.ts +5 -8
  59. package/src/plugins/storage/service.ts +79 -15
  60. package/src/plugins/todo/index.ts +166 -0
  61. package/src/plugins/todo/service.ts +123 -0
  62. package/src/plugins/ui/index.ts +8 -1
  63. package/src/services/plugins/domain.ts +2 -0
  64. package/src/services/plugins/model-registry.ts +146 -0
  65. package/src/services/plugins/registry.ts +6 -4
  66. package/src/services/plugins/service.ts +2 -6
  67. package/dist/agents/openbot/index.js +0 -76
  68. package/dist/agents/openbot/middleware/approval.js +0 -132
  69. package/dist/agents/openbot/runtime.js +0 -289
  70. package/dist/agents/openbot/system-prompt.js +0 -32
  71. package/dist/agents/openbot/tools/delegation.js +0 -78
  72. package/dist/agents/openbot/tools/mcp.js +0 -99
  73. package/dist/agents/openbot/tools/shell.js +0 -91
  74. package/dist/agents/openbot/tools/storage.js +0 -75
  75. package/dist/agents/openbot/tools/ui.js +0 -176
  76. package/dist/agents/system.js +0 -33
  77. package/dist/bus/agent-package.js +0 -1
  78. package/dist/bus/plugin.js +0 -1
  79. package/dist/bus/services.js +0 -754
  80. package/dist/bus/types.js +0 -1
  81. package/dist/harness/agent-harness.js +0 -45
  82. package/dist/harness/agent-invoke-run.js +0 -44
  83. package/dist/harness/agent-turn.js +0 -99
  84. package/dist/harness/channel-participants.js +0 -40
  85. package/dist/harness/constants.js +0 -2
  86. package/dist/harness/context-meter.js +0 -97
  87. package/dist/harness/context.js +0 -363
  88. package/dist/harness/dispatch.js +0 -144
  89. package/dist/harness/dispatcher.js +0 -156
  90. package/dist/harness/event-normalizer.js +0 -59
  91. package/dist/harness/history.js +0 -177
  92. package/dist/harness/mcp.js +0 -61
  93. package/dist/harness/orchestration.js +0 -88
  94. package/dist/harness/orchestrator.js +0 -149
  95. package/dist/harness/participants.js +0 -22
  96. package/dist/harness/process.js +0 -29
  97. package/dist/harness/queue-processor.js +0 -187
  98. package/dist/harness/run-harness.js +0 -154
  99. package/dist/harness/run.js +0 -98
  100. package/dist/harness/runtime-factory.js +0 -73
  101. package/dist/harness/runtime.js +0 -57
  102. package/dist/harness/todo-advance.js +0 -93
  103. package/dist/harness/todo-dispatch.js +0 -51
  104. package/dist/harness/todos.js +0 -5
  105. package/dist/harness/turn.js +0 -79
  106. package/dist/harness/types.js +0 -1
  107. package/dist/plugins/ai-sdk/index.js +0 -34
  108. package/dist/plugins/ai-sdk/runtime.js +0 -395
  109. package/dist/plugins/ai-sdk/system-prompt.js +0 -18
  110. package/dist/plugins/ai-sdk.js +0 -331
  111. package/dist/plugins/approval.js +0 -163
  112. package/dist/plugins/delegation.js +0 -108
  113. package/dist/plugins/mcp/index.js +0 -108
  114. package/dist/plugins/mcp.js +0 -140
  115. package/dist/plugins/shell/index.js +0 -100
  116. package/dist/plugins/shell.js +0 -123
  117. package/dist/plugins/storage-tools/index.js +0 -76
  118. package/dist/plugins/storage.js +0 -737
  119. package/dist/plugins/thread-namer/index.js +0 -72
  120. package/dist/plugins/threads/index.js +0 -114
  121. package/dist/plugins/ui.js +0 -211
  122. package/dist/plugins/workflow/index.js +0 -65
  123. package/dist/registry/agents.js +0 -138
  124. package/dist/registry/plugins.js +0 -110
  125. package/dist/services/agent-packages.js +0 -103
  126. package/dist/services/memory.js +0 -152
  127. package/dist/services/plugins.js +0 -98
  128. package/dist/services/storage.js +0 -1028
  129. package/dist/workflow/service.js +0 -106
  130. package/dist/workflow/types.js +0 -3
@@ -1,108 +0,0 @@
1
- import z from 'zod';
2
- import { mcpService } from '../../harness/mcp.js';
3
- function stringifyResult(value) {
4
- if (typeof value === 'string')
5
- return value;
6
- try {
7
- return JSON.stringify(value, null, 2);
8
- }
9
- catch {
10
- return String(value);
11
- }
12
- }
13
- const mcpToolDefinitions = {
14
- mcp_list_tools: {
15
- description: 'List available tools from a configured MCP server. Use this first before calling tools on an unknown server.',
16
- inputSchema: z.object({
17
- serverId: z.string().describe('Configured MCP server id (e.g. github, notion, linear).'),
18
- }),
19
- },
20
- mcp_call: {
21
- description: 'Call a tool on a configured MCP server. Provide tool arguments as a JSON object. Use mcp_list_tools first when uncertain.',
22
- inputSchema: z.object({
23
- serverId: z.string().describe('Configured MCP server id.'),
24
- toolName: z.string().describe('Exact MCP tool name from mcp_list_tools.'),
25
- args: z
26
- .record(z.string(), z.unknown())
27
- .default({})
28
- .describe('Tool arguments as a JSON object.'),
29
- }),
30
- },
31
- };
32
- const mcpPluginRuntime = () => (builder) => {
33
- builder.on('action:mcp_list_tools', async function* (event, context) {
34
- const serverId = event.data?.serverId;
35
- try {
36
- const tools = await mcpService.listTools(serverId);
37
- const toolNames = tools.map((tool) => `- ${tool.name}${tool.description ? `: ${tool.description}` : ''}`);
38
- yield {
39
- type: 'action:mcp_list_tools:result',
40
- data: { success: true, serverId, tools },
41
- meta: event.meta,
42
- };
43
- yield {
44
- type: 'agent:output',
45
- data: {
46
- content: toolNames.length > 0
47
- ? `MCP tools available on \`${serverId}\`:\n${toolNames.join('\n')}`
48
- : `MCP server \`${serverId}\` has no tools.`,
49
- },
50
- meta: { ...(event.meta || {}), agentId: context.state.agentId },
51
- };
52
- }
53
- catch (error) {
54
- const message = error instanceof Error ? error.message : 'Unknown MCP error';
55
- yield {
56
- type: 'action:mcp_list_tools:result',
57
- data: { success: false, serverId, tools: [], error: message },
58
- meta: event.meta,
59
- };
60
- yield {
61
- type: 'agent:output',
62
- data: { content: `Failed to list MCP tools for \`${serverId}\`: ${message}` },
63
- meta: { ...(event.meta || {}), agentId: context.state.agentId },
64
- };
65
- }
66
- });
67
- builder.on('action:mcp_call', async function* (event, context) {
68
- const data = event.data;
69
- const serverId = data?.serverId;
70
- const toolName = data?.toolName;
71
- const args = (data?.args || {});
72
- try {
73
- const result = await mcpService.callTool(serverId, toolName, args);
74
- const rendered = stringifyResult(result);
75
- yield {
76
- type: 'action:mcp_call:result',
77
- data: { success: true, serverId, toolName, result },
78
- meta: event.meta,
79
- };
80
- yield {
81
- type: 'agent:output',
82
- data: { content: `MCP \`${serverId}.${toolName}\` result:\n\n${rendered}` },
83
- meta: { ...(event.meta || {}), agentId: context.state.agentId },
84
- };
85
- }
86
- catch (error) {
87
- const message = error instanceof Error ? error.message : 'Unknown MCP error';
88
- yield {
89
- type: 'action:mcp_call:result',
90
- data: { success: false, serverId, toolName, error: message },
91
- meta: event.meta,
92
- };
93
- yield {
94
- type: 'agent:output',
95
- data: { content: `MCP call failed for \`${serverId}.${toolName}\`: ${message}` },
96
- meta: { ...(event.meta || {}), agentId: context.state.agentId },
97
- };
98
- }
99
- });
100
- };
101
- export const mcpPlugin = {
102
- id: 'mcp',
103
- name: 'MCP',
104
- description: 'Connect to Model Context Protocol servers and call their tools.',
105
- toolDefinitions: mcpToolDefinitions,
106
- factory: () => mcpPluginRuntime(),
107
- };
108
- export default mcpPlugin;
@@ -1,140 +0,0 @@
1
- import z from 'zod';
2
- import { mcpService } from '../harness/mcp.js';
3
- function stringifyResult(value) {
4
- if (typeof value === 'string') {
5
- return value;
6
- }
7
- try {
8
- return JSON.stringify(value, null, 2);
9
- }
10
- catch {
11
- return String(value);
12
- }
13
- }
14
- export const mcpToolDefinitions = {
15
- mcp_list_tools: {
16
- description: 'List available tools from a configured MCP server. Use this first before calling tools on an unknown server.',
17
- inputSchema: z.object({
18
- serverId: z.string().describe('Configured MCP server id (for example: github, notion, linear).'),
19
- }),
20
- },
21
- mcp_call: {
22
- description: 'Call a tool on a configured MCP server. Provide tool arguments as a JSON object. Use mcp_list_tools first when uncertain.',
23
- inputSchema: z.object({
24
- serverId: z.string().describe('Configured MCP server id.'),
25
- toolName: z.string().describe('Exact MCP tool name from mcp_list_tools.'),
26
- args: z.record(z.string(), z.unknown()).default({}).describe('Tool arguments as a JSON object.'),
27
- }),
28
- },
29
- };
30
- export const mcpPlugin = () => (builder) => {
31
- builder.on('action:mcp_list_tools', async function* (event, context) {
32
- const serverId = event.data?.serverId;
33
- try {
34
- const tools = await mcpService.listTools(serverId);
35
- const toolNames = tools.map((tool) => `- ${tool.name}${tool.description ? `: ${tool.description}` : ''}`);
36
- yield {
37
- type: 'action:mcp_list_tools:result',
38
- data: {
39
- success: true,
40
- serverId,
41
- tools,
42
- },
43
- meta: event.meta,
44
- };
45
- yield {
46
- type: 'agent:output',
47
- data: {
48
- content: toolNames.length > 0
49
- ? `MCP tools available on \`${serverId}\`:\n${toolNames.join('\n')}`
50
- : `MCP server \`${serverId}\` has no tools.`,
51
- },
52
- meta: {
53
- ...(event.meta || {}),
54
- agentId: context.state.agentId,
55
- },
56
- };
57
- }
58
- catch (error) {
59
- const message = error instanceof Error ? error.message : 'Unknown MCP error';
60
- yield {
61
- type: 'action:mcp_list_tools:result',
62
- data: {
63
- success: false,
64
- serverId,
65
- tools: [],
66
- error: message,
67
- },
68
- meta: event.meta,
69
- };
70
- yield {
71
- type: 'agent:output',
72
- data: {
73
- content: `Failed to list MCP tools for \`${serverId}\`: ${message}`,
74
- },
75
- meta: {
76
- ...(event.meta || {}),
77
- agentId: context.state.agentId,
78
- },
79
- };
80
- }
81
- });
82
- builder.on('action:mcp_call', async function* (event, context) {
83
- const serverId = event.data?.serverId;
84
- const toolName = event.data?.toolName;
85
- const args = (event.data?.args || {});
86
- try {
87
- const result = await mcpService.callTool(serverId, toolName, args);
88
- const rendered = stringifyResult(result);
89
- yield {
90
- type: 'action:mcp_call:result',
91
- data: {
92
- success: true,
93
- serverId,
94
- toolName,
95
- result,
96
- },
97
- meta: event.meta,
98
- };
99
- yield {
100
- type: 'agent:output',
101
- data: {
102
- content: `MCP \`${serverId}.${toolName}\` result:\n\n${rendered}`,
103
- },
104
- meta: {
105
- ...(event.meta || {}),
106
- agentId: context.state.agentId,
107
- },
108
- };
109
- }
110
- catch (error) {
111
- const message = error instanceof Error ? error.message : 'Unknown MCP error';
112
- yield {
113
- type: 'action:mcp_call:result',
114
- data: {
115
- success: false,
116
- serverId,
117
- toolName,
118
- error: message,
119
- },
120
- meta: event.meta,
121
- };
122
- yield {
123
- type: 'agent:output',
124
- data: {
125
- content: `MCP call failed for \`${serverId}.${toolName}\`: ${message}`,
126
- },
127
- meta: {
128
- ...(event.meta || {}),
129
- agentId: context.state.agentId,
130
- },
131
- };
132
- }
133
- });
134
- };
135
- export const plugin = {
136
- name: 'mcp',
137
- description: 'Basic MCP integration for configured servers',
138
- factory: mcpPlugin,
139
- toolDefinitions: mcpToolDefinitions,
140
- };
@@ -1,100 +0,0 @@
1
- import { z } from 'zod';
2
- import { spawn } from 'node:child_process';
3
- import { resolvePath } from '../../app/config.js';
4
- const shellToolDefinitions = {
5
- shell_exec: {
6
- description: 'Execute a shell command in the terminal. Use this for file operations, running scripts, or system tasks.',
7
- inputSchema: z.object({
8
- command: z.string().describe('The shell command to execute.'),
9
- cwd: z
10
- .string()
11
- .optional()
12
- .describe('Working directory. Defaults to the channel cwd or workspace root. Leave empty unless the user requests a specific directory.'),
13
- shell: z.enum(['bash', 'sh', 'zsh']).optional().describe('Shell to use. Defaults to bash.'),
14
- timeoutMs: z
15
- .number()
16
- .optional()
17
- .default(30000)
18
- .describe('Maximum execution time in milliseconds. Defaults to 30000 (30s).'),
19
- }),
20
- },
21
- };
22
- const shellPluginRuntime = () => (builder) => {
23
- builder.on('action:shell_exec', async function* (event, context) {
24
- const { command, cwd, shell = 'bash', timeoutMs = 30000 } = event.data;
25
- const actualTimeout = Math.max(1000, Math.min(timeoutMs, 60000));
26
- const actualCwd = resolvePath(cwd || context.state.channelDetails?.cwd || process.cwd());
27
- try {
28
- const result = await new Promise((resolve) => {
29
- const child = spawn(command, {
30
- shell,
31
- cwd: actualCwd,
32
- env: { ...process.env },
33
- });
34
- let stdout = '';
35
- let stderr = '';
36
- let timedOut = false;
37
- const timer = setTimeout(() => {
38
- timedOut = true;
39
- child.kill();
40
- }, actualTimeout);
41
- child.stdout.on('data', (data) => {
42
- stdout += data.toString();
43
- if (stdout.length > 100000) {
44
- stdout = stdout.substring(0, 100000) + '\n... [output truncated]';
45
- child.kill();
46
- }
47
- });
48
- child.stderr.on('data', (data) => {
49
- stderr += data.toString();
50
- if (stderr.length > 100000) {
51
- stderr = stderr.substring(0, 100000) + '\n... [output truncated]';
52
- }
53
- });
54
- child.on('close', (code) => {
55
- clearTimeout(timer);
56
- resolve({ exitCode: code, stdout, stderr, timedOut });
57
- });
58
- child.on('error', (err) => {
59
- clearTimeout(timer);
60
- resolve({ exitCode: -1, stdout, stderr: stderr + err.message, timedOut: false });
61
- });
62
- });
63
- const success = result.exitCode === 0 && !result.timedOut;
64
- yield {
65
- type: 'action:shell_exec:result',
66
- data: {
67
- success,
68
- exitCode: result.exitCode,
69
- stdout: result.stdout,
70
- stderr: result.stderr,
71
- timedOut: result.timedOut,
72
- },
73
- meta: event.meta,
74
- };
75
- }
76
- catch (error) {
77
- const message = error instanceof Error ? error.message : 'Unknown shell error';
78
- yield {
79
- type: 'action:shell_exec:result',
80
- data: {
81
- success: false,
82
- exitCode: -1,
83
- stdout: '',
84
- stderr: message,
85
- timedOut: false,
86
- error: message,
87
- },
88
- meta: event.meta,
89
- };
90
- }
91
- });
92
- };
93
- export const shellPlugin = {
94
- id: 'shell',
95
- name: 'Shell',
96
- description: 'Execute shell commands in the channel workspace.',
97
- toolDefinitions: shellToolDefinitions,
98
- factory: () => shellPluginRuntime(),
99
- };
100
- export default shellPlugin;
@@ -1,123 +0,0 @@
1
- import { z } from 'zod';
2
- import { spawn } from 'node:child_process';
3
- export const shellToolDefinitions = {
4
- shell_exec: {
5
- description: 'Execute a shell command in the terminal. Use this for file operations, running scripts, or system tasks.',
6
- inputSchema: z.object({
7
- command: z.string().describe('The shell command to execute.'),
8
- cwd: z.string().optional().describe('The working directory for the command. Defaults to the channel cwd or workspace root. Leave it empty unless user asks for a specific directory.'),
9
- shell: z.enum(['bash', 'sh', 'zsh']).optional().describe('The shell to use. Defaults to bash.'),
10
- timeoutMs: z.number().optional().default(30000).describe('Maximum execution time in milliseconds. Defaults to 30000 (30s).'),
11
- }),
12
- },
13
- };
14
- export const shellPlugin = () => (builder) => {
15
- builder.on('action:shell_exec', async function* (event, context) {
16
- const { command, cwd, shell = 'bash', timeoutMs = 30000 } = event.data;
17
- // Clamp timeout between 1s and 60s
18
- const actualTimeout = Math.max(1000, Math.min(timeoutMs, 60000));
19
- // Default CWD to channel CWD if not provided
20
- const actualCwd = cwd || context.state.channelDetails?.cwd || process.cwd();
21
- try {
22
- const result = await new Promise((resolve) => {
23
- const child = spawn(command, {
24
- shell,
25
- cwd: actualCwd,
26
- env: { ...process.env },
27
- });
28
- let stdout = '';
29
- let stderr = '';
30
- let timedOut = false;
31
- const timer = setTimeout(() => {
32
- timedOut = true;
33
- child.kill();
34
- }, actualTimeout);
35
- child.stdout.on('data', (data) => {
36
- stdout += data.toString();
37
- // Cap output at 100KB
38
- if (stdout.length > 100000) {
39
- stdout = stdout.substring(0, 100000) + '\n... [output truncated]';
40
- child.kill();
41
- }
42
- });
43
- child.stderr.on('data', (data) => {
44
- stderr += data.toString();
45
- if (stderr.length > 100000) {
46
- stderr = stderr.substring(0, 100000) + '\n... [output truncated]';
47
- }
48
- });
49
- child.on('close', (code) => {
50
- clearTimeout(timer);
51
- resolve({ exitCode: code, stdout, stderr, timedOut });
52
- });
53
- child.on('error', (err) => {
54
- clearTimeout(timer);
55
- resolve({ exitCode: -1, stdout, stderr: stderr + err.message, timedOut: false });
56
- });
57
- });
58
- const success = result.exitCode === 0 && !result.timedOut;
59
- yield {
60
- type: 'action:shell_exec:result',
61
- data: {
62
- success,
63
- exitCode: result.exitCode,
64
- stdout: result.stdout,
65
- stderr: result.stderr,
66
- timedOut: result.timedOut,
67
- },
68
- meta: event.meta,
69
- };
70
- // const output = [
71
- // `Command: \`${command}\``,
72
- // result.exitCode !== null ? `Exit code: ${result.exitCode}` : 'Exit code: unknown',
73
- // result.timedOut ? '⚠️ Command timed out.' : '',
74
- // result.stdout ? `\n**STDOUT**:\n${result.stdout}` : '',
75
- // result.stderr ? `\n**STDERR**:\n${result.stderr}` : '',
76
- // ].filter(Boolean).join('\n');
77
- // yield {
78
- // type: 'agent:output',
79
- // data: {
80
- // content: output,
81
- // },
82
- // meta: {
83
- // ...(event.meta || {}),
84
- // agentId: context.state.agentId,
85
- // },
86
- // } as any;
87
- }
88
- catch (error) {
89
- const message = error instanceof Error ? error.message : 'Unknown shell error';
90
- yield {
91
- type: 'action:shell_exec:result',
92
- data: {
93
- success: false,
94
- exitCode: -1,
95
- stdout: '',
96
- stderr: message,
97
- timedOut: false,
98
- error: message,
99
- },
100
- meta: event.meta,
101
- };
102
- // yield {
103
- // type: 'agent:output',
104
- // data: {
105
- // content: `Failed to execute shell command: ${message}`,
106
- // },
107
- // meta: {
108
- // ...(event.meta || {}),
109
- // agentId: context.state.agentId,
110
- // },
111
- // } as any;
112
- }
113
- });
114
- };
115
- export const plugin = {
116
- name: 'shell',
117
- description: 'Execute shell commands in the terminal',
118
- version: '1.0.0',
119
- author: 'OpenBot',
120
- license: 'MIT',
121
- factory: shellPlugin,
122
- toolDefinitions: shellToolDefinitions,
123
- };
@@ -1,76 +0,0 @@
1
- import z from 'zod';
2
- /**
3
- * `storage-tools` — exposes channel/thread/variable mutation tools to runtime
4
- * plugins. The actual handlers live in `bus/services.ts` because storage is
5
- * platform infrastructure, not agent behaviour.
6
- */
7
- const storageToolDefinitions = {
8
- create_channel: {
9
- description: 'Create a new channel. Use when the user intent is clearly different from the current channel and should be split. Always confirm before creating. Skip for simple Q&A.',
10
- inputSchema: z.object({
11
- channelId: z
12
- .string()
13
- .describe('Unique channel ID (e.g. product-launch, backend-platform, channel_roadmap).'),
14
- spec: z
15
- .string()
16
- .optional()
17
- .describe('Optional initial markdown content for the channel spec.'),
18
- initialState: z
19
- .record(z.string(), z.unknown())
20
- .optional()
21
- .describe('Optional initial state object for the channel.'),
22
- cwd: z
23
- .string()
24
- .optional()
25
- .describe('Optional initial current working directory for the channel.'),
26
- }),
27
- },
28
- patch_channel_details: {
29
- description: 'Patch current channel details (state, spec, cwd).',
30
- inputSchema: z
31
- .object({
32
- state: z
33
- .record(z.string(), z.unknown())
34
- .optional()
35
- .describe('JSON state object for the channel. Use for structured metadata.'),
36
- spec: z
37
- .string()
38
- .optional()
39
- .describe('Markdown content for the channel specification (SPEC.md). Use for goals and rules.'),
40
- cwd: z.string().optional().describe('Current working directory for the channel.'),
41
- })
42
- .refine((value) => value.state !== undefined || value.spec !== undefined || value.cwd !== undefined, { message: 'Provide at least one of state, spec, or cwd.' }),
43
- },
44
- patch_thread_details: {
45
- description: 'Patch current thread details (state).',
46
- inputSchema: z.object({
47
- state: z
48
- .record(z.string(), z.unknown())
49
- .describe('JSON state object for the thread. Use for structured progress or metadata.'),
50
- }),
51
- },
52
- create_variable: {
53
- description: 'Create or update a variable in the workspace storage.',
54
- inputSchema: z.object({
55
- key: z.string().describe('The key of the variable.'),
56
- value: z.string().describe('The value of the variable.'),
57
- secret: z.boolean().optional().describe('Whether the variable is a secret.'),
58
- }),
59
- },
60
- delete_variable: {
61
- description: 'Delete a variable from the workspace storage.',
62
- inputSchema: z.object({
63
- key: z.string().describe('The key of the variable to delete.'),
64
- }),
65
- },
66
- };
67
- export const storageToolsPlugin = {
68
- id: 'storage-tools',
69
- name: 'Storage Tools',
70
- description: 'Tools for creating channels, patching state, and managing workspace variables.',
71
- toolDefinitions: storageToolDefinitions,
72
- factory: () => () => {
73
- // Handlers live in bus/services.ts; this plugin only contributes tool definitions.
74
- },
75
- };
76
- export default storageToolsPlugin;