@hiabhee/archdraw-mcp-server 1.0.5 → 1.0.6
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/README.md +119 -0
- package/dist/cli/project-link.d.ts +18 -0
- package/dist/cli/project-link.d.ts.map +1 -0
- package/dist/cli/project-link.js +129 -0
- package/dist/cli/project-link.js.map +1 -0
- package/dist/index.js +16 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/project-binding.d.ts +29 -0
- package/dist/lib/project-binding.d.ts.map +1 -0
- package/dist/lib/project-binding.js +57 -0
- package/dist/lib/project-binding.js.map +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# @hiabhee/archdraw-mcp-server
|
|
2
|
+
|
|
3
|
+
The MCP server for [ArchDraw](https://archdraw.hiabhee.online). It lets an AI agent make, change, validate, and export software architecture diagrams.
|
|
4
|
+
|
|
5
|
+
The server uses the same Mermaid → Dagre layout pipeline as the ArchDraw editor. Each new diagram gets a preview link that you can open in a browser.
|
|
6
|
+
|
|
7
|
+
This document uses ASD-STE100 Simplified Technical English.
|
|
8
|
+
|
|
9
|
+
## Select a connection type
|
|
10
|
+
|
|
11
|
+
| Connection type | Value | Use it when |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| **Remote (HTTP)** | `https://archdraw.hiabhee.online/api/mcp` | The client can connect to a remote MCP server. This is the recommended type. You do not install this package. |
|
|
14
|
+
| **Local (stdio)** | `npx -y @hiabhee/archdraw-mcp-server@1.0.6` | The client can only start a local process. |
|
|
15
|
+
|
|
16
|
+
For the steps for each client (Claude Code, Claude apps, Codex, Cursor, VS Code, Gemini CLI, OpenCode, and others), refer to the [connection guide](https://archdraw.hiabhee.online/docs/connect-agents).
|
|
17
|
+
|
|
18
|
+
## Use the local server
|
|
19
|
+
|
|
20
|
+
### Requirements
|
|
21
|
+
|
|
22
|
+
- Node.js 18 or later
|
|
23
|
+
- Network access to `archdraw.hiabhee.online`
|
|
24
|
+
|
|
25
|
+
### Configuration
|
|
26
|
+
|
|
27
|
+
Most clients use this format:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"mcpServers": {
|
|
32
|
+
"archdraw": {
|
|
33
|
+
"command": "npx",
|
|
34
|
+
"args": ["-y", "@hiabhee/archdraw-mcp-server@1.0.6"],
|
|
35
|
+
"env": {
|
|
36
|
+
"API_BASE_URL": "https://archdraw.hiabhee.online"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> **CAUTION:** You must set `API_BASE_URL`. If you do not set it, the server starts and shows its tools, but `generate_diagram`, `fix_layout`, and preview links do not operate.
|
|
44
|
+
|
|
45
|
+
### Environment variables
|
|
46
|
+
|
|
47
|
+
| Variable | Necessary | Function |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| `API_BASE_URL` | Yes | The ArchDraw web API that does the layout, publishes previews, and keeps sessions. Use `https://archdraw.hiabhee.online`, or the URL of your own deployment. |
|
|
50
|
+
|
|
51
|
+
## Link a repository to a live project
|
|
52
|
+
|
|
53
|
+
A live project is an ArchDraw canvas that shows which coding-agent session works on which component. To connect a repository to a live project:
|
|
54
|
+
|
|
55
|
+
1. In the ArchDraw editor, open the canvas and select **Make live project**.
|
|
56
|
+
2. In the repository, run:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx -y @hiabhee/archdraw-mcp-server@1.0.6 link --api https://archdraw.hiabhee.online
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
3. In the editor, select **Live project → Connect an agent** and enter the code that the command shows.
|
|
63
|
+
|
|
64
|
+
The command keeps the link in `~/.archdraw/projects.json` (mode `0600`), outside the repository. The file contains a project token. Do not share it. Other commands:
|
|
65
|
+
|
|
66
|
+
| Command | Result |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| `link --api <URL>` | Links the current repository (or its main repository, for a git worktree). |
|
|
69
|
+
| `status` | Shows the project that the current repository is linked to. |
|
|
70
|
+
| `unlink` | Removes the local link. To revoke the token, select **Stop** in the editor. |
|
|
71
|
+
|
|
72
|
+
The ArchDraw plugin for Claude Code uses this link to report the files that each session edits. It sends file paths only.
|
|
73
|
+
|
|
74
|
+
## Tools
|
|
75
|
+
|
|
76
|
+
| Tool | Function |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| `read_me` | Gives the reference guide for the agent. The agent calls it first. |
|
|
79
|
+
| `generate_diagram` | Makes a diagram from Mermaid text or from nodes and edges. |
|
|
80
|
+
| `update_diagram` | Adds, removes, or changes nodes and edges in the current diagram. |
|
|
81
|
+
| `get_diagram_state` | Gives the nodes and edges of the current diagram. |
|
|
82
|
+
| `validate_diagram` | Finds structural problems and gives recommendations. |
|
|
83
|
+
| `fix_layout` | Calculates the layout again with the ArchDraw editor pipeline. |
|
|
84
|
+
| `apply_template` | Loads an architecture template. |
|
|
85
|
+
| `list_templates` | Gives the list of templates. |
|
|
86
|
+
| `list_node_types` | Gives the list of component types in the ArchDraw library. |
|
|
87
|
+
| `save_checkpoint` | Saves the current diagram with a name. |
|
|
88
|
+
| `load_checkpoint` | Restores a saved diagram. |
|
|
89
|
+
| `export_diagram` | Exports the diagram as JSON, PNG, or SVG. |
|
|
90
|
+
|
|
91
|
+
## Data and privacy
|
|
92
|
+
|
|
93
|
+
- The server sends the diagram content that the agent gives it to `API_BASE_URL`. This includes component names, labels, connections, and Mermaid text. The server does not read your source files.
|
|
94
|
+
- Each new diagram gets a preview link by default. Anyone with the link can see the diagram. The link expires after 7 days. To prevent a link, tell the agent to keep the diagram private (`publish: false`).
|
|
95
|
+
- The local server keeps the working diagram and its checkpoints in memory. It discards them when the process stops.
|
|
96
|
+
|
|
97
|
+
> **WARNING:** Do not put passwords, API keys, or other secrets in diagram labels.
|
|
98
|
+
|
|
99
|
+
Refer to the [privacy policy](https://archdraw.hiabhee.online/privacy).
|
|
100
|
+
|
|
101
|
+
## Use the server in your own code
|
|
102
|
+
|
|
103
|
+
The package exports a server factory for Streamable HTTP hosts:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { createArchDrawMCPServer, handleMcpHttpRequest } from '@hiabhee/archdraw-mcp-server/server';
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The hosted endpoint at `/api/mcp` uses this export.
|
|
110
|
+
|
|
111
|
+
## Links
|
|
112
|
+
|
|
113
|
+
- [Source code](https://github.com/hiabhee/ArchDraw/tree/main/mcp-server)
|
|
114
|
+
- [Connection guide](https://archdraw.hiabhee.online/docs/connect-agents)
|
|
115
|
+
- [Issues](https://github.com/hiabhee/ArchDraw/issues)
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `archdraw-mcp-server link|unlink|status` — pair this git checkout with an
|
|
3
|
+
* ArchDraw live project. Pairing uses the browser approval flow
|
|
4
|
+
* (`/api/agentic/pairing`): the CLI shows a code, the user enters it in the
|
|
5
|
+
* editor's Live project panel, and the CLI receives a project-scoped token.
|
|
6
|
+
* Output goes to stderr except the final machine-readable line.
|
|
7
|
+
*/
|
|
8
|
+
export declare const PROJECT_COMMANDS: Set<string>;
|
|
9
|
+
interface CliIO {
|
|
10
|
+
log: (message: string) => void;
|
|
11
|
+
fetch: typeof fetch;
|
|
12
|
+
sleep: (ms: number) => Promise<void>;
|
|
13
|
+
cwd: string;
|
|
14
|
+
env: NodeJS.ProcessEnv;
|
|
15
|
+
}
|
|
16
|
+
export declare function runProjectCommand(command: string, argv: string[], io?: CliIO): Promise<number>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=project-link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-link.d.ts","sourceRoot":"","sources":["../../src/cli/project-link.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,eAAO,MAAM,gBAAgB,aAAwC,CAAC;AAItE,UAAU,KAAK;IACb,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACxB;AA0HD,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,KAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAKjH"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { getBinding, removeBinding, resolveRepoRoot, saveBinding, bindingFilePath } from '../lib/project-binding.js';
|
|
2
|
+
/**
|
|
3
|
+
* `archdraw-mcp-server link|unlink|status` — pair this git checkout with an
|
|
4
|
+
* ArchDraw live project. Pairing uses the browser approval flow
|
|
5
|
+
* (`/api/agentic/pairing`): the CLI shows a code, the user enters it in the
|
|
6
|
+
* editor's Live project panel, and the CLI receives a project-scoped token.
|
|
7
|
+
* Output goes to stderr except the final machine-readable line.
|
|
8
|
+
*/
|
|
9
|
+
export const PROJECT_COMMANDS = new Set(['link', 'unlink', 'status']);
|
|
10
|
+
const POLL_INTERVAL_MS = 3000;
|
|
11
|
+
const defaultIO = () => ({
|
|
12
|
+
log: (message) => process.stderr.write(`${message}\n`),
|
|
13
|
+
fetch,
|
|
14
|
+
sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
|
|
15
|
+
cwd: process.cwd(),
|
|
16
|
+
env: process.env,
|
|
17
|
+
});
|
|
18
|
+
function parseArgs(argv) {
|
|
19
|
+
const flags = {};
|
|
20
|
+
for (let i = 0; i < argv.length; i++) {
|
|
21
|
+
const arg = argv[i];
|
|
22
|
+
if (arg.startsWith('--')) {
|
|
23
|
+
const [key, inline] = arg.slice(2).split('=', 2);
|
|
24
|
+
flags[key] = inline ?? argv[++i] ?? '';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return flags;
|
|
28
|
+
}
|
|
29
|
+
function formatUserCode(code) {
|
|
30
|
+
return code.match(/.{1,4}/g)?.join('-') ?? code;
|
|
31
|
+
}
|
|
32
|
+
function normalizeApiBase(value) {
|
|
33
|
+
if (!value)
|
|
34
|
+
return null;
|
|
35
|
+
try {
|
|
36
|
+
const url = new URL(value);
|
|
37
|
+
if (url.protocol !== 'https:' && !['localhost', '127.0.0.1'].includes(url.hostname))
|
|
38
|
+
return null;
|
|
39
|
+
return url.origin;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function link(flags, io) {
|
|
46
|
+
const apiBase = normalizeApiBase(flags.api || io.env.API_BASE_URL);
|
|
47
|
+
if (!apiBase) {
|
|
48
|
+
io.log('Pass the ArchDraw URL: link --api https://archdraw.hiabhee.online (https, or http://localhost for development).');
|
|
49
|
+
return 2;
|
|
50
|
+
}
|
|
51
|
+
const repoRoot = resolveRepoRoot(io.cwd);
|
|
52
|
+
const start = await io.fetch(`${apiBase}/api/agentic/pairing`, { method: 'POST' });
|
|
53
|
+
if (!start.ok) {
|
|
54
|
+
io.log(`Could not start pairing (${start.status}).`);
|
|
55
|
+
return 1;
|
|
56
|
+
}
|
|
57
|
+
const pairing = (await start.json());
|
|
58
|
+
io.log('');
|
|
59
|
+
io.log(`Linking ${repoRoot} to an ArchDraw live project.`);
|
|
60
|
+
io.log(`Open your project canvas in ArchDraw → Live project → Connect an agent, and enter:`);
|
|
61
|
+
io.log('');
|
|
62
|
+
io.log(` ${formatUserCode(pairing.userCode)}`);
|
|
63
|
+
io.log('');
|
|
64
|
+
io.log(`Waiting for approval (expires ${new Date(pairing.expiresAt).toLocaleTimeString()})…`);
|
|
65
|
+
const deadline = new Date(pairing.expiresAt).getTime();
|
|
66
|
+
while (Date.now() < deadline) {
|
|
67
|
+
await io.sleep(POLL_INTERVAL_MS);
|
|
68
|
+
const res = await io.fetch(`${apiBase}/api/agentic/pairing/poll`, {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
headers: { 'Content-Type': 'application/json' },
|
|
71
|
+
body: JSON.stringify({ pairingId: pairing.pairingId, pollToken: pairing.pollToken }),
|
|
72
|
+
});
|
|
73
|
+
if (res.status === 202)
|
|
74
|
+
continue;
|
|
75
|
+
if (res.status === 410)
|
|
76
|
+
break;
|
|
77
|
+
const body = (await res.json().catch(() => ({})));
|
|
78
|
+
if (res.ok && body.status === 'complete' && body.projectId && body.workspaceId) {
|
|
79
|
+
if (!body.canvasId) {
|
|
80
|
+
io.log('Approved, but that project is not linked to a canvas. Use "Make live project" on a canvas and try again.');
|
|
81
|
+
return 1;
|
|
82
|
+
}
|
|
83
|
+
saveBinding(repoRoot, {
|
|
84
|
+
apiBase,
|
|
85
|
+
canvasId: body.canvasId,
|
|
86
|
+
agenticProjectId: body.projectId,
|
|
87
|
+
workspaceId: body.workspaceId,
|
|
88
|
+
token: pairing.pollToken,
|
|
89
|
+
linkedAt: new Date().toISOString(),
|
|
90
|
+
});
|
|
91
|
+
io.log(`Linked. Credentials saved to ${bindingFilePath()} (outside the repository).`);
|
|
92
|
+
io.log(`Project canvas: ${apiBase}/editor?canvas=${encodeURIComponent(body.canvasId)}`);
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
if (!res.ok && res.status !== 409) {
|
|
96
|
+
io.log(`Pairing failed (${res.status}).`);
|
|
97
|
+
return 1;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
io.log('Pairing code expired. Run link again.');
|
|
101
|
+
return 1;
|
|
102
|
+
}
|
|
103
|
+
function unlink(io) {
|
|
104
|
+
const repoRoot = resolveRepoRoot(io.cwd);
|
|
105
|
+
const removed = removeBinding(repoRoot);
|
|
106
|
+
io.log(removed
|
|
107
|
+
? `Unlinked ${repoRoot}. To revoke the credential too, use "Stop" in the editor's Live project panel.`
|
|
108
|
+
: `${repoRoot} is not linked.`);
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
function status(io) {
|
|
112
|
+
const repoRoot = resolveRepoRoot(io.cwd);
|
|
113
|
+
const binding = getBinding(repoRoot);
|
|
114
|
+
if (!binding) {
|
|
115
|
+
io.log(`${repoRoot} is not linked to an ArchDraw project.`);
|
|
116
|
+
return 1;
|
|
117
|
+
}
|
|
118
|
+
io.log(`${repoRoot} → ${binding.apiBase}/editor?canvas=${encodeURIComponent(binding.canvasId)} (linked ${binding.linkedAt})`);
|
|
119
|
+
return 0;
|
|
120
|
+
}
|
|
121
|
+
export async function runProjectCommand(command, argv, io = defaultIO()) {
|
|
122
|
+
const flags = parseArgs(argv);
|
|
123
|
+
if (command === 'link')
|
|
124
|
+
return link(flags, io);
|
|
125
|
+
if (command === 'unlink')
|
|
126
|
+
return unlink(io);
|
|
127
|
+
return status(io);
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=project-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-link.js","sourceRoot":"","sources":["../../src/cli/project-link.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import { createArchDrawMCPServer } from './server.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
.
|
|
4
|
+
import { PROJECT_COMMANDS, runProjectCommand } from './cli/project-link.js';
|
|
5
|
+
const command = process.argv[2];
|
|
6
|
+
if (command && PROJECT_COMMANDS.has(command)) {
|
|
7
|
+
runProjectCommand(command, process.argv.slice(3))
|
|
8
|
+
.then((code) => process.exit(code))
|
|
9
|
+
.catch((error) => {
|
|
10
|
+
console.error(error instanceof Error ? error.message : error);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
const server = createArchDrawMCPServer();
|
|
16
|
+
server.connect(new StdioServerTransport())
|
|
17
|
+
.then(() => console.error('ArchDraw MCP server running on stdio'))
|
|
18
|
+
.catch(console.error);
|
|
19
|
+
}
|
|
8
20
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE5E,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChC,IAAI,OAAO,IAAI,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7C,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC9C,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAClC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC;KAAM,CAAC;IACN,MAAM,MAAM,GAAG,uBAAuB,EAAE,CAAC;IACzC,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC;SACvC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;SACjE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local link between a git checkout and an ArchDraw live project canvas.
|
|
3
|
+
* Stored outside the repository (never committed) in
|
|
4
|
+
* `~/.archdraw/projects.json`, mode 0600. The plugin hook script reads the
|
|
5
|
+
* same file — keep the format stable (`version: 1`).
|
|
6
|
+
*/
|
|
7
|
+
export interface ProjectBinding {
|
|
8
|
+
apiBase: string;
|
|
9
|
+
canvasId: string;
|
|
10
|
+
agenticProjectId: string;
|
|
11
|
+
workspaceId: string;
|
|
12
|
+
/** Project-scoped `adp_` agent credential. Never print or log it. */
|
|
13
|
+
token: string;
|
|
14
|
+
linkedAt: string;
|
|
15
|
+
}
|
|
16
|
+
interface BindingFile {
|
|
17
|
+
version: 1;
|
|
18
|
+
projects: Record<string, ProjectBinding>;
|
|
19
|
+
}
|
|
20
|
+
export declare function archdrawHome(): string;
|
|
21
|
+
export declare function bindingFilePath(): string;
|
|
22
|
+
/** Repository root for `cwd` (git top-level), falling back to cwd itself. */
|
|
23
|
+
export declare function resolveRepoRoot(cwd?: string): string;
|
|
24
|
+
export declare function readBindings(): BindingFile;
|
|
25
|
+
export declare function getBinding(repoRoot: string): ProjectBinding | undefined;
|
|
26
|
+
export declare function saveBinding(repoRoot: string, binding: ProjectBinding): void;
|
|
27
|
+
export declare function removeBinding(repoRoot: string): boolean;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=project-binding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-binding.d.ts","sourceRoot":"","sources":["../../src/lib/project-binding.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,WAAW;IACnB,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC1C;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAMnE;AAED,wBAAgB,YAAY,IAAI,WAAW,CAS1C;AAYD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEvE;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,QAIpE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMvD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { join, resolve } from 'node:path';
|
|
5
|
+
export function archdrawHome() {
|
|
6
|
+
return process.env.ARCHDRAW_HOME || join(homedir(), '.archdraw');
|
|
7
|
+
}
|
|
8
|
+
export function bindingFilePath() {
|
|
9
|
+
return join(archdrawHome(), 'projects.json');
|
|
10
|
+
}
|
|
11
|
+
/** Repository root for `cwd` (git top-level), falling back to cwd itself. */
|
|
12
|
+
export function resolveRepoRoot(cwd = process.cwd()) {
|
|
13
|
+
try {
|
|
14
|
+
return execFileSync('git', ['rev-parse', '--show-toplevel'], { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return resolve(cwd);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function readBindings() {
|
|
21
|
+
const path = bindingFilePath();
|
|
22
|
+
if (!existsSync(path))
|
|
23
|
+
return { version: 1, projects: {} };
|
|
24
|
+
try {
|
|
25
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
26
|
+
return { version: 1, projects: parsed.projects && typeof parsed.projects === 'object' ? parsed.projects : {} };
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return { version: 1, projects: {} };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function writeBindings(file) {
|
|
33
|
+
const dir = archdrawHome();
|
|
34
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
35
|
+
const path = bindingFilePath();
|
|
36
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
37
|
+
writeFileSync(tmp, `${JSON.stringify(file, null, 2)}\n`, { mode: 0o600 });
|
|
38
|
+
renameSync(tmp, path);
|
|
39
|
+
chmodSync(path, 0o600);
|
|
40
|
+
}
|
|
41
|
+
export function getBinding(repoRoot) {
|
|
42
|
+
return readBindings().projects[repoRoot];
|
|
43
|
+
}
|
|
44
|
+
export function saveBinding(repoRoot, binding) {
|
|
45
|
+
const file = readBindings();
|
|
46
|
+
file.projects[repoRoot] = binding;
|
|
47
|
+
writeBindings(file);
|
|
48
|
+
}
|
|
49
|
+
export function removeBinding(repoRoot) {
|
|
50
|
+
const file = readBindings();
|
|
51
|
+
if (!file.projects[repoRoot])
|
|
52
|
+
return false;
|
|
53
|
+
delete file.projects[repoRoot];
|
|
54
|
+
writeBindings(file);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=project-binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-binding.js","sourceRoot":"","sources":["../../src/lib/project-binding.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
2
2
|
import { type DiagramState } from './lib/diagram-state.js';
|
|
3
3
|
import { type Checkpoint } from './lib/checkpoints.js';
|
|
4
4
|
import { runWithMcpContext, type McpRequestContext } from './lib/http.js';
|
|
5
|
-
export declare const SERVER_VERSION = "1.0.
|
|
5
|
+
export declare const SERVER_VERSION = "1.0.6";
|
|
6
6
|
/** Everything a working session holds between tool calls. */
|
|
7
7
|
export interface WorkingSessionSnapshot {
|
|
8
8
|
diagram: DiagramState | null;
|
package/dist/server.js
CHANGED
|
@@ -525,7 +525,7 @@ Useful for multi-turn workflows: save before a major change, restore if needed.`
|
|
|
525
525
|
},
|
|
526
526
|
},
|
|
527
527
|
];
|
|
528
|
-
export const SERVER_VERSION = '1.0.
|
|
528
|
+
export const SERVER_VERSION = '1.0.6';
|
|
529
529
|
const STATEFUL_TOOLS = new Set([
|
|
530
530
|
'generate_diagram',
|
|
531
531
|
'apply_template',
|