devglide 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +338 -0
- package/bin/claude-md-template.js +94 -0
- package/bin/devglide.js +387 -0
- package/package.json +85 -0
- package/pnpm-workspace.yaml +3 -0
- package/src/apps/coder/.turbo/turbo-lint.log +5 -0
- package/src/apps/coder/package.json +16 -0
- package/src/apps/coder/public/favicon.svg +7 -0
- package/src/apps/coder/public/page.css +275 -0
- package/src/apps/coder/public/page.js +528 -0
- package/src/apps/coder/server.js +3 -0
- package/src/apps/documentation/public/page.css +597 -0
- package/src/apps/documentation/public/page.js +609 -0
- package/src/apps/kanban/.turbo/turbo-lint.log +97 -0
- package/src/apps/kanban/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/kanban/package.json +32 -0
- package/src/apps/kanban/public/favicon.svg +7 -0
- package/src/apps/kanban/public/page.css +1010 -0
- package/src/apps/kanban/public/page.js +1730 -0
- package/src/apps/kanban/public/vendor/marked.min.js +6 -0
- package/src/apps/kanban/public/vendor/sortable.min.js +2 -0
- package/src/apps/kanban/src/db.ts +319 -0
- package/src/apps/kanban/src/index.ts +14 -0
- package/src/apps/kanban/src/mcp-helpers.test.ts +88 -0
- package/src/apps/kanban/src/mcp-helpers.ts +60 -0
- package/src/apps/kanban/src/mcp.ts +59 -0
- package/src/apps/kanban/src/routes/attachments.ts +161 -0
- package/src/apps/kanban/src/routes/features.ts +233 -0
- package/src/apps/kanban/src/routes/issues.ts +373 -0
- package/src/apps/kanban/src/tools/feature-tools.ts +164 -0
- package/src/apps/kanban/src/tools/item-tools.ts +307 -0
- package/src/apps/kanban/src/tools/versioned-entry-tools.ts +72 -0
- package/src/apps/kanban/tsconfig.check.json +9 -0
- package/src/apps/kanban/tsconfig.json +9 -0
- package/src/apps/keymap/.turbo/turbo-lint.log +5 -0
- package/src/apps/keymap/package.json +16 -0
- package/src/apps/keymap/public/page.css +275 -0
- package/src/apps/keymap/public/page.js +294 -0
- package/src/apps/keymap/server.js +25 -0
- package/src/apps/log/.turbo/turbo-build.log +5 -0
- package/src/apps/log/.turbo/turbo-lint.log +45 -0
- package/src/apps/log/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/log/node_modules/.bin/tsc +21 -0
- package/src/apps/log/node_modules/.bin/tsserver +21 -0
- package/src/apps/log/node_modules/.bin/tsx +21 -0
- package/src/apps/log/package.json +36 -0
- package/src/apps/log/public/console-sniffer.js +221 -0
- package/src/apps/log/public/favicon.svg +7 -0
- package/src/apps/log/public/page.css +322 -0
- package/src/apps/log/public/page.js +463 -0
- package/src/apps/log/src/index.ts +9 -0
- package/src/apps/log/src/mcp.ts +122 -0
- package/src/apps/log/src/routes/log.ts +333 -0
- package/src/apps/log/src/routes/status.ts +25 -0
- package/src/apps/log/src/server-sniffer.ts +118 -0
- package/src/apps/log/src/services/file-patterns.ts +39 -0
- package/src/apps/log/src/services/file-tailer.ts +228 -0
- package/src/apps/log/src/services/line-parser.ts +94 -0
- package/src/apps/log/src/services/log-writer.ts +39 -0
- package/src/apps/log/tsconfig.json +8 -0
- package/src/apps/prompts/.turbo/turbo-build.log +5 -0
- package/src/apps/prompts/.turbo/turbo-lint.log +24 -0
- package/src/apps/prompts/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/prompts/mcp.ts +175 -0
- package/src/apps/prompts/node_modules/.bin/tsc +21 -0
- package/src/apps/prompts/node_modules/.bin/tsserver +21 -0
- package/src/apps/prompts/node_modules/.bin/tsx +21 -0
- package/src/apps/prompts/package.json +25 -0
- package/src/apps/prompts/public/page.css +315 -0
- package/src/apps/prompts/public/page.js +541 -0
- package/src/apps/prompts/services/prompt-store.ts +212 -0
- package/src/apps/prompts/src/index.ts +9 -0
- package/src/apps/prompts/tsconfig.json +8 -0
- package/src/apps/prompts/types.ts +27 -0
- package/src/apps/shell/.turbo/turbo-build.log +5 -0
- package/src/apps/shell/.turbo/turbo-lint.log +34 -0
- package/src/apps/shell/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/shell/package.json +35 -0
- package/src/apps/shell/public/favicon.svg +7 -0
- package/src/apps/shell/public/page.css +407 -0
- package/src/apps/shell/public/page.js +1577 -0
- package/src/apps/shell/src/index.ts +150 -0
- package/src/apps/shell/src/mcp.ts +398 -0
- package/src/apps/shell/src/shell-types.ts +41 -0
- package/src/apps/shell/tsconfig.json +8 -0
- package/src/apps/test/.turbo/turbo-build.log +5 -0
- package/src/apps/test/.turbo/turbo-lint.log +27 -0
- package/src/apps/test/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/test/node_modules/.bin/tsc +21 -0
- package/src/apps/test/node_modules/.bin/tsserver +21 -0
- package/src/apps/test/node_modules/.bin/tsx +21 -0
- package/src/apps/test/node_modules/.bin/uuid +21 -0
- package/src/apps/test/package.json +35 -0
- package/src/apps/test/public/favicon.svg +7 -0
- package/src/apps/test/public/page.css +499 -0
- package/src/apps/test/public/page.js +417 -0
- package/src/apps/test/public/scenario-runner.js +450 -0
- package/src/apps/test/src/index.ts +9 -0
- package/src/apps/test/src/mcp.ts +192 -0
- package/src/apps/test/src/routes/trigger.ts +285 -0
- package/src/apps/test/src/services/scenario-broadcaster.ts +60 -0
- package/src/apps/test/src/services/scenario-manager.ts +361 -0
- package/src/apps/test/src/services/scenario-store.ts +145 -0
- package/src/apps/test/tsconfig.json +8 -0
- package/src/apps/vocabulary/.turbo/turbo-build.log +5 -0
- package/src/apps/vocabulary/.turbo/turbo-lint.log +25 -0
- package/src/apps/vocabulary/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/vocabulary/mcp.ts +173 -0
- package/src/apps/vocabulary/node_modules/.bin/tsc +21 -0
- package/src/apps/vocabulary/node_modules/.bin/tsserver +21 -0
- package/src/apps/vocabulary/node_modules/.bin/tsx +21 -0
- package/src/apps/vocabulary/package.json +25 -0
- package/src/apps/vocabulary/public/page.css +247 -0
- package/src/apps/vocabulary/public/page.js +444 -0
- package/src/apps/vocabulary/services/vocabulary-store.ts +179 -0
- package/src/apps/vocabulary/src/index.ts +10 -0
- package/src/apps/vocabulary/tsconfig.json +8 -0
- package/src/apps/vocabulary/types.ts +22 -0
- package/src/apps/voice/.turbo/turbo-build.log +5 -0
- package/src/apps/voice/.turbo/turbo-lint.log +43 -0
- package/src/apps/voice/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/voice/node_modules/.bin/openai +21 -0
- package/src/apps/voice/node_modules/.bin/tsc +21 -0
- package/src/apps/voice/node_modules/.bin/tsserver +21 -0
- package/src/apps/voice/node_modules/.bin/tsx +21 -0
- package/src/apps/voice/package.json +35 -0
- package/src/apps/voice/public/favicon.svg +7 -0
- package/src/apps/voice/public/page.css +388 -0
- package/src/apps/voice/public/page.js +718 -0
- package/src/apps/voice/src/index.ts +10 -0
- package/src/apps/voice/src/mcp.ts +70 -0
- package/src/apps/voice/src/providers/index.ts +85 -0
- package/src/apps/voice/src/providers/openai-compatible.ts +94 -0
- package/src/apps/voice/src/providers/types.ts +27 -0
- package/src/apps/voice/src/routes/config.ts +118 -0
- package/src/apps/voice/src/routes/transcribe.ts +90 -0
- package/src/apps/voice/src/services/config-store.ts +129 -0
- package/src/apps/voice/src/services/stats.ts +108 -0
- package/src/apps/voice/src/transcribe.ts +11 -0
- package/src/apps/voice/src/utils/mime.ts +16 -0
- package/src/apps/voice/tsconfig.json +8 -0
- package/src/apps/workflow/.turbo/turbo-build.log +5 -0
- package/src/apps/workflow/.turbo/turbo-lint.log +96 -0
- package/src/apps/workflow/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/workflow/engine/executors/decision-executor.ts +87 -0
- package/src/apps/workflow/engine/executors/file-executor.ts +90 -0
- package/src/apps/workflow/engine/executors/git-executor.ts +137 -0
- package/src/apps/workflow/engine/executors/http-executor.ts +65 -0
- package/src/apps/workflow/engine/executors/index.ts +28 -0
- package/src/apps/workflow/engine/executors/kanban-executor.ts +154 -0
- package/src/apps/workflow/engine/executors/llm-executor.ts +46 -0
- package/src/apps/workflow/engine/executors/log-executor.ts +62 -0
- package/src/apps/workflow/engine/executors/loop-executor.ts +14 -0
- package/src/apps/workflow/engine/executors/shell-executor.ts +107 -0
- package/src/apps/workflow/engine/executors/sub-workflow-executor.ts +61 -0
- package/src/apps/workflow/engine/executors/test-executor.ts +73 -0
- package/src/apps/workflow/engine/executors/trigger-executor.ts +39 -0
- package/src/apps/workflow/engine/expression-evaluator.ts +117 -0
- package/src/apps/workflow/engine/graph-runner.ts +438 -0
- package/src/apps/workflow/engine/node-executor.ts +104 -0
- package/src/apps/workflow/engine/node-registry.ts +15 -0
- package/src/apps/workflow/engine/variable-resolver.ts +109 -0
- package/src/apps/workflow/mcp.ts +223 -0
- package/src/apps/workflow/node_modules/.bin/tsc +21 -0
- package/src/apps/workflow/node_modules/.bin/tsserver +21 -0
- package/src/apps/workflow/node_modules/.bin/tsx +21 -0
- package/src/apps/workflow/package.json +25 -0
- package/src/apps/workflow/public/editor/canvas.js +366 -0
- package/src/apps/workflow/public/editor/drag-manager.js +326 -0
- package/src/apps/workflow/public/editor/edge-renderer.js +235 -0
- package/src/apps/workflow/public/editor/history-manager.js +147 -0
- package/src/apps/workflow/public/editor/layout-engine.js +159 -0
- package/src/apps/workflow/public/editor/node-renderer.js +199 -0
- package/src/apps/workflow/public/editor/selection-manager.js +193 -0
- package/src/apps/workflow/public/favicon.svg +7 -0
- package/src/apps/workflow/public/models/node-types.js +300 -0
- package/src/apps/workflow/public/models/workflow-model.js +257 -0
- package/src/apps/workflow/public/page.css +406 -0
- package/src/apps/workflow/public/page.js +658 -0
- package/src/apps/workflow/public/panels/inspector.js +360 -0
- package/src/apps/workflow/public/panels/palette.js +106 -0
- package/src/apps/workflow/public/panels/run-view.js +275 -0
- package/src/apps/workflow/public/panels/toolbar.js +232 -0
- package/src/apps/workflow/public/panels/workflow-list.js +237 -0
- package/src/apps/workflow/public/state/store.js +47 -0
- package/src/apps/workflow/services/custom-node-loader.ts +48 -0
- package/src/apps/workflow/services/legacy-converter.ts +72 -0
- package/src/apps/workflow/services/run-manager.ts +190 -0
- package/src/apps/workflow/services/workflow-store.ts +424 -0
- package/src/apps/workflow/services/workflow-validator.test.ts +103 -0
- package/src/apps/workflow/services/workflow-validator.ts +98 -0
- package/src/apps/workflow/src/index.ts +10 -0
- package/src/apps/workflow/templates/ci-pipeline.json +18 -0
- package/src/apps/workflow/templates/code-review.json +22 -0
- package/src/apps/workflow/templates/kanban-testing.json +24 -0
- package/src/apps/workflow/tsconfig.json +8 -0
- package/src/apps/workflow/types.ts +268 -0
- package/src/packages/auth-middleware.ts +14 -0
- package/src/packages/design-tokens/.turbo/turbo-build.log +10 -0
- package/src/packages/design-tokens/STYLEGUIDE.md +414 -0
- package/src/packages/design-tokens/build.js +413 -0
- package/src/packages/design-tokens/demo/index.html +1367 -0
- package/src/packages/design-tokens/demo/proposition-a.html +717 -0
- package/src/packages/design-tokens/demo/proposition-b.html +1239 -0
- package/src/packages/design-tokens/demo/proposition-c.html +1049 -0
- package/src/packages/design-tokens/dist/tailwind-preset.js +115 -0
- package/src/packages/design-tokens/dist/tokens.css +345 -0
- package/src/packages/design-tokens/dist/tokens.d.ts +229 -0
- package/src/packages/design-tokens/dist/tokens.js +386 -0
- package/src/packages/design-tokens/package.json +25 -0
- package/src/packages/design-tokens/tokens.json +228 -0
- package/src/packages/devtools-middleware.ts +22 -0
- package/src/packages/eslint-config/index.js +63 -0
- package/src/packages/eslint-config/node_modules/.bin/eslint +21 -0
- package/src/packages/eslint-config/package.json +18 -0
- package/src/packages/json-file-store.ts +232 -0
- package/src/packages/mcp-utils/.turbo/turbo-build.log +5 -0
- package/src/packages/mcp-utils/dist/index.d.ts +33 -0
- package/src/packages/mcp-utils/dist/index.d.ts.map +1 -0
- package/src/packages/mcp-utils/dist/index.js +126 -0
- package/src/packages/mcp-utils/dist/index.js.map +1 -0
- package/src/packages/mcp-utils/node_modules/.bin/tsc +21 -0
- package/src/packages/mcp-utils/node_modules/.bin/tsserver +21 -0
- package/src/packages/mcp-utils/package.json +32 -0
- package/src/packages/mcp-utils/src/index.ts +171 -0
- package/src/packages/mcp-utils/tsconfig.json +9 -0
- package/src/packages/paths.ts +18 -0
- package/src/packages/project-context/index.js +55 -0
- package/src/packages/project-context/package.json +13 -0
- package/src/packages/project-store.ts +127 -0
- package/src/packages/server-sniffer.ts +132 -0
- package/src/packages/shared-assets/favicon.svg +7 -0
- package/src/packages/shared-assets/keymap-registry.js +512 -0
- package/src/packages/shared-assets/logo.svg +6 -0
- package/src/packages/shared-assets/package.json +11 -0
- package/src/packages/shared-assets/ui-utils.js +48 -0
- package/src/packages/shared-assets/voice-widget.d.ts +37 -0
- package/src/packages/shared-assets/voice-widget.js +695 -0
- package/src/packages/shared-types/.turbo/turbo-build.log +5 -0
- package/src/packages/shared-types/dist/index.d.ts +39 -0
- package/src/packages/shared-types/dist/index.d.ts.map +1 -0
- package/src/packages/shared-types/node_modules/.bin/tsc +21 -0
- package/src/packages/shared-types/node_modules/.bin/tsserver +21 -0
- package/src/packages/shared-types/package.json +25 -0
- package/src/packages/shared-types/src/index.ts +41 -0
- package/src/packages/shared-types/tsconfig.json +11 -0
- package/src/packages/tsconfig/base.json +15 -0
- package/src/packages/tsconfig/next.json +14 -0
- package/src/packages/tsconfig/node.json +11 -0
- package/src/packages/tsconfig/package.json +10 -0
- package/turbo.json +25 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const tsPlugin = require("@typescript-eslint/eslint-plugin");
|
|
2
|
+
const tsParser = require("@typescript-eslint/parser");
|
|
3
|
+
const importPlugin = require("eslint-plugin-import");
|
|
4
|
+
|
|
5
|
+
/** @type {import('eslint').Linter.Config[]} */
|
|
6
|
+
module.exports = [
|
|
7
|
+
{
|
|
8
|
+
files: ["**/*.{ts,tsx}"],
|
|
9
|
+
languageOptions: {
|
|
10
|
+
parser: tsParser,
|
|
11
|
+
parserOptions: {
|
|
12
|
+
ecmaVersion: "latest",
|
|
13
|
+
sourceType: "module",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
plugins: {
|
|
17
|
+
"@typescript-eslint": tsPlugin,
|
|
18
|
+
import: importPlugin,
|
|
19
|
+
},
|
|
20
|
+
rules: {
|
|
21
|
+
// --- Base ---
|
|
22
|
+
"no-unused-vars": "off",
|
|
23
|
+
"no-console": "off",
|
|
24
|
+
|
|
25
|
+
// --- TypeScript ---
|
|
26
|
+
"@typescript-eslint/no-unused-vars": [
|
|
27
|
+
"warn",
|
|
28
|
+
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
|
|
29
|
+
],
|
|
30
|
+
"@typescript-eslint/no-explicit-any": "warn",
|
|
31
|
+
"@typescript-eslint/consistent-type-imports": [
|
|
32
|
+
"warn",
|
|
33
|
+
{ prefer: "type-imports" },
|
|
34
|
+
],
|
|
35
|
+
"@typescript-eslint/no-require-imports": "warn",
|
|
36
|
+
|
|
37
|
+
// --- Import ordering ---
|
|
38
|
+
"import/order": [
|
|
39
|
+
"warn",
|
|
40
|
+
{
|
|
41
|
+
groups: [
|
|
42
|
+
"builtin",
|
|
43
|
+
"external",
|
|
44
|
+
"internal",
|
|
45
|
+
"parent",
|
|
46
|
+
"sibling",
|
|
47
|
+
"index",
|
|
48
|
+
],
|
|
49
|
+
"newlines-between": "always",
|
|
50
|
+
alphabetize: { order: "asc", caseInsensitive: true },
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
"import/no-duplicates": "warn",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
files: ["**/*.{js,mjs,cjs}"],
|
|
58
|
+
rules: {
|
|
59
|
+
"no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
|
|
60
|
+
"no-console": "off",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
+
|
|
4
|
+
case `uname` in
|
|
5
|
+
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
+
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
+
basedir=`cygpath -w "$basedir"`
|
|
8
|
+
fi
|
|
9
|
+
;;
|
|
10
|
+
esac
|
|
11
|
+
|
|
12
|
+
if [ -z "$NODE_PATH" ]; then
|
|
13
|
+
export NODE_PATH="/home/runner/_work/devglide/devglide/node_modules/.pnpm/eslint@9.39.4/node_modules/eslint/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/eslint@9.39.4/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/node_modules"
|
|
14
|
+
else
|
|
15
|
+
export NODE_PATH="/home/runner/_work/devglide/devglide/node_modules/.pnpm/eslint@9.39.4/node_modules/eslint/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/eslint@9.39.4/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
+
fi
|
|
17
|
+
if [ -x "$basedir/node" ]; then
|
|
18
|
+
exec "$basedir/node" "$basedir/../eslint/bin/eslint.js" "$@"
|
|
19
|
+
else
|
|
20
|
+
exec node "$basedir/../eslint/bin/eslint.js" "$@"
|
|
21
|
+
fi
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@devglide/eslint-config",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"index.js"
|
|
9
|
+
],
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@typescript-eslint/eslint-plugin": "^8.56.1",
|
|
12
|
+
"@typescript-eslint/parser": "^8.56.1",
|
|
13
|
+
"eslint-plugin-import": "^2.32.0"
|
|
14
|
+
},
|
|
15
|
+
"peerDependencies": {
|
|
16
|
+
"eslint": ">=9.0.0"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic base class for project-scoped + global JSON-per-entity file stores.
|
|
3
|
+
* Extracts the common CRUD, scope resolution, locking, and directory patterns
|
|
4
|
+
* shared by VocabularyStore and WorkflowStore.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'fs/promises';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { randomUUID } from 'crypto';
|
|
10
|
+
import { getActiveProject } from '../project-context.js';
|
|
11
|
+
|
|
12
|
+
/** Minimal shape every entity must have. */
|
|
13
|
+
export interface BaseEntity {
|
|
14
|
+
id: string;
|
|
15
|
+
createdAt: string;
|
|
16
|
+
updatedAt: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export abstract class JsonFileStore<T extends BaseEntity> {
|
|
20
|
+
private writeLocks = new Map<string, Promise<void>>();
|
|
21
|
+
|
|
22
|
+
/** The root directory for this entity type (e.g. WORKFLOWS_DIR). */
|
|
23
|
+
protected abstract readonly baseDir: string;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Read and parse a single JSON file into an entity.
|
|
27
|
+
* Subclasses can add validation (e.g. Zod) here.
|
|
28
|
+
*/
|
|
29
|
+
protected async readEntityFile(filePath: string): Promise<T | null> {
|
|
30
|
+
try {
|
|
31
|
+
const raw = await fs.readFile(filePath, 'utf-8');
|
|
32
|
+
return JSON.parse(raw) as T;
|
|
33
|
+
} catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ── Locking ─────────────────────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
protected async withLock<R>(key: string, fn: () => Promise<R>): Promise<R> {
|
|
41
|
+
const prev = this.writeLocks.get(key) ?? Promise.resolve();
|
|
42
|
+
let resolve!: () => void;
|
|
43
|
+
const next = new Promise<void>((r) => { resolve = r; });
|
|
44
|
+
this.writeLocks.set(key, next);
|
|
45
|
+
await prev;
|
|
46
|
+
try {
|
|
47
|
+
return await fn();
|
|
48
|
+
} finally {
|
|
49
|
+
resolve();
|
|
50
|
+
if (this.writeLocks.get(key) === next) {
|
|
51
|
+
this.writeLocks.delete(key);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ── Directory helpers ──────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
protected getProjectDir(): string | null {
|
|
59
|
+
const ap = getActiveProject();
|
|
60
|
+
if (!ap) return null;
|
|
61
|
+
return path.join(this.baseDir, ap.id);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
protected getDirForProject(projectId: string): string {
|
|
65
|
+
return path.join(this.baseDir, projectId);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
protected getGlobalDir(): string {
|
|
69
|
+
return this.baseDir;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
protected async ensureDir(dir: string): Promise<void> {
|
|
73
|
+
await fs.mkdir(dir, { recursive: true });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ── Core CRUD ─────────────────────────────────────────────────────────
|
|
77
|
+
|
|
78
|
+
async get(id: string): Promise<T | null> {
|
|
79
|
+
const projectDir = this.getProjectDir();
|
|
80
|
+
if (projectDir) {
|
|
81
|
+
const entity = await this.readEntityFile(path.join(projectDir, `${id}.json`));
|
|
82
|
+
if (entity) return entity;
|
|
83
|
+
}
|
|
84
|
+
// Try global dir
|
|
85
|
+
const global = await this.readEntityFile(path.join(this.getGlobalDir(), `${id}.json`));
|
|
86
|
+
if (global) return global;
|
|
87
|
+
|
|
88
|
+
// No active project — search all project subdirectories
|
|
89
|
+
if (!projectDir) {
|
|
90
|
+
return this.findInAllDirs(id);
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async delete(id: string): Promise<boolean> {
|
|
96
|
+
return this.withLock(id, async () => {
|
|
97
|
+
const projectDir = this.getProjectDir();
|
|
98
|
+
if (projectDir) {
|
|
99
|
+
try {
|
|
100
|
+
await fs.unlink(path.join(projectDir, `${id}.json`));
|
|
101
|
+
return true;
|
|
102
|
+
} catch {
|
|
103
|
+
// Not in project dir, try global
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
await fs.unlink(path.join(this.getGlobalDir(), `${id}.json`));
|
|
108
|
+
return true;
|
|
109
|
+
} catch {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Search all project subdirectories for an entity by ID. */
|
|
116
|
+
private async findInAllDirs(id: string): Promise<T | null> {
|
|
117
|
+
let names: string[];
|
|
118
|
+
try {
|
|
119
|
+
names = await fs.readdir(this.baseDir);
|
|
120
|
+
} catch {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
for (const name of names) {
|
|
124
|
+
if (name.endsWith('.json')) continue;
|
|
125
|
+
const entity = await this.readEntityFile(path.join(this.baseDir, name, `${id}.json`));
|
|
126
|
+
if (entity) return entity;
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ── Scope resolution ──────────────────────────────────────────────────
|
|
132
|
+
|
|
133
|
+
protected async resolveExistingScope(id: string): Promise<'project' | 'global' | undefined> {
|
|
134
|
+
const projectDir = this.getProjectDir();
|
|
135
|
+
if (projectDir) {
|
|
136
|
+
try {
|
|
137
|
+
await fs.access(path.join(projectDir, `${id}.json`));
|
|
138
|
+
return 'project';
|
|
139
|
+
} catch { /* not in project dir */ }
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
await fs.access(path.join(this.getGlobalDir(), `${id}.json`));
|
|
143
|
+
return 'global';
|
|
144
|
+
} catch { /* not found */ }
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Determine target dir and write the entity JSON file. */
|
|
149
|
+
protected async writeEntity(entity: T, scope: 'project' | 'global', projectId?: string): Promise<void> {
|
|
150
|
+
const targetDir = scope === 'project' && projectId
|
|
151
|
+
? this.getDirForProject(projectId)
|
|
152
|
+
: this.getGlobalDir();
|
|
153
|
+
await this.ensureDir(targetDir);
|
|
154
|
+
await fs.writeFile(
|
|
155
|
+
path.join(targetDir, `${entity.id}.json`),
|
|
156
|
+
JSON.stringify(entity, null, 2),
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Remove entity file from a specific scope (used when scope changes). */
|
|
161
|
+
protected async removeFromScope(id: string, scope: 'project' | 'global', projectId?: string): Promise<void> {
|
|
162
|
+
const dir = scope === 'project' && projectId
|
|
163
|
+
? this.getDirForProject(projectId)
|
|
164
|
+
: this.getGlobalDir();
|
|
165
|
+
try { await fs.unlink(path.join(dir, `${id}.json`)); } catch { /* not found */ }
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ── Directory scanning ────────────────────────────────────────────────
|
|
169
|
+
|
|
170
|
+
/** Scan a directory and return all valid entities. */
|
|
171
|
+
protected async scanDirFull(dir: string): Promise<T[]> {
|
|
172
|
+
let entries: string[];
|
|
173
|
+
try {
|
|
174
|
+
entries = await fs.readdir(dir);
|
|
175
|
+
} catch {
|
|
176
|
+
return [];
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const results: T[] = [];
|
|
180
|
+
for (const entry of entries) {
|
|
181
|
+
if (!entry.endsWith('.json')) continue;
|
|
182
|
+
const entity = await this.readEntityFile(path.join(dir, entry));
|
|
183
|
+
if (entity) results.push(entity);
|
|
184
|
+
}
|
|
185
|
+
return results;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Scan the base dir AND all project subdirectories.
|
|
190
|
+
* Used when no active project is set (e.g. stdio MCP mode) to ensure
|
|
191
|
+
* all entries are discoverable regardless of which project created them.
|
|
192
|
+
*/
|
|
193
|
+
protected async scanAllDirs(): Promise<T[]> {
|
|
194
|
+
const results: T[] = [];
|
|
195
|
+
const seen = new Set<string>();
|
|
196
|
+
|
|
197
|
+
let names: string[];
|
|
198
|
+
try {
|
|
199
|
+
names = await fs.readdir(this.baseDir);
|
|
200
|
+
} catch {
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
for (const name of names) {
|
|
205
|
+
const fullPath = path.join(this.baseDir, name);
|
|
206
|
+
if (name.endsWith('.json')) {
|
|
207
|
+
// JSON file in the global root
|
|
208
|
+
const entity = await this.readEntityFile(fullPath);
|
|
209
|
+
if (entity && !seen.has(entity.id)) {
|
|
210
|
+
seen.add(entity.id);
|
|
211
|
+
results.push(entity);
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
// Likely a project subdirectory — scan it
|
|
215
|
+
for (const e of await this.scanDirFull(fullPath)) {
|
|
216
|
+
if (!seen.has(e.id)) {
|
|
217
|
+
seen.add(e.id);
|
|
218
|
+
results.push(e);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return results;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// ── ID generation ─────────────────────────────────────────────────────
|
|
228
|
+
|
|
229
|
+
protected generateId(): string {
|
|
230
|
+
return randomUUID();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
/** Format a JSON-serializable value as an MCP text result. */
|
|
3
|
+
export declare function jsonResult(data: unknown): {
|
|
4
|
+
content: {
|
|
5
|
+
type: "text";
|
|
6
|
+
text: string;
|
|
7
|
+
}[];
|
|
8
|
+
};
|
|
9
|
+
/** Format an error message as an MCP error result. */
|
|
10
|
+
export declare function errorResult(message: string): {
|
|
11
|
+
content: {
|
|
12
|
+
type: "text";
|
|
13
|
+
text: string;
|
|
14
|
+
}[];
|
|
15
|
+
isError: boolean;
|
|
16
|
+
};
|
|
17
|
+
export declare function createDevglideMcpServer(name: string, version: string, description?: string, options?: {
|
|
18
|
+
instructions?: string | string[];
|
|
19
|
+
}): McpServer;
|
|
20
|
+
/**
|
|
21
|
+
* Mount an MCP StreamableHTTP endpoint on an Express-compatible app.
|
|
22
|
+
* Each session gets its own McpServer instance via the factory function.
|
|
23
|
+
*/
|
|
24
|
+
export declare function mountMcpHttp(app: {
|
|
25
|
+
post: (path: string, handler: (...args: any[]) => any) => void;
|
|
26
|
+
get: (path: string, handler: (...args: any[]) => any) => void;
|
|
27
|
+
delete: (path: string, handler: (...args: any[]) => any) => void;
|
|
28
|
+
}, serverFactory: () => McpServer, path?: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Run an MCP server in stdio mode (for Claude Desktop / CLI usage).
|
|
31
|
+
*/
|
|
32
|
+
export declare function runStdio(server: McpServer): Promise<void>;
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO;;;;;EAIvC;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM;;;;;;EAK1C;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,GAC7C,SAAS,CAaX;AAwBD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE;IACH,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,KAAK,IAAI,CAAC;IAC/D,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,KAAK,IAAI,CAAC;IAC9D,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,KAAK,IAAI,CAAC;CAClE,EACD,aAAa,EAAE,MAAM,SAAS,EAC9B,IAAI,GAAE,MAAe,GACpB,IAAI,CAwFN;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/D"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
|
+
import { randomUUID } from "crypto";
|
|
5
|
+
/** Format a JSON-serializable value as an MCP text result. */
|
|
6
|
+
export function jsonResult(data) {
|
|
7
|
+
return {
|
|
8
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** Format an error message as an MCP error result. */
|
|
12
|
+
export function errorResult(message) {
|
|
13
|
+
return {
|
|
14
|
+
content: [{ type: "text", text: message }],
|
|
15
|
+
isError: true,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function createDevglideMcpServer(name, version, description, options) {
|
|
19
|
+
const serverOpts = options
|
|
20
|
+
? {
|
|
21
|
+
...options,
|
|
22
|
+
instructions: Array.isArray(options.instructions)
|
|
23
|
+
? options.instructions.join('\n')
|
|
24
|
+
: options.instructions,
|
|
25
|
+
}
|
|
26
|
+
: undefined;
|
|
27
|
+
return new McpServer({ name, version, ...(description && { description }) }, ...(serverOpts ? [serverOpts] : []));
|
|
28
|
+
}
|
|
29
|
+
function isInitializeRequest(body) {
|
|
30
|
+
if (Array.isArray(body)) {
|
|
31
|
+
return body.some((msg) => typeof msg === "object" &&
|
|
32
|
+
msg !== null &&
|
|
33
|
+
msg.method === "initialize");
|
|
34
|
+
}
|
|
35
|
+
return (typeof body === "object" &&
|
|
36
|
+
body !== null &&
|
|
37
|
+
body.method === "initialize");
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Mount an MCP StreamableHTTP endpoint on an Express-compatible app.
|
|
41
|
+
* Each session gets its own McpServer instance via the factory function.
|
|
42
|
+
*/
|
|
43
|
+
export function mountMcpHttp(app, serverFactory, path = "/mcp") {
|
|
44
|
+
const sessions = new Map();
|
|
45
|
+
// TTL cleanup: remove sessions not accessed in 30 minutes
|
|
46
|
+
const SESSION_TTL_MS = 30 * 60 * 1000;
|
|
47
|
+
const ttlTimer = setInterval(() => {
|
|
48
|
+
const cutoff = Date.now() - SESSION_TTL_MS;
|
|
49
|
+
for (const [id, session] of sessions) {
|
|
50
|
+
if (session.lastAccessed < cutoff) {
|
|
51
|
+
session.transport.close?.();
|
|
52
|
+
sessions.delete(id);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}, 5 * 60 * 1000);
|
|
56
|
+
ttlTimer.unref();
|
|
57
|
+
app.post(path, async (req, res) => {
|
|
58
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
59
|
+
if (sessionId && sessions.has(sessionId)) {
|
|
60
|
+
const session = sessions.get(sessionId);
|
|
61
|
+
session.lastAccessed = Date.now();
|
|
62
|
+
await session.transport.handleRequest(req, res, req.body);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (!sessionId && isInitializeRequest(req.body)) {
|
|
66
|
+
const transport = new StreamableHTTPServerTransport({
|
|
67
|
+
sessionIdGenerator: () => randomUUID(),
|
|
68
|
+
onsessioninitialized: (id) => {
|
|
69
|
+
sessions.set(id, { transport, server, lastAccessed: Date.now() });
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
transport.onclose = () => {
|
|
73
|
+
if (transport.sessionId)
|
|
74
|
+
sessions.delete(transport.sessionId);
|
|
75
|
+
};
|
|
76
|
+
const server = serverFactory();
|
|
77
|
+
await server.connect(transport);
|
|
78
|
+
await transport.handleRequest(req, res, req.body);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
82
|
+
res.end(JSON.stringify({
|
|
83
|
+
jsonrpc: "2.0",
|
|
84
|
+
error: { code: -32000, message: "Bad Request: No valid session ID" },
|
|
85
|
+
id: null,
|
|
86
|
+
}));
|
|
87
|
+
});
|
|
88
|
+
app.get(path, async (req, res) => {
|
|
89
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
90
|
+
if (!sessionId || !sessions.has(sessionId)) {
|
|
91
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
92
|
+
res.end(JSON.stringify({
|
|
93
|
+
jsonrpc: "2.0",
|
|
94
|
+
error: { code: -32000, message: "Bad Request: No valid session ID" },
|
|
95
|
+
id: null,
|
|
96
|
+
}));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const getSession = sessions.get(sessionId);
|
|
100
|
+
getSession.lastAccessed = Date.now();
|
|
101
|
+
await getSession.transport.handleRequest(req, res);
|
|
102
|
+
});
|
|
103
|
+
app.delete(path, async (req, res) => {
|
|
104
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
105
|
+
if (!sessionId || !sessions.has(sessionId)) {
|
|
106
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
107
|
+
res.end(JSON.stringify({
|
|
108
|
+
jsonrpc: "2.0",
|
|
109
|
+
error: { code: -32000, message: "Bad Request: No valid session ID" },
|
|
110
|
+
id: null,
|
|
111
|
+
}));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const delSession = sessions.get(sessionId);
|
|
115
|
+
delSession.lastAccessed = Date.now();
|
|
116
|
+
await delSession.transport.handleRequest(req, res);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Run an MCP server in stdio mode (for Claude Desktop / CLI usage).
|
|
121
|
+
*/
|
|
122
|
+
export async function runStdio(server) {
|
|
123
|
+
const transport = new StdioServerTransport();
|
|
124
|
+
await server.connect(transport);
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
+
|
|
4
|
+
case `uname` in
|
|
5
|
+
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
+
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
+
basedir=`cygpath -w "$basedir"`
|
|
8
|
+
fi
|
|
9
|
+
;;
|
|
10
|
+
esac
|
|
11
|
+
|
|
12
|
+
if [ -z "$NODE_PATH" ]; then
|
|
13
|
+
export NODE_PATH="/home/runner/_work/devglide/devglide/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/node_modules"
|
|
14
|
+
else
|
|
15
|
+
export NODE_PATH="/home/runner/_work/devglide/devglide/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
+
fi
|
|
17
|
+
if [ -x "$basedir/node" ]; then
|
|
18
|
+
exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
|
|
19
|
+
else
|
|
20
|
+
exec node "$basedir/../typescript/bin/tsc" "$@"
|
|
21
|
+
fi
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
+
|
|
4
|
+
case `uname` in
|
|
5
|
+
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
+
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
+
basedir=`cygpath -w "$basedir"`
|
|
8
|
+
fi
|
|
9
|
+
;;
|
|
10
|
+
esac
|
|
11
|
+
|
|
12
|
+
if [ -z "$NODE_PATH" ]; then
|
|
13
|
+
export NODE_PATH="/home/runner/_work/devglide/devglide/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/node_modules"
|
|
14
|
+
else
|
|
15
|
+
export NODE_PATH="/home/runner/_work/devglide/devglide/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/_work/devglide/devglide/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
+
fi
|
|
17
|
+
if [ -x "$basedir/node" ]; then
|
|
18
|
+
exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
|
|
19
|
+
else
|
|
20
|
+
exec node "$basedir/../typescript/bin/tsserver" "$@"
|
|
21
|
+
fi
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@devglide/mcp-utils",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Shared MCP server utilities for devglide packages",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"default": "./dist/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"clean": "rm -rf dist"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@modelcontextprotocol/sdk": "^1.12.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^20.19.37",
|
|
27
|
+
"typescript": "^5.8.0"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
}
|
|
32
|
+
}
|