studiograph 1.1.2 → 1.2.0-beta.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 +191 -0
- package/README.md +301 -10
- package/dist/agent/orchestrator.d.ts +17 -9
- package/dist/agent/orchestrator.js +142 -97
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/prompts/system.md +186 -0
- package/dist/agent/skill-loader.d.ts +48 -0
- package/dist/agent/skill-loader.js +166 -0
- package/dist/agent/skill-loader.js.map +1 -0
- package/dist/agent/skills/enrich-entities.md +136 -0
- package/dist/agent/skills/entity-schema.md +502 -0
- package/dist/agent/skills/gather-context.md +46 -0
- package/dist/agent/skills/obsidian-source-setup.md +246 -0
- package/dist/agent/skills/skill-loader.d.ts +48 -0
- package/dist/agent/skills/skill-loader.js +166 -0
- package/dist/agent/skills/skill-loader.js.map +1 -0
- package/dist/agent/skills/sync-configuration.md +144 -0
- package/dist/agent/skills/sync-setup.md +68 -0
- package/dist/agent/tools/connector-tools.d.ts +37 -0
- package/dist/agent/tools/connector-tools.js +132 -0
- package/dist/agent/tools/connector-tools.js.map +1 -0
- package/dist/agent/tools/fs-tools.d.ts +39 -0
- package/dist/agent/tools/fs-tools.js +106 -0
- package/dist/agent/tools/fs-tools.js.map +1 -0
- package/dist/agent/tools/graph-tools.d.ts +30 -2
- package/dist/agent/tools/graph-tools.js +154 -37
- package/dist/agent/tools/graph-tools.js.map +1 -1
- package/dist/agent/tools/load-skill.d.ts +42 -0
- package/dist/agent/tools/load-skill.js +45 -0
- package/dist/agent/tools/load-skill.js.map +1 -0
- package/dist/agent/tools/sync-tools.d.ts +25 -0
- package/dist/agent/tools/sync-tools.js +691 -0
- package/dist/agent/tools/sync-tools.js.map +1 -0
- package/dist/agent/tools/tool-loader.d.ts +25 -0
- package/dist/agent/tools/tool-loader.js +73 -0
- package/dist/agent/tools/tool-loader.js.map +1 -0
- package/dist/auth/github.d.ts +11 -8
- package/dist/auth/github.js +56 -75
- package/dist/auth/github.js.map +1 -1
- package/dist/cli/colors.d.ts +54 -0
- package/dist/cli/colors.js +133 -0
- package/dist/cli/colors.js.map +1 -0
- package/dist/cli/commands/app.d.ts +7 -0
- package/dist/cli/commands/app.js +167 -0
- package/dist/cli/commands/app.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +1 -1
- package/dist/cli/commands/auth.js +26 -10
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/clone.d.ts +9 -0
- package/dist/cli/commands/clone.js +167 -0
- package/dist/cli/commands/clone.js.map +1 -0
- package/dist/cli/commands/commit.d.ts +8 -0
- package/dist/cli/commands/commit.js +43 -0
- package/dist/cli/commands/commit.js.map +1 -0
- package/dist/cli/commands/config.d.ts +13 -0
- package/dist/cli/commands/config.js +276 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/connector.d.ts +33 -0
- package/dist/cli/commands/connector.js +178 -0
- package/dist/cli/commands/connector.js.map +1 -0
- package/dist/cli/commands/deploy.d.ts +11 -0
- package/dist/cli/commands/deploy.js +153 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/enrich.d.ts +11 -0
- package/dist/cli/commands/enrich.js +135 -0
- package/dist/cli/commands/enrich.js.map +1 -0
- package/dist/cli/commands/graphrag.d.ts +12 -0
- package/dist/cli/commands/graphrag.js +122 -0
- package/dist/cli/commands/graphrag.js.map +1 -0
- package/dist/cli/commands/index.d.ts +15 -0
- package/dist/cli/commands/index.js +117 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/init.js +110 -210
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/join.js +89 -24
- package/dist/cli/commands/join.js.map +1 -1
- package/dist/cli/commands/lint.d.ts +8 -0
- package/dist/cli/commands/lint.js +70 -0
- package/dist/cli/commands/lint.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +27 -0
- package/dist/cli/commands/mcp.js +56 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/orphans.d.ts +8 -0
- package/dist/cli/commands/orphans.js +125 -0
- package/dist/cli/commands/orphans.js.map +1 -0
- package/dist/cli/commands/provision.d.ts +8 -0
- package/dist/cli/commands/provision.js +116 -0
- package/dist/cli/commands/provision.js.map +1 -0
- package/dist/cli/commands/r2.d.ts +2 -0
- package/dist/cli/commands/r2.js +87 -6
- package/dist/cli/commands/r2.js.map +1 -1
- package/dist/cli/commands/reset.d.ts +12 -0
- package/dist/cli/commands/reset.js +137 -0
- package/dist/cli/commands/reset.js.map +1 -0
- package/dist/cli/commands/review.d.ts +19 -0
- package/dist/cli/commands/review.js +128 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/serve.js +47 -2
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/source.d.ts +16 -0
- package/dist/cli/commands/source.js +159 -0
- package/dist/cli/commands/source.js.map +1 -0
- package/dist/cli/commands/start.js +472 -103
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/sync-entities.d.ts +13 -0
- package/dist/cli/commands/sync-entities.js +242 -0
- package/dist/cli/commands/sync-entities.js.map +1 -0
- package/dist/cli/commands/sync.js +40 -9
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/commands/update.d.ts +8 -0
- package/dist/cli/commands/update.js +155 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/index.js +114 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/scaffolding.d.ts +10 -0
- package/dist/cli/scaffolding.js +302 -0
- package/dist/cli/scaffolding.js.map +1 -0
- package/dist/cli/setup-wizard.d.ts +30 -0
- package/dist/cli/setup-wizard.js +244 -0
- package/dist/cli/setup-wizard.js.map +1 -0
- package/dist/cli/sync-review-interactive.d.ts +31 -0
- package/dist/cli/sync-review-interactive.js +393 -0
- package/dist/cli/sync-review-interactive.js.map +1 -0
- package/dist/cli/theme.d.ts +31 -0
- package/dist/cli/theme.js +116 -0
- package/dist/cli/theme.js.map +1 -0
- package/dist/core/graph.d.ts +16 -9
- package/dist/core/graph.js +263 -145
- package/dist/core/graph.js.map +1 -1
- package/dist/core/migration-runner.d.ts +42 -0
- package/dist/core/migration-runner.js +232 -0
- package/dist/core/migration-runner.js.map +1 -0
- package/dist/core/migration-types.d.ts +101 -0
- package/dist/core/migration-types.js +21 -0
- package/dist/core/migration-types.js.map +1 -0
- package/dist/core/migrations/20260219-formalize-memory-location.d.ts +2 -0
- package/dist/core/migrations/20260219-formalize-memory-location.js +35 -0
- package/dist/core/migrations/20260219-formalize-memory-location.js.map +1 -0
- package/dist/core/migrations/20260220-add-workspace-metadata.d.ts +12 -0
- package/dist/core/migrations/20260220-add-workspace-metadata.js +65 -0
- package/dist/core/migrations/20260220-add-workspace-metadata.js.map +1 -0
- package/dist/core/migrations/20260220-add-workspace-readme.d.ts +11 -0
- package/dist/core/migrations/20260220-add-workspace-readme.js +82 -0
- package/dist/core/migrations/20260220-add-workspace-readme.js.map +1 -0
- package/dist/core/migrations/20260220-migrate-yaml-to-json.d.ts +9 -0
- package/dist/core/migrations/20260220-migrate-yaml-to-json.js +64 -0
- package/dist/core/migrations/20260220-migrate-yaml-to-json.js.map +1 -0
- package/dist/core/migrations/index.d.ts +11 -0
- package/dist/core/migrations/index.js +23 -0
- package/dist/core/migrations/index.js.map +1 -0
- package/dist/core/schema-registry.d.ts +36 -0
- package/dist/core/schema-registry.js +161 -0
- package/dist/core/schema-registry.js.map +1 -0
- package/dist/core/types.d.ts +242 -3
- package/dist/core/types.js +21 -2
- package/dist/core/types.js.map +1 -1
- package/dist/core/user-config.d.ts +16 -0
- package/dist/core/user-config.js +8 -0
- package/dist/core/user-config.js.map +1 -1
- package/dist/core/validation.d.ts +973 -32
- package/dist/core/validation.js +163 -4
- package/dist/core/validation.js.map +1 -1
- package/dist/core/workspace-manager.d.ts +26 -2
- package/dist/core/workspace-manager.js +113 -15
- package/dist/core/workspace-manager.js.map +1 -1
- package/dist/core/workspace.d.ts +20 -11
- package/dist/core/workspace.js +123 -34
- package/dist/core/workspace.js.map +1 -1
- package/dist/mcp/connector-manager.d.ts +65 -0
- package/dist/mcp/connector-manager.js +223 -0
- package/dist/mcp/connector-manager.js.map +1 -0
- package/dist/mcp/connectors/asana.d.ts +2 -0
- package/dist/mcp/connectors/asana.js +20 -0
- package/dist/mcp/connectors/asana.js.map +1 -0
- package/dist/mcp/connectors/definitions.d.ts +45 -0
- package/dist/mcp/connectors/definitions.js +32 -0
- package/dist/mcp/connectors/definitions.js.map +1 -0
- package/dist/mcp/connectors/figma.d.ts +5 -0
- package/dist/mcp/connectors/figma.js +21 -0
- package/dist/mcp/connectors/figma.js.map +1 -0
- package/dist/mcp/connectors/gdrive.d.ts +2 -0
- package/dist/mcp/connectors/gdrive.js +20 -0
- package/dist/mcp/connectors/gdrive.js.map +1 -0
- package/dist/mcp/connectors/granola.d.ts +2 -0
- package/dist/mcp/connectors/granola.js +12 -0
- package/dist/mcp/connectors/granola.js.map +1 -0
- package/dist/mcp/connectors/linear.d.ts +2 -0
- package/dist/mcp/connectors/linear.js +19 -0
- package/dist/mcp/connectors/linear.js.map +1 -0
- package/dist/mcp/connectors/obsidian.d.ts +2 -0
- package/dist/mcp/connectors/obsidian.js +19 -0
- package/dist/mcp/connectors/obsidian.js.map +1 -0
- package/dist/mcp/connectors/pipedrive.d.ts +2 -0
- package/dist/mcp/connectors/pipedrive.js +20 -0
- package/dist/mcp/connectors/pipedrive.js.map +1 -0
- package/dist/mcp/connectors/slack.d.ts +2 -0
- package/dist/mcp/connectors/slack.js +21 -0
- package/dist/mcp/connectors/slack.js.map +1 -0
- package/dist/mcp/oauth-provider.d.ts +41 -0
- package/dist/mcp/oauth-provider.js +160 -0
- package/dist/mcp/oauth-provider.js.map +1 -0
- package/dist/mcp/server.d.ts +11 -0
- package/dist/mcp/server.js +28 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +14 -0
- package/dist/mcp/tools.js +172 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/server/index.js +17 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/plugin-loader.d.ts +15 -0
- package/dist/server/plugin-loader.js +68 -2
- package/dist/server/plugin-loader.js.map +1 -1
- package/dist/server/routes/graph-api.js +1 -1
- package/dist/server/routes/graph-api.js.map +1 -1
- package/dist/server/routes/webhook.js +33 -0
- package/dist/server/routes/webhook.js.map +1 -1
- package/dist/services/github-provisioner.d.ts +9 -3
- package/dist/services/github-provisioner.js +46 -8
- package/dist/services/github-provisioner.js.map +1 -1
- package/dist/services/lint-service.d.ts +27 -0
- package/dist/services/lint-service.js +83 -0
- package/dist/services/lint-service.js.map +1 -0
- package/dist/services/markdown.d.ts +9 -0
- package/dist/services/markdown.js +26 -5
- package/dist/services/markdown.js.map +1 -1
- package/dist/services/memory-service.d.ts +1 -2
- package/dist/services/memory-service.js +5 -4
- package/dist/services/memory-service.js.map +1 -1
- package/dist/services/orphan-service.d.ts +31 -0
- package/dist/services/orphan-service.js +100 -0
- package/dist/services/orphan-service.js.map +1 -0
- package/dist/services/sync/commit.d.ts +58 -0
- package/dist/services/sync/commit.js +350 -0
- package/dist/services/sync/commit.js.map +1 -0
- package/dist/services/sync/context-index.d.ts +69 -0
- package/dist/services/sync/context-index.js +280 -0
- package/dist/services/sync/context-index.js.map +1 -0
- package/dist/services/sync/derive.d.ts +34 -0
- package/dist/services/sync/derive.js +164 -0
- package/dist/services/sync/derive.js.map +1 -0
- package/dist/services/sync/enrichment-state.d.ts +31 -0
- package/dist/services/sync/enrichment-state.js +63 -0
- package/dist/services/sync/enrichment-state.js.map +1 -0
- package/dist/services/sync/enrichment.d.ts +25 -0
- package/dist/services/sync/enrichment.js +121 -0
- package/dist/services/sync/enrichment.js.map +1 -0
- package/dist/services/sync/frontmatter-extractor.d.ts +40 -0
- package/dist/services/sync/frontmatter-extractor.js +273 -0
- package/dist/services/sync/frontmatter-extractor.js.map +1 -0
- package/dist/services/sync/graph-match-state.d.ts +33 -0
- package/dist/services/sync/graph-match-state.js +61 -0
- package/dist/services/sync/graph-match-state.js.map +1 -0
- package/dist/services/sync/graph-match.d.ts +53 -0
- package/dist/services/sync/graph-match.js +316 -0
- package/dist/services/sync/graph-match.js.map +1 -0
- package/dist/services/sync/graphrag-client.d.ts +43 -0
- package/dist/services/sync/graphrag-client.js +94 -0
- package/dist/services/sync/graphrag-client.js.map +1 -0
- package/dist/services/sync/graphrag-config.d.ts +16 -0
- package/dist/services/sync/graphrag-config.js +39 -0
- package/dist/services/sync/graphrag-config.js.map +1 -0
- package/dist/services/sync/graphrag-context.d.ts +14 -0
- package/dist/services/sync/graphrag-context.js +109 -0
- package/dist/services/sync/graphrag-context.js.map +1 -0
- package/dist/services/sync/graphrag-indexer.d.ts +30 -0
- package/dist/services/sync/graphrag-indexer.js +358 -0
- package/dist/services/sync/graphrag-indexer.js.map +1 -0
- package/dist/services/sync/llm.d.ts +32 -0
- package/dist/services/sync/llm.js +115 -0
- package/dist/services/sync/llm.js.map +1 -0
- package/dist/services/sync/mcp-client.d.ts +59 -0
- package/dist/services/sync/mcp-client.js +285 -0
- package/dist/services/sync/mcp-client.js.map +1 -0
- package/dist/services/sync/model-factory.d.ts +10 -0
- package/dist/services/sync/model-factory.js +24 -0
- package/dist/services/sync/model-factory.js.map +1 -0
- package/dist/services/sync/name-quality.d.ts +31 -0
- package/dist/services/sync/name-quality.js +60 -0
- package/dist/services/sync/name-quality.js.map +1 -0
- package/dist/services/sync/output-schemas.d.ts +92 -0
- package/dist/services/sync/output-schemas.js +43 -0
- package/dist/services/sync/output-schemas.js.map +1 -0
- package/dist/services/sync/prompts.d.ts +19 -0
- package/dist/services/sync/prompts.js +128 -0
- package/dist/services/sync/prompts.js.map +1 -0
- package/dist/services/sync/reconciler.d.ts +48 -0
- package/dist/services/sync/reconciler.js +295 -0
- package/dist/services/sync/reconciler.js.map +1 -0
- package/dist/services/sync/source-config.d.ts +45 -0
- package/dist/services/sync/source-config.js +208 -0
- package/dist/services/sync/source-config.js.map +1 -0
- package/dist/services/sync/source-definitions/asana.d.ts +15 -0
- package/dist/services/sync/source-definitions/asana.js +48 -0
- package/dist/services/sync/source-definitions/asana.js.map +1 -0
- package/dist/services/sync/source-definitions/definitions.d.ts +21 -0
- package/dist/services/sync/source-definitions/definitions.js +26 -0
- package/dist/services/sync/source-definitions/definitions.js.map +1 -0
- package/dist/services/sync/source-definitions/gdrive.d.ts +16 -0
- package/dist/services/sync/source-definitions/gdrive.js +68 -0
- package/dist/services/sync/source-definitions/gdrive.js.map +1 -0
- package/dist/services/sync/source-definitions/granola.d.ts +2 -0
- package/dist/services/sync/source-definitions/granola.js +28 -0
- package/dist/services/sync/source-definitions/granola.js.map +1 -0
- package/dist/services/sync/source-definitions/linear.d.ts +2 -0
- package/dist/services/sync/source-definitions/linear.js +60 -0
- package/dist/services/sync/source-definitions/linear.js.map +1 -0
- package/dist/services/sync/source-definitions/obsidian.d.ts +2 -0
- package/dist/services/sync/source-definitions/obsidian.js +55 -0
- package/dist/services/sync/source-definitions/obsidian.js.map +1 -0
- package/dist/services/sync/source-definitions/pipedrive.d.ts +2 -0
- package/dist/services/sync/source-definitions/pipedrive.js +52 -0
- package/dist/services/sync/source-definitions/pipedrive.js.map +1 -0
- package/dist/services/sync/staging.d.ts +53 -0
- package/dist/services/sync/staging.js +131 -0
- package/dist/services/sync/staging.js.map +1 -0
- package/dist/services/sync/structured-extractor.d.ts +49 -0
- package/dist/services/sync/structured-extractor.js +344 -0
- package/dist/services/sync/structured-extractor.js.map +1 -0
- package/dist/services/sync/sync-runner.d.ts +32 -0
- package/dist/services/sync/sync-runner.js +195 -0
- package/dist/services/sync/sync-runner.js.map +1 -0
- package/dist/services/sync/sync-state.d.ts +43 -0
- package/dist/services/sync/sync-state.js +154 -0
- package/dist/services/sync/sync-state.js.map +1 -0
- package/dist/services/sync/types.d.ts +203 -0
- package/dist/services/sync/types.js +8 -0
- package/dist/services/sync/types.js.map +1 -0
- package/dist/services/sync/unstructured-extractor.d.ts +29 -0
- package/dist/services/sync/unstructured-extractor.js +197 -0
- package/dist/services/sync/unstructured-extractor.js.map +1 -0
- package/dist/services/vector-service.d.ts +88 -0
- package/dist/services/vector-service.js +322 -0
- package/dist/services/vector-service.js.map +1 -0
- package/dist/utils/git.d.ts +26 -4
- package/dist/utils/git.js +55 -7
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/merge-resolver.d.ts +34 -0
- package/dist/utils/merge-resolver.js +201 -0
- package/dist/utils/merge-resolver.js.map +1 -0
- package/dist/utils/preflight.d.ts +2 -1
- package/dist/utils/preflight.js +8 -1
- package/dist/utils/preflight.js.map +1 -1
- package/dist/utils/version-checker.d.ts +23 -0
- package/dist/utils/version-checker.js +116 -0
- package/dist/utils/version-checker.js.map +1 -0
- package/dist/utils/workspace-config.d.ts +8 -0
- package/dist/utils/workspace-config.js +22 -0
- package/dist/utils/workspace-config.js.map +1 -0
- package/package.json +24 -11
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Client Provider for MCP Connectors
|
|
3
|
+
*
|
|
4
|
+
* Implements OAuthClientProvider from the MCP SDK to support OAuth-based
|
|
5
|
+
* MCP servers (Figma, Linear, etc.) using dynamic client registration.
|
|
6
|
+
*
|
|
7
|
+
* Storage: ~/.studiograph/connectors/<name>.oauth.json (tokens, client info, PKCE verifier)
|
|
8
|
+
* Auth flow: opens browser → local callback server → exchanges code for tokens
|
|
9
|
+
*
|
|
10
|
+
* Works with any MCP server that supports RFC 8414 (OAuth metadata discovery)
|
|
11
|
+
* and RFC 7591 (dynamic client registration). No pre-registered client secrets needed.
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
14
|
+
import { join } from 'path';
|
|
15
|
+
import { createServer } from 'http';
|
|
16
|
+
import { CONNECTORS_DIR } from './connector-manager.js';
|
|
17
|
+
const CALLBACK_PORT = 38741; // Fixed port for OAuth callbacks
|
|
18
|
+
const CALLBACK_PATH = '/oauth/callback';
|
|
19
|
+
const REDIRECT_URI = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;
|
|
20
|
+
/**
|
|
21
|
+
* File-backed OAuth provider for a single connector.
|
|
22
|
+
* Stores tokens and client info alongside the connector config.
|
|
23
|
+
*/
|
|
24
|
+
export class ConnectorOAuthProvider {
|
|
25
|
+
connectorName;
|
|
26
|
+
storagePath;
|
|
27
|
+
constructor(connectorName) {
|
|
28
|
+
this.connectorName = connectorName;
|
|
29
|
+
this.storagePath = join(CONNECTORS_DIR, `${connectorName}.oauth.json`);
|
|
30
|
+
}
|
|
31
|
+
get redirectUrl() {
|
|
32
|
+
return new URL(REDIRECT_URI);
|
|
33
|
+
}
|
|
34
|
+
get clientMetadata() {
|
|
35
|
+
return {
|
|
36
|
+
redirect_uris: [REDIRECT_URI],
|
|
37
|
+
client_name: 'Studiograph',
|
|
38
|
+
grant_types: ['authorization_code', 'refresh_token'],
|
|
39
|
+
response_types: ['code'],
|
|
40
|
+
token_endpoint_auth_method: 'none', // public client — no secret
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
async clientInformation() {
|
|
44
|
+
return this._load().clientInfo;
|
|
45
|
+
}
|
|
46
|
+
async saveClientInformation(info) {
|
|
47
|
+
const data = this._load();
|
|
48
|
+
data.clientInfo = info;
|
|
49
|
+
this._save(data);
|
|
50
|
+
}
|
|
51
|
+
async tokens() {
|
|
52
|
+
return this._load().tokens;
|
|
53
|
+
}
|
|
54
|
+
async saveTokens(tokens) {
|
|
55
|
+
const data = this._load();
|
|
56
|
+
data.tokens = tokens;
|
|
57
|
+
this._save(data);
|
|
58
|
+
}
|
|
59
|
+
async redirectToAuthorization(authorizationUrl) {
|
|
60
|
+
// Open browser to authorization URL
|
|
61
|
+
const { exec } = await import('child_process');
|
|
62
|
+
const url = authorizationUrl.toString();
|
|
63
|
+
const platform = process.platform;
|
|
64
|
+
if (platform === 'darwin') {
|
|
65
|
+
exec(`open "${url}"`);
|
|
66
|
+
}
|
|
67
|
+
else if (platform === 'win32') {
|
|
68
|
+
exec(`start "" "${url}"`);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
exec(`xdg-open "${url}"`);
|
|
72
|
+
}
|
|
73
|
+
console.log(`[connectors] Opening browser for ${this.connectorName} authorization...`);
|
|
74
|
+
}
|
|
75
|
+
async saveCodeVerifier(codeVerifier) {
|
|
76
|
+
const data = this._load();
|
|
77
|
+
data.codeVerifier = codeVerifier;
|
|
78
|
+
this._save(data);
|
|
79
|
+
}
|
|
80
|
+
async codeVerifier() {
|
|
81
|
+
const data = this._load();
|
|
82
|
+
return data.codeVerifier ?? '';
|
|
83
|
+
}
|
|
84
|
+
async invalidateCredentials(scope) {
|
|
85
|
+
const data = this._load();
|
|
86
|
+
if (scope === 'all' || scope === 'tokens')
|
|
87
|
+
data.tokens = undefined;
|
|
88
|
+
if (scope === 'all' || scope === 'client')
|
|
89
|
+
data.clientInfo = undefined;
|
|
90
|
+
if (scope === 'all' || scope === 'verifier')
|
|
91
|
+
data.codeVerifier = undefined;
|
|
92
|
+
this._save(data);
|
|
93
|
+
}
|
|
94
|
+
// ── storage helpers ──────────────────────────────────────────────────────
|
|
95
|
+
_load() {
|
|
96
|
+
if (!existsSync(this.storagePath))
|
|
97
|
+
return {};
|
|
98
|
+
try {
|
|
99
|
+
return JSON.parse(readFileSync(this.storagePath, 'utf-8'));
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
_save(data) {
|
|
106
|
+
mkdirSync(CONNECTORS_DIR, { recursive: true });
|
|
107
|
+
writeFileSync(this.storagePath, JSON.stringify(data, null, 2) + '\n', { mode: 0o600 });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// ── Callback server ──────────────────────────────────────────────────────────
|
|
111
|
+
/**
|
|
112
|
+
* Start a temporary local HTTP server to receive the OAuth callback.
|
|
113
|
+
* Returns a promise that resolves with the authorization code.
|
|
114
|
+
* Server auto-closes after receiving the callback or timing out.
|
|
115
|
+
*/
|
|
116
|
+
export function waitForOAuthCallback(timeoutMs = 120_000) {
|
|
117
|
+
return new Promise((resolve, reject) => {
|
|
118
|
+
let server;
|
|
119
|
+
const timeout = setTimeout(() => {
|
|
120
|
+
server?.close();
|
|
121
|
+
reject(new Error('OAuth callback timed out (2 minutes)'));
|
|
122
|
+
}, timeoutMs);
|
|
123
|
+
server = createServer((req, res) => {
|
|
124
|
+
const url = new URL(req.url ?? '/', `http://localhost:${CALLBACK_PORT}`);
|
|
125
|
+
if (url.pathname !== CALLBACK_PATH) {
|
|
126
|
+
res.writeHead(404);
|
|
127
|
+
res.end('Not found');
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const code = url.searchParams.get('code');
|
|
131
|
+
const error = url.searchParams.get('error');
|
|
132
|
+
if (error) {
|
|
133
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
134
|
+
res.end(`<html><body><h2>Authorization failed</h2><p>${error}</p><p>You can close this tab.</p></body></html>`);
|
|
135
|
+
clearTimeout(timeout);
|
|
136
|
+
server.close();
|
|
137
|
+
reject(new Error(`OAuth authorization denied: ${error}`));
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (!code) {
|
|
141
|
+
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
142
|
+
res.end('<html><body><h2>Missing authorization code</h2><p>You can close this tab.</p></body></html>');
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
146
|
+
res.end('<html><body><h2>Authorization successful</h2><p>You can close this tab and return to Studiograph.</p></body></html>');
|
|
147
|
+
clearTimeout(timeout);
|
|
148
|
+
server.close();
|
|
149
|
+
resolve(code);
|
|
150
|
+
});
|
|
151
|
+
server.listen(CALLBACK_PORT, () => {
|
|
152
|
+
// Server ready — browser will be opened by redirectToAuthorization()
|
|
153
|
+
});
|
|
154
|
+
server.on('error', (err) => {
|
|
155
|
+
clearTimeout(timeout);
|
|
156
|
+
reject(new Error(`Failed to start OAuth callback server: ${err.message}`));
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=oauth-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-provider.js","sourceRoot":"","sources":["../../src/mcp/oauth-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Studiograph MCP server
|
|
3
|
+
*
|
|
4
|
+
* Creates a McpServer instance, registers all tools, and connects via stdio
|
|
5
|
+
* transport for integration with Claude Desktop and other MCP clients.
|
|
6
|
+
*
|
|
7
|
+
* NOTE: All logging uses console.error() — stdout is reserved for the
|
|
8
|
+
* JSON-RPC protocol messages and must not be written to directly.
|
|
9
|
+
*/
|
|
10
|
+
import { WorkspaceManager } from '../core/workspace-manager.js';
|
|
11
|
+
export declare function startMcpServer(workspaceManager: WorkspaceManager): Promise<void>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Studiograph MCP server
|
|
3
|
+
*
|
|
4
|
+
* Creates a McpServer instance, registers all tools, and connects via stdio
|
|
5
|
+
* transport for integration with Claude Desktop and other MCP clients.
|
|
6
|
+
*
|
|
7
|
+
* NOTE: All logging uses console.error() — stdout is reserved for the
|
|
8
|
+
* JSON-RPC protocol messages and must not be written to directly.
|
|
9
|
+
*/
|
|
10
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
12
|
+
import { registerTools } from './tools.js';
|
|
13
|
+
export async function startMcpServer(workspaceManager) {
|
|
14
|
+
const server = new McpServer({
|
|
15
|
+
name: 'studiograph',
|
|
16
|
+
version: '1.0.0',
|
|
17
|
+
});
|
|
18
|
+
registerTools(server, workspaceManager);
|
|
19
|
+
const transport = new StdioServerTransport();
|
|
20
|
+
await server.connect(transport);
|
|
21
|
+
console.error('Studiograph MCP server ready');
|
|
22
|
+
// Keep the process alive — the transport closes when the client disconnects
|
|
23
|
+
process.on('SIGINT', async () => {
|
|
24
|
+
await server.close();
|
|
25
|
+
process.exit(0);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,gBAAkC;IACrE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAK,aAAa;QACtB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,aAAa,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAExC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAE9C,4EAA4E;IAC5E,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Studiograph MCP tool definitions
|
|
3
|
+
*
|
|
4
|
+
* Each tool is a thin wrapper around existing WorkspaceManager / BaseGraphManager
|
|
5
|
+
* methods — no new business logic. Results are returned as JSON text so the
|
|
6
|
+
* MCP client (Claude Desktop) can process structured data.
|
|
7
|
+
*
|
|
8
|
+
* Note: `inputSchema` is cast to `any` at each call site because the MCP SDK's
|
|
9
|
+
* ZodRawShapeCompat type does not accept ZodObject in TypeScript's strict mode.
|
|
10
|
+
* Runtime schema validation is handled correctly by the SDK regardless.
|
|
11
|
+
*/
|
|
12
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
13
|
+
import { WorkspaceManager } from '../core/workspace-manager.js';
|
|
14
|
+
export declare function registerTools(server: McpServer, wm: WorkspaceManager): void;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Studiograph MCP tool definitions
|
|
3
|
+
*
|
|
4
|
+
* Each tool is a thin wrapper around existing WorkspaceManager / BaseGraphManager
|
|
5
|
+
* methods — no new business logic. Results are returned as JSON text so the
|
|
6
|
+
* MCP client (Claude Desktop) can process structured data.
|
|
7
|
+
*
|
|
8
|
+
* Note: `inputSchema` is cast to `any` at each call site because the MCP SDK's
|
|
9
|
+
* ZodRawShapeCompat type does not accept ZodObject in TypeScript's strict mode.
|
|
10
|
+
* Runtime schema validation is handled correctly by the SDK regardless.
|
|
11
|
+
*/
|
|
12
|
+
import { z } from 'zod';
|
|
13
|
+
// ── helpers ───────────────────────────────────────────────────────────────────
|
|
14
|
+
function ok(data) {
|
|
15
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
16
|
+
}
|
|
17
|
+
function fail(err) {
|
|
18
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
19
|
+
return { content: [{ type: 'text', text: msg }], isError: true };
|
|
20
|
+
}
|
|
21
|
+
// Strip frontmatter fields that duplicate the top-level id/type keys
|
|
22
|
+
function shape(id, entityType, data, extra) {
|
|
23
|
+
const { id: _id, entity_type: _et, ...rest } = data;
|
|
24
|
+
return { id, type: entityType, ...rest, ...extra };
|
|
25
|
+
}
|
|
26
|
+
// ── tool registration ─────────────────────────────────────────────────────────
|
|
27
|
+
export function registerTools(server, wm) {
|
|
28
|
+
// ── list_repos ────────────────────────────────────────────────────────────
|
|
29
|
+
server.registerTool('list_repos', { description: 'List all repositories registered in the Studiograph workspace' }, async () => ok(wm.getAllRepoConfigs()));
|
|
30
|
+
// ── list_entities ─────────────────────────────────────────────────────────
|
|
31
|
+
const listEntitiesSchema = z.object({
|
|
32
|
+
repo: z.string().optional().describe('Repo name — omit to list across all repos'),
|
|
33
|
+
entity_type: z.string().optional().describe('Entity type filter (project, client, person, deck…)'),
|
|
34
|
+
limit: z.number().int().positive().optional().describe('Maximum number of results'),
|
|
35
|
+
});
|
|
36
|
+
server.registerTool('list_entities', { description: 'List entities in a repo (or all repos). Optionally filter by entity type.', inputSchema: listEntitiesSchema }, async (args) => {
|
|
37
|
+
const { repo, entity_type, limit } = listEntitiesSchema.parse(args);
|
|
38
|
+
try {
|
|
39
|
+
if (repo) {
|
|
40
|
+
const entities = wm.getGraph(repo).list(entity_type, limit);
|
|
41
|
+
return ok(entities.map(e => shape(e.id, e.entityType, e.data)));
|
|
42
|
+
}
|
|
43
|
+
const entities = wm.list(entity_type, limit);
|
|
44
|
+
return ok(entities.map(e => shape(e.id, e.entityType, e.data, { repo: e.repoName })));
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
return fail(err);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
// ── get_entity ────────────────────────────────────────────────────────────
|
|
51
|
+
const getEntitySchema = z.object({
|
|
52
|
+
repo: z.string().describe('Repo name'),
|
|
53
|
+
entity_type: z.string().describe('Entity type (project, client, deck…)'),
|
|
54
|
+
entity_id: z.string().describe('Entity ID (kebab-case slug)'),
|
|
55
|
+
});
|
|
56
|
+
server.registerTool('get_entity', { description: 'Get a specific entity — includes full markdown content and frontmatter', inputSchema: getEntitySchema }, async (args) => {
|
|
57
|
+
const { repo, entity_type, entity_id } = getEntitySchema.parse(args);
|
|
58
|
+
try {
|
|
59
|
+
const entity = wm.getGraph(repo).get(entity_type, entity_id);
|
|
60
|
+
return ok({ id: entity.id, type: entity.entityType, data: entity.data, content: entity.document.content });
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
return fail(err);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
// ── search_entities ───────────────────────────────────────────────────────
|
|
67
|
+
const searchSchema = z.object({
|
|
68
|
+
query: z.string().optional().describe('Text search query'),
|
|
69
|
+
entity_type: z.string().optional().describe('Filter by entity type'),
|
|
70
|
+
repos: z.array(z.string()).optional().describe('Limit to specific repo names'),
|
|
71
|
+
limit: z.number().int().positive().optional().describe('Maximum number of results'),
|
|
72
|
+
});
|
|
73
|
+
server.registerTool('search_entities', { description: 'Full-text search for entities across all workspace repos', inputSchema: searchSchema }, async (args) => {
|
|
74
|
+
const { query, entity_type, repos, limit } = searchSchema.parse(args);
|
|
75
|
+
try {
|
|
76
|
+
const results = await wm.search({ query, entityType: entity_type, repoNames: repos, limit });
|
|
77
|
+
return ok(results.map(e => shape(e.id, e.entityType, e.data, { repo: e.repoName })));
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
return fail(err);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
// ── create_entity ─────────────────────────────────────────────────────────
|
|
84
|
+
const createSchema = z.object({
|
|
85
|
+
repo: z.string().describe('Repo name'),
|
|
86
|
+
entity_type: z.string().describe('Entity type'),
|
|
87
|
+
entity_id: z.string().describe('Entity ID (kebab-case slug)'),
|
|
88
|
+
data: z.record(z.unknown()).describe('Frontmatter fields as a JSON object'),
|
|
89
|
+
content: z.string().optional().describe('Markdown body content'),
|
|
90
|
+
});
|
|
91
|
+
server.registerTool('create_entity', { description: 'Create a new entity in a workspace repo. Commits to git automatically.', inputSchema: createSchema }, async (args) => {
|
|
92
|
+
const { repo, entity_type, entity_id, data, content } = createSchema.parse(args);
|
|
93
|
+
try {
|
|
94
|
+
const entity = await wm.getGraph(repo).create({
|
|
95
|
+
entityType: entity_type,
|
|
96
|
+
entityId: entity_id,
|
|
97
|
+
data: data,
|
|
98
|
+
content,
|
|
99
|
+
});
|
|
100
|
+
return ok({ success: true, id: entity.id, type: entity.entityType });
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
return fail(err);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
// ── update_entity ─────────────────────────────────────────────────────────
|
|
107
|
+
const updateSchema = z.object({
|
|
108
|
+
repo: z.string().describe('Repo name'),
|
|
109
|
+
entity_type: z.string().describe('Entity type'),
|
|
110
|
+
entity_id: z.string().describe('Entity ID'),
|
|
111
|
+
data: z.record(z.unknown()).optional().describe('Frontmatter fields to update (merged with existing)'),
|
|
112
|
+
content: z.string().optional().describe('New markdown body content'),
|
|
113
|
+
});
|
|
114
|
+
server.registerTool('update_entity', { description: 'Update an existing entity. Data fields are merged with existing frontmatter.', inputSchema: updateSchema }, async (args) => {
|
|
115
|
+
const { repo, entity_type, entity_id, data, content } = updateSchema.parse(args);
|
|
116
|
+
try {
|
|
117
|
+
const entity = await wm.getGraph(repo).update({
|
|
118
|
+
entityType: entity_type,
|
|
119
|
+
entityId: entity_id,
|
|
120
|
+
data: data,
|
|
121
|
+
content,
|
|
122
|
+
});
|
|
123
|
+
return ok({ success: true, id: entity.id, type: entity.entityType });
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
return fail(err);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
// ── validate_wikilinks ────────────────────────────────────────────────────
|
|
130
|
+
const validateWikilinksSchema = z.object({
|
|
131
|
+
repo: z.string().describe('Repo name'),
|
|
132
|
+
entity_type: z.string().describe('Entity type'),
|
|
133
|
+
entity_id: z.string().describe('Entity ID'),
|
|
134
|
+
});
|
|
135
|
+
server.registerTool('validate_wikilinks', { description: 'Check which wikilinks in an entity resolve to real entities and which are broken', inputSchema: validateWikilinksSchema }, async (args) => {
|
|
136
|
+
const { repo, entity_type, entity_id } = validateWikilinksSchema.parse(args);
|
|
137
|
+
try {
|
|
138
|
+
const result = wm.getGraph(repo).validateWikilinks(entity_type, entity_id);
|
|
139
|
+
return ok({ entity_id, valid: result.valid, broken: result.broken, total: result.valid.length + result.broken.length });
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
return fail(err);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
// ── find_related ──────────────────────────────────────────────────────────
|
|
146
|
+
const relatedSchema = z.object({
|
|
147
|
+
repo: z.string().describe('Repo name'),
|
|
148
|
+
entity_type: z.string().describe('Entity type'),
|
|
149
|
+
entity_id: z.string().describe('Entity ID'),
|
|
150
|
+
direction: z.enum(['outgoing', 'incoming', 'both']).default('both')
|
|
151
|
+
.describe('outgoing = links from this entity, incoming = links to this entity'),
|
|
152
|
+
});
|
|
153
|
+
server.registerTool('find_related', { description: 'Find entities related via wikilinks (outgoing) or backlinks (incoming)', inputSchema: relatedSchema }, async (args) => {
|
|
154
|
+
const { repo, entity_type, entity_id, direction } = relatedSchema.parse(args);
|
|
155
|
+
try {
|
|
156
|
+
const results = [];
|
|
157
|
+
if (direction === 'outgoing' || direction === 'both') {
|
|
158
|
+
const related = wm.getGraph(repo).getRelated(entity_type, entity_id);
|
|
159
|
+
results.push(...related.map(e => shape(e.id, e.entityType, e.data, { direction: 'outgoing' })));
|
|
160
|
+
}
|
|
161
|
+
if (direction === 'incoming' || direction === 'both') {
|
|
162
|
+
const backlinks = wm.getBacklinks(repo, entity_type, entity_id);
|
|
163
|
+
results.push(...backlinks.map(e => shape(e.id, e.entityType, e.data, { direction: 'incoming', repo: e.repoName })));
|
|
164
|
+
}
|
|
165
|
+
return ok(results);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
return fail(err);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"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"}
|
package/dist/server/index.js
CHANGED
|
@@ -55,18 +55,31 @@ export async function createServer(config) {
|
|
|
55
55
|
});
|
|
56
56
|
// Register graph API routes (unauthenticated read-only)
|
|
57
57
|
await registerGraphApiRoutes(fastify, config.workspaceManager);
|
|
58
|
-
//
|
|
58
|
+
// Discover installed apps and collect their skill/tool dirs
|
|
59
|
+
const loader = new PluginLoader();
|
|
60
|
+
const manifests = loader.loadApps(config.appsDir);
|
|
61
|
+
const appSkillsDirs = [];
|
|
62
|
+
const appToolsDirs = [];
|
|
63
|
+
for (const manifest of manifests) {
|
|
64
|
+
const skillsDir = loader.getSkillsDir(config.appsDir, manifest);
|
|
65
|
+
if (skillsDir)
|
|
66
|
+
appSkillsDirs.push(skillsDir);
|
|
67
|
+
const toolsDir = loader.getToolsDir(config.appsDir, manifest);
|
|
68
|
+
if (toolsDir)
|
|
69
|
+
appToolsDirs.push(toolsDir);
|
|
70
|
+
}
|
|
71
|
+
// Initialize agent — skills/tools dirs are resolved before agent starts
|
|
59
72
|
const agent = new AgentOrchestrator({
|
|
60
73
|
workspacePath: config.workspacePath,
|
|
61
74
|
workspaceConfig: config.workspaceConfig,
|
|
62
75
|
gitUser: config.gitUser,
|
|
76
|
+
skillsDirs: appSkillsDirs,
|
|
77
|
+
toolsDirs: appToolsDirs,
|
|
63
78
|
});
|
|
64
79
|
await registerChatRoutes(fastify, agent);
|
|
65
80
|
// GitHub webhook route
|
|
66
81
|
await registerWebhookRoutes(fastify, config.workspaceManager, config.webhookSecret);
|
|
67
|
-
//
|
|
68
|
-
const loader = new PluginLoader();
|
|
69
|
-
const manifests = loader.loadApps(config.appsDir);
|
|
82
|
+
// Mount app plugins
|
|
70
83
|
for (const manifest of manifests) {
|
|
71
84
|
try {
|
|
72
85
|
await loader.mountPlugin(fastify, manifest, config.appsDir, {
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,OAAiC,MAAM,SAAS,CAAC;AACxD,OAAO,IAAI,MAAM,eAAe,CAAC;AAGjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAc5D;;;GAGG;AACH,SAAS,aAAa,CAAC,OAAiB;IACtC,OAAO,KAAK,EAAE,GAAQ,EAAE,KAAU,EAAE,EAAE;QACpC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,uCAAuC;QAEzE,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAuB,CAAC;QAChE,MAAM,KAAK,GAAG,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEtE,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAoB;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,OAAO;IACP,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;QAC3B,MAAM,EAAE,IAAI;KACb,CAAC,CAAC;IAEH,6CAA6C;IAC7C,OAAO,CAAC,oBAAoB,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAC1F,IAAI,CAAC;YACF,GAAW,CAAC,OAAO,GAAG,IAAI,CAAC;YAC5B,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE/C,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QACjD,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QACnD,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,MAAM,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,wDAAwD;IACxD,MAAM,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAE/D,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,OAAiC,MAAM,SAAS,CAAC;AACxD,OAAO,IAAI,MAAM,eAAe,CAAC;AAGjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAc5D;;;GAGG;AACH,SAAS,aAAa,CAAC,OAAiB;IACtC,OAAO,KAAK,EAAE,GAAQ,EAAE,KAAU,EAAE,EAAE;QACpC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,uCAAuC;QAEzE,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAuB,CAAC;QAChE,MAAM,KAAK,GAAG,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEtE,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAoB;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,OAAO;IACP,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;QAC3B,MAAM,EAAE,IAAI;KACb,CAAC,CAAC;IAEH,6CAA6C;IAC7C,OAAO,CAAC,oBAAoB,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAC1F,IAAI,CAAC;YACF,GAAW,CAAC,OAAO,GAAG,IAAI,CAAC;YAC5B,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE/C,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QACjD,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QACnD,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,MAAM,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,wDAAwD;IACxD,MAAM,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAE/D,4DAA4D;IAC5D,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElD,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAChE,IAAI,SAAS;YAAE,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE7C,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC9D,IAAI,QAAQ;YAAE,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,wEAAwE;IACxE,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC;QAClC,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,aAAa;QACzB,SAAS,EAAE,YAAY;KACxB,CAAC,CAAC;IAEH,MAAM,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAEzC,uBAAuB;IACvB,MAAM,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAEpF,oBAAoB;IACpB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE;gBAC1D,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;gBACzC,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,QAAQ,CAAC,IAAI,QAAQ,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;QAC9E,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,wBAAwB,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Scans .studiograph/apps/ for installed apps, parses their manifests,
|
|
5
5
|
* and mounts their Fastify plugins under the declared mountPath.
|
|
6
|
+
* Also serves static assets from each app's static/ directory.
|
|
6
7
|
*/
|
|
7
8
|
import type { FastifyInstance } from 'fastify';
|
|
8
9
|
import { WorkspaceManager } from '../core/workspace-manager.js';
|
|
@@ -21,8 +22,22 @@ export declare class PluginLoader {
|
|
|
21
22
|
* Returns empty array if the directory does not exist.
|
|
22
23
|
*/
|
|
23
24
|
loadApps(appsDir: string): AppManifest[];
|
|
25
|
+
/**
|
|
26
|
+
* Return the skills directory for a given app, if it exists.
|
|
27
|
+
*/
|
|
28
|
+
getSkillsDir(appsDir: string, manifest: AppManifest): string | null;
|
|
29
|
+
/**
|
|
30
|
+
* Return the tools directory for a given app, if it exists.
|
|
31
|
+
*/
|
|
32
|
+
getToolsDir(appsDir: string, manifest: AppManifest): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Return the static assets directory for a given app, if it exists.
|
|
35
|
+
*/
|
|
36
|
+
getStaticDir(appsDir: string, manifest: AppManifest): string | null;
|
|
24
37
|
/**
|
|
25
38
|
* Dynamically import and register a plugin under its mountPath.
|
|
39
|
+
* Also mounts a static file handler at {mountPath}/static/* if the
|
|
40
|
+
* app has a static/ directory.
|
|
26
41
|
*/
|
|
27
42
|
mountPlugin(fastify: FastifyInstance, manifest: AppManifest, appDir: string, opts: {
|
|
28
43
|
workspaceManager: WorkspaceManager;
|
|
@@ -3,9 +3,31 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Scans .studiograph/apps/ for installed apps, parses their manifests,
|
|
5
5
|
* and mounts their Fastify plugins under the declared mountPath.
|
|
6
|
+
* Also serves static assets from each app's static/ directory.
|
|
6
7
|
*/
|
|
7
|
-
import { existsSync, readdirSync, readFileSync } from 'fs';
|
|
8
|
-
import { join } from 'path';
|
|
8
|
+
import { existsSync, readdirSync, readFileSync, createReadStream } from 'fs';
|
|
9
|
+
import { join, extname } from 'path';
|
|
10
|
+
const MIME_TYPES = {
|
|
11
|
+
'.html': 'text/html',
|
|
12
|
+
'.css': 'text/css',
|
|
13
|
+
'.js': 'application/javascript',
|
|
14
|
+
'.mjs': 'application/javascript',
|
|
15
|
+
'.json': 'application/json',
|
|
16
|
+
'.png': 'image/png',
|
|
17
|
+
'.jpg': 'image/jpeg',
|
|
18
|
+
'.jpeg': 'image/jpeg',
|
|
19
|
+
'.gif': 'image/gif',
|
|
20
|
+
'.svg': 'image/svg+xml',
|
|
21
|
+
'.ico': 'image/x-icon',
|
|
22
|
+
'.woff': 'font/woff',
|
|
23
|
+
'.woff2': 'font/woff2',
|
|
24
|
+
'.ttf': 'font/ttf',
|
|
25
|
+
'.otf': 'font/otf',
|
|
26
|
+
'.webp': 'image/webp',
|
|
27
|
+
'.avif': 'image/avif',
|
|
28
|
+
'.mp4': 'video/mp4',
|
|
29
|
+
'.webm': 'video/webm',
|
|
30
|
+
};
|
|
9
31
|
export class PluginLoader {
|
|
10
32
|
/**
|
|
11
33
|
* Scan appsDir for installed apps and return their manifests.
|
|
@@ -56,8 +78,31 @@ export class PluginLoader {
|
|
|
56
78
|
}
|
|
57
79
|
return manifests;
|
|
58
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Return the skills directory for a given app, if it exists.
|
|
83
|
+
*/
|
|
84
|
+
getSkillsDir(appsDir, manifest) {
|
|
85
|
+
const dir = join(appsDir, manifest.name, 'skills');
|
|
86
|
+
return existsSync(dir) ? dir : null;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Return the tools directory for a given app, if it exists.
|
|
90
|
+
*/
|
|
91
|
+
getToolsDir(appsDir, manifest) {
|
|
92
|
+
const dir = join(appsDir, manifest.name, 'tools');
|
|
93
|
+
return existsSync(dir) ? dir : null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Return the static assets directory for a given app, if it exists.
|
|
97
|
+
*/
|
|
98
|
+
getStaticDir(appsDir, manifest) {
|
|
99
|
+
const dir = join(appsDir, manifest.name, 'static');
|
|
100
|
+
return existsSync(dir) ? dir : null;
|
|
101
|
+
}
|
|
59
102
|
/**
|
|
60
103
|
* Dynamically import and register a plugin under its mountPath.
|
|
104
|
+
* Also mounts a static file handler at {mountPath}/static/* if the
|
|
105
|
+
* app has a static/ directory.
|
|
61
106
|
*/
|
|
62
107
|
async mountPlugin(fastify, manifest, appDir, opts) {
|
|
63
108
|
const pluginPath = join(appDir, manifest.name, manifest.plugin);
|
|
@@ -70,12 +115,33 @@ export class PluginLoader {
|
|
|
70
115
|
if (typeof pluginFn !== 'function') {
|
|
71
116
|
throw new Error(`Plugin at ${pluginPath} does not export a function`);
|
|
72
117
|
}
|
|
118
|
+
const staticDir = this.getStaticDir(appDir, manifest);
|
|
73
119
|
await fastify.register(pluginFn, {
|
|
74
120
|
prefix: manifest.mountPath,
|
|
75
121
|
workspaceManager: opts.workspaceManager,
|
|
76
122
|
gitUser: opts.gitUser,
|
|
77
123
|
appsDir: appDir,
|
|
124
|
+
staticDir,
|
|
78
125
|
});
|
|
126
|
+
// Mount static file handler if app has a static/ directory
|
|
127
|
+
if (staticDir) {
|
|
128
|
+
await fastify.register(async (instance) => {
|
|
129
|
+
instance.get('/*', async (req, reply) => {
|
|
130
|
+
const filePath = req.params['*'];
|
|
131
|
+
if (!filePath || filePath.includes('..')) {
|
|
132
|
+
return reply.status(400).send({ error: 'Invalid path' });
|
|
133
|
+
}
|
|
134
|
+
const fullPath = join(staticDir, filePath);
|
|
135
|
+
if (!existsSync(fullPath)) {
|
|
136
|
+
return reply.status(404).send({ error: 'Not found' });
|
|
137
|
+
}
|
|
138
|
+
const ext = extname(fullPath).toLowerCase();
|
|
139
|
+
const contentType = MIME_TYPES[ext] || 'application/octet-stream';
|
|
140
|
+
reply.type(contentType);
|
|
141
|
+
return reply.send(createReadStream(fullPath));
|
|
142
|
+
});
|
|
143
|
+
}, { prefix: `${manifest.mountPath}/static` });
|
|
144
|
+
}
|
|
79
145
|
}
|
|
80
146
|
}
|
|
81
147
|
//# sourceMappingURL=plugin-loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-loader.js","sourceRoot":"","sources":["../../src/server/plugin-loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"plugin-loader.js","sourceRoot":"","sources":["../../src/server/plugin-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -60,7 +60,7 @@ export async function registerGraphApiRoutes(fastify, workspaceManager) {
|
|
|
60
60
|
// GET /api/search?q=&type=&tags=&repos= — cross-repo search
|
|
61
61
|
fastify.get('/api/search', async (req, reply) => {
|
|
62
62
|
const { q, type, tags, repos } = req.query;
|
|
63
|
-
const results = workspaceManager.search({
|
|
63
|
+
const results = await workspaceManager.search({
|
|
64
64
|
query: q,
|
|
65
65
|
entityType: type,
|
|
66
66
|
tags: tags ? tags.split(',').map(t => t.trim()) : undefined,
|