@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
@@ -1,84 +0,0 @@
1
- export interface TruncatableElement {
2
- ref: string;
3
- role: string;
4
- name: string;
5
- inViewport: boolean;
6
- [key: string]: unknown;
7
- }
8
-
9
- export interface TruncateOptions {
10
- maxElements?: number;
11
- }
12
-
13
- export interface TruncateResult<T extends TruncatableElement> {
14
- elements: T[];
15
- totalElements: number;
16
- includedElements: number;
17
- truncated: boolean;
18
- }
19
-
20
- export const ROLE_PRIORITIES: Record<string, number> = {
21
- button: 100,
22
- textbox: 95,
23
- searchbox: 95,
24
- checkbox: 90,
25
- radio: 90,
26
- switch: 90,
27
- combobox: 85,
28
- listbox: 85,
29
- slider: 85,
30
- spinbutton: 85,
31
- link: 80,
32
- tab: 75,
33
- menuitem: 70,
34
- menuitemcheckbox: 70,
35
- menuitemradio: 70,
36
- option: 70,
37
- navigation: 60,
38
- menu: 60,
39
- tablist: 55,
40
- form: 50,
41
- dialog: 50,
42
- alertdialog: 50,
43
- };
44
-
45
- const VIEWPORT_BONUS = 50;
46
- const DEFAULT_PRIORITY = 50;
47
-
48
- export function getElementPriority(role: string, inViewport: boolean): number {
49
- const basePriority = ROLE_PRIORITIES[role] ?? DEFAULT_PRIORITY;
50
- return inViewport ? basePriority + VIEWPORT_BONUS : basePriority;
51
- }
52
-
53
- export function truncateElements<T extends TruncatableElement>(
54
- elements: T[],
55
- options: TruncateOptions
56
- ): TruncateResult<T> {
57
- const maxElements = options.maxElements ?? 300;
58
- const totalElements = elements.length;
59
-
60
- if (totalElements <= maxElements) {
61
- return {
62
- elements,
63
- totalElements,
64
- includedElements: totalElements,
65
- truncated: false,
66
- };
67
- }
68
-
69
- const scored = elements.map(element => ({
70
- element,
71
- score: getElementPriority(element.role, element.inViewport),
72
- }));
73
-
74
- scored.sort((a, b) => b.score - a.score);
75
-
76
- const truncatedElements = scored.slice(0, maxElements).map(s => s.element);
77
-
78
- return {
79
- elements: truncatedElements,
80
- totalElements,
81
- includedElements: maxElements,
82
- truncated: true,
83
- };
84
- }
@@ -1,64 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { estimateTokens, estimateElementTokens } from './tokens';
3
-
4
- describe('token estimation', () => {
5
- describe('estimateElementTokens', () => {
6
- it('should estimate basic element at ~15 tokens', () => {
7
- const tokens = estimateElementTokens({
8
- role: 'button',
9
- name: 'Submit',
10
- ref: 'e1',
11
- });
12
- // role (1) + name (2) + ref (2) + yaml overhead (5) + attributes (2-5)
13
- expect(tokens).toBeGreaterThanOrEqual(10);
14
- expect(tokens).toBeLessThanOrEqual(20);
15
- });
16
-
17
- it('should cap long names at 50 token contribution', () => {
18
- const shortName = estimateElementTokens({
19
- role: 'button',
20
- name: 'OK',
21
- ref: 'e1',
22
- });
23
- const longName = estimateElementTokens({
24
- role: 'button',
25
- name: 'A'.repeat(1000), // Very long name
26
- ref: 'e2',
27
- });
28
- // Difference should be at most 50 (capped)
29
- expect(longName - shortName).toBeLessThanOrEqual(50);
30
- });
31
-
32
- it('should add tokens for extra attributes', () => {
33
- const basic = estimateElementTokens({
34
- role: 'checkbox',
35
- name: 'Accept',
36
- ref: 'e1',
37
- });
38
- const withAttrs = estimateElementTokens({
39
- role: 'checkbox',
40
- name: 'Accept',
41
- ref: 'e1',
42
- checked: true,
43
- disabled: true,
44
- });
45
- expect(withAttrs).toBeGreaterThan(basic);
46
- });
47
- });
48
-
49
- describe('estimateTokens', () => {
50
- it('should estimate YAML string tokens', () => {
51
- const yaml = `- button "Submit" [ref=e1]
52
- - textbox "Email" [ref=e2]
53
- - link "Home" [ref=e3]`;
54
- const tokens = estimateTokens(yaml);
55
- // ~15 tokens per element * 3 = ~45
56
- expect(tokens).toBeGreaterThanOrEqual(30);
57
- expect(tokens).toBeLessThanOrEqual(60);
58
- });
59
-
60
- it('should handle empty string', () => {
61
- expect(estimateTokens('')).toBe(0);
62
- });
63
- });
64
- });
@@ -1,36 +0,0 @@
1
- import type { SnapshotElement } from './types';
2
-
3
- const CHARS_PER_TOKEN = 2;
4
- const YAML_OVERHEAD = 5;
5
- const ATTRIBUTE_TOKENS = 2;
6
- const MAX_NAME_TOKENS = 50;
7
-
8
- export function estimateElementTokens(element: Partial<SnapshotElement>): number {
9
- let tokens = YAML_OVERHEAD;
10
-
11
- tokens += Math.ceil((element.role?.length ?? 0) / CHARS_PER_TOKEN);
12
-
13
- const nameLength = element.name?.length ?? 0;
14
- const nameTokens = Math.ceil(nameLength / CHARS_PER_TOKEN);
15
- tokens += Math.min(nameTokens, MAX_NAME_TOKENS);
16
-
17
- tokens += 2;
18
-
19
- if (element.checked !== undefined) tokens += ATTRIBUTE_TOKENS;
20
- if (element.disabled !== undefined) tokens += ATTRIBUTE_TOKENS;
21
- if (element.expanded !== undefined) tokens += ATTRIBUTE_TOKENS;
22
- if (element.selected !== undefined) tokens += ATTRIBUTE_TOKENS;
23
- if (element.pressed !== undefined) tokens += ATTRIBUTE_TOKENS;
24
-
25
- if (element.value) {
26
- const valueTokens = Math.ceil(element.value.length / CHARS_PER_TOKEN);
27
- tokens += Math.min(valueTokens, MAX_NAME_TOKENS);
28
- }
29
-
30
- return tokens;
31
- }
32
-
33
- export function estimateTokens(yaml: string): number {
34
- if (!yaml) return 0;
35
- return Math.ceil(yaml.length / CHARS_PER_TOKEN);
36
- }
@@ -1,89 +0,0 @@
1
- export interface SnapshotElement {
2
- ref: string;
3
- role: string;
4
- name: string;
5
- value?: string;
6
- checked?: boolean | 'mixed';
7
- disabled?: boolean;
8
- expanded?: boolean;
9
- selected?: boolean;
10
- level?: number;
11
- pressed?: boolean | 'mixed';
12
- url?: string;
13
- placeholder?: string;
14
- }
15
-
16
- export interface ElementPriority {
17
- ref: string;
18
- score: number;
19
- inViewport: boolean;
20
- }
21
-
22
- export interface SnapshotMetadata {
23
- totalElements: number;
24
- includedElements: number;
25
- truncated: boolean;
26
- estimatedTokens: number;
27
- }
28
-
29
- export interface ParsedSnapshot {
30
- url: string;
31
- title: string;
32
- timestamp: number;
33
- elements: Map<string, SnapshotElement>;
34
- rawYaml: string;
35
- metadata?: SnapshotMetadata;
36
- }
37
-
38
- export interface SnapshotOptions {
39
- fullSnapshot?: boolean;
40
- interactiveOnly?: boolean;
41
- maxElements?: number;
42
- viewportOnly?: boolean;
43
- maxTokens?: number;
44
- includeHistory?: boolean;
45
- }
46
-
47
- export const DEFAULT_SNAPSHOT_OPTIONS: Required<SnapshotOptions> = {
48
- fullSnapshot: false,
49
- interactiveOnly: true,
50
- maxElements: 300,
51
- viewportOnly: false,
52
- maxTokens: 8000,
53
- includeHistory: true,
54
- };
55
-
56
- export interface ElementChange {
57
- ref: string;
58
- element: SnapshotElement;
59
- previousValue?: string;
60
- previousChecked?: boolean | 'mixed';
61
- previousDisabled?: boolean;
62
- previousExpanded?: boolean;
63
- previousSelected?: boolean;
64
- changeType: 'added' | 'modified' | 'removed';
65
- }
66
-
67
- export interface SnapshotDiff {
68
- unchangedRefs: string[];
69
- changes: ElementChange[];
70
- addedRefs: string[];
71
- removedRefs: string[];
72
- }
73
-
74
- export type SnapshotResult =
75
- | { type: 'full'; content: string }
76
- | { type: 'diff'; content: string; unchangedRefs: string[] };
77
-
78
- export interface SessionHistoryEntry {
79
- url: string;
80
- title: string;
81
- timestamp: number;
82
- actionsTaken: string[];
83
- }
84
-
85
- export interface SessionSummary {
86
- history: string;
87
- pagesVisited: number;
88
- navigationPatternHash?: string;
89
- }
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "esModuleInterop": true,
7
- "strict": true,
8
- "skipLibCheck": true,
9
- "resolveJsonModule": true,
10
- "isolatedModules": true,
11
- "noEmit": true
12
- },
13
- "include": ["src/**/*.ts"],
14
- "exclude": ["node_modules"]
15
- }
@@ -1,125 +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 PERMISSION_API_PORT = process.env.PERMISSION_API_PORT || '9226';
11
- const PERMISSION_API_URL = `http://localhost:${PERMISSION_API_PORT}/permission`;
12
-
13
- interface FilePermissionInput {
14
- operation: 'create' | 'delete' | 'rename' | 'move' | 'modify' | 'overwrite';
15
- filePath?: string;
16
- filePaths?: string[];
17
- targetPath?: string;
18
- contentPreview?: string;
19
- }
20
-
21
- const server = new Server(
22
- { name: 'file-permission', version: '1.0.0' },
23
- { capabilities: { tools: {} } }
24
- );
25
-
26
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
27
- tools: [
28
- {
29
- name: 'request_file_permission',
30
- description:
31
- 'Request user permission before performing file operations (create, delete, rename, move, modify, overwrite). Always call this tool BEFORE executing any file modification. Returns "allowed" or "denied".',
32
- inputSchema: {
33
- type: 'object',
34
- properties: {
35
- operation: {
36
- type: 'string',
37
- enum: ['create', 'delete', 'rename', 'move', 'modify', 'overwrite'],
38
- description: 'The type of file operation to perform',
39
- },
40
- filePath: {
41
- type: 'string',
42
- description: 'Absolute path to the file being operated on',
43
- },
44
- filePaths: {
45
- type: 'array',
46
- items: { type: 'string' },
47
- description: 'Array of absolute paths for batch operations (e.g., deleting multiple files)',
48
- },
49
- targetPath: {
50
- type: 'string',
51
- description: 'Target path for rename/move operations',
52
- },
53
- contentPreview: {
54
- type: 'string',
55
- description: 'Preview of file content for create/modify operations (first ~500 chars)',
56
- },
57
- },
58
- required: ['operation'],
59
- },
60
- },
61
- ],
62
- }));
63
-
64
- server.setRequestHandler(CallToolRequestSchema, async (request): Promise<CallToolResult> => {
65
- if (request.params.name !== 'request_file_permission') {
66
- return {
67
- content: [{ type: 'text', text: `Error: Unknown tool: ${request.params.name}` }],
68
- isError: true,
69
- };
70
- }
71
-
72
- const args = request.params.arguments as FilePermissionInput;
73
- const { operation, filePath, filePaths, targetPath, contentPreview } = args;
74
-
75
- if (!operation || (!filePath && (!filePaths || filePaths.length === 0))) {
76
- return {
77
- content: [{ type: 'text', text: 'Error: operation and either filePath or filePaths are required' }],
78
- isError: true,
79
- };
80
- }
81
-
82
- try {
83
- const response = await fetch(PERMISSION_API_URL, {
84
- method: 'POST',
85
- headers: { 'Content-Type': 'application/json' },
86
- body: JSON.stringify({
87
- operation,
88
- filePath,
89
- filePaths,
90
- targetPath,
91
- contentPreview: contentPreview?.substring(0, 500),
92
- }),
93
- });
94
-
95
- if (!response.ok) {
96
- const errorText = await response.text();
97
- return {
98
- content: [{ type: 'text', text: `Error: Permission API returned ${response.status}: ${errorText}` }],
99
- isError: true,
100
- };
101
- }
102
-
103
- const result = (await response.json()) as { allowed: boolean };
104
- return {
105
- content: [{ type: 'text', text: result.allowed ? 'allowed' : 'denied' }],
106
- };
107
- } catch (error) {
108
- const errorMessage = error instanceof Error ? error.message : String(error);
109
- return {
110
- content: [{ type: 'text', text: `Error: Failed to request permission: ${errorMessage}` }],
111
- isError: true,
112
- };
113
- }
114
- });
115
-
116
- async function main() {
117
- const transport = new StdioServerTransport();
118
- await server.connect(transport);
119
- console.error('File Permission MCP Server started');
120
- }
121
-
122
- main().catch((error) => {
123
- console.error('Failed to start server:', error);
124
- process.exit(1);
125
- });
@@ -1,17 +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
- "rootDir": "./src",
11
- "paths": {
12
- "@/*": ["./src/*"]
13
- }
14
- },
15
- "include": ["src/**/*"],
16
- "exclude": ["node_modules", "dist"]
17
- }
@@ -1,127 +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 THOUGHT_STREAM_PORT = process.env.THOUGHT_STREAM_PORT || '9228';
11
- const CHECKPOINT_URL = `http://127.0.0.1:${THOUGHT_STREAM_PORT}/checkpoint`;
12
- const THOUGHT_STREAM_TASK_ID =
13
- process.env.THOUGHT_STREAM_TASK_ID || process.env.ACCOMPLISH_TASK_ID || '';
14
-
15
- interface ReportCheckpointInput {
16
- status: 'progress' | 'complete' | 'stuck';
17
- summary: string;
18
- nextPlanned?: string;
19
- blocker?: string;
20
- }
21
-
22
- const server = new Server(
23
- { name: 'report-checkpoint', version: '1.0.0' },
24
- { capabilities: { tools: {} } }
25
- );
26
-
27
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
28
- tools: [
29
- {
30
- name: 'report_checkpoint',
31
- description:
32
- 'Report a progress checkpoint to the UI. Use this to mark significant milestones, completion of subtasks, or when stuck and needing help.',
33
- inputSchema: {
34
- type: 'object',
35
- properties: {
36
- status: {
37
- type: 'string',
38
- enum: ['progress', 'complete', 'stuck'],
39
- description:
40
- 'Status: progress (ongoing work), complete (task finished), stuck (blocked/need help)',
41
- },
42
- summary: {
43
- type: 'string',
44
- description: 'Brief summary of what was accomplished or the current state',
45
- },
46
- nextPlanned: {
47
- type: 'string',
48
- description: 'What you plan to do next (optional, for progress status)',
49
- },
50
- blocker: {
51
- type: 'string',
52
- description: 'Description of what is blocking progress (optional, for stuck status)',
53
- },
54
- },
55
- required: ['status', 'summary'],
56
- },
57
- },
58
- ],
59
- }));
60
-
61
- server.setRequestHandler(CallToolRequestSchema, async (request): Promise<CallToolResult> => {
62
- if (request.params.name !== 'report_checkpoint') {
63
- return {
64
- content: [{ type: 'text', text: `Error: Unknown tool: ${request.params.name}` }],
65
- isError: true,
66
- };
67
- }
68
-
69
- const args = request.params.arguments as unknown as ReportCheckpointInput;
70
- const { status, summary, nextPlanned, blocker } = args;
71
-
72
- if (!status || !summary) {
73
- return {
74
- content: [{ type: 'text', text: 'Error: status and summary are required' }],
75
- isError: true,
76
- };
77
- }
78
-
79
- console.error(`[report-checkpoint] [${status}] ${summary}`);
80
- if (nextPlanned) {
81
- console.error(`[report-checkpoint] Next planned: ${nextPlanned}`);
82
- }
83
- if (blocker) {
84
- console.error(`[report-checkpoint] Blocker: ${blocker}`);
85
- }
86
-
87
- if (THOUGHT_STREAM_TASK_ID) {
88
- try {
89
- const response = await fetch(CHECKPOINT_URL, {
90
- method: 'POST',
91
- headers: { 'Content-Type': 'application/json' },
92
- body: JSON.stringify({
93
- taskId: THOUGHT_STREAM_TASK_ID,
94
- status,
95
- summary,
96
- nextPlanned,
97
- blocker,
98
- agentName: process.env.ACCOMPLISH_AGENT_NAME || 'agent',
99
- timestamp: Date.now(),
100
- }),
101
- signal: AbortSignal.timeout(1000),
102
- });
103
-
104
- if (!response.ok) {
105
- console.error(`[report-checkpoint] HTTP error (non-fatal): ${response.status}`);
106
- }
107
- } catch (error) {
108
- const errorMessage = error instanceof Error ? error.message : String(error);
109
- console.error(`[report-checkpoint] HTTP error (non-fatal): ${errorMessage}`);
110
- }
111
- }
112
-
113
- return {
114
- content: [{ type: 'text', text: 'Checkpoint recorded.' }],
115
- };
116
- });
117
-
118
- async function main() {
119
- const transport = new StdioServerTransport();
120
- await server.connect(transport);
121
- console.error('[report-checkpoint] MCP server running');
122
- }
123
-
124
- main().catch((error) => {
125
- console.error('[report-checkpoint] Fatal error:', error);
126
- process.exit(1);
127
- });
@@ -1,12 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "outDir": "dist",
7
- "strict": true,
8
- "esModuleInterop": true,
9
- "skipLibCheck": true
10
- },
11
- "include": ["src/**/*"]
12
- }
@@ -1,109 +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 THOUGHT_STREAM_PORT = process.env.THOUGHT_STREAM_PORT || '9228';
11
- const THOUGHT_STREAM_URL = `http://127.0.0.1:${THOUGHT_STREAM_PORT}/thought`;
12
- const THOUGHT_STREAM_TASK_ID =
13
- process.env.THOUGHT_STREAM_TASK_ID || process.env.ACCOMPLISH_TASK_ID || '';
14
-
15
- interface ReportThoughtInput {
16
- content: string;
17
- category: 'observation' | 'reasoning' | 'decision' | 'action';
18
- }
19
-
20
- const server = new Server(
21
- { name: 'report-thought', version: '1.0.0' },
22
- { capabilities: { tools: {} } }
23
- );
24
-
25
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
26
- tools: [
27
- {
28
- name: 'report_thought',
29
- description:
30
- 'Stream a thought to the UI for real-time visibility into agent reasoning. Use frequently to narrate what you see and do.',
31
- inputSchema: {
32
- type: 'object',
33
- properties: {
34
- content: {
35
- type: 'string',
36
- description: 'The thought content to display',
37
- },
38
- category: {
39
- type: 'string',
40
- enum: ['observation', 'reasoning', 'decision', 'action'],
41
- description:
42
- 'Category: observation (what you see), reasoning (why), decision (what you chose), action (what you are doing)',
43
- },
44
- },
45
- required: ['content', 'category'],
46
- },
47
- },
48
- ],
49
- }));
50
-
51
- server.setRequestHandler(CallToolRequestSchema, async (request): Promise<CallToolResult> => {
52
- if (request.params.name !== 'report_thought') {
53
- return {
54
- content: [{ type: 'text', text: `Error: Unknown tool: ${request.params.name}` }],
55
- isError: true,
56
- };
57
- }
58
-
59
- const args = request.params.arguments as unknown as ReportThoughtInput;
60
- const { content, category } = args;
61
-
62
- if (!content || !category) {
63
- return {
64
- content: [{ type: 'text', text: 'Error: content and category are required' }],
65
- isError: true,
66
- };
67
- }
68
-
69
- console.error(`[report-thought] [${category}] ${content}`);
70
-
71
- if (THOUGHT_STREAM_TASK_ID) {
72
- try {
73
- const response = await fetch(THOUGHT_STREAM_URL, {
74
- method: 'POST',
75
- headers: { 'Content-Type': 'application/json' },
76
- body: JSON.stringify({
77
- taskId: THOUGHT_STREAM_TASK_ID,
78
- content,
79
- category,
80
- agentName: process.env.ACCOMPLISH_AGENT_NAME || 'agent',
81
- timestamp: Date.now(),
82
- }),
83
- signal: AbortSignal.timeout(1000),
84
- });
85
-
86
- if (!response.ok) {
87
- console.error(`[report-thought] HTTP error (non-fatal): ${response.status}`);
88
- }
89
- } catch (error) {
90
- const errorMessage = error instanceof Error ? error.message : String(error);
91
- console.error(`[report-thought] HTTP error (non-fatal): ${errorMessage}`);
92
- }
93
- }
94
-
95
- return {
96
- content: [{ type: 'text', text: 'Thought recorded.' }],
97
- };
98
- });
99
-
100
- async function main() {
101
- const transport = new StdioServerTransport();
102
- await server.connect(transport);
103
- console.error('[report-thought] MCP server running');
104
- }
105
-
106
- main().catch((error) => {
107
- console.error('[report-thought] Fatal error:', error);
108
- process.exit(1);
109
- });
@@ -1,12 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "outDir": "dist",
7
- "strict": true,
8
- "esModuleInterop": true,
9
- "skipLibCheck": true
10
- },
11
- "include": ["src/**/*"]
12
- }