@sudocode-ai/mcp 0.1.0 → 0.1.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.
- package/dist/client.js +159 -0
- package/dist/client.js.map +1 -0
- package/dist/index.js +48 -47
- package/dist/index.js.map +1 -7
- package/dist/server.js +575 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/analytics.js +21 -0
- package/dist/tools/analytics.js.map +1 -0
- package/dist/tools/feedback.js +24 -0
- package/dist/tools/feedback.js.map +1 -0
- package/dist/tools/init.js +15 -0
- package/dist/tools/init.js.map +1 -0
- package/dist/tools/issues.js +106 -0
- package/dist/tools/issues.js.map +1 -0
- package/dist/tools/references.js +49 -0
- package/dist/tools/references.js.map +1 -0
- package/dist/tools/relationships.js +18 -0
- package/dist/tools/relationships.js.map +1 -0
- package/dist/tools/specs.js +85 -0
- package/dist/tools/specs.js.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/package.json +4 -5
- package/LICENSE +0 -21
package/dist/client.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sudocode CLI client wrapper
|
|
3
|
+
*
|
|
4
|
+
* This module provides a client class that spawns `sudocode` CLI commands
|
|
5
|
+
* and parses their JSON output for use in MCP tools.
|
|
6
|
+
*/
|
|
7
|
+
import { spawn } from "child_process";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
9
|
+
import { dirname, join } from "path";
|
|
10
|
+
import { existsSync } from "fs";
|
|
11
|
+
import { SudocodeError } from "./types.js";
|
|
12
|
+
export class SudocodeClient {
|
|
13
|
+
workingDir;
|
|
14
|
+
cliPath;
|
|
15
|
+
cliArgs;
|
|
16
|
+
dbPath;
|
|
17
|
+
versionChecked = false;
|
|
18
|
+
constructor(config) {
|
|
19
|
+
// Get working directory and expand variables if needed
|
|
20
|
+
let workingDir = config?.workingDir || process.env.SUDOCODE_WORKING_DIR || process.cwd();
|
|
21
|
+
// Fix unexpanded ${workspaceFolder} variable - use PWD or cwd() instead
|
|
22
|
+
if (workingDir === "${workspaceFolder}" || workingDir.includes("${")) {
|
|
23
|
+
workingDir = process.env.PWD || process.cwd();
|
|
24
|
+
}
|
|
25
|
+
this.workingDir = workingDir;
|
|
26
|
+
this.dbPath = config?.dbPath || process.env.SUDOCODE_DB;
|
|
27
|
+
// Auto-discover CLI path from node_modules or use configured/env path
|
|
28
|
+
const cliInfo = this.findCliPath();
|
|
29
|
+
this.cliPath = cliInfo.path;
|
|
30
|
+
this.cliArgs = cliInfo.args;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Find the CLI by looking in node_modules/@sudocode-ai/cli
|
|
34
|
+
* Since we added @sudocode-ai/cli as a dependency, it should be there
|
|
35
|
+
*/
|
|
36
|
+
findCliPath() {
|
|
37
|
+
try {
|
|
38
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
39
|
+
const currentDir = dirname(currentFile);
|
|
40
|
+
// Look for @sudocode-ai/cli in various possible locations
|
|
41
|
+
const possiblePaths = [
|
|
42
|
+
// Workspace root node_modules (development)
|
|
43
|
+
join(currentDir, "..", "..", "node_modules", "@sudocode-ai", "cli", "dist", "cli.js"),
|
|
44
|
+
// Local package node_modules (when installed from npm)
|
|
45
|
+
join(currentDir, "..", "node_modules", "@sudocode-ai", "cli", "dist", "cli.js"),
|
|
46
|
+
];
|
|
47
|
+
for (const cliJsPath of possiblePaths) {
|
|
48
|
+
if (existsSync(cliJsPath)) {
|
|
49
|
+
// Return node + cli.js path instead of creating a wrapper
|
|
50
|
+
return {
|
|
51
|
+
path: process.execPath, // Use current node binary
|
|
52
|
+
args: [cliJsPath], // Pass cli.js as first argument
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
// Ignore errors and fall back to 'sudocode' command
|
|
59
|
+
}
|
|
60
|
+
// Fall back to 'sudocode' command in PATH
|
|
61
|
+
return { path: "sudocode", args: [] };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Execute a CLI command and return parsed JSON output
|
|
65
|
+
*/
|
|
66
|
+
async exec(args, options) {
|
|
67
|
+
// Check CLI version on first call
|
|
68
|
+
if (!this.versionChecked) {
|
|
69
|
+
await this.checkVersion();
|
|
70
|
+
this.versionChecked = true;
|
|
71
|
+
}
|
|
72
|
+
// Build command arguments - prepend cliArgs (e.g., cli.js path)
|
|
73
|
+
const cmdArgs = [...this.cliArgs, ...args];
|
|
74
|
+
// Add --json flag if not already present
|
|
75
|
+
if (!cmdArgs.includes("--json")) {
|
|
76
|
+
cmdArgs.push("--json");
|
|
77
|
+
}
|
|
78
|
+
// Add --db flag if dbPath is configured
|
|
79
|
+
if (this.dbPath && !cmdArgs.includes("--db")) {
|
|
80
|
+
cmdArgs.push("--db", this.dbPath);
|
|
81
|
+
}
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
const proc = spawn(this.cliPath, cmdArgs, {
|
|
84
|
+
cwd: this.workingDir,
|
|
85
|
+
env: process.env,
|
|
86
|
+
});
|
|
87
|
+
let stdout = "";
|
|
88
|
+
let stderr = "";
|
|
89
|
+
proc.stdout.on("data", (data) => {
|
|
90
|
+
stdout += data.toString();
|
|
91
|
+
});
|
|
92
|
+
proc.stderr.on("data", (data) => {
|
|
93
|
+
stderr += data.toString();
|
|
94
|
+
});
|
|
95
|
+
// Set timeout if specified
|
|
96
|
+
const timeout = options?.timeout || 30000; // Default 30s
|
|
97
|
+
const timer = setTimeout(() => {
|
|
98
|
+
proc.kill();
|
|
99
|
+
reject(new SudocodeError(`Command timed out after ${timeout}ms`, -1, "Timeout"));
|
|
100
|
+
}, timeout);
|
|
101
|
+
proc.on("close", (code) => {
|
|
102
|
+
clearTimeout(timer);
|
|
103
|
+
if (code !== 0) {
|
|
104
|
+
reject(new SudocodeError(`CLI command failed with exit code ${code}`, code || -1, stderr));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// Parse JSON output
|
|
108
|
+
try {
|
|
109
|
+
const result = JSON.parse(stdout);
|
|
110
|
+
resolve(result);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
reject(new SudocodeError(`Failed to parse JSON output: ${error instanceof Error ? error.message : String(error)}`, -1, stdout));
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
proc.on("error", (error) => {
|
|
117
|
+
clearTimeout(timer);
|
|
118
|
+
reject(new SudocodeError(`Failed to spawn CLI: ${error.message}`, -1, error.message));
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Check that the CLI is installed and get its version
|
|
124
|
+
*/
|
|
125
|
+
async checkVersion() {
|
|
126
|
+
try {
|
|
127
|
+
const proc = spawn(this.cliPath, [...this.cliArgs, "--version"], {
|
|
128
|
+
cwd: this.workingDir,
|
|
129
|
+
});
|
|
130
|
+
let stdout = "";
|
|
131
|
+
let stderr = "";
|
|
132
|
+
proc.stdout.on("data", (data) => {
|
|
133
|
+
stdout += data.toString();
|
|
134
|
+
});
|
|
135
|
+
proc.stderr.on("data", (data) => {
|
|
136
|
+
stderr += data.toString();
|
|
137
|
+
});
|
|
138
|
+
return new Promise((resolve, reject) => {
|
|
139
|
+
proc.on("close", (code) => {
|
|
140
|
+
if (code !== 0) {
|
|
141
|
+
reject(new SudocodeError(`CLI not found or failed to execute. Make sure 'sudocode' is installed and in your PATH.`, code || -1, stderr));
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
// Version output format: "sudocode version X.Y.Z" or just "X.Y.Z"
|
|
145
|
+
const versionMatch = stdout.match(/(\d+\.\d+\.\d+)/);
|
|
146
|
+
const version = versionMatch ? versionMatch[1] : stdout.trim();
|
|
147
|
+
resolve({ version });
|
|
148
|
+
});
|
|
149
|
+
proc.on("error", () => {
|
|
150
|
+
reject(new SudocodeError(`CLI not found at path: ${this.cliPath}. Make sure 'sudocode' is installed.`, -1, "CLI not found"));
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
throw new SudocodeError(`Failed to check CLI version: ${error instanceof Error ? error.message : String(error)}`, -1, "");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,49 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Server as j}from"@modelcontextprotocol/sdk/server/index.js";import{StdioServerTransport as z}from"@modelcontextprotocol/sdk/server/stdio.js";import{CallToolRequestSchema as $,ListResourcesRequestSchema as N,ListToolsRequestSchema as H,ReadResourceRequestSchema as M}from"@modelcontextprotocol/sdk/types.js";import{spawn as w}from"child_process";import{fileURLToPath as E}from"url";import{dirname as R,join as b}from"path";import{existsSync as O}from"fs";var d=class extends Error{constructor(t,i,s){super(t);this.exitCode=i;this.stderr=s;this.name="SudocodeError"}};var l=class{workingDir;cliPath;cliArgs;dbPath;versionChecked=!1;constructor(e){let t=e?.workingDir||process.env.SUDOCODE_WORKING_DIR||process.cwd();(t==="${workspaceFolder}"||t.includes("${"))&&(t=process.env.PWD||process.cwd()),this.workingDir=t,this.dbPath=e?.dbPath||process.env.SUDOCODE_DB;let i=this.findCliPath();this.cliPath=i.path,this.cliArgs=i.args}findCliPath(){try{let e=E(import.meta.url),t=R(e),i=[b(t,"..","..","node_modules","@sudocode-ai","cli","dist","cli.js"),b(t,"..","node_modules","@sudocode-ai","cli","dist","cli.js")];for(let s of i)if(O(s))return{path:process.execPath,args:[s]}}catch{}return{path:"sudocode",args:[]}}async exec(e,t){this.versionChecked||(await this.checkVersion(),this.versionChecked=!0);let i=[...this.cliArgs,...e];return i.includes("--json")||i.push("--json"),this.dbPath&&!i.includes("--db")&&i.push("--db",this.dbPath),new Promise((s,n)=>{let o=w(this.cliPath,i,{cwd:this.workingDir,env:process.env}),c="",u="";o.stdout.on("data",a=>{c+=a.toString()}),o.stderr.on("data",a=>{u+=a.toString()});let g=t?.timeout||3e4,m=setTimeout(()=>{o.kill(),n(new d(`Command timed out after ${g}ms`,-1,"Timeout"))},g);o.on("close",a=>{if(clearTimeout(m),a!==0){n(new d(`CLI command failed with exit code ${a}`,a||-1,u));return}try{let p=JSON.parse(c);s(p)}catch(p){n(new d(`Failed to parse JSON output: ${p instanceof Error?p.message:String(p)}`,-1,c))}}),o.on("error",a=>{clearTimeout(m),n(new d(`Failed to spawn CLI: ${a.message}`,-1,a.message))})})}async checkVersion(){try{let e=w(this.cliPath,[...this.cliArgs,"--version"],{cwd:this.workingDir}),t="",i="";return e.stdout.on("data",s=>{t+=s.toString()}),e.stderr.on("data",s=>{i+=s.toString()}),new Promise((s,n)=>{e.on("close",o=>{if(o!==0){n(new d("CLI not found or failed to execute. Make sure 'sudocode' is installed and in your PATH.",o||-1,i));return}let c=t.match(/(\d+\.\d+\.\d+)/),u=c?c[1]:t.trim();s({version:u})}),e.on("error",()=>{n(new d(`CLI not found at path: ${this.cliPath}. Make sure 'sudocode' is installed.`,-1,"CLI not found"))})})}catch(e){throw new d(`Failed to check CLI version: ${e instanceof Error?e.message:String(e)}`,-1,"")}}};async function S(r,e={}){let t=await r.exec(["ready"]),i=await r.exec(["status"]);return t.issues&&Array.isArray(t.issues)&&(t.issues=t.issues.map(s=>{let{content:n,...o}=s;return o})),{ready:t,status:i}}async function k(r,e={}){let t=["issue","list"];e.status&&t.push("--status",e.status),e.priority!==void 0&&t.push("--priority",e.priority.toString()),e.limit!==void 0&&t.push("--limit",e.limit.toString()),e.search&&t.push("--grep",e.search);let i=e.archived!==void 0?e.archived:!1;t.push("--archived",i.toString());let s=await r.exec(t);return Array.isArray(s)?s.map(n=>{let{content:o,...c}=n;return c}):s}async function x(r,e){let t=["issue","show",e.issue_id];return r.exec(t)}async function v(r,e){if(!!e.issue_id){let i=["issue","update",e.issue_id];return e.status&&i.push("--status",e.status),e.priority!==void 0&&i.push("--priority",e.priority.toString()),e.title&&i.push("--title",e.title),e.description&&i.push("--description",e.description),e.archived!==void 0&&i.push("--archived",e.archived.toString()),r.exec(i)}else{if(!e.title)throw new Error("title is required when creating a new issue");let i=["issue","create",e.title];return e.description&&i.push("--description",e.description),e.priority!==void 0&&i.push("--priority",e.priority.toString()),e.parent&&i.push("--parent",e.parent),e.tags&&e.tags.length>0&&i.push("--tags",e.tags.join(",")),r.exec(i)}}async function _(r,e={}){let t=["spec","list"];e.limit!==void 0&&t.push("--limit",e.limit.toString()),e.search&&t.push("--grep",e.search);let i=e.archived!==void 0?e.archived:!1;t.push("--archived",i.toString());let s=await r.exec(t);return Array.isArray(s)?s.map(n=>{let{content:o,...c}=n;return c}):s}async function I(r,e){let t=["spec","show",e.spec_id];return r.exec(t)}async function P(r,e){if(!!e.spec_id){let i=["spec","update",e.spec_id];return e.title&&i.push("--title",e.title),e.priority!==void 0&&i.push("--priority",e.priority.toString()),e.description&&i.push("--description",e.description),e.parent!==void 0&&i.push("--parent",e.parent||""),e.tags!==void 0&&i.push("--tags",e.tags.join(",")),e.archived!==void 0&&i.push("--archived",e.archived.toString()),r.exec(i)}else{if(!e.title)throw new Error("title is required when creating a new spec");let i=["spec","create",e.title];return e.priority!==void 0&&i.push("--priority",e.priority.toString()),e.description&&i.push("--description",e.description),e.parent&&i.push("--parent",e.parent),e.tags&&e.tags.length>0&&i.push("--tags",e.tags.join(",")),r.exec(i)}}async function C(r,e){let t=["link",e.from_id,e.to_id];if(e.from_id===e.to_id)throw new Error("from_id and to_id cannot be the same");return e.type&&t.push("--type",e.type),r.exec(t)}async function D(r,e){let t=["feedback","add",e.issue_id,e.spec_id];return t.push("--content",e.content),e.type&&t.push("--type",e.type),e.line!==void 0&&t.push("--line",e.line.toString()),e.text&&t.push("--text",e.text),r.exec(t)}async function T(r,e){let t=i=>{let s=[i,"add-ref",e.entity_id,e.reference_id];return e.line!==void 0&&s.push("--line",e.line.toString()),e.text&&s.push("--text",e.text),e.display_text&&s.push("--display",e.display_text),e.relationship_type&&s.push("--type",e.relationship_type),e.format&&s.push("--format",e.format),e.position&&s.push("--position",e.position),s};try{return await r.exec(t("spec"))}catch{try{return await r.exec(t("issue"))}catch(s){throw s}}}import{existsSync as h}from"fs";import{join as f}from"path";var y=class{server;client;config;isInitialized=!1;constructor(e){this.config=e||{},this.server=new j({name:"sudocode",version:"0.1.0"},{capabilities:{tools:{},resources:{}}}),this.client=new l(e),this.setupHandlers()}setupHandlers(){this.server.setRequestHandler(H,async()=>({tools:[{name:"ready",description:"Find issues ready to work on (no blockers) and gets project status.",inputSchema:{type:"object",properties:{}}},{name:"list_issues",description:"List all issues with optional filters",inputSchema:{type:"object",properties:{status:{type:"string",enum:["open","in_progress","blocked","closed"],description:"Filter by status (optional)"},priority:{type:"number",description:"Filter by priority (0-4) (optional)"},archived:{type:"boolean",description:"Filter by archived status (optional, defaults to false to exclude archived)"},limit:{type:"number",description:"Max results (optional)",default:50},search:{type:"string",description:"Search issues by title or description (optional)"}}}},{name:"show_issue",description:"Show detailed issue information including relationships and feedback",inputSchema:{type:"object",properties:{issue_id:{type:"string",description:'Issue ID (e.g., "ISSUE-001")'}},required:["issue_id"]}},{name:"upsert_issue",description:"Create or update an issue. If issue_id is provided, updates the issue; otherwise creates a new one. To close an issue, set status='closed'. To archive an issue, set archived=true.",inputSchema:{type:"object",properties:{issue_id:{type:"string",description:"Issue ID (optional - if provided, updates the issue; if not, creates new)"},title:{type:"string",description:"Issue title (required for create, optional for update)"},description:{type:"string",description:"Issue descriptions. Supports inline references to other specs/issues by ID in Obsidian internal link format (e.g. `[[SPEC-002]]`)."},priority:{type:"number",description:"Priority (0-4, 0=highest) (optional)"},parent:{type:"string",description:"Parent issue ID (optional)"},tags:{type:"array",items:{type:"string"},description:"Tags (optional)"},status:{type:"string",enum:["open","in_progress","blocked","closed"],description:"Issue status (optional)"},archived:{type:"boolean",description:"Archive status (optional)"}}}},{name:"list_specs",description:"List all specs with optional filters",inputSchema:{type:"object",properties:{limit:{type:"number",description:"Max results (optional)",default:50},search:{type:"string",description:"Search specs by title or description (optional)"}}}},{name:"show_spec",description:"Show detailed spec information including all feedback anchored to the spec",inputSchema:{type:"object",properties:{spec_id:{type:"string",description:'Spec ID (e.g., "SPEC-001")'}},required:["spec_id"]}},{name:"upsert_spec",description:"Create a new spec (update not yet supported in CLI)",inputSchema:{type:"object",properties:{spec_id:{type:"string",description:"Spec ID (optional - if provided, updates the spec; if not, creates new)"},title:{type:"string",description:"Spec title (required for create)"},priority:{type:"number",description:"Priority (0-4, 0=highest) (optional)"},description:{type:"string",description:"Spec description (optional)"},parent:{type:"string",description:"Parent spec ID (optional)"},tags:{type:"array",items:{type:"string"},description:"Tags (optional)"}}}},{name:"link",description:"Create a relationship between two entities (specs or issues)",inputSchema:{type:"object",properties:{from_id:{type:"string",description:"Source entity ID"},to_id:{type:"string",description:"Target entity ID"},type:{type:"string",enum:["blocks","implements","references","depends-on","discovered-from","related"],description:"Relationship type"}},required:["from_id","to_id"]}},{name:"add_reference",description:"Add an inline cross-reference/mention to a spec or issue using Obsidian-style [[ID]] syntax. References are inserted at a specific location in the markdown content. Use this to add references to an issue or spec without having to modify the content directly.",inputSchema:{type:"object",properties:{entity_id:{type:"string",description:"Target entity ID (where to add the reference)"},reference_id:{type:"string",description:"ID to reference (e.g., ISSUE-001, SPEC-002)"},display_text:{type:"string",description:"Display text (optional)"},relationship_type:{type:"string",enum:["blocks","implements","references","depends-on","discovered-from","related"],description:"Relationship type (optional)"},line:{type:"number",description:"Line number to insert reference (use line OR text, not both)"},text:{type:"string",description:"Text to search for insertion point (use line OR text, not both)"},format:{type:"string",enum:["inline","newline"],description:"Format: inline (same line) or newline (new line)",default:"inline"}},required:["entity_id","reference_id"]}},{name:"add_feedback",description:"Provide anchored feedback to a spec. IMPORTANT: You MUST specify either 'line' OR 'text' to anchor the feedback to a specific location in the spec. ",inputSchema:{type:"object",properties:{issue_id:{type:"string",description:"Issue ID providing feedback (required for create)"},spec_id:{type:"string",description:"Spec ID receiving feedback (required for create)"},content:{type:"string",description:"Feedback content (required for create)"},type:{type:"string",enum:["comment","suggestion","request"],description:"Feedback type"},line:{type:"number",description:"Line number to anchor feedback (REQUIRED: must use either 'line' OR 'text', not both). Use this if you know the exact line number in the spec markdown file."},text:{type:"string",description:"Text snippet to anchor feedback (REQUIRED: must use either 'line' OR 'text', not both). Must be an EXACT substring match from the spec content - case-sensitive and whitespace-sensitive. Use show_spec first to see the exact content and copy the text precisely."}}}}]})),this.server.setRequestHandler($,async e=>{let{name:t,arguments:i}=e.params;if(!this.isInitialized)return{content:[{type:"text",text:`\u26A0\uFE0F sudocode is not initialized in this directory.
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
## Typical Workflow
|
|
31
|
-
|
|
32
|
-
1. **Check ready work**: \`ready\` tool to find tasks with no blockers
|
|
33
|
-
2. **Claim work**: \`update_issue\` with status=in_progress
|
|
34
|
-
3. **Review specs**: \`show_spec\` to understand requirements
|
|
35
|
-
4. **Provide feedback**: \`add_feedback\` when specs are unclear
|
|
36
|
-
5. **Complete work**: \`close_issue\` when done
|
|
37
|
-
6. **Link entities**: Use \`link\` to create relationships
|
|
38
|
-
|
|
39
|
-
## Relationship Types
|
|
40
|
-
- \`blocks\`: Hard blocker (to_id must complete before from_id)
|
|
41
|
-
- \`implements\`: Issue implements a spec
|
|
42
|
-
- \`references\`: Soft reference
|
|
43
|
-
- \`depends-on\`: General dependency
|
|
44
|
-
- \`discovered-from\`: New work found during implementation
|
|
45
|
-
- \`related\`: General relationship
|
|
46
|
-
`}]};throw new Error(`Unknown resource: ${t}`)})}async checkForInit(){let e=this.client.workingDir||process.cwd(),t=f(e,".sudocode"),i=f(t,"cache.db"),s=f(t,"issues.jsonl"),n=f(t,"specs.jsonl");if(!h(t))return{initialized:!1,sudocodeExists:!1,message:"No .sudocode directory found"};if(!h(i))if(h(s)||h(n))try{return console.error("Found .sudocode directory but no cache.db, running import..."),await this.client.exec(["import"]),console.error("\u2713 Successfully imported data to cache.db"),{initialized:!0,sudocodeExists:!0,message:"Auto-imported from JSONL files"}}catch(o){return{initialized:!1,sudocodeExists:!0,message:`Failed to import: ${o instanceof Error?o.message:String(o)}`}}else try{return console.error("Found .sudocode directory but no issues.jsonl or specs.jsonl, running init..."),await this.client.exec(["init"]),console.error("\u2713 Successfully initialized sudocode"),await this.client.exec(["import"]),{initialized:!0,sudocodeExists:!0,message:"Initialized sudocode"}}catch(o){return{initialized:!1,sudocodeExists:!0,message:`Failed to initialize: ${o instanceof Error?o.message:String(o)}`}}return{initialized:!0,sudocodeExists:!0}}async checkInitialization(){let e=await this.checkForInit(),t=this.client.workingDir||process.cwd();e.initialized?(this.isInitialized=!0,console.error("\u2713 sudocode initialized successfully"),e.message&&console.error(` ${e.message}`)):(this.isInitialized=!1,console.error(""),console.error("\u26A0\uFE0F WARNING: sudocode is not initialized"),console.error(` Working directory: ${t}`),console.error(""),e.sudocodeExists?(console.error(` Issue: ${e.message}`),console.error(" The .sudocode directory exists but is incomplete."),console.error(" Try running:"),console.error(" $ sudocode import")):(console.error(" No .sudocode directory found."),console.error(" To initialize, run:"),console.error(" $ sudocode init")))}async run(){await this.checkInitialization();let e=new z;await this.server.connect(e),console.error("sudocode MCP server running on stdio")}};function W(){let r={},e=process.argv.slice(2);for(let t=0;t<e.length;t++){let i=e[t];switch(i){case"--working-dir":case"-w":r.workingDir=e[++t];break;case"--cli-path":r.cliPath=e[++t];break;case"--db-path":case"--db":r.dbPath=e[++t];break;case"--no-sync":r.syncOnStartup=!1;break;case"--help":case"-h":console.log(`
|
|
2
|
+
/**
|
|
3
|
+
* sudocode MCP Server entry point
|
|
4
|
+
*/
|
|
5
|
+
import { SudocodeMCPServer } from "./server.js";
|
|
6
|
+
function parseArgs() {
|
|
7
|
+
const config = {};
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
for (let i = 0; i < args.length; i++) {
|
|
10
|
+
const arg = args[i];
|
|
11
|
+
switch (arg) {
|
|
12
|
+
case "--working-dir":
|
|
13
|
+
case "-w":
|
|
14
|
+
config.workingDir = args[++i];
|
|
15
|
+
break;
|
|
16
|
+
case "--cli-path":
|
|
17
|
+
config.cliPath = args[++i];
|
|
18
|
+
break;
|
|
19
|
+
case "--db-path":
|
|
20
|
+
case "--db":
|
|
21
|
+
config.dbPath = args[++i];
|
|
22
|
+
break;
|
|
23
|
+
case "--no-sync":
|
|
24
|
+
config.syncOnStartup = false;
|
|
25
|
+
break;
|
|
26
|
+
case "--help":
|
|
27
|
+
case "-h":
|
|
28
|
+
console.log(`
|
|
47
29
|
sudocode MCP Server
|
|
48
30
|
|
|
49
31
|
Usage: sudocode-mcp [options]
|
|
@@ -59,5 +41,24 @@ Environment Variables:
|
|
|
59
41
|
SUDOCODE_WORKING_DIR Default working directory
|
|
60
42
|
SUDOCODE_PATH Default CLI path
|
|
61
43
|
SUDOCODE_DB Default database path
|
|
62
|
-
`)
|
|
63
|
-
|
|
44
|
+
`);
|
|
45
|
+
process.exit(0);
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
console.error(`Unknown option: ${arg}`);
|
|
49
|
+
console.error("Use --help for usage information");
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return config;
|
|
54
|
+
}
|
|
55
|
+
async function main() {
|
|
56
|
+
const config = parseArgs();
|
|
57
|
+
const server = new SudocodeMCPServer(config);
|
|
58
|
+
await server.run();
|
|
59
|
+
}
|
|
60
|
+
main().catch((error) => {
|
|
61
|
+
console.error("Fatal error:", error);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/server.ts", "../src/client.ts", "../src/types.ts", "../src/tools/issues.ts", "../src/tools/specs.ts", "../src/tools/relationships.ts", "../src/tools/feedback.ts", "../src/tools/references.ts", "../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * MCP Server for sudocode\n *\n * This module sets up the MCP server with tools and resources.\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { SudocodeClient } from \"./client.js\";\nimport * as issueTools from \"./tools/issues.js\";\nimport * as specTools from \"./tools/specs.js\";\nimport * as relationshipTools from \"./tools/relationships.js\";\nimport * as feedbackTools from \"./tools/feedback.js\";\nimport * as referenceTools from \"./tools/references.js\";\nimport { SudocodeClientConfig } from \"./types.js\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\n\nexport class SudocodeMCPServer {\n private server: Server;\n private client: SudocodeClient;\n private config: SudocodeClientConfig;\n private isInitialized: boolean = false;\n\n constructor(config?: SudocodeClientConfig) {\n this.config = config || {};\n this.server = new Server(\n {\n name: \"sudocode\",\n version: \"0.1.0\",\n },\n {\n capabilities: {\n tools: {},\n resources: {},\n },\n }\n );\n\n this.client = new SudocodeClient(config);\n this.setupHandlers();\n }\n\n private setupHandlers() {\n // List available tools\n this.server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: \"ready\",\n description:\n \"Find issues ready to work on (no blockers) and gets project status.\",\n inputSchema: {\n type: \"object\",\n properties: {},\n },\n },\n {\n name: \"list_issues\",\n description: \"List all issues with optional filters\",\n inputSchema: {\n type: \"object\",\n properties: {\n status: {\n type: \"string\",\n enum: [\"open\", \"in_progress\", \"blocked\", \"closed\"],\n description: \"Filter by status (optional)\",\n },\n priority: {\n type: \"number\",\n description: \"Filter by priority (0-4) (optional)\",\n },\n archived: {\n type: \"boolean\",\n description:\n \"Filter by archived status (optional, defaults to false to exclude archived)\",\n },\n limit: {\n type: \"number\",\n description: \"Max results (optional)\",\n default: 50,\n },\n search: {\n type: \"string\",\n description:\n \"Search issues by title or description (optional)\",\n },\n },\n },\n },\n {\n name: \"show_issue\",\n description:\n \"Show detailed issue information including relationships and feedback\",\n inputSchema: {\n type: \"object\",\n properties: {\n issue_id: {\n type: \"string\",\n description: 'Issue ID (e.g., \"ISSUE-001\")',\n },\n },\n required: [\"issue_id\"],\n },\n },\n {\n name: \"upsert_issue\",\n description:\n \"Create or update an issue. If issue_id is provided, updates the issue; otherwise creates a new one. To close an issue, set status='closed'. To archive an issue, set archived=true.\",\n inputSchema: {\n type: \"object\",\n properties: {\n issue_id: {\n type: \"string\",\n description:\n \"Issue ID (optional - if provided, updates the issue; if not, creates new)\",\n },\n title: {\n type: \"string\",\n description:\n \"Issue title (required for create, optional for update)\",\n },\n description: {\n type: \"string\",\n description:\n \"Issue descriptions. Supports inline references to other specs/issues by ID in Obsidian internal link format (e.g. `[[SPEC-002]]`).\",\n },\n priority: {\n type: \"number\",\n description: \"Priority (0-4, 0=highest) (optional)\",\n },\n parent: {\n type: \"string\",\n description: \"Parent issue ID (optional)\",\n },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Tags (optional)\",\n },\n status: {\n type: \"string\",\n enum: [\"open\", \"in_progress\", \"blocked\", \"closed\"],\n description: \"Issue status (optional)\",\n },\n archived: {\n type: \"boolean\",\n description: \"Archive status (optional)\",\n },\n },\n },\n },\n {\n name: \"list_specs\",\n description: \"List all specs with optional filters\",\n inputSchema: {\n type: \"object\",\n properties: {\n limit: {\n type: \"number\",\n description: \"Max results (optional)\",\n default: 50,\n },\n search: {\n type: \"string\",\n description:\n \"Search specs by title or description (optional)\",\n },\n },\n },\n },\n {\n name: \"show_spec\",\n description:\n \"Show detailed spec information including all feedback anchored to the spec\",\n inputSchema: {\n type: \"object\",\n properties: {\n spec_id: {\n type: \"string\",\n description: 'Spec ID (e.g., \"SPEC-001\")',\n },\n },\n required: [\"spec_id\"],\n },\n },\n {\n name: \"upsert_spec\",\n description: \"Create a new spec (update not yet supported in CLI)\",\n inputSchema: {\n type: \"object\",\n properties: {\n spec_id: {\n type: \"string\",\n description:\n \"Spec ID (optional - if provided, updates the spec; if not, creates new)\",\n },\n title: {\n type: \"string\",\n description: \"Spec title (required for create)\",\n },\n priority: {\n type: \"number\",\n description: \"Priority (0-4, 0=highest) (optional)\",\n },\n description: {\n type: \"string\",\n description: \"Spec description (optional)\",\n },\n parent: {\n type: \"string\",\n description: \"Parent spec ID (optional)\",\n },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Tags (optional)\",\n },\n },\n },\n },\n {\n name: \"link\",\n description:\n \"Create a relationship between two entities (specs or issues)\",\n inputSchema: {\n type: \"object\",\n properties: {\n from_id: {\n type: \"string\",\n description: \"Source entity ID\",\n },\n to_id: {\n type: \"string\",\n description: \"Target entity ID\",\n },\n type: {\n type: \"string\",\n enum: [\n \"blocks\",\n \"implements\",\n \"references\",\n \"depends-on\",\n \"discovered-from\",\n \"related\",\n ],\n description: \"Relationship type\",\n },\n },\n required: [\"from_id\", \"to_id\"],\n },\n },\n {\n name: \"add_reference\",\n description:\n \"Add an inline cross-reference/mention to a spec or issue using Obsidian-style [[ID]] syntax. References are inserted at a specific location in the markdown content. Use this to add references to an issue or spec without having to modify the content directly.\",\n inputSchema: {\n type: \"object\",\n properties: {\n entity_id: {\n type: \"string\",\n description: \"Target entity ID (where to add the reference)\",\n },\n reference_id: {\n type: \"string\",\n description: \"ID to reference (e.g., ISSUE-001, SPEC-002)\",\n },\n display_text: {\n type: \"string\",\n description: \"Display text (optional)\",\n },\n relationship_type: {\n type: \"string\",\n enum: [\n \"blocks\",\n \"implements\",\n \"references\",\n \"depends-on\",\n \"discovered-from\",\n \"related\",\n ],\n description: \"Relationship type (optional)\",\n },\n line: {\n type: \"number\",\n description:\n \"Line number to insert reference (use line OR text, not both)\",\n },\n text: {\n type: \"string\",\n description:\n \"Text to search for insertion point (use line OR text, not both)\",\n },\n format: {\n type: \"string\",\n enum: [\"inline\", \"newline\"],\n description:\n \"Format: inline (same line) or newline (new line)\",\n default: \"inline\",\n },\n // TODO: Add position handling later if needed.\n },\n required: [\"entity_id\", \"reference_id\"],\n },\n },\n {\n name: \"add_feedback\",\n description:\n \"Provide anchored feedback to a spec. IMPORTANT: You MUST specify either 'line' OR 'text' to anchor the feedback to a specific location in the spec. \",\n inputSchema: {\n type: \"object\",\n properties: {\n issue_id: {\n type: \"string\",\n description:\n \"Issue ID providing feedback (required for create)\",\n },\n spec_id: {\n type: \"string\",\n description:\n \"Spec ID receiving feedback (required for create)\",\n },\n content: {\n type: \"string\",\n description: \"Feedback content (required for create)\",\n },\n type: {\n type: \"string\",\n enum: [\"comment\", \"suggestion\", \"request\"],\n description: \"Feedback type\",\n },\n line: {\n type: \"number\",\n description:\n \"Line number to anchor feedback (REQUIRED: must use either 'line' OR 'text', not both). Use this if you know the exact line number in the spec markdown file.\",\n },\n text: {\n type: \"string\",\n description:\n \"Text snippet to anchor feedback (REQUIRED: must use either 'line' OR 'text', not both). Must be an EXACT substring match from the spec content - case-sensitive and whitespace-sensitive. Use show_spec first to see the exact content and copy the text precisely.\",\n },\n // TODO: Re-enable when the agent data structure is more developed.\n // agent: {\n // type: \"string\",\n // description: \"Agent providing feedback\",\n // },\n },\n },\n },\n ],\n };\n });\n\n // Handle tool calls\n this.server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n if (!this.isInitialized) {\n const workingDir = this.client[\"workingDir\"] || process.cwd();\n return {\n content: [\n {\n type: \"text\",\n text: `\u26A0\uFE0F sudocode is not initialized in this directory.\\n\\nWorking directory: ${workingDir}\\n\\nPlease run 'sudocode init' in your project root first.`,\n },\n ],\n isError: true,\n };\n }\n\n try {\n let result: any;\n\n switch (name) {\n case \"ready\":\n result = await issueTools.ready(this.client, args as any);\n break;\n\n case \"list_issues\":\n result = await issueTools.listIssues(this.client, args as any);\n break;\n\n case \"show_issue\":\n result = await issueTools.showIssue(this.client, args as any);\n break;\n\n case \"upsert_issue\":\n result = await issueTools.upsertIssue(this.client, args as any);\n break;\n\n case \"list_specs\":\n result = await specTools.listSpecs(this.client, args as any);\n break;\n\n case \"show_spec\":\n result = await specTools.showSpec(this.client, args as any);\n break;\n\n case \"upsert_spec\":\n result = await specTools.upsertSpec(this.client, args as any);\n break;\n\n case \"link\":\n result = await relationshipTools.link(this.client, args as any);\n break;\n\n case \"add_reference\":\n result = await referenceTools.addReference(\n this.client,\n args as any\n );\n break;\n\n case \"add_feedback\":\n result = await feedbackTools.addFeedback(this.client, args as any);\n break;\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n } catch (error) {\n let errorText = `Error: ${\n error instanceof Error ? error.message : String(error)\n }`;\n\n // Include stderr if this is a sudocode error\n if (error instanceof Error && \"stderr\" in error && error.stderr) {\n errorText += `\\n\\nStderr:\\n${error.stderr}`;\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: errorText,\n },\n ],\n isError: true,\n };\n }\n });\n\n // List available resources\n this.server.setRequestHandler(ListResourcesRequestSchema, async () => {\n return {\n resources: [\n {\n uri: \"sudocode://quickstart\",\n name: \"sudocode Quickstart Guide\",\n description:\n \"Introduction to sudocode workflow and best practices for agents\",\n mimeType: \"text/markdown\",\n },\n ],\n };\n });\n\n // Read resource content\n this.server.setRequestHandler(\n ReadResourceRequestSchema,\n async (request) => {\n const { uri } = request.params;\n\n if (uri === \"sudocode://quickstart\") {\n return {\n contents: [\n {\n uri,\n mimeType: \"text/markdown\",\n text: `# sudocode Quickstart\n\nsudocode is a git-native spec and issue management system designed for AI-assisted development.\n\n## Core Concepts\n\n**Specs**: Technical specifications stored as markdown files\n- Types: architecture, api, database, feature, research\n- Status: draft \u2192 review \u2192 approved \u2192 deprecated\n- Each spec has a unique ID (e.g., SPEC-001) and file path\n\n**Issues**: Work items tracked in the database\n- Types: bug, feature, task, epic, chore\n- Status: open \u2192 in_progress \u2192 blocked \u2192 closed\n- Can reference and implement specs\n\n**Feedback**: Issues can provide anchored feedback on specs\n- Anchors track specific lines/sections in spec markdown\n- Auto-relocates when specs change (smart anchoring)\n- Types: comment, suggestion, request\n\n## Typical Workflow\n\n1. **Check ready work**: \\`ready\\` tool to find tasks with no blockers\n2. **Claim work**: \\`update_issue\\` with status=in_progress\n3. **Review specs**: \\`show_spec\\` to understand requirements\n4. **Provide feedback**: \\`add_feedback\\` when specs are unclear\n5. **Complete work**: \\`close_issue\\` when done\n6. **Link entities**: Use \\`link\\` to create relationships\n\n## Relationship Types\n- \\`blocks\\`: Hard blocker (to_id must complete before from_id)\n- \\`implements\\`: Issue implements a spec\n- \\`references\\`: Soft reference\n- \\`depends-on\\`: General dependency\n- \\`discovered-from\\`: New work found during implementation\n- \\`related\\`: General relationship\n`,\n },\n ],\n };\n }\n\n throw new Error(`Unknown resource: ${uri}`);\n }\n );\n }\n\n /**\n * Check for .sudocode directory and required files\n * Returns initialization status and handles auto-import if needed\n */\n private async checkForInit(): Promise<{\n initialized: boolean;\n sudocodeExists: boolean;\n message?: string;\n }> {\n const workingDir = this.client[\"workingDir\"] || process.cwd();\n const sudocodeDir = join(workingDir, \".sudocode\");\n const cacheDbPath = join(sudocodeDir, \"cache.db\");\n const issuesPath = join(sudocodeDir, \"issues.jsonl\");\n const specsPath = join(sudocodeDir, \"specs.jsonl\");\n\n // Check if .sudocode directory exists\n if (!existsSync(sudocodeDir)) {\n return {\n initialized: false,\n sudocodeExists: false,\n message: \"No .sudocode directory found\",\n };\n }\n\n // .sudocode exists, check for cache.db\n if (!existsSync(cacheDbPath)) {\n // Try to auto-import from JSONL files if they exist\n if (existsSync(issuesPath) || existsSync(specsPath)) {\n try {\n console.error(\n \"Found .sudocode directory but no cache.db, running import...\"\n );\n await this.client.exec([\"import\"]);\n console.error(\"\u2713 Successfully imported data to cache.db\");\n return {\n initialized: true,\n sudocodeExists: true,\n message: \"Auto-imported from JSONL files\",\n };\n } catch (error) {\n return {\n initialized: false,\n sudocodeExists: true,\n message: `Failed to import: ${\n error instanceof Error ? error.message : String(error)\n }`,\n };\n }\n } else {\n try {\n console.error(\n \"Found .sudocode directory but no issues.jsonl or specs.jsonl, running init...\"\n );\n await this.client.exec([\"init\"]);\n console.error(\"\u2713 Successfully initialized sudocode\");\n await this.client.exec([\"import\"]);\n return {\n initialized: true,\n sudocodeExists: true,\n message: \"Initialized sudocode\",\n };\n } catch (error) {\n return {\n initialized: false,\n sudocodeExists: true,\n message: `Failed to initialize: ${\n error instanceof Error ? error.message : String(error)\n }`,\n };\n }\n }\n }\n\n return {\n initialized: true,\n sudocodeExists: true,\n };\n }\n\n /**\n * Check if sudocode is initialized in the working directory\n * This provides early warning to users without blocking server startup\n */\n private async checkInitialization() {\n const initStatus = await this.checkForInit();\n const workingDir = this.client[\"workingDir\"] || process.cwd();\n\n if (initStatus.initialized) {\n this.isInitialized = true;\n console.error(\"\u2713 sudocode initialized successfully\");\n if (initStatus.message) {\n console.error(` ${initStatus.message}`);\n }\n } else {\n this.isInitialized = false;\n console.error(\"\");\n console.error(\"\u26A0\uFE0F WARNING: sudocode is not initialized\");\n console.error(` Working directory: ${workingDir}`);\n console.error(\"\");\n\n if (!initStatus.sudocodeExists) {\n console.error(\" No .sudocode directory found.\");\n console.error(\" To initialize, run:\");\n console.error(\" $ sudocode init\");\n } else {\n console.error(` Issue: ${initStatus.message}`);\n console.error(\" The .sudocode directory exists but is incomplete.\");\n console.error(\" Try running:\");\n console.error(\" $ sudocode import\");\n }\n }\n }\n\n async run() {\n // Check if sudocode is initialized (non-blocking warning)\n await this.checkInitialization();\n\n const transport = new StdioServerTransport();\n await this.server.connect(transport);\n console.error(\"sudocode MCP server running on stdio\");\n }\n}\n", "/**\n * sudocode CLI client wrapper\n *\n * This module provides a client class that spawns `sudocode` CLI commands\n * and parses their JSON output for use in MCP tools.\n */\n\nimport { spawn } from \"child_process\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join } from \"path\";\nimport { existsSync, writeFileSync, chmodSync } from \"fs\";\nimport { SudocodeClientConfig, SudocodeError } from \"./types.js\";\n\nexport class SudocodeClient {\n private workingDir: string;\n private cliPath: string;\n private cliArgs: string[];\n private dbPath?: string;\n private versionChecked = false;\n\n constructor(config?: SudocodeClientConfig) {\n // Get working directory and expand variables if needed\n let workingDir =\n config?.workingDir || process.env.SUDOCODE_WORKING_DIR || process.cwd();\n\n // Fix unexpanded ${workspaceFolder} variable - use PWD or cwd() instead\n if (workingDir === \"${workspaceFolder}\" || workingDir.includes(\"${\")) {\n workingDir = process.env.PWD || process.cwd();\n }\n\n this.workingDir = workingDir;\n this.dbPath = config?.dbPath || process.env.SUDOCODE_DB;\n\n // Auto-discover CLI path from node_modules or use configured/env path\n const cliInfo = this.findCliPath();\n this.cliPath = cliInfo.path;\n this.cliArgs = cliInfo.args;\n }\n\n /**\n * Find the CLI by looking in node_modules/@sudocode-ai/cli\n * Since we added @sudocode-ai/cli as a dependency, it should be there\n */\n private findCliPath(): { path: string; args: string[] } {\n try {\n const currentFile = fileURLToPath(import.meta.url);\n const currentDir = dirname(currentFile);\n\n // Look for @sudocode-ai/cli in various possible locations\n const possiblePaths = [\n // Workspace root node_modules (development)\n join(\n currentDir,\n \"..\",\n \"..\",\n \"node_modules\",\n \"@sudocode-ai\",\n \"cli\",\n \"dist\",\n \"cli.js\"\n ),\n // Local package node_modules (when installed from npm)\n join(\n currentDir,\n \"..\",\n \"node_modules\",\n \"@sudocode-ai\",\n \"cli\",\n \"dist\",\n \"cli.js\"\n ),\n ];\n\n for (const cliJsPath of possiblePaths) {\n if (existsSync(cliJsPath)) {\n // Return node + cli.js path instead of creating a wrapper\n return {\n path: process.execPath, // Use current node binary\n args: [cliJsPath], // Pass cli.js as first argument\n };\n }\n }\n } catch (error) {\n // Ignore errors and fall back to 'sudocode' command\n }\n\n // Fall back to 'sudocode' command in PATH\n return { path: \"sudocode\", args: [] };\n }\n\n /**\n * Execute a CLI command and return parsed JSON output\n */\n async exec(args: string[], options?: { timeout?: number }): Promise<any> {\n // Check CLI version on first call\n if (!this.versionChecked) {\n await this.checkVersion();\n this.versionChecked = true;\n }\n\n // Build command arguments - prepend cliArgs (e.g., cli.js path)\n const cmdArgs = [...this.cliArgs, ...args];\n\n // Add --json flag if not already present\n if (!cmdArgs.includes(\"--json\")) {\n cmdArgs.push(\"--json\");\n }\n\n // Add --db flag if dbPath is configured\n if (this.dbPath && !cmdArgs.includes(\"--db\")) {\n cmdArgs.push(\"--db\", this.dbPath);\n }\n\n return new Promise((resolve, reject) => {\n const proc = spawn(this.cliPath, cmdArgs, {\n cwd: this.workingDir,\n env: process.env,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n proc.stdout.on(\"data\", (data) => {\n stdout += data.toString();\n });\n\n proc.stderr.on(\"data\", (data) => {\n stderr += data.toString();\n });\n\n // Set timeout if specified\n const timeout = options?.timeout || 30000; // Default 30s\n const timer = setTimeout(() => {\n proc.kill();\n reject(\n new SudocodeError(\n `Command timed out after ${timeout}ms`,\n -1,\n \"Timeout\"\n )\n );\n }, timeout);\n\n proc.on(\"close\", (code) => {\n clearTimeout(timer);\n\n if (code !== 0) {\n reject(\n new SudocodeError(\n `CLI command failed with exit code ${code}`,\n code || -1,\n stderr\n )\n );\n return;\n }\n\n // Parse JSON output\n try {\n const result = JSON.parse(stdout);\n resolve(result);\n } catch (error) {\n reject(\n new SudocodeError(\n `Failed to parse JSON output: ${\n error instanceof Error ? error.message : String(error)\n }`,\n -1,\n stdout\n )\n );\n }\n });\n\n proc.on(\"error\", (error) => {\n clearTimeout(timer);\n reject(\n new SudocodeError(\n `Failed to spawn CLI: ${error.message}`,\n -1,\n error.message\n )\n );\n });\n });\n }\n\n /**\n * Check that the CLI is installed and get its version\n */\n async checkVersion(): Promise<{ version: string }> {\n try {\n const proc = spawn(this.cliPath, [...this.cliArgs, \"--version\"], {\n cwd: this.workingDir,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n proc.stdout.on(\"data\", (data) => {\n stdout += data.toString();\n });\n\n proc.stderr.on(\"data\", (data) => {\n stderr += data.toString();\n });\n\n return new Promise((resolve, reject) => {\n proc.on(\"close\", (code) => {\n if (code !== 0) {\n reject(\n new SudocodeError(\n `CLI not found or failed to execute. Make sure 'sudocode' is installed and in your PATH.`,\n code || -1,\n stderr\n )\n );\n return;\n }\n\n // Version output format: \"sudocode version X.Y.Z\" or just \"X.Y.Z\"\n const versionMatch = stdout.match(/(\\d+\\.\\d+\\.\\d+)/);\n const version = versionMatch ? versionMatch[1] : stdout.trim();\n\n resolve({ version });\n });\n\n proc.on(\"error\", () => {\n reject(\n new SudocodeError(\n `CLI not found at path: ${this.cliPath}. Make sure 'sudocode' is installed.`,\n -1,\n \"CLI not found\"\n )\n );\n });\n });\n } catch (error) {\n throw new SudocodeError(\n `Failed to check CLI version: ${\n error instanceof Error ? error.message : String(error)\n }`,\n -1,\n \"\"\n );\n }\n }\n}\n", "/**\n * Type definitions for sudocode MCP server\n *\n * Core entity types are imported from the main sudocode package.\n * This file contains MCP-specific types and some forward-compatible types\n * for fields that may be added to the core package in the future.\n */\n\n// Re-export core types from the main package\nexport type {\n Spec,\n Issue,\n Relationship,\n EntityType,\n RelationshipType,\n IssueStatus,\n FeedbackAnchor,\n FeedbackType,\n IssueFeedback as Feedback,\n} from \"@sudocode-ai/types\";\n\n// ============================================================================\n// MCP-SPECIFIC TYPES\n// These types are used by the MCP interface but may not be fully supported\n// by the current CLI implementation. They represent forward-compatible\n// features that may be added in the future.\n// ============================================================================\n\n/**\n * Issue type classification\n * NOTE: Not yet stored in database or supported by CLI filtering\n */\nexport type IssueType = \"bug\" | \"feature\" | \"task\" | \"epic\" | \"chore\";\n\n/**\n * Spec status lifecycle\n * NOTE: Not yet stored in database or supported by CLI filtering\n */\nexport type SpecStatus = \"draft\" | \"review\" | \"approved\" | \"deprecated\";\n\n/**\n * Spec type classification\n * NOTE: Not yet stored in database or supported by CLI filtering\n */\nexport type SpecType =\n | \"architecture\"\n | \"api\"\n | \"database\"\n | \"feature\"\n | \"research\";\n\n// ============================================================================\n// CLIENT CONFIGURATION\n// ============================================================================\n\nexport interface SudocodeClientConfig {\n workingDir?: string;\n cliPath?: string;\n dbPath?: string;\n syncOnStartup?: boolean;\n}\n\n// ============================================================================\n// ERROR TYPES\n// ============================================================================\n\nexport class SudocodeError extends Error {\n constructor(\n message: string,\n public exitCode: number,\n public stderr: string\n ) {\n super(message);\n this.name = \"SudocodeError\";\n }\n}\n", "/**\n * MCP tools for issue management\n */\n\nimport { SudocodeClient } from \"../client.js\";\nimport { Issue, IssueStatus } from \"../types.js\";\n\n// Tool parameter types\nexport interface ReadyParams {}\n\nexport interface ListIssuesParams {\n status?: IssueStatus;\n priority?: number;\n limit?: number;\n search?: string;\n archived?: boolean;\n}\n\nexport interface ShowIssueParams {\n issue_id: string;\n}\n\nexport interface UpsertIssueParams {\n issue_id?: string; // If provided, update; otherwise create\n title?: string; // Required for create, optional for update\n description?: string;\n priority?: number;\n parent?: string;\n tags?: string[];\n status?: IssueStatus;\n archived?: boolean;\n // TODO: Reintroduce assignee later on when first-class agents are supported.\n}\n\n// Tool implementations\n\n/**\n * Find issues ready to work on (no blockers) and get project status\n */\nexport async function ready(\n client: SudocodeClient,\n params: ReadyParams = {}\n): Promise<any> {\n const readyResult = await client.exec([\"ready\"]);\n const statusResult = await client.exec([\"status\"]);\n\n // Redact content field from issues to keep response shorter\n if (readyResult.issues && Array.isArray(readyResult.issues)) {\n readyResult.issues = readyResult.issues.map((issue: any) => {\n const { content, ...rest } = issue;\n return rest;\n });\n }\n\n return {\n ready: readyResult,\n status: statusResult,\n };\n}\n\n/**\n * List all issues with optional filters\n */\nexport async function listIssues(\n client: SudocodeClient,\n params: ListIssuesParams = {}\n): Promise<Issue[]> {\n const args = [\"issue\", \"list\"];\n\n if (params.status) {\n args.push(\"--status\", params.status);\n }\n if (params.priority !== undefined) {\n args.push(\"--priority\", params.priority.toString());\n }\n if (params.limit !== undefined) {\n args.push(\"--limit\", params.limit.toString());\n }\n if (params.search) {\n args.push(\"--grep\", params.search);\n }\n // Default to excluding archived unless explicitly specified\n const archived = params.archived !== undefined ? params.archived : false;\n args.push(\"--archived\", archived.toString());\n\n const issues = await client.exec(args);\n\n // Redact content field from issues to keep response shorter\n if (Array.isArray(issues)) {\n return issues.map((issue: any) => {\n const { content, ...rest } = issue;\n return rest;\n });\n }\n\n return issues;\n}\n\n/**\n * Show detailed issue information including relationships and feedback\n */\nexport async function showIssue(\n client: SudocodeClient,\n params: ShowIssueParams\n): Promise<any> {\n const args = [\"issue\", \"show\", params.issue_id];\n return client.exec(args);\n}\n\n/**\n * Upsert an issue (create if no issue_id, update if issue_id provided)\n */\nexport async function upsertIssue(\n client: SudocodeClient,\n params: UpsertIssueParams\n): Promise<Issue> {\n const isUpdate = !!params.issue_id;\n\n if (isUpdate) {\n // Update mode\n const args = [\"issue\", \"update\", params.issue_id!];\n\n if (params.status) {\n args.push(\"--status\", params.status);\n }\n if (params.priority !== undefined) {\n args.push(\"--priority\", params.priority.toString());\n }\n if (params.title) {\n args.push(\"--title\", params.title);\n }\n if (params.description) {\n args.push(\"--description\", params.description);\n }\n if (params.archived !== undefined) {\n args.push(\"--archived\", params.archived.toString());\n }\n\n return client.exec(args);\n } else {\n // Create mode\n if (!params.title) {\n throw new Error(\"title is required when creating a new issue\");\n }\n\n const args = [\"issue\", \"create\", params.title];\n\n if (params.description) {\n args.push(\"--description\", params.description);\n }\n if (params.priority !== undefined) {\n args.push(\"--priority\", params.priority.toString());\n }\n if (params.parent) {\n args.push(\"--parent\", params.parent);\n }\n if (params.tags && params.tags.length > 0) {\n args.push(\"--tags\", params.tags.join(\",\"));\n }\n\n return client.exec(args);\n }\n}\n", "/**\n * MCP tools for spec management\n */\n\nimport { SudocodeClient } from \"../client.js\";\nimport { Spec } from \"../types.js\";\n\n// Tool parameter types\nexport interface ListSpecsParams {\n limit?: number;\n search?: string;\n archived?: boolean;\n}\n\nexport interface ShowSpecParams {\n spec_id: string;\n}\n\nexport interface UpsertSpecParams {\n spec_id?: string; // If provided, update; otherwise create\n title?: string; // Required for create, optional for update\n priority?: number;\n description?: string;\n parent?: string;\n tags?: string[];\n archived?: boolean;\n}\n\n// Tool implementations\n\n/**\n * List all specs with optional filters\n */\nexport async function listSpecs(\n client: SudocodeClient,\n params: ListSpecsParams = {}\n): Promise<Spec[]> {\n const args = [\"spec\", \"list\"];\n\n if (params.limit !== undefined) {\n args.push(\"--limit\", params.limit.toString());\n }\n if (params.search) {\n args.push(\"--grep\", params.search);\n }\n // Default to excluding archived unless explicitly specified\n const archived = params.archived !== undefined ? params.archived : false;\n args.push(\"--archived\", archived.toString());\n\n const specs = await client.exec(args);\n\n // Redact content field from specs to keep response shorter\n if (Array.isArray(specs)) {\n return specs.map((spec: any) => {\n const { content, ...rest } = spec;\n return rest;\n });\n }\n\n return specs;\n}\n\n/**\n * Show detailed spec information including feedback\n */\nexport async function showSpec(\n client: SudocodeClient,\n params: ShowSpecParams\n): Promise<any> {\n const args = [\"spec\", \"show\", params.spec_id];\n return client.exec(args);\n}\n\n/**\n * Upsert a spec (create if no spec_id, update if spec_id provided)\n */\nexport async function upsertSpec(\n client: SudocodeClient,\n params: UpsertSpecParams\n): Promise<Spec> {\n const isUpdate = !!params.spec_id;\n\n if (isUpdate) {\n // Update mode\n const args = [\"spec\", \"update\", params.spec_id!];\n\n if (params.title) {\n args.push(\"--title\", params.title);\n }\n if (params.priority !== undefined) {\n args.push(\"--priority\", params.priority.toString());\n }\n if (params.description) {\n args.push(\"--description\", params.description);\n }\n if (params.parent !== undefined) {\n args.push(\"--parent\", params.parent || \"\");\n }\n if (params.tags !== undefined) {\n args.push(\"--tags\", params.tags.join(\",\"));\n }\n if (params.archived !== undefined) {\n args.push(\"--archived\", params.archived.toString());\n }\n\n return client.exec(args);\n } else {\n // Create mode\n if (!params.title) {\n throw new Error(\"title is required when creating a new spec\");\n }\n\n const args = [\"spec\", \"create\", params.title];\n\n if (params.priority !== undefined) {\n args.push(\"--priority\", params.priority.toString());\n }\n if (params.description) {\n args.push(\"--description\", params.description);\n }\n if (params.parent) {\n args.push(\"--parent\", params.parent);\n }\n if (params.tags && params.tags.length > 0) {\n args.push(\"--tags\", params.tags.join(\",\"));\n }\n\n return client.exec(args);\n }\n}\n", "/**\n * MCP tools for relationship management\n */\n\nimport { SudocodeClient } from \"../client.js\";\n\n// Tool parameter types\nexport type RelationshipType =\n | \"blocks\"\n | \"implements\"\n | \"references\"\n | \"depends-on\"\n | \"discovered-from\"\n | \"related\";\n\nexport interface LinkParams {\n from_id: string;\n to_id: string;\n type?: RelationshipType;\n}\n\n// Tool implementation\n\n/**\n * Create a relationship between two entities (specs or issues)\n */\nexport async function link(\n client: SudocodeClient,\n params: LinkParams\n): Promise<any> {\n const args = [\"link\", params.from_id, params.to_id];\n\n if (params.from_id === params.to_id) {\n throw new Error(\"from_id and to_id cannot be the same\");\n }\n if (params.type) {\n args.push(\"--type\", params.type);\n }\n\n return client.exec(args);\n}\n", "/**\n * MCP tools for feedback management\n */\n\nimport { SudocodeClient } from \"../client.js\";\nimport { Feedback, FeedbackType } from \"../types.js\";\n\n// Tool parameter types\nexport interface AddFeedbackParams {\n issue_id: string;\n spec_id: string;\n content: string;\n type?: FeedbackType;\n line?: number;\n text?: string;\n agent?: string;\n}\n\n/**\n * Add anchored feedback to a spec\n */\nexport async function addFeedback(\n client: SudocodeClient,\n params: AddFeedbackParams\n): Promise<Feedback> {\n const args = [\"feedback\", \"add\", params.issue_id, params.spec_id];\n\n args.push(\"--content\", params.content);\n\n if (params.type) {\n args.push(\"--type\", params.type);\n }\n if (params.line !== undefined) {\n args.push(\"--line\", params.line.toString());\n }\n if (params.text) {\n args.push(\"--text\", params.text);\n }\n // if (params.agent) {\n // args.push(\"--agent\", params.agent);\n // }\n\n return client.exec(args);\n}\n", "/**\n * MCP tools for reference management\n */\n\nimport { SudocodeClient } from \"../client.js\";\n\n// Tool parameter types\nexport interface AddReferenceParams {\n entity_id: string;\n reference_id: string;\n display_text?: string;\n relationship_type?: string;\n line?: number;\n text?: string;\n format?: \"inline\" | \"newline\";\n position?: \"before\" | \"after\";\n}\n\n/**\n * Add a cross-reference to a spec or issue\n *\n * Tries spec first, then issue. The CLI command handles entity validation.\n */\nexport async function addReference(\n client: SudocodeClient,\n params: AddReferenceParams\n): Promise<any> {\n // Build command args\n const buildArgs = (command: \"spec\" | \"issue\") => {\n const args = [command, \"add-ref\", params.entity_id, params.reference_id];\n\n if (params.line !== undefined) {\n args.push(\"--line\", params.line.toString());\n }\n if (params.text) {\n args.push(\"--text\", params.text);\n }\n if (params.display_text) {\n args.push(\"--display\", params.display_text);\n }\n if (params.relationship_type) {\n args.push(\"--type\", params.relationship_type);\n }\n if (params.format) {\n args.push(\"--format\", params.format);\n }\n if (params.position) {\n args.push(\"--position\", params.position);\n }\n\n return args;\n };\n\n // TODO: Infer entity type from ID pattern if possible.\n // Try spec first\n try {\n return await client.exec(buildArgs(\"spec\"));\n } catch (specError) {\n // If spec command fails, try issue\n try {\n return await client.exec(buildArgs(\"issue\"));\n } catch (issueError) {\n // If both fail, throw the issue error (it will have the proper error message)\n throw issueError;\n }\n }\n}\n", "#!/usr/bin/env node\n\n/**\n * sudocode MCP Server entry point\n */\n\nimport { SudocodeMCPServer } from \"./server.js\";\nimport { SudocodeClientConfig } from \"./types.js\";\n\nfunction parseArgs(): SudocodeClientConfig {\n const config: SudocodeClientConfig = {};\n const args = process.argv.slice(2);\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n switch (arg) {\n case \"--working-dir\":\n case \"-w\":\n config.workingDir = args[++i];\n break;\n case \"--cli-path\":\n config.cliPath = args[++i];\n break;\n case \"--db-path\":\n case \"--db\":\n config.dbPath = args[++i];\n break;\n case \"--no-sync\":\n config.syncOnStartup = false;\n break;\n case \"--help\":\n case \"-h\":\n console.log(`\nsudocode MCP Server\n\nUsage: sudocode-mcp [options]\n\nOptions:\n -w, --working-dir <path> Working directory (default: cwd or SUDOCODE_WORKING_DIR)\n --cli-path <path> Path to sudocode CLI (default: 'sudocode' or SUDOCODE_PATH)\n --db-path <path> Database path (default: auto-discover or SUDOCODE_DB)\n --no-sync Skip initial sync on startup (default: sync enabled)\n -h, --help Show this help message\n\nEnvironment Variables:\n SUDOCODE_WORKING_DIR Default working directory\n SUDOCODE_PATH Default CLI path\n SUDOCODE_DB Default database path\n `);\n process.exit(0);\n break;\n default:\n console.error(`Unknown option: ${arg}`);\n console.error(\"Use --help for usage information\");\n process.exit(1);\n }\n }\n\n return config;\n}\n\nasync function main() {\n const config = parseArgs();\n const server = new SudocodeMCPServer(config);\n await server.run();\n}\n\nmain().catch((error) => {\n console.error(\"Fatal error:\", error);\n process.exit(1);\n});\n"],
|
|
5
|
-
"mappings": "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EAChB,CACE,KAAM,WACN,QAAS,OACX,EACA,CACE,aAAc,CACZ,MAAO,CAAC,EACR,UAAW,CAAC,CACd,CACF,CACF,EAEA,KAAK,OAAS,IAAIC,EAAeF,CAAM,EACvC,KAAK,cAAc,CACrB,CAEQ,eAAgB,CAEtB,KAAK,OAAO,kBAAkBG,EAAwB,UAC7C,CACL,MAAO,CACL,CACE,KAAM,QACN,YACE,sEACF,YAAa,CACX,KAAM,SACN,WAAY,CAAC,CACf,CACF,EACA,CACE,KAAM,cACN,YAAa,wCACb,YAAa,CACX,KAAM,SACN,WAAY,CACV,OAAQ,CACN,KAAM,SACN,KAAM,CAAC,OAAQ,cAAe,UAAW,QAAQ,EACjD,YAAa,6BACf,EACA,SAAU,CACR,KAAM,SACN,YAAa,qCACf,EACA,SAAU,CACR,KAAM,UACN,YACE,6EACJ,EACA,MAAO,CACL,KAAM,SACN,YAAa,yBACb,QAAS,EACX,EACA,OAAQ,CACN,KAAM,SACN,YACE,kDACJ,CACF,CACF,CACF,EACA,CACE,KAAM,aACN,YACE,uEACF,YAAa,CACX,KAAM,SACN,WAAY,CACV,SAAU,CACR,KAAM,SACN,YAAa,8BACf,CACF,EACA,SAAU,CAAC,UAAU,CACvB,CACF,EACA,CACE,KAAM,eACN,YACE,sLACF,YAAa,CACX,KAAM,SACN,WAAY,CACV,SAAU,CACR,KAAM,SACN,YACE,2EACJ,EACA,MAAO,CACL,KAAM,SACN,YACE,wDACJ,EACA,YAAa,CACX,KAAM,SACN,YACE,oIACJ,EACA,SAAU,CACR,KAAM,SACN,YAAa,sCACf,EACA,OAAQ,CACN,KAAM,SACN,YAAa,4BACf,EACA,KAAM,CACJ,KAAM,QACN,MAAO,CAAE,KAAM,QAAS,EACxB,YAAa,iBACf,EACA,OAAQ,CACN,KAAM,SACN,KAAM,CAAC,OAAQ,cAAe,UAAW,QAAQ,EACjD,YAAa,yBACf,EACA,SAAU,CACR,KAAM,UACN,YAAa,2BACf,CACF,CACF,CACF,EACA,CACE,KAAM,aACN,YAAa,uCACb,YAAa,CACX,KAAM,SACN,WAAY,CACV,MAAO,CACL,KAAM,SACN,YAAa,yBACb,QAAS,EACX,EACA,OAAQ,CACN,KAAM,SACN,YACE,iDACJ,CACF,CACF,CACF,EACA,CACE,KAAM,YACN,YACE,6EACF,YAAa,CACX,KAAM,SACN,WAAY,CACV,QAAS,CACP,KAAM,SACN,YAAa,4BACf,CACF,EACA,SAAU,CAAC,SAAS,CACtB,CACF,EACA,CACE,KAAM,cACN,YAAa,sDACb,YAAa,CACX,KAAM,SACN,WAAY,CACV,QAAS,CACP,KAAM,SACN,YACE,yEACJ,EACA,MAAO,CACL,KAAM,SACN,YAAa,kCACf,EACA,SAAU,CACR,KAAM,SACN,YAAa,sCACf,EACA,YAAa,CACX,KAAM,SACN,YAAa,6BACf,EACA,OAAQ,CACN,KAAM,SACN,YAAa,2BACf,EACA,KAAM,CACJ,KAAM,QACN,MAAO,CAAE,KAAM,QAAS,EACxB,YAAa,iBACf,CACF,CACF,CACF,EACA,CACE,KAAM,OACN,YACE,+DACF,YAAa,CACX,KAAM,SACN,WAAY,CACV,QAAS,CACP,KAAM,SACN,YAAa,kBACf,EACA,MAAO,CACL,KAAM,SACN,YAAa,kBACf,EACA,KAAM,CACJ,KAAM,SACN,KAAM,CACJ,SACA,aACA,aACA,aACA,kBACA,SACF,EACA,YAAa,mBACf,CACF,EACA,SAAU,CAAC,UAAW,OAAO,CAC/B,CACF,EACA,CACE,KAAM,gBACN,YACE,qQACF,YAAa,CACX,KAAM,SACN,WAAY,CACV,UAAW,CACT,KAAM,SACN,YAAa,+CACf,EACA,aAAc,CACZ,KAAM,SACN,YAAa,6CACf,EACA,aAAc,CACZ,KAAM,SACN,YAAa,yBACf,EACA,kBAAmB,CACjB,KAAM,SACN,KAAM,CACJ,SACA,aACA,aACA,aACA,kBACA,SACF,EACA,YAAa,8BACf,EACA,KAAM,CACJ,KAAM,SACN,YACE,8DACJ,EACA,KAAM,CACJ,KAAM,SACN,YACE,iEACJ,EACA,OAAQ,CACN,KAAM,SACN,KAAM,CAAC,SAAU,SAAS,EAC1B,YACE,mDACF,QAAS,QACX,CAEF,EACA,SAAU,CAAC,YAAa,cAAc,CACxC,CACF,E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",
|
|
6
|
-
"names": ["Server", "StdioServerTransport", "CallToolRequestSchema", "ListResourcesRequestSchema", "ListToolsRequestSchema", "ReadResourceRequestSchema", "spawn", "fileURLToPath", "dirname", "join", "existsSync", "SudocodeError", "message", "exitCode", "stderr", "SudocodeClient", "config", "workingDir", "cliInfo", "currentFile", "fileURLToPath", "currentDir", "dirname", "possiblePaths", "join", "cliJsPath", "existsSync", "args", "options", "cmdArgs", "resolve", "reject", "proc", "spawn", "stdout", "stderr", "data", "timeout", "timer", "SudocodeError", "code", "result", "error", "versionMatch", "version", "ready", "client", "params", "readyResult", "statusResult", "issue", "content", "rest", "listIssues", "args", "archived", "issues", "showIssue", "upsertIssue", "listSpecs", "client", "params", "args", "archived", "specs", "spec", "content", "rest", "showSpec", "upsertSpec", "link", "client", "params", "args", "addFeedback", "client", "params", "args", "addReference", "client", "params", "buildArgs", "command", "args", "issueError", "existsSync", "join", "SudocodeMCPServer", "config", "Server", "SudocodeClient", "ListToolsRequestSchema", "CallToolRequestSchema", "request", "name", "args", "result", "ready", "listIssues", "showIssue", "upsertIssue", "listSpecs", "showSpec", "upsertSpec", "link", "addReference", "addFeedback", "error", "errorText", "ListResourcesRequestSchema", "ReadResourceRequestSchema", "uri", "workingDir", "sudocodeDir", "cacheDbPath", "issuesPath", "specsPath", "initStatus", "transport", "StdioServerTransport", "parseArgs", "config", "args", "i", "arg", "main", "SudocodeMCPServer", "error"]
|
|
7
|
-
}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;GAEG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,SAAS,SAAS;IAChB,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,eAAe,CAAC;YACrB,KAAK,IAAI;gBACP,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC9B,MAAM;YACR,KAAK,YAAY;gBACf,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC3B,MAAM;YACR,KAAK,WAAW,CAAC;YACjB,KAAK,MAAM;gBACT,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC1B,MAAM;YACR,KAAK,WAAW;gBACd,MAAM,CAAC,aAAa,GAAG,KAAK,CAAC;gBAC7B,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;SAgBX,CAAC,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAChB,MAAM;YACR;gBACE,OAAO,CAAC,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;gBACxC,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;AACrB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|