@bbyqtbean/taco-helper 0.1.0
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.
- package/dist/agents/config-writer.d.ts +38 -0
- package/dist/agents/config-writer.d.ts.map +1 -0
- package/dist/agents/config-writer.js +142 -0
- package/dist/agents/config-writer.js.map +1 -0
- package/dist/agents/index.d.ts +24 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +64 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +74 -0
- package/dist/cli.js.map +1 -0
- package/dist/comment-store.d.ts +42 -0
- package/dist/comment-store.d.ts.map +1 -0
- package/dist/comment-store.js +53 -0
- package/dist/comment-store.js.map +1 -0
- package/dist/http-server.d.ts +12 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +199 -0
- package/dist/http-server.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +12 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +140 -0
- package/dist/mcp-server.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config writer — reads, merges, and writes agent MCP config files.
|
|
3
|
+
*/
|
|
4
|
+
import { AgentConfig } from './index.js';
|
|
5
|
+
/**
|
|
6
|
+
* Write the "taco" MCP entry into the agent's config file.
|
|
7
|
+
*
|
|
8
|
+
* - If the file doesn't exist, create it with only taco added as a tool.
|
|
9
|
+
* - If the file exists, parse it and add "taco" as a value under the
|
|
10
|
+
* agent's wrapper key (e.g. "mcpServers"), preserving all existing entries.
|
|
11
|
+
*/
|
|
12
|
+
export declare function writeConfig(agent: AgentConfig): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Remove the "taco" MCP entry from the agent's config file.
|
|
15
|
+
*
|
|
16
|
+
* - If the file doesn't exist, there's nothing to remove.
|
|
17
|
+
* - Only removes the "taco" key — all other entries are preserved.
|
|
18
|
+
* - If the wrapper key is empty after removal, it's cleaned up too.
|
|
19
|
+
*/
|
|
20
|
+
export declare function removeConfig(agent: AgentConfig): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* Clean taco-specific lines from the agent's rules file.
|
|
23
|
+
*
|
|
24
|
+
* During setup, taco-helper wraps its injected content with sentinel comments:
|
|
25
|
+
* # --- taco-start ---
|
|
26
|
+
* ...taco rules...
|
|
27
|
+
* # --- taco-end ---
|
|
28
|
+
*
|
|
29
|
+
* This function removes only the lines between the sentinels (inclusive),
|
|
30
|
+
* preserving any user-authored content outside the sentinels.
|
|
31
|
+
* The file is never deleted — even if empty after cleanup.
|
|
32
|
+
*
|
|
33
|
+
* @param agent - The agent config (must have a non-null rulesFileName)
|
|
34
|
+
* @param projectDir - The project directory containing the rules file
|
|
35
|
+
* @returns true if taco lines were found and removed
|
|
36
|
+
*/
|
|
37
|
+
export declare function cleanRulesFile(agent: AgentConfig, projectDir: string): Promise<boolean>;
|
|
38
|
+
//# sourceMappingURL=config-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-writer.d.ts","sourceRoot":"","sources":["../../src/agents/config-writer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAQzC;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BnE;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAgCvE;AAKD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoD7F"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config writer — reads, merges, and writes agent MCP config files.
|
|
3
|
+
*/
|
|
4
|
+
import { readFile, writeFile, mkdir } from 'fs/promises';
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
|
+
import { dirname, join } from 'path';
|
|
7
|
+
/** The MCP server entry that taco-helper writes into agent configs. */
|
|
8
|
+
const TACO_MCP_ENTRY = {
|
|
9
|
+
command: 'npx',
|
|
10
|
+
args: ['-y', '@bbyqtbean/taco-helper@latest'],
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Write the "taco" MCP entry into the agent's config file.
|
|
14
|
+
*
|
|
15
|
+
* - If the file doesn't exist, create it with only taco added as a tool.
|
|
16
|
+
* - If the file exists, parse it and add "taco" as a value under the
|
|
17
|
+
* agent's wrapper key (e.g. "mcpServers"), preserving all existing entries.
|
|
18
|
+
*/
|
|
19
|
+
export async function writeConfig(agent) {
|
|
20
|
+
const { configPath, wrapperKey } = agent;
|
|
21
|
+
// Ensure the parent directory exists
|
|
22
|
+
const dir = dirname(configPath);
|
|
23
|
+
if (!existsSync(dir)) {
|
|
24
|
+
await mkdir(dir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
let config = {};
|
|
27
|
+
// If the file already exists, parse it
|
|
28
|
+
if (existsSync(configPath)) {
|
|
29
|
+
try {
|
|
30
|
+
const raw = await readFile(configPath, 'utf-8');
|
|
31
|
+
config = JSON.parse(raw);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// If parsing fails, start fresh but warn the user
|
|
35
|
+
console.error(`⚠️ Could not parse ${configPath} — creating a fresh config.`);
|
|
36
|
+
config = {};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Add "taco" under the wrapper key, preserving existing entries
|
|
40
|
+
const servers = config[wrapperKey] ?? {};
|
|
41
|
+
servers['taco'] = TACO_MCP_ENTRY;
|
|
42
|
+
config[wrapperKey] = servers;
|
|
43
|
+
// Write back
|
|
44
|
+
await writeFile(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Remove the "taco" MCP entry from the agent's config file.
|
|
48
|
+
*
|
|
49
|
+
* - If the file doesn't exist, there's nothing to remove.
|
|
50
|
+
* - Only removes the "taco" key — all other entries are preserved.
|
|
51
|
+
* - If the wrapper key is empty after removal, it's cleaned up too.
|
|
52
|
+
*/
|
|
53
|
+
export async function removeConfig(agent) {
|
|
54
|
+
const { configPath, wrapperKey } = agent;
|
|
55
|
+
if (!existsSync(configPath)) {
|
|
56
|
+
return false; // Nothing to remove
|
|
57
|
+
}
|
|
58
|
+
let config;
|
|
59
|
+
try {
|
|
60
|
+
const raw = await readFile(configPath, 'utf-8');
|
|
61
|
+
config = JSON.parse(raw);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
console.error(`⚠️ Could not parse ${configPath} — nothing to remove.`);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const servers = config[wrapperKey];
|
|
68
|
+
if (!servers || !('taco' in servers)) {
|
|
69
|
+
return false; // "taco" entry doesn't exist
|
|
70
|
+
}
|
|
71
|
+
// Remove just the "taco" key
|
|
72
|
+
delete servers['taco'];
|
|
73
|
+
// If the wrapper key is now empty, remove it too
|
|
74
|
+
if (Object.keys(servers).length === 0) {
|
|
75
|
+
delete config[wrapperKey];
|
|
76
|
+
}
|
|
77
|
+
// Write back
|
|
78
|
+
await writeFile(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
const SENTINEL_START = '# --- taco-start ---';
|
|
82
|
+
const SENTINEL_END = '# --- taco-end ---';
|
|
83
|
+
/**
|
|
84
|
+
* Clean taco-specific lines from the agent's rules file.
|
|
85
|
+
*
|
|
86
|
+
* During setup, taco-helper wraps its injected content with sentinel comments:
|
|
87
|
+
* # --- taco-start ---
|
|
88
|
+
* ...taco rules...
|
|
89
|
+
* # --- taco-end ---
|
|
90
|
+
*
|
|
91
|
+
* This function removes only the lines between the sentinels (inclusive),
|
|
92
|
+
* preserving any user-authored content outside the sentinels.
|
|
93
|
+
* The file is never deleted — even if empty after cleanup.
|
|
94
|
+
*
|
|
95
|
+
* @param agent - The agent config (must have a non-null rulesFileName)
|
|
96
|
+
* @param projectDir - The project directory containing the rules file
|
|
97
|
+
* @returns true if taco lines were found and removed
|
|
98
|
+
*/
|
|
99
|
+
export async function cleanRulesFile(agent, projectDir) {
|
|
100
|
+
const { rulesFileName } = agent;
|
|
101
|
+
if (!rulesFileName) {
|
|
102
|
+
return false; // Agent has no rules file
|
|
103
|
+
}
|
|
104
|
+
const rulesPath = join(projectDir, rulesFileName);
|
|
105
|
+
if (!existsSync(rulesPath)) {
|
|
106
|
+
return false; // Nothing to clean
|
|
107
|
+
}
|
|
108
|
+
let content;
|
|
109
|
+
try {
|
|
110
|
+
content = await readFile(rulesPath, 'utf-8');
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
console.error(`⚠️ Could not read ${rulesPath} — skipping rules cleanup.`);
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
const lines = content.split('\n');
|
|
117
|
+
const resultLines = [];
|
|
118
|
+
let insideSentinel = false;
|
|
119
|
+
let foundSentinel = false;
|
|
120
|
+
for (const line of lines) {
|
|
121
|
+
const trimmed = line.trim();
|
|
122
|
+
if (trimmed === SENTINEL_START) {
|
|
123
|
+
insideSentinel = true;
|
|
124
|
+
foundSentinel = true;
|
|
125
|
+
continue; // Skip this line
|
|
126
|
+
}
|
|
127
|
+
if (trimmed === SENTINEL_END) {
|
|
128
|
+
insideSentinel = false;
|
|
129
|
+
continue; // Skip this line
|
|
130
|
+
}
|
|
131
|
+
if (!insideSentinel) {
|
|
132
|
+
resultLines.push(line);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (!foundSentinel) {
|
|
136
|
+
return false; // No taco content found
|
|
137
|
+
}
|
|
138
|
+
// Write back the cleaned content (file is kept even if empty)
|
|
139
|
+
await writeFile(rulesPath, resultLines.join('\n'), 'utf-8');
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=config-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-writer.js","sourceRoot":"","sources":["../../src/agents/config-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent registry — maps agent IDs to their config file paths and formats.
|
|
3
|
+
*/
|
|
4
|
+
export interface AgentConfig {
|
|
5
|
+
name: string;
|
|
6
|
+
agentId: string;
|
|
7
|
+
/** Absolute path to the agent's MCP config file */
|
|
8
|
+
configPath: string;
|
|
9
|
+
/** The top-level key that holds MCP server entries (e.g. "mcpServers") */
|
|
10
|
+
wrapperKey: string;
|
|
11
|
+
/** Filename for the agent's rules file (e.g. ".cursorrules", "CLAUDE.md"). null if the agent has no rules file. */
|
|
12
|
+
rulesFileName: string | null;
|
|
13
|
+
}
|
|
14
|
+
export declare const AGENTS: Record<string, AgentConfig>;
|
|
15
|
+
/**
|
|
16
|
+
* Look up an agent by its --agent flag value.
|
|
17
|
+
* Returns undefined if the agent ID is not recognised.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getAgent(agentId: string): AgentConfig | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* List all supported agent IDs (for help text / error messages).
|
|
22
|
+
*/
|
|
23
|
+
export declare function listAgentIds(): string[];
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,mHAAmH;IACnH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAID,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CA2C9C,CAAC;AAEF;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEjE;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent registry — maps agent IDs to their config file paths and formats.
|
|
3
|
+
*/
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
const home = homedir();
|
|
7
|
+
export const AGENTS = {
|
|
8
|
+
cursor: {
|
|
9
|
+
name: 'Cursor',
|
|
10
|
+
agentId: 'cursor',
|
|
11
|
+
configPath: join(home, '.cursor', 'mcp.json'),
|
|
12
|
+
wrapperKey: 'mcpServers',
|
|
13
|
+
rulesFileName: '.cursorrules',
|
|
14
|
+
},
|
|
15
|
+
'claude-desktop': {
|
|
16
|
+
name: 'Claude Desktop',
|
|
17
|
+
agentId: 'claude-desktop',
|
|
18
|
+
configPath: join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
|
|
19
|
+
wrapperKey: 'mcpServers',
|
|
20
|
+
rulesFileName: null,
|
|
21
|
+
},
|
|
22
|
+
'claude-code': {
|
|
23
|
+
name: 'Claude Code',
|
|
24
|
+
agentId: 'claude-code',
|
|
25
|
+
configPath: join(home, '.claude.json'),
|
|
26
|
+
wrapperKey: 'mcpServers',
|
|
27
|
+
rulesFileName: 'CLAUDE.md',
|
|
28
|
+
},
|
|
29
|
+
windsurf: {
|
|
30
|
+
name: 'Windsurf',
|
|
31
|
+
agentId: 'windsurf',
|
|
32
|
+
configPath: join(home, '.windsurf', 'mcp.json'),
|
|
33
|
+
wrapperKey: 'mcpServers',
|
|
34
|
+
rulesFileName: '.windsurfrules',
|
|
35
|
+
},
|
|
36
|
+
antigravity: {
|
|
37
|
+
name: 'Antigravity',
|
|
38
|
+
agentId: 'antigravity',
|
|
39
|
+
configPath: join(home, '.antigravity', 'mcp.json'),
|
|
40
|
+
wrapperKey: 'mcpServers',
|
|
41
|
+
rulesFileName: '.antigravityrules',
|
|
42
|
+
},
|
|
43
|
+
codex: {
|
|
44
|
+
name: 'Codex (ChatGPT)',
|
|
45
|
+
agentId: 'codex',
|
|
46
|
+
configPath: join(home, '.codex', 'mcp.json'),
|
|
47
|
+
wrapperKey: 'mcpServers',
|
|
48
|
+
rulesFileName: '.codexrules',
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Look up an agent by its --agent flag value.
|
|
53
|
+
* Returns undefined if the agent ID is not recognised.
|
|
54
|
+
*/
|
|
55
|
+
export function getAgent(agentId) {
|
|
56
|
+
return AGENTS[agentId];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* List all supported agent IDs (for help text / error messages).
|
|
60
|
+
*/
|
|
61
|
+
export function listAgentIds() {
|
|
62
|
+
return Object.keys(AGENTS);
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAa5B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;AAEvB,MAAM,CAAC,MAAM,MAAM,GAAgC;IAC/C,MAAM,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,QAAQ;QACjB,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC;QAC7C,UAAU,EAAE,YAAY;QACxB,aAAa,EAAE,cAAc;KAChC;IACD,gBAAgB,EAAE;QACd,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,gBAAgB;QACzB,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAE,4BAA4B,CAAC;QAChG,UAAU,EAAE,YAAY;QACxB,aAAa,EAAE,IAAI;KACtB;IACD,aAAa,EAAE;QACX,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,aAAa;QACtB,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC;QACtC,UAAU,EAAE,YAAY;QACxB,aAAa,EAAE,WAAW;KAC7B;IACD,QAAQ,EAAE;QACN,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,UAAU;QACnB,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,CAAC;QAC/C,UAAU,EAAE,YAAY;QACxB,aAAa,EAAE,gBAAgB;KAClC;IACD,WAAW,EAAE;QACT,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,aAAa;QACtB,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,UAAU,CAAC;QAClD,UAAU,EAAE,YAAY;QACxB,aAAa,EAAE,mBAAmB;KACrC;IACD,KAAK,EAAE;QACH,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,OAAO;QAChB,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC;QAC5C,UAAU,EAAE,YAAY;QACxB,aAAa,EAAE,aAAa;KAC/B;CACJ,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe;IACpC,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IACxB,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI commands — setup and uninstall.
|
|
3
|
+
* These are run by the user directly via npx.
|
|
4
|
+
*/
|
|
5
|
+
export declare function runSetup(args: string[]): Promise<void>;
|
|
6
|
+
export declare function runUninstall(args: string[]): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B5D;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsChE"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI commands — setup and uninstall.
|
|
3
|
+
* These are run by the user directly via npx.
|
|
4
|
+
*/
|
|
5
|
+
import { getAgent, listAgentIds } from './agents/index.js';
|
|
6
|
+
import { writeConfig, removeConfig, cleanRulesFile } from './agents/config-writer.js';
|
|
7
|
+
export async function runSetup(args) {
|
|
8
|
+
const agentId = getArgValue(args, '--agent');
|
|
9
|
+
if (!agentId) {
|
|
10
|
+
console.error('Usage: npx taco-helper setup --agent <agent_id>');
|
|
11
|
+
console.error(`\nSupported agents: ${listAgentIds().join(', ')}`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const agent = getAgent(agentId);
|
|
15
|
+
if (!agent) {
|
|
16
|
+
console.error(`❌ Unknown agent: "${agentId}"`);
|
|
17
|
+
console.error(`Supported agents: ${listAgentIds().join(', ')}`);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
console.log(`\n🌮 Setting up Taco for ${agent.name}...\n`);
|
|
21
|
+
try {
|
|
22
|
+
await writeConfig(agent);
|
|
23
|
+
console.log(`✅ Taco has been added to ${agent.name}'s MCP config.`);
|
|
24
|
+
console.log(` Config file: ${agent.configPath}`);
|
|
25
|
+
console.log(`\n👉 Restart ${agent.name} to activate the connection.\n`);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error(`❌ Failed to write config:`, err);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function runUninstall(args) {
|
|
33
|
+
const agentId = getArgValue(args, '--agent');
|
|
34
|
+
if (!agentId) {
|
|
35
|
+
console.error('Usage: npx taco-helper uninstall --agent <agent_id>');
|
|
36
|
+
console.error(`\nSupported agents: ${listAgentIds().join(', ')}`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
const agent = getAgent(agentId);
|
|
40
|
+
if (!agent) {
|
|
41
|
+
console.error(`❌ Unknown agent: "${agentId}"`);
|
|
42
|
+
console.error(`Supported agents: ${listAgentIds().join(', ')}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
console.log(`\n🌮 Removing Taco from ${agent.name}...\n`);
|
|
46
|
+
try {
|
|
47
|
+
const removed = await removeConfig(agent);
|
|
48
|
+
if (removed) {
|
|
49
|
+
console.log(`✅ Taco has been removed from ${agent.name}'s MCP config.`);
|
|
50
|
+
console.log(` Config file: ${agent.configPath}`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
console.log(`ℹ️ No Taco entry found in ${agent.name}'s config. Nothing to remove.`);
|
|
54
|
+
}
|
|
55
|
+
// Clean taco-specific lines from the agent's rules file
|
|
56
|
+
const rulesCleaned = await cleanRulesFile(agent, process.cwd());
|
|
57
|
+
if (rulesCleaned) {
|
|
58
|
+
console.log(`✅ Taco lines cleaned from ${agent.rulesFileName}.`);
|
|
59
|
+
}
|
|
60
|
+
console.log(`\n👉 Restart ${agent.name} to complete the disconnection.\n`);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
console.error(`❌ Failed to remove config:`, err);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Extract a --flag value from an args array. */
|
|
68
|
+
function getArgValue(args, flag) {
|
|
69
|
+
const idx = args.indexOf(flag);
|
|
70
|
+
if (idx === -1 || idx + 1 >= args.length)
|
|
71
|
+
return undefined;
|
|
72
|
+
return args[idx + 1];
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEtF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAc;IACzC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAE7C,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,uBAAuB,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,GAAG,CAAC,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,qBAAqB,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC;IAE3D,IAAI,CAAC;QACD,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,4BAA4B,KAAK,CAAC,IAAI,gBAAgB,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,IAAI,gCAAgC,CAAC,CAAC;IAC5E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAc;IAC7C,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAE7C,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,OAAO,CAAC,KAAK,CAAC,uBAAuB,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,GAAG,CAAC,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,qBAAqB,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC;IAE1D,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,GAAG,CAAC,gCAAgC,KAAK,CAAC,IAAI,gBAAgB,CAAC,CAAC;YACxE,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,8BAA8B,KAAK,CAAC,IAAI,+BAA+B,CAAC,CAAC;QACzF,CAAC;QAED,wDAAwD;QACxD,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAChE,IAAI,YAAY,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,IAAI,mCAAmC,CAAC,CAAC;IAC/E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC;AAED,iDAAiD;AACjD,SAAS,WAAW,CAAC,IAAc,EAAE,IAAY;IAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC3D,OAAO,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory comment store — shared between the MCP server and HTTP server.
|
|
3
|
+
*
|
|
4
|
+
* Comments live only in memory. When the agent restarts, the store is fresh
|
|
5
|
+
* and the Chrome extension re-pushes comments on connect.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
export interface TacoComment {
|
|
9
|
+
id: string;
|
|
10
|
+
text: string;
|
|
11
|
+
selector: string;
|
|
12
|
+
pageUrl: string;
|
|
13
|
+
screenshot?: string;
|
|
14
|
+
timestamp: string;
|
|
15
|
+
resolved: boolean;
|
|
16
|
+
elementName?: string;
|
|
17
|
+
metadata?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
export declare class CommentStore extends EventEmitter {
|
|
20
|
+
private comments;
|
|
21
|
+
/**
|
|
22
|
+
* Add one or more comments to the store.
|
|
23
|
+
* If a comment with the same ID already exists, it is overwritten.
|
|
24
|
+
* Returns the number of comments added.
|
|
25
|
+
*/
|
|
26
|
+
addComments(comments: TacoComment[]): number;
|
|
27
|
+
/**
|
|
28
|
+
* Get all comments. By default, only returns unresolved comments.
|
|
29
|
+
* Pass `true` to include resolved ones.
|
|
30
|
+
*/
|
|
31
|
+
getComments(includeResolved?: boolean): TacoComment[];
|
|
32
|
+
/**
|
|
33
|
+
* Mark a comment as resolved by ID.
|
|
34
|
+
* Returns true if the comment was found and updated, false otherwise.
|
|
35
|
+
*/
|
|
36
|
+
markResolved(id: string): boolean;
|
|
37
|
+
/** Remove all comments from the store. */
|
|
38
|
+
clear(): void;
|
|
39
|
+
/** Get the total number of comments in the store. */
|
|
40
|
+
get size(): number;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=comment-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-store.d.ts","sourceRoot":"","sources":["../src/comment-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,qBAAa,YAAa,SAAQ,YAAY;IAC1C,OAAO,CAAC,QAAQ,CAAuC;IAEvD;;;;OAIG;IACH,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM;IAQ5C;;;OAGG;IACH,WAAW,CAAC,eAAe,UAAQ,GAAG,WAAW,EAAE;IAMnD;;;OAGG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQjC,0CAA0C;IAC1C,KAAK,IAAI,IAAI;IAIb,qDAAqD;IACrD,IAAI,IAAI,IAAI,MAAM,CAEjB;CACJ"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory comment store — shared between the MCP server and HTTP server.
|
|
3
|
+
*
|
|
4
|
+
* Comments live only in memory. When the agent restarts, the store is fresh
|
|
5
|
+
* and the Chrome extension re-pushes comments on connect.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
export class CommentStore extends EventEmitter {
|
|
9
|
+
comments = new Map();
|
|
10
|
+
/**
|
|
11
|
+
* Add one or more comments to the store.
|
|
12
|
+
* If a comment with the same ID already exists, it is overwritten.
|
|
13
|
+
* Returns the number of comments added.
|
|
14
|
+
*/
|
|
15
|
+
addComments(comments) {
|
|
16
|
+
for (const comment of comments) {
|
|
17
|
+
this.comments.set(comment.id, comment);
|
|
18
|
+
this.emit('comment-received', { id: comment.id });
|
|
19
|
+
}
|
|
20
|
+
return comments.length;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get all comments. By default, only returns unresolved comments.
|
|
24
|
+
* Pass `true` to include resolved ones.
|
|
25
|
+
*/
|
|
26
|
+
getComments(includeResolved = false) {
|
|
27
|
+
const all = Array.from(this.comments.values());
|
|
28
|
+
if (includeResolved)
|
|
29
|
+
return all;
|
|
30
|
+
return all.filter((c) => !c.resolved);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Mark a comment as resolved by ID.
|
|
34
|
+
* Returns true if the comment was found and updated, false otherwise.
|
|
35
|
+
*/
|
|
36
|
+
markResolved(id) {
|
|
37
|
+
const comment = this.comments.get(id);
|
|
38
|
+
if (!comment)
|
|
39
|
+
return false;
|
|
40
|
+
comment.resolved = true;
|
|
41
|
+
this.emit('comment-resolved', { id });
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
/** Remove all comments from the store. */
|
|
45
|
+
clear() {
|
|
46
|
+
this.comments.clear();
|
|
47
|
+
}
|
|
48
|
+
/** Get the total number of comments in the store. */
|
|
49
|
+
get size() {
|
|
50
|
+
return this.comments.size;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=comment-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-store.js","sourceRoot":"","sources":["../src/comment-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AActC,MAAM,OAAO,YAAa,SAAQ,YAAY;IAClC,QAAQ,GAA6B,IAAI,GAAG,EAAE,CAAC;IAEvD;;;;OAIG;IACH,WAAW,CAAC,QAAuB;QAC/B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,QAAQ,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,eAAe,GAAG,KAAK;QAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/C,IAAI,eAAe;YAAE,OAAO,GAAG,CAAC;QAChC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,EAAU;QACnB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAC3B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,0CAA0C;IAC1C,KAAK;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;IAED,qDAAqD;IACrD,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC9B,CAAC;CACJ"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP server — listens on localhost:7867.
|
|
3
|
+
* The Taco Chrome extension pushes comments here via fetch().
|
|
4
|
+
*/
|
|
5
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
6
|
+
import { CommentStore } from './comment-store.js';
|
|
7
|
+
/**
|
|
8
|
+
* Start the HTTP server on localhost:7867.
|
|
9
|
+
* Returns a reference to the server so it can be closed in tests.
|
|
10
|
+
*/
|
|
11
|
+
export declare function startHttpServer(store: CommentStore): import("http").Server<typeof IncomingMessage, typeof ServerResponse>;
|
|
12
|
+
//# sourceMappingURL=http-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAgB,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAGrE,OAAO,EAAE,YAAY,EAAe,MAAM,oBAAoB,CAAC;AAoD/D;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,wEA+JlD"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP server — listens on localhost:7867.
|
|
3
|
+
* The Taco Chrome extension pushes comments here via fetch().
|
|
4
|
+
*/
|
|
5
|
+
import { createServer } from 'http';
|
|
6
|
+
import { readFile } from 'fs/promises';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import { getAgent } from './agents/index.js';
|
|
9
|
+
import { removeConfig, cleanRulesFile } from './agents/config-writer.js';
|
|
10
|
+
const PORT = 7867;
|
|
11
|
+
/** Active SSE connections */
|
|
12
|
+
const sseClients = new Set();
|
|
13
|
+
/** Read the full request body as a string. */
|
|
14
|
+
function readBody(req) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const chunks = [];
|
|
17
|
+
req.on('data', (chunk) => chunks.push(chunk));
|
|
18
|
+
req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
|
|
19
|
+
req.on('error', reject);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/** Send a JSON response. */
|
|
23
|
+
function json(res, status, data) {
|
|
24
|
+
res.writeHead(status, {
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
'Access-Control-Allow-Origin': '*',
|
|
27
|
+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
28
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
29
|
+
});
|
|
30
|
+
res.end(JSON.stringify(data));
|
|
31
|
+
}
|
|
32
|
+
/** Set CORS headers and handle preflight. Returns true if this was a preflight request. */
|
|
33
|
+
function handleCors(req, res) {
|
|
34
|
+
if (req.method === 'OPTIONS') {
|
|
35
|
+
res.writeHead(204, {
|
|
36
|
+
'Access-Control-Allow-Origin': '*',
|
|
37
|
+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
38
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
39
|
+
});
|
|
40
|
+
res.end();
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
/** Broadcast an SSE event to all connected clients. */
|
|
46
|
+
function broadcastSSE(event, data) {
|
|
47
|
+
const message = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
48
|
+
for (const client of sseClients) {
|
|
49
|
+
client.write(message);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Start the HTTP server on localhost:7867.
|
|
54
|
+
* Returns a reference to the server so it can be closed in tests.
|
|
55
|
+
*/
|
|
56
|
+
export function startHttpServer(store) {
|
|
57
|
+
// Wire store events to SSE broadcasts
|
|
58
|
+
store.on('comment-resolved', (payload) => {
|
|
59
|
+
console.error(`🌮 [SSE] Broadcasting comment-resolved: ${payload.id}`);
|
|
60
|
+
broadcastSSE('comment-resolved', payload);
|
|
61
|
+
});
|
|
62
|
+
store.on('comment-received', (payload) => {
|
|
63
|
+
broadcastSSE('comment-received', payload);
|
|
64
|
+
});
|
|
65
|
+
const server = createServer(async (req, res) => {
|
|
66
|
+
// Handle CORS preflight
|
|
67
|
+
if (handleCors(req, res))
|
|
68
|
+
return;
|
|
69
|
+
const url = req.url ?? '/';
|
|
70
|
+
const method = req.method ?? 'GET';
|
|
71
|
+
try {
|
|
72
|
+
// GET /health
|
|
73
|
+
if (url === '/health' && method === 'GET') {
|
|
74
|
+
// Try to read project name from package.json in working directory
|
|
75
|
+
let projectName = null;
|
|
76
|
+
try {
|
|
77
|
+
const pkgPath = join(process.cwd(), 'package.json');
|
|
78
|
+
const pkgContent = await readFile(pkgPath, 'utf-8');
|
|
79
|
+
const pkg = JSON.parse(pkgContent);
|
|
80
|
+
projectName = pkg.name || null;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// package.json not found or unreadable — that's okay
|
|
84
|
+
}
|
|
85
|
+
json(res, 200, { status: 'ok', projectName });
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// GET /events — Server-Sent Events stream
|
|
89
|
+
if (url === '/events' && method === 'GET') {
|
|
90
|
+
res.writeHead(200, {
|
|
91
|
+
'Content-Type': 'text/event-stream',
|
|
92
|
+
'Cache-Control': 'no-cache',
|
|
93
|
+
'Connection': 'keep-alive',
|
|
94
|
+
'Access-Control-Allow-Origin': '*',
|
|
95
|
+
});
|
|
96
|
+
// Send initial connected event
|
|
97
|
+
res.write(`event: connected\ndata: {}\n\n`);
|
|
98
|
+
// Add to active clients
|
|
99
|
+
sseClients.add(res);
|
|
100
|
+
console.error(`🌮 [SSE] Client connected (${sseClients.size} active)`);
|
|
101
|
+
// Remove on disconnect
|
|
102
|
+
req.on('close', () => {
|
|
103
|
+
sseClients.delete(res);
|
|
104
|
+
console.error(`🌮 [SSE] Client disconnected (${sseClients.size} active)`);
|
|
105
|
+
});
|
|
106
|
+
// Keep connection alive with periodic heartbeat
|
|
107
|
+
const heartbeat = setInterval(() => {
|
|
108
|
+
res.write(`: heartbeat\n\n`);
|
|
109
|
+
}, 30_000);
|
|
110
|
+
req.on('close', () => clearInterval(heartbeat));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
// GET /comments — retrieve current comments
|
|
114
|
+
// Supports ?include_resolved=true to include resolved comments
|
|
115
|
+
const parsedUrl = new URL(url, 'http://localhost');
|
|
116
|
+
if (parsedUrl.pathname === '/comments' && method === 'GET') {
|
|
117
|
+
const includeResolved = parsedUrl.searchParams.get('include_resolved') === 'true';
|
|
118
|
+
const comments = store.getComments(includeResolved);
|
|
119
|
+
json(res, 200, comments);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
// POST /comments — push new comments from the extension
|
|
123
|
+
if (url === '/comments' && method === 'POST') {
|
|
124
|
+
const body = await readBody(req);
|
|
125
|
+
const comments = JSON.parse(body);
|
|
126
|
+
const count = store.addComments(comments);
|
|
127
|
+
json(res, 200, { received: count });
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// POST /comments/:id/resolve — mark a comment as resolved
|
|
131
|
+
const resolveMatch = url.match(/^\/comments\/([^/]+)\/resolve$/);
|
|
132
|
+
if (resolveMatch && method === 'POST') {
|
|
133
|
+
const id = decodeURIComponent(resolveMatch[1]);
|
|
134
|
+
const success = store.markResolved(id);
|
|
135
|
+
if (success) {
|
|
136
|
+
json(res, 200, { success: true });
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
json(res, 404, { error: 'Comment not found' });
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// POST /uninstall — self-uninstall: remove MCP config + clean rules file, then shut down
|
|
144
|
+
if (url === '/uninstall' && method === 'POST') {
|
|
145
|
+
const body = await readBody(req);
|
|
146
|
+
const { agent_id } = JSON.parse(body);
|
|
147
|
+
const agent = getAgent(agent_id);
|
|
148
|
+
if (!agent) {
|
|
149
|
+
json(res, 400, { error: `Unknown agent: "${agent_id}"` });
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
console.error(`🌮 Uninstalling Taco from ${agent.name}...`);
|
|
153
|
+
const removed = [];
|
|
154
|
+
try {
|
|
155
|
+
const configRemoved = await removeConfig(agent);
|
|
156
|
+
if (configRemoved)
|
|
157
|
+
removed.push('mcp_config');
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
console.error(`⚠️ Failed to remove MCP config:`, err);
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
const rulesRemoved = await cleanRulesFile(agent, process.cwd());
|
|
164
|
+
if (rulesRemoved)
|
|
165
|
+
removed.push('rules_file');
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
console.error(`⚠️ Failed to clean rules file:`, err);
|
|
169
|
+
}
|
|
170
|
+
json(res, 200, { success: true, removed });
|
|
171
|
+
// Shut down after a brief delay to allow the response to flush
|
|
172
|
+
setTimeout(() => {
|
|
173
|
+
console.error('🌮 Taco Helper shutting down after uninstall.');
|
|
174
|
+
process.exit(0);
|
|
175
|
+
}, 100);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
// 404 for anything else
|
|
179
|
+
json(res, 404, { error: 'Not found' });
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
console.error('HTTP error:', err);
|
|
183
|
+
json(res, 500, { error: 'Internal server error' });
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
server.listen(PORT, '127.0.0.1', () => {
|
|
187
|
+
// Log to stderr — stdout is reserved for MCP
|
|
188
|
+
console.error(`🌮 Taco Helper HTTP server listening on http://127.0.0.1:${PORT}`);
|
|
189
|
+
});
|
|
190
|
+
server.on('error', (err) => {
|
|
191
|
+
if (err.code === 'EADDRINUSE') {
|
|
192
|
+
console.error(`❌ Port ${PORT} is already in use. Is another instance of taco-helper running?`);
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
195
|
+
throw err;
|
|
196
|
+
});
|
|
197
|
+
return server;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=http-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-server.js","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* taco-helper — entry point.
|
|
4
|
+
*
|
|
5
|
+
* This file detects how the package was invoked:
|
|
6
|
+
*
|
|
7
|
+
* CLI mode (user runs manually):
|
|
8
|
+
* npx taco-helper setup --agent cursor
|
|
9
|
+
* npx taco-helper uninstall --agent cursor
|
|
10
|
+
*
|
|
11
|
+
* Server mode (agent launches automatically):
|
|
12
|
+
* npx taco-helper
|
|
13
|
+
* → starts MCP server on stdio + HTTP server on :7867
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* taco-helper — entry point.
|
|
4
|
+
*
|
|
5
|
+
* This file detects how the package was invoked:
|
|
6
|
+
*
|
|
7
|
+
* CLI mode (user runs manually):
|
|
8
|
+
* npx taco-helper setup --agent cursor
|
|
9
|
+
* npx taco-helper uninstall --agent cursor
|
|
10
|
+
*
|
|
11
|
+
* Server mode (agent launches automatically):
|
|
12
|
+
* npx taco-helper
|
|
13
|
+
* → starts MCP server on stdio + HTTP server on :7867
|
|
14
|
+
*/
|
|
15
|
+
import { runSetup, runUninstall } from './cli.js';
|
|
16
|
+
import { CommentStore } from './comment-store.js';
|
|
17
|
+
import { startHttpServer } from './http-server.js';
|
|
18
|
+
import { startMcpServer } from './mcp-server.js';
|
|
19
|
+
const command = process.argv[2];
|
|
20
|
+
if (command === 'setup') {
|
|
21
|
+
// CLI mode: write MCP config and exit
|
|
22
|
+
await runSetup(process.argv.slice(2));
|
|
23
|
+
}
|
|
24
|
+
else if (command === 'uninstall') {
|
|
25
|
+
// CLI mode: remove MCP config and exit
|
|
26
|
+
await runUninstall(process.argv.slice(2));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// Server mode: start both servers
|
|
30
|
+
const store = new CommentStore();
|
|
31
|
+
// Start the HTTP server (for the Chrome extension)
|
|
32
|
+
startHttpServer(store);
|
|
33
|
+
// Start the MCP server on stdio (for the agent)
|
|
34
|
+
await startMcpServer(store);
|
|
35
|
+
console.error('🌮 Taco Helper is running. Press Ctrl+C to stop.');
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;IACtB,sCAAsC;IACtC,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC;KAAM,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;IACjC,uCAAuC;IACvC,MAAM,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;KAAM,CAAC;IACJ,kCAAkC;IAClC,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE,CAAC;IAEjC,mDAAmD;IACnD,eAAe,CAAC,KAAK,CAAC,CAAC;IAEvB,gDAAgD;IAChD,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC;IAE5B,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server — speaks MCP protocol over stdio.
|
|
3
|
+
* Exposes tools for AI agents to query and manage comments.
|
|
4
|
+
* Supports sampling to autonomously trigger implementation when comments arrive.
|
|
5
|
+
*/
|
|
6
|
+
import { CommentStore } from './comment-store.js';
|
|
7
|
+
/**
|
|
8
|
+
* Create and start the MCP server on stdio.
|
|
9
|
+
* The agent communicates with this server via stdin/stdout.
|
|
10
|
+
*/
|
|
11
|
+
export declare function startMcpServer(store: CommentStore): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=mcp-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,YAAY,EAAe,MAAM,oBAAoB,CAAC;AAE/D;;;GAGG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4FvE"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server — speaks MCP protocol over stdio.
|
|
3
|
+
* Exposes tools for AI agents to query and manage comments.
|
|
4
|
+
* Supports sampling to autonomously trigger implementation when comments arrive.
|
|
5
|
+
*/
|
|
6
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
7
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
/**
|
|
10
|
+
* Create and start the MCP server on stdio.
|
|
11
|
+
* The agent communicates with this server via stdin/stdout.
|
|
12
|
+
*/
|
|
13
|
+
export async function startMcpServer(store) {
|
|
14
|
+
const server = new McpServer({
|
|
15
|
+
name: 'taco-helper',
|
|
16
|
+
version: '0.1.0',
|
|
17
|
+
});
|
|
18
|
+
// Tool: get_comments — retrieve all pending (unresolved) comments
|
|
19
|
+
server.tool('get_comments', 'Retrieve all pending (unresolved) comments left by the user in the Taco Chrome extension. Each comment includes the text, CSS selector of the annotated element, page URL, and optionally a screenshot.', {}, async () => {
|
|
20
|
+
const comments = store.getComments(false);
|
|
21
|
+
return {
|
|
22
|
+
content: [
|
|
23
|
+
{
|
|
24
|
+
type: 'text',
|
|
25
|
+
text: comments.length === 0
|
|
26
|
+
? 'No pending comments.'
|
|
27
|
+
: JSON.stringify(comments, null, 2),
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
// Tool: get_all_comments — retrieve all comments including resolved
|
|
33
|
+
server.tool('get_all_comments', 'Retrieve all comments including resolved ones. Use this to see the full history of comments.', {
|
|
34
|
+
include_resolved: z.boolean().optional().describe('Whether to include resolved comments (default: true)'),
|
|
35
|
+
}, async ({ include_resolved }) => {
|
|
36
|
+
const comments = store.getComments(include_resolved ?? true);
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: 'text',
|
|
41
|
+
text: comments.length === 0
|
|
42
|
+
? 'No comments found.'
|
|
43
|
+
: JSON.stringify(comments, null, 2),
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
// Tool: mark_resolved — mark a comment as resolved
|
|
49
|
+
server.tool('mark_resolved', 'Mark a comment as resolved by its ID. Use this after you have addressed a comment.', {
|
|
50
|
+
id: z.string().describe('The ID of the comment to mark as resolved'),
|
|
51
|
+
}, async ({ id }) => {
|
|
52
|
+
const success = store.markResolved(id);
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: success
|
|
58
|
+
? `Comment ${id} marked as resolved.`
|
|
59
|
+
: `Comment ${id} not found.`,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
// Connect to stdio transport
|
|
65
|
+
const transport = new StdioServerTransport();
|
|
66
|
+
await server.connect(transport);
|
|
67
|
+
console.error('🌮 Taco Helper MCP server running on stdio');
|
|
68
|
+
// --- Sampling: auto-trigger agent when new comments arrive ---
|
|
69
|
+
// After connection, listen for new comments and request the agent to implement them.
|
|
70
|
+
// This only works if the connected agent supports the sampling capability.
|
|
71
|
+
store.on('comment-received', async () => {
|
|
72
|
+
// Debounce: wait briefly for batch of comments to arrive
|
|
73
|
+
// (the extension sends multiple comments in one POST, which triggers
|
|
74
|
+
// multiple 'comment-received' events — we only want one sampling request)
|
|
75
|
+
if (samplingDebounceTimer)
|
|
76
|
+
clearTimeout(samplingDebounceTimer);
|
|
77
|
+
samplingDebounceTimer = setTimeout(() => {
|
|
78
|
+
requestAgentImplementation(server, store).catch((err) => {
|
|
79
|
+
console.error('🌮 [Sampling] Error requesting agent implementation:', err.message ?? err);
|
|
80
|
+
});
|
|
81
|
+
}, 1000);
|
|
82
|
+
});
|
|
83
|
+
console.error('🌮 Taco Helper sampling listener registered');
|
|
84
|
+
}
|
|
85
|
+
let samplingDebounceTimer = null;
|
|
86
|
+
/**
|
|
87
|
+
* Request the connected agent to implement pending comments via MCP sampling.
|
|
88
|
+
* If the agent doesn't support sampling, this silently does nothing.
|
|
89
|
+
*/
|
|
90
|
+
async function requestAgentImplementation(mcpServer, store) {
|
|
91
|
+
const comments = store.getComments(false); // unresolved only
|
|
92
|
+
if (comments.length === 0)
|
|
93
|
+
return;
|
|
94
|
+
const commentSummary = comments.map((c, i) => {
|
|
95
|
+
let desc = `${i + 1}. [${c.id}] "${c.text}"`;
|
|
96
|
+
if (c.elementName)
|
|
97
|
+
desc += ` (element: ${c.elementName})`;
|
|
98
|
+
if (c.selector)
|
|
99
|
+
desc += ` [selector: ${c.selector}]`;
|
|
100
|
+
if (c.pageUrl)
|
|
101
|
+
desc += ` on ${c.pageUrl}`;
|
|
102
|
+
return desc;
|
|
103
|
+
}).join('\n');
|
|
104
|
+
const prompt = `You have received ${comments.length} new UI feedback comment(s) from the Taco Chrome extension. Please implement each requested change:
|
|
105
|
+
|
|
106
|
+
${commentSummary}
|
|
107
|
+
|
|
108
|
+
For each comment:
|
|
109
|
+
1. Understand the requested change
|
|
110
|
+
2. Implement it in the codebase
|
|
111
|
+
3. Call the mark_resolved tool with the comment ID after implementing
|
|
112
|
+
|
|
113
|
+
Begin implementing now.`;
|
|
114
|
+
try {
|
|
115
|
+
console.error(`🌮 [Sampling] Requesting agent to implement ${comments.length} comment(s)...`);
|
|
116
|
+
await mcpServer.server.createMessage({
|
|
117
|
+
messages: [
|
|
118
|
+
{
|
|
119
|
+
role: 'user',
|
|
120
|
+
content: {
|
|
121
|
+
type: 'text',
|
|
122
|
+
text: prompt,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
maxTokens: 4096,
|
|
127
|
+
});
|
|
128
|
+
console.error('🌮 [Sampling] Agent acknowledged the request');
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
// Expected failure if agent doesn't support sampling — not an error
|
|
132
|
+
if (err?.code === -32601 || err?.message?.includes('not supported') || err?.message?.includes('Method not found')) {
|
|
133
|
+
console.error('🌮 [Sampling] Agent does not support sampling — user must prompt manually');
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
throw err;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bbyqtbean/taco-helper",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server + CLI for connecting the Taco Chrome extension to AI agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"taco-helper": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"mcp",
|
|
17
|
+
"taco",
|
|
18
|
+
"chrome-extension",
|
|
19
|
+
"ai-agent"
|
|
20
|
+
],
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@modelcontextprotocol/sdk": "^1.26.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^20.11.0",
|
|
27
|
+
"typescript": "^5.3.3"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18.0.0"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist"
|
|
37
|
+
]
|
|
38
|
+
}
|