@saccolabs/tars 1.36.0 → 1.37.1

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 (39) hide show
  1. package/dist/channels/channel-manager.d.ts +5 -0
  2. package/dist/channels/channel-manager.js +7 -0
  3. package/dist/channels/channel-manager.js.map +1 -1
  4. package/dist/channels/tui/tui-channel.d.ts +98 -0
  5. package/dist/channels/tui/tui-channel.js +362 -0
  6. package/dist/channels/tui/tui-channel.js.map +1 -0
  7. package/dist/channels/tui/tui-renderer.d.ts +49 -0
  8. package/dist/channels/tui/tui-renderer.js +112 -0
  9. package/dist/channels/tui/tui-renderer.js.map +1 -0
  10. package/dist/cli/commands/chat.d.ts +9 -0
  11. package/dist/cli/commands/chat.js +51 -0
  12. package/dist/cli/commands/chat.js.map +1 -0
  13. package/dist/cli/commands/refresh.js +7 -1
  14. package/dist/cli/commands/refresh.js.map +1 -1
  15. package/dist/cli/index.d.ts +1 -1
  16. package/dist/cli/index.js +9 -0
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/cli/suppress-warnings.d.ts +1 -0
  19. package/dist/cli/suppress-warnings.js +9 -0
  20. package/dist/cli/suppress-warnings.js.map +1 -0
  21. package/dist/supervisor/bootstrap.d.ts +48 -0
  22. package/dist/supervisor/bootstrap.js +602 -0
  23. package/dist/supervisor/bootstrap.js.map +1 -0
  24. package/dist/supervisor/main.js +5 -537
  25. package/dist/supervisor/main.js.map +1 -1
  26. package/dist/supervisor/mcp-bridge.js +10 -1
  27. package/dist/supervisor/mcp-bridge.js.map +1 -1
  28. package/dist/utils/logger.d.ts +5 -0
  29. package/dist/utils/logger.js +23 -0
  30. package/dist/utils/logger.js.map +1 -1
  31. package/extensions/search/dist/search-helper.js +43 -0
  32. package/extensions/search/dist/server.js +111 -0
  33. package/extensions/search/package-lock.json +1485 -0
  34. package/extensions/search/package.json +21 -0
  35. package/extensions/search/src/search-helper.ts +62 -0
  36. package/extensions/search/src/server.ts +127 -0
  37. package/extensions/search/tars-extension.json +11 -0
  38. package/extensions/search/tsconfig.json +14 -0
  39. package/package.json +2 -1
@@ -1,4 +1,6 @@
1
1
  import winston from 'winston';
2
+ import path from 'path';
3
+ import fs from 'fs';
2
4
  /**
3
5
  * Centralized logger for the supervisor application
4
6
  */
@@ -11,5 +13,26 @@ export const logger = winston.createLogger({
11
13
  })),
12
14
  transports: [new winston.transports.Console()]
13
15
  });
16
+ /**
17
+ * Reconfigures the logger for TUI Chat Mode, diverting all output
18
+ * to a file to prevent polluting the interactive terminal.
19
+ */
20
+ export function configureChatLogging(homeDir) {
21
+ logger.clear();
22
+ const logDir = path.join(homeDir, 'logs');
23
+ if (!fs.existsSync(logDir)) {
24
+ fs.mkdirSync(logDir, { recursive: true });
25
+ }
26
+ logger.add(new winston.transports.File({
27
+ filename: path.join(logDir, 'chat.log'),
28
+ level: process.env.LOG_LEVEL || 'info',
29
+ format: winston.format.combine(winston.format.timestamp({
30
+ format: 'YYYY-MM-DD HH:mm:ss'
31
+ }), winston.format.uncolorize(), // No ANSI color codes in log files
32
+ winston.format.printf(({ timestamp, level, message }) => {
33
+ return `${timestamp} [${level}]: ${message}`;
34
+ }))
35
+ }));
36
+ }
14
37
  export default logger;
15
38
  //# sourceMappingURL=logger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IACvC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;IACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAC1B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;QACrB,MAAM,EAAE,qBAAqB;KAChC,CAAC,EACF,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,EACzB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;QACpD,OAAO,GAAG,SAAS,KAAK,KAAK,MAAM,OAAO,EAAE,CAAC;IACjD,CAAC,CAAC,CACL;IACD,UAAU,EAAE,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;CACjD,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IACvC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;IACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAC1B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;QACrB,MAAM,EAAE,qBAAqB;KAChC,CAAC,EACF,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,EACzB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;QACpD,OAAO,GAAG,SAAS,KAAK,KAAK,MAAM,OAAO,EAAE,CAAC;IACjD,CAAC,CAAC,CACL;IACD,UAAU,EAAE,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;CACjD,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAChD,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,MAAM,CAAC,GAAG,CACN,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;QACxB,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC;QACvC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;QACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAC1B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;YACrB,MAAM,EAAE,qBAAqB;SAChC,CAAC,EACF,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,mCAAmC;QAChE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;YACpD,OAAO,GAAG,SAAS,KAAK,KAAK,MAAM,OAAO,EAAE,CAAC;QACjD,CAAC,CAAC,CACL;KACJ,CAAC,CACL,CAAC;AACN,CAAC;AAED,eAAe,MAAM,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { search } from 'duck-duck-scrape';
