@accomplish_ai/agent-core 0.2.0 → 0.2.2

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 (78) hide show
  1. package/README.md +141 -0
  2. package/dist/common/constants.d.ts +1 -1
  3. package/dist/common/constants.d.ts.map +1 -1
  4. package/dist/common/constants.js +1 -1
  5. package/dist/common/constants.js.map +1 -1
  6. package/dist/common/types/index.d.ts +14 -10
  7. package/dist/common/types/index.d.ts.map +1 -1
  8. package/dist/common/types/index.js +4 -10
  9. package/dist/common/types/index.js.map +1 -1
  10. package/dist/common/utils/index.d.ts +3 -3
  11. package/dist/common/utils/index.d.ts.map +1 -1
  12. package/dist/common/utils/index.js +3 -3
  13. package/dist/common/utils/index.js.map +1 -1
  14. package/dist/factories/speech.d.ts.map +1 -1
  15. package/dist/factories/speech.js.map +1 -1
  16. package/dist/index.d.ts +1 -6
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +8 -20
  19. package/dist/index.js.map +1 -1
  20. package/dist/internal/classes/SecureStorage.d.ts.map +1 -1
  21. package/dist/internal/classes/SecureStorage.js +3 -0
  22. package/dist/internal/classes/SecureStorage.js.map +1 -1
  23. package/dist/internal/classes/TaskManager.d.ts +3 -2
  24. package/dist/internal/classes/TaskManager.d.ts.map +1 -1
  25. package/dist/internal/classes/TaskManager.js +34 -1
  26. package/dist/internal/classes/TaskManager.js.map +1 -1
  27. package/dist/storage/index.d.ts +4 -1
  28. package/dist/storage/index.d.ts.map +1 -1
  29. package/dist/storage/index.js +4 -1
  30. package/dist/storage/index.js.map +1 -1
  31. package/dist/types/log-writer.d.ts +2 -15
  32. package/dist/types/log-writer.d.ts.map +1 -1
  33. package/dist/types/skills-manager.d.ts +13 -0
  34. package/dist/types/skills-manager.d.ts.map +1 -1
  35. package/dist/types/speech.d.ts +3 -2
  36. package/dist/types/speech.d.ts.map +1 -1
  37. package/dist/types/storage.d.ts +70 -0
  38. package/dist/types/storage.d.ts.map +1 -1
  39. package/dist/types/task-manager.d.ts +13 -3
  40. package/dist/types/task-manager.d.ts.map +1 -1
  41. package/dist/types.d.ts +0 -17
  42. package/dist/types.d.ts.map +1 -1
  43. package/dist/utils/index.d.ts +16 -13
  44. package/dist/utils/index.d.ts.map +1 -1
  45. package/dist/utils/index.js +13 -13
  46. package/dist/utils/index.js.map +1 -1
  47. package/mcp-tools/dev-browser/server.cjs +144 -0
  48. package/package.json +16 -3
  49. package/mcp-tools/ask-user-question/src/index.ts +0 -183
  50. package/mcp-tools/ask-user-question/tsconfig.json +0 -12
  51. package/mcp-tools/complete-task/src/index.ts +0 -92
  52. package/mcp-tools/dev-browser/src/index.ts +0 -290
  53. package/mcp-tools/dev-browser/src/relay.ts +0 -652
  54. package/mcp-tools/dev-browser/src/types.ts +0 -31
  55. package/mcp-tools/dev-browser/tsconfig.json +0 -36
  56. package/mcp-tools/dev-browser-mcp/src/index.ts +0 -3940
  57. package/mcp-tools/dev-browser-mcp/src/snapshot/compactor.test.ts +0 -86
  58. package/mcp-tools/dev-browser-mcp/src/snapshot/compactor.ts +0 -31
  59. package/mcp-tools/dev-browser-mcp/src/snapshot/differ.test.ts +0 -178
  60. package/mcp-tools/dev-browser-mcp/src/snapshot/differ.ts +0 -167
  61. package/mcp-tools/dev-browser-mcp/src/snapshot/index.ts +0 -19
  62. package/mcp-tools/dev-browser-mcp/src/snapshot/manager.test.ts +0 -247
  63. package/mcp-tools/dev-browser-mcp/src/snapshot/manager.ts +0 -131
  64. package/mcp-tools/dev-browser-mcp/src/snapshot/parser.test.ts +0 -94
  65. package/mcp-tools/dev-browser-mcp/src/snapshot/parser.ts +0 -81
  66. package/mcp-tools/dev-browser-mcp/src/snapshot/priority.test.ts +0 -104
  67. package/mcp-tools/dev-browser-mcp/src/snapshot/priority.ts +0 -84
  68. package/mcp-tools/dev-browser-mcp/src/snapshot/tokens.test.ts +0 -64
  69. package/mcp-tools/dev-browser-mcp/src/snapshot/tokens.ts +0 -36
  70. package/mcp-tools/dev-browser-mcp/src/snapshot/types.ts +0 -89
  71. package/mcp-tools/dev-browser-mcp/tsconfig.json +0 -15
  72. package/mcp-tools/file-permission/src/index.ts +0 -125
  73. package/mcp-tools/file-permission/tsconfig.json +0 -17
  74. package/mcp-tools/report-checkpoint/src/index.ts +0 -127
  75. package/mcp-tools/report-checkpoint/tsconfig.json +0 -12
  76. package/mcp-tools/report-thought/src/index.ts +0 -109
  77. package/mcp-tools/report-thought/tsconfig.json +0 -12
  78. package/mcp-tools/start-task/src/index.ts +0 -86
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Cross-platform dev-browser server launcher.
4
+ * Replaces server.sh for Windows compatibility.
5
+ *
6
+ * This script uses the local tsx binary directly instead of npx to avoid
7
+ * issues with path resolution when running from the packaged Electron app.
8
+ */
9
+ const { spawn } = require('child_process');
10
+ const path = require('path');
11
+ const fs = require('fs');
12
+
13
+ const skillDir = __dirname;
14
+ const isWindows = process.platform === 'win32';
15
+
16
+ // Parse command line arguments
17
+ const headless = process.argv.includes('--headless');
18
+
19
+ // Logging helper - logs to stderr so it doesn't interfere with stdio inheritance
20
+ function log(...args) {
21
+ const timestamp = new Date().toISOString();
22
+ console.error(`[dev-browser server.cjs ${timestamp}]`, ...args);
23
+ }
24
+
25
+ log('Starting dev-browser server launcher...');
26
+ log(' skillDir:', skillDir);
27
+ log(' isWindows:', isWindows);
28
+ log(' headless:', headless);
29
+ log(' NODE_BIN_PATH:', process.env.NODE_BIN_PATH || '(not set)');
30
+ log(' PATH (first 500 chars):', (process.env.PATH || '').substring(0, 500));
31
+
32
+ // Find the node executable
33
+ let nodeExe = 'node';
34
+ if (process.env.NODE_BIN_PATH) {
35
+ const bundledNode = path.join(process.env.NODE_BIN_PATH, isWindows ? 'node.exe' : 'node');
36
+ if (fs.existsSync(bundledNode)) {
37
+ nodeExe = bundledNode;
38
+ log(' Using bundled node:', nodeExe);
39
+ } else {
40
+ log(' Bundled node not found at:', bundledNode, '- falling back to system node');
41
+ }
42
+ } else {
43
+ log(' Using system node');
44
+ }
45
+
46
+ // Prefer bundled server if present (no tsx needed)
47
+ const bundledServer = path.join(skillDir, 'dist', 'start-server.mjs');
48
+
49
+ let tsxCommand;
50
+ let tsxArgs;
51
+
52
+ if (fs.existsSync(bundledServer)) {
53
+ tsxCommand = nodeExe;
54
+ tsxArgs = [bundledServer];
55
+ log(' Using bundled server:', bundledServer);
56
+ } else {
57
+ // Find tsx - on Windows, ALWAYS prefer cli.mjs over tsx.cmd to avoid shell quoting issues
58
+ // with paths containing spaces (e.g., "C:\\Program Files\\...")
59
+ const localTsxJs = path.join(skillDir, 'node_modules', 'tsx', 'dist', 'cli.mjs');
60
+ const localTsxBin = path.join(skillDir, 'node_modules', '.bin', isWindows ? 'tsx.cmd' : 'tsx');
61
+
62
+ // On Windows: prefer cli.mjs (run via node.exe, no shell needed, no path quoting issues)
63
+ // On Unix: prefer the tsx binary (simpler)
64
+ if (isWindows && fs.existsSync(localTsxJs)) {
65
+ // Windows: run tsx via node directly to avoid shell quoting issues with spaces in paths
66
+ tsxCommand = nodeExe;
67
+ tsxArgs = [localTsxJs, path.join('scripts', 'start-server.ts')];
68
+ log(' Using tsx via node (Windows):', localTsxJs);
69
+ } else if (!isWindows && fs.existsSync(localTsxBin)) {
70
+ // Unix: use tsx binary directly
71
+ tsxCommand = localTsxBin;
72
+ tsxArgs = [path.join('scripts', 'start-server.ts')];
73
+ log(' Using local tsx binary (Unix):', localTsxBin);
74
+ } else if (fs.existsSync(localTsxJs)) {
75
+ // Fallback for any platform: run tsx via node directly
76
+ tsxCommand = nodeExe;
77
+ tsxArgs = [localTsxJs, path.join('scripts', 'start-server.ts')];
78
+ log(' Using tsx via node (fallback):', localTsxJs);
79
+ } else if (fs.existsSync(localTsxBin)) {
80
+ // Fallback: try tsx binary even on Windows (may have issues with spaces)
81
+ tsxCommand = localTsxBin;
82
+ tsxArgs = [path.join('scripts', 'start-server.ts')];
83
+ log(' Using local tsx binary (fallback):', localTsxBin);
84
+ } else {
85
+ // Last resort: try npx (may fail with path issues)
86
+ log(' WARNING: Local tsx not found, falling back to npx');
87
+ log(' Checked:', localTsxJs);
88
+ log(' Checked:', localTsxBin);
89
+
90
+ let npxCommand = isWindows ? 'npx.cmd' : 'npx';
91
+ if (process.env.NODE_BIN_PATH) {
92
+ npxCommand = path.join(process.env.NODE_BIN_PATH, isWindows ? 'npx.cmd' : 'npx');
93
+ }
94
+ tsxCommand = npxCommand;
95
+ tsxArgs = ['tsx', path.join('scripts', 'start-server.ts')];
96
+ log(' Using npx:', npxCommand);
97
+ }
98
+ }
99
+
100
+ // Build environment
101
+ const env = { ...process.env };
102
+ if (headless) {
103
+ env.HEADLESS = 'true';
104
+ }
105
+
106
+ log('Spawning:', tsxCommand, tsxArgs.join(' '));
107
+ log(' cwd:', skillDir);
108
+
109
+ // Spawn options
110
+ const spawnOptions = {
111
+ cwd: skillDir,
112
+ stdio: 'inherit',
113
+ env,
114
+ windowsHide: true,
115
+ };
116
+
117
+ // On Windows, .cmd batch files REQUIRE shell: true to execute.
118
+ // When running node directly (with cli.mjs), we can use shell: false.
119
+ const isCmdFile = isWindows && tsxCommand.endsWith('.cmd');
120
+ if (isCmdFile) {
121
+ spawnOptions.shell = true;
122
+ log(' shell: true (Windows .cmd file)');
123
+ } else {
124
+ // For node direct execution (cli.mjs) or Unix, shell is not needed
125
+ spawnOptions.shell = false;
126
+ log(' shell: false (direct executable)');
127
+ }
128
+
129
+ const child = spawn(tsxCommand, tsxArgs, spawnOptions);
130
+
131
+ child.on('error', (err) => {
132
+ log('ERROR: Failed to spawn:', err.message);
133
+ log(' Command:', tsxCommand);
134
+ log(' Args:', tsxArgs);
135
+ log(' Error code:', err.code);
136
+ process.exit(1);
137
+ });
138
+
139
+ child.on('close', (code, signal) => {
140
+ log('Process exited with code:', code, 'signal:', signal);
141
+ process.exit(code || 0);
142
+ });
143
+
144
+ log('Spawn initiated, waiting for process...');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@accomplish_ai/agent-core",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Core logic for Accomplish - OpenCode adapter, storage, providers, MCP tools, and skills",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -9,6 +9,19 @@
9
9
  "url": "https://github.com/accomplish-ai/accomplish.git",
10
10
  "directory": "packages/agent-core"
11
11
  },
12
+ "homepage": "https://github.com/accomplish-ai/accomplish/tree/main/packages/agent-core#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/accomplish-ai/accomplish/issues"
15
+ },
16
+ "keywords": [
17
+ "automation",
18
+ "agent",
19
+ "opencode",
20
+ "task-manager",
21
+ "mcp",
22
+ "ai",
23
+ "electron"
24
+ ],
12
25
  "publishConfig": {
13
26
  "name": "@accomplish_ai/agent-core",
14
27
  "access": "public"
@@ -16,6 +29,7 @@
16
29
  "sideEffects": false,
17
30
  "main": "./dist/index.js",
18
31
  "types": "./dist/index.d.ts",
32
+ "module": "./dist/index.js",
19
33
  "exports": {
20
34
  ".": {
21
35
  "types": "./dist/index.d.ts",
@@ -30,10 +44,9 @@
30
44
  },
31
45
  "files": [
32
46
  "dist",
33
- "mcp-tools/*/src",
34
47
  "mcp-tools/*/dist",
35
48
  "mcp-tools/*/package.json",
36
- "mcp-tools/*/tsconfig.json",
49
+ "mcp-tools/*/*.cjs",
37
50
  "mcp-tools/*/*.md",
38
51
  "mcp-tools/package.json"
39
52
  ],
@@ -1,183 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import {
5
- CallToolRequestSchema,
6
- ListToolsRequestSchema,
7
- type CallToolResult,
8
- } from '@modelcontextprotocol/sdk/types.js';
9
-
10
- const QUESTION_API_PORT = process.env.QUESTION_API_PORT || '9227';
11
- const QUESTION_API_URL = `http://localhost:${QUESTION_API_PORT}/question`;
12
-
13
- interface QuestionOption {
14
- label: string;
15
- description?: string;
16
- }
17
-
18
- interface AskUserQuestionInput {
19
- questions: Array<{
20
- question: string;
21
- header?: string;
22
- options?: QuestionOption[];
23
- multiSelect?: boolean;
24
- }>;
25
- }
26
-
27
- const server = new Server(
28
- { name: 'ask-user-question', version: '1.0.0' },
29
- { capabilities: { tools: {} } }
30
- );
31
-
32
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
33
- tools: [
34
- {
35
- name: 'AskUserQuestion',
36
- description:
37
- 'Ask the user a question and wait for their response. Use this for clarifications, confirmations before sensitive actions, or when you need user input to proceed. Returns the user\'s selected option(s) or custom text response.',
38
- inputSchema: {
39
- type: 'object',
40
- properties: {
41
- questions: {
42
- type: 'array',
43
- description: 'Array of questions to ask (typically just one)',
44
- items: {
45
- type: 'object',
46
- properties: {
47
- question: {
48
- type: 'string',
49
- description: 'The question to ask the user',
50
- },
51
- header: {
52
- type: 'string',
53
- description: 'Short header/category for the question (max 12 chars)',
54
- },
55
- options: {
56
- type: 'array',
57
- description: 'Available choices for the user (2-4 options)',
58
- items: {
59
- type: 'object',
60
- properties: {
61
- label: {
62
- type: 'string',
63
- description: 'Display text for this option',
64
- },
65
- description: {
66
- type: 'string',
67
- description: 'Explanation of what this option means',
68
- },
69
- },
70
- required: ['label'],
71
- },
72
- },
73
- multiSelect: {
74
- type: 'boolean',
75
- description: 'Allow selecting multiple options',
76
- default: false,
77
- },
78
- },
79
- required: ['question'],
80
- },
81
- minItems: 1,
82
- maxItems: 4,
83
- },
84
- },
85
- required: ['questions'],
86
- },
87
- },
88
- ],
89
- }));
90
-
91
- server.setRequestHandler(CallToolRequestSchema, async (request): Promise<CallToolResult> => {
92
- if (request.params.name !== 'AskUserQuestion') {
93
- return {
94
- content: [{ type: 'text', text: `Error: Unknown tool: ${request.params.name}` }],
95
- isError: true,
96
- };
97
- }
98
-
99
- const args = request.params.arguments as AskUserQuestionInput;
100
- const { questions } = args;
101
-
102
- if (!questions || questions.length === 0) {
103
- return {
104
- content: [{ type: 'text', text: 'Error: At least one question is required' }],
105
- isError: true,
106
- };
107
- }
108
-
109
- const question = questions[0];
110
- if (!question.question) {
111
- return {
112
- content: [{ type: 'text', text: 'Error: Question text is required' }],
113
- isError: true,
114
- };
115
- }
116
-
117
- try {
118
- const response = await fetch(QUESTION_API_URL, {
119
- method: 'POST',
120
- headers: { 'Content-Type': 'application/json' },
121
- body: JSON.stringify({
122
- question: question.question,
123
- header: question.header,
124
- options: question.options,
125
- multiSelect: question.multiSelect,
126
- }),
127
- });
128
-
129
- if (!response.ok) {
130
- const errorText = await response.text();
131
- return {
132
- content: [{ type: 'text', text: `Error: Question API returned ${response.status}: ${errorText}` }],
133
- isError: true,
134
- };
135
- }
136
-
137
- const result = (await response.json()) as {
138
- answered: boolean;
139
- selectedOptions?: string[];
140
- customText?: string;
141
- denied?: boolean;
142
- };
143
-
144
- if (result.denied) {
145
- return {
146
- content: [{ type: 'text', text: 'User declined to answer the question.' }],
147
- };
148
- }
149
-
150
- if (result.selectedOptions && result.selectedOptions.length > 0) {
151
- return {
152
- content: [{ type: 'text', text: `User selected: ${result.selectedOptions.join(', ')}` }],
153
- };
154
- }
155
-
156
- if (result.customText) {
157
- return {
158
- content: [{ type: 'text', text: `User responded: ${result.customText}` }],
159
- };
160
- }
161
-
162
- return {
163
- content: [{ type: 'text', text: 'User provided no response.' }],
164
- };
165
- } catch (error) {
166
- const errorMessage = error instanceof Error ? error.message : String(error);
167
- return {
168
- content: [{ type: 'text', text: `Error: Failed to ask question: ${errorMessage}` }],
169
- isError: true,
170
- };
171
- }
172
- });
173
-
174
- async function main() {
175
- const transport = new StdioServerTransport();
176
- await server.connect(transport);
177
- console.error('AskUserQuestion MCP Server started');
178
- }
179
-
180
- main().catch((error) => {
181
- console.error('Failed to start server:', error);
182
- process.exit(1);
183
- });
@@ -1,12 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "esModuleInterop": true,
7
- "strict": true,
8
- "skipLibCheck": true,
9
- "outDir": "dist"
10
- },
11
- "include": ["src/**/*"]
12
- }
@@ -1,92 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import {
5
- CallToolRequestSchema,
6
- ListToolsRequestSchema,
7
- } from '@modelcontextprotocol/sdk/types.js';
8
-
9
- const server = new Server(
10
- { name: 'complete-task', version: '1.0.0' },
11
- { capabilities: { tools: {} } }
12
- );
13
-
14
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
15
- tools: [
16
- {
17
- name: 'complete_task',
18
- description:
19
- 'Call this tool when you have finished the task or cannot continue. You MUST call this tool to end a task - do not stop without calling it.',
20
- inputSchema: {
21
- type: 'object',
22
- required: ['status', 'summary', 'original_request_summary'],
23
- properties: {
24
- status: {
25
- type: 'string',
26
- enum: ['success', 'blocked', 'partial'],
27
- description:
28
- 'success = fully completed, blocked = cannot continue, partial = completed some but not all',
29
- },
30
- original_request_summary: {
31
- type: 'string',
32
- description: 'Briefly restate what the user originally asked for',
33
- },
34
- summary: {
35
- type: 'string',
36
- description: 'What you accomplished. Be specific about each part.',
37
- },
38
- remaining_work: {
39
- type: 'string',
40
- description:
41
- 'If blocked or partial, describe what remains and why you could not complete it',
42
- },
43
- },
44
- },
45
- },
46
- ],
47
- }));
48
-
49
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
50
- if (request.params.name !== 'complete_task') {
51
- throw new Error(`Unknown tool: ${request.params.name}`);
52
- }
53
-
54
- const { status, summary, original_request_summary, remaining_work } =
55
- request.params.arguments as {
56
- status: 'success' | 'blocked' | 'partial';
57
- summary: string;
58
- original_request_summary: string;
59
- remaining_work?: string;
60
- };
61
-
62
- console.error(`[complete-task] status=${status}`);
63
- console.error(`[complete-task] original_request=${original_request_summary}`);
64
- console.error(`[complete-task] summary=${summary}`);
65
- if (remaining_work) {
66
- console.error(`[complete-task] remaining=${remaining_work}`);
67
- }
68
-
69
- let responseText = `Task ${status}.`;
70
- if (status === 'success') {
71
- responseText = `Task completed successfully.`;
72
- } else if (status === 'blocked') {
73
- responseText = `Task blocked. Remaining work: ${remaining_work || 'not specified'}`;
74
- } else if (status === 'partial') {
75
- responseText = `Task partially completed. Remaining work: ${remaining_work || 'not specified'}`;
76
- }
77
-
78
- return {
79
- content: [{ type: 'text', text: responseText }],
80
- };
81
- });
82
-
83
- async function main() {
84
- const transport = new StdioServerTransport();
85
- await server.connect(transport);
86
- console.error('[complete-task] MCP server running');
87
- }
88
-
89
- main().catch((error) => {
90
- console.error('[complete-task] Fatal error:', error);
91
- process.exit(1);
92
- });