2
+ import { parseHTML } from 'linkedom';
3
+ import TurndownService from 'turndown';
4
+ /**
5
+ * Executes a DuckDuckGo search query and returns mapped search results.
6
+ */
7
+ export async function performWebSearch(query, limit = 5) {
8
+ const response = await search(query);
9
+ const rawResults = response.results || [];
10
+ return rawResults.slice(0, limit).map((r) => ({
11
+ title: r.title || '',
12
+ url: r.url || '',
13
+ snippet: r.description || r.snippet || ''
14
+ }));
15
+ }
16
+ /**
17
+ * Fetches HTML from a URL, removes noise/boilerplate, and converts it to clean Markdown.
18
+ */
19
+ export async function fetchWebPage(url, maxLength = 15000) {
20
+ const res = await fetch(url, {
21
+ headers: {
22
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
23
+ }
24
+ });
25
+ if (!res.ok) {
26
+ throw new Error(`Failed to fetch page: HTTP ${res.status} ${res.statusText}`);
27
+ }
28
+ const html = await res.text();
29
+ const { document } = parseHTML(html);
30
+ // Strip boilerplate, navigation, and script/style tags
31
+ const elementsToRemove = document.querySelectorAll('script, style, noscript, iframe, nav, header, footer, aside, svg, img, form, button');
32
+ elementsToRemove.forEach((el) => el.remove());
33
+ const bodyHtml = document.body ? document.body.innerHTML : document.documentElement.innerHTML;
34
+ const turndown = new TurndownService({
35
+ headingStyle: 'atx',
36
+ codeBlockStyle: 'fenced'
37
+ });
38
+ let markdown = turndown.turndown(bodyHtml).trim();
39
+ if (markdown.length > maxLength) {
40
+ markdown = markdown.substring(0, maxLength) + '\n\n...[Content truncated for brevity]...';
41
+ }
42
+ return markdown;
43
+ }
@@ -0,0 +1,111 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
4
+ import { performWebSearch, fetchWebPage } from './search-helper.js';
5
+ const server = new Server({
6
+ name: 'tars-search',
7
+ version: '1.0.0'
8
+ }, {
9
+ capabilities: {
10
+ tools: {}
11
+ }
12
+ });
13
+ /**
14
+ * Tool Definitions
15
+ */
16
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
17
+ return {
18
+ tools: [
19
+ {
20
+ name: 'web_search',
21
+ description: 'Search the web using DuckDuckGo (free, keyless) and return a list of matches.',
22
+ inputSchema: {
23
+ type: 'object',
24
+ properties: {
25
+ query: {
26
+ type: 'string',
27
+ description: 'The search query to execute (e.g. "latest version of Node.js")'
28
+ },
29
+ limit: {
30
+ type: 'number',
31
+ description: 'Maximum number of results to return (default: 5, max: 10)',
32
+ minimum: 1,
33
+ maximum: 10
34
+ }
35
+ },
36
+ required: ['query']
37
+ }
38
+ },
39
+ {
40
+ name: 'web_fetch',
41
+ description: 'Fetch the text/Markdown content of a specific web URL, stripped of header/footer boilerplate.',
42
+ inputSchema: {
43
+ type: 'object',
44
+ properties: {
45
+ url: {
46
+ type: 'string',
47
+ description: 'The URL to fetch content from'
48
+ }
49
+ },
50
+ required: ['url']
51
+ }
52
+ }
53
+ ]
54
+ };
55
+ });
56
+ /**
57
+ * Tool Handlers
58
+ */
59
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
60
+ const { name, arguments: args } = request.params;
61
+ try {
62
+ switch (name) {
63
+ case 'web_search': {
64
+ const { query, limit = 5 } = args;
65
+ if (!query)
66
+ throw new Error('Query is required.');
67
+ const results = await performWebSearch(query, limit);
68
+ return {
69
+ content: [
70
+ {
71
+ type: 'text',
72
+ text: JSON.stringify(results, null, 2)
73
+ }
74
+ ]
75
+ };
76
+ }
77
+ case 'web_fetch': {
78
+ const { url } = args;
79
+ if (!url)
80
+ throw new Error('URL is required.');
81
+ const markdown = await fetchWebPage(url);
82
+ return {
83
+ content: [
84
+ {
85
+ type: 'text',
86
+ text: markdown
87
+ }
88
+ ]
89
+ };
90
+ }
91
+ default:
92
+ throw new Error(`Unknown tool: ${name}`);
93
+ }
94
+ }
95
+ catch (error) {
96
+ return {
97
+ content: [{ type: 'text', text: `❌ Error: ${error.message}` }],
98
+ isError: true
99
+ };
100
+ }
101
+ });
102
+ // Start Server
103
+ async function main() {
104
+ const transport = new StdioServerTransport();
105
+ await server.connect(transport);
106
+ console.error('tars-search MCP server running on stdio');
107
+ }
108
+ main().catch((error) => {
109
+ console.error('Server error:', error);
110
+ process.exit(1);
111
+ });