@contentrain/mcp 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -3
- package/dist/{annotations-DSzewhL4.mjs → annotations-D3tlsF38.mjs} +39 -4
- package/dist/annotations-D3tlsF38.mjs.map +1 -0
- package/dist/{availability-Bj9zOfEn.mjs → availability-sWWRz2W0.mjs} +8 -2
- package/dist/availability-sWWRz2W0.mjs.map +1 -0
- package/dist/{content-manager-BExZy6Eu.d.mts → content-manager-DcmNwvmq.d.mts} +2 -2
- package/dist/{content-manager-BExZy6Eu.d.mts.map → content-manager-DcmNwvmq.d.mts.map} +1 -1
- package/dist/core/config.d.mts +1 -1
- package/dist/core/content-manager.d.mts +1 -1
- package/dist/core/context.d.mts +1 -1
- package/dist/core/contracts/index.d.mts +2 -2
- package/dist/core/model-manager.d.mts +1 -1
- package/dist/core/ops/index.d.mts +2 -2
- package/dist/core/overlay-reader.d.mts +1 -1
- package/dist/core/validator/index.d.mts +1 -1
- package/dist/index-DDX-qYNw.d.mts +2 -0
- package/dist/index.mjs +2 -2
- package/dist/providers/github/index.d.mts +1 -1
- package/dist/providers/gitlab/index.d.mts +1 -1
- package/dist/providers/local/index.d.mts +1 -1
- package/dist/server/http/index.d.mts +1 -1
- package/dist/server/http/index.mjs +2 -2
- package/dist/{server-B6_fzRmK.mjs → server-DtabGAY6.mjs} +134 -4
- package/dist/server-DtabGAY6.mjs.map +1 -0
- package/dist/{server-B1KfvywF.d.mts → server-vA1tM7DA.d.mts} +2 -2
- package/dist/{server-B1KfvywF.d.mts.map → server-vA1tM7DA.d.mts.map} +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.mjs +2 -2
- package/dist/tools/annotations.d.mts +3 -3
- package/dist/tools/annotations.d.mts.map +1 -1
- package/dist/tools/annotations.mjs +1 -1
- package/dist/tools/availability.d.mts +3 -0
- package/dist/tools/availability.d.mts.map +1 -1
- package/dist/tools/availability.mjs +1 -1
- package/package.json +3 -3
- package/dist/annotations-DSzewhL4.mjs.map +0 -1
- package/dist/availability-Bj9zOfEn.mjs.map +0 -1
- package/dist/index-6yasXNLQ.d.mts +0 -2
- package/dist/server-B6_fzRmK.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -71,9 +71,9 @@ All write operations are designed around git-backed safety:
|
|
|
71
71
|
|
|
72
72
|
## Tool Surface
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
24 MCP tools — 19 core + 5 media — with [annotations](https://spec.modelcontextprotocol.io/specification/2025-03-26/server/tools/#annotations) (`readOnlyHint`, `destructiveHint`, `idempotentHint`, and `openWorldHint: false` everywhere except `contentrain_media_ingest`, which fetches a caller-supplied URL server-side) for client safety hints.
|
|
75
75
|
|
|
76
|
-
**Tool listing is capability-aware.** `tools/list` only advertises tools the resolved provider + `projectRoot` pair can actually satisfy. A local stdio server lists
|
|
76
|
+
**Tool listing is capability-aware.** `tools/list` only advertises tools the resolved provider + `projectRoot` pair can actually satisfy. A local stdio server lists the 19 core tools; a session driven by a remote provider (GitHub/GitLab, no local checkout) lists only the remote-safe subset — `status`, `describe`, `describe_format`, `model_save`, `model_delete`, `content_save`, `content_delete`, `content_list`, `validate`. The requirement map lives in `TOOL_REQUIREMENTS` (`@contentrain/mcp/tools/availability`).
|
|
77
77
|
|
|
78
78
|
| Tool | Purpose | Read-only | Destructive |
|
|
79
79
|
| --- | --- | --- | --- |
|
|
@@ -96,6 +96,13 @@ All write operations are designed around git-backed safety:
|
|
|
96
96
|
| `contentrain_scan` | Graph- and candidate-based hardcoded string scan | Yes | — |
|
|
97
97
|
| `contentrain_apply` | Normalize extract/reuse execution with dry-run support | — | — |
|
|
98
98
|
| `contentrain_bulk` | Bulk locale copy, status updates, and deletes | — | — |
|
|
99
|
+
| `contentrain_media_list` | List media assets (search, tag filter, cursor pagination) | Yes | — |
|
|
100
|
+
| `contentrain_media_get` | Get one media asset by id | Yes | — |
|
|
101
|
+
| `contentrain_media_ingest` | Ingest an asset from a source URL (provider fetches server-side) | — | — |
|
|
102
|
+
| `contentrain_media_update` | Update asset metadata (alt, tags, filename) | — | — |
|
|
103
|
+
| `contentrain_media_delete` | Delete an asset from the media stack | — | **Yes** |
|
|
104
|
+
|
|
105
|
+
The five `contentrain_media_*` tools are a deterministic passthrough to the provider's optional media facet (`RepoProvider.media`) and are registered **only when the provider exposes one** (e.g. Studio MCP Cloud). Local stdio servers and plain GitHub/GitLab providers never list them. Ingest is URL-based (MCP has no binary channel); the provider implementation owns SSRF/MIME/size policy for the fetch.
|
|
99
106
|
|
|
100
107
|
## Quick Start
|
|
101
108
|
|
|
@@ -257,7 +264,7 @@ These are intended for Contentrain tooling and advanced integrations, not for di
|
|
|
257
264
|
Key design decisions in this package:
|
|
258
265
|
|
|
259
266
|
- local-first **by default** — stdio transport + LocalProvider works without any network dependency
|
|
260
|
-
- provider-agnostic engine — the same
|
|
267
|
+
- provider-agnostic engine — the same core tools run over LocalProvider, GitHubProvider, or GitLabProvider behind a single `RepoProvider` contract; media tools ride the provider's optional media facet
|
|
261
268
|
- remote provider SDKs (`@octokit/rest`, `@gitbeaker/rest`) are optional peer dependencies — pulled in only when their provider is used
|
|
262
269
|
- JSON-only content storage
|
|
263
270
|
- git-backed write workflow (worktree transaction locally, single atomic commit over the Git Data / REST APIs remotely)
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Centralized tool annotations registry.
|
|
4
4
|
* MCP clients use these hints to distinguish read-only vs. write vs. destructive tools.
|
|
5
|
-
* `openWorldHint` is `false`
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* `openWorldHint` is `false` everywhere except `contentrain_media_ingest`,
|
|
6
|
+
* which fetches a caller-supplied external URL server-side; every other
|
|
7
|
+
* tool operates on the configured content repository only.
|
|
8
8
|
*
|
|
9
9
|
* Also serves as the **single source of truth for the tool name list**. Consumers
|
|
10
10
|
* that need to enumerate every registered tool (e.g. parity tests in
|
|
@@ -144,6 +144,41 @@ const TOOL_ANNOTATIONS = {
|
|
|
144
144
|
destructiveHint: false,
|
|
145
145
|
idempotentHint: false,
|
|
146
146
|
openWorldHint: false
|
|
147
|
+
},
|
|
148
|
+
contentrain_media_list: {
|
|
149
|
+
title: "List Media Assets",
|
|
150
|
+
readOnlyHint: true,
|
|
151
|
+
destructiveHint: false,
|
|
152
|
+
idempotentHint: true,
|
|
153
|
+
openWorldHint: false
|
|
154
|
+
},
|
|
155
|
+
contentrain_media_get: {
|
|
156
|
+
title: "Get Media Asset",
|
|
157
|
+
readOnlyHint: true,
|
|
158
|
+
destructiveHint: false,
|
|
159
|
+
idempotentHint: true,
|
|
160
|
+
openWorldHint: false
|
|
161
|
+
},
|
|
162
|
+
contentrain_media_ingest: {
|
|
163
|
+
title: "Ingest Media From URL",
|
|
164
|
+
readOnlyHint: false,
|
|
165
|
+
destructiveHint: false,
|
|
166
|
+
idempotentHint: false,
|
|
167
|
+
openWorldHint: true
|
|
168
|
+
},
|
|
169
|
+
contentrain_media_update: {
|
|
170
|
+
title: "Update Media Metadata",
|
|
171
|
+
readOnlyHint: false,
|
|
172
|
+
destructiveHint: false,
|
|
173
|
+
idempotentHint: true,
|
|
174
|
+
openWorldHint: false
|
|
175
|
+
},
|
|
176
|
+
contentrain_media_delete: {
|
|
177
|
+
title: "Delete Media Asset",
|
|
178
|
+
readOnlyHint: false,
|
|
179
|
+
destructiveHint: true,
|
|
180
|
+
idempotentHint: false,
|
|
181
|
+
openWorldHint: false
|
|
147
182
|
}
|
|
148
183
|
};
|
|
149
184
|
/**
|
|
@@ -157,4 +192,4 @@ const TOOL_NAMES = Object.freeze(Object.keys(TOOL_ANNOTATIONS));
|
|
|
157
192
|
//#endregion
|
|
158
193
|
export { TOOL_NAMES as n, TOOL_ANNOTATIONS as t };
|
|
159
194
|
|
|
160
|
-
//# sourceMappingURL=annotations-
|
|
195
|
+
//# sourceMappingURL=annotations-D3tlsF38.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotations-D3tlsF38.mjs","names":[],"sources":["../src/tools/annotations.ts"],"sourcesContent":["import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\n\n/**\n * Centralized tool annotations registry.\n * MCP clients use these hints to distinguish read-only vs. write vs. destructive tools.\n * `openWorldHint` is `false` everywhere except `contentrain_media_ingest`,\n * which fetches a caller-supplied external URL server-side; every other\n * tool operates on the configured content repository only.\n *\n * Also serves as the **single source of truth for the tool name list**. Consumers\n * that need to enumerate every registered tool (e.g. parity tests in\n * `@contentrain/rules` / `@contentrain/skills`) should import `TOOL_NAMES` below\n * rather than hardcoding the list.\n */\nexport const TOOL_ANNOTATIONS: Record<string, ToolAnnotations> = {\n // ─── Context (read-only) ───\n contentrain_status: {\n title: 'Project Status',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_describe: {\n title: 'Describe Model',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_describe_format: {\n title: 'Describe Format',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_doctor: {\n title: 'Project Health Report',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n\n // ─── Setup (write + git) ───\n contentrain_init: {\n title: 'Initialize Project',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n contentrain_scaffold: {\n title: 'Scaffold Template',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n\n // ─── Model (write + git) ───\n contentrain_model_save: {\n title: 'Save Model',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_model_delete: {\n title: 'Delete Model',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n\n // ─── Content (mixed) ───\n contentrain_content_save: {\n title: 'Save Content',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_content_delete: {\n title: 'Delete Content',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n contentrain_content_list: {\n title: 'List Content',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n\n // ─── Workflow (mixed) ───\n contentrain_validate: {\n title: 'Validate Project',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_submit: {\n title: 'Submit Branches',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_merge: {\n title: 'Merge Branch',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n contentrain_branch_list: {\n title: 'List Branches',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_branch_delete: {\n title: 'Delete Branch',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n\n // ─── Normalize (mixed) ───\n contentrain_scan: {\n title: 'Scan Source Code',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_apply: {\n title: 'Apply Normalize',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n\n // ─── Bulk (write + git) ───\n contentrain_bulk: {\n title: 'Bulk Operations',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n\n // ─── Media (provider media facet — registered only when RepoProvider.media is present) ───\n contentrain_media_list: {\n title: 'List Media Assets',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_media_get: {\n title: 'Get Media Asset',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_media_ingest: {\n title: 'Ingest Media From URL',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n },\n contentrain_media_update: {\n title: 'Update Media Metadata',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n contentrain_media_delete: {\n title: 'Delete Media Asset',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n}\n\n/**\n * Canonical list of every registered MCP tool name, derived from the\n * single source of truth above. Re-exported here with a stable name so\n * parity tests in sibling packages (`@contentrain/rules`,\n * `@contentrain/skills`) can assert against it without depending on\n * `TOOL_ANNOTATIONS` internals.\n */\nexport const TOOL_NAMES: readonly string[] = Object.freeze(Object.keys(TOOL_ANNOTATIONS))\n"],"mappings":";;;;;;;;;;;;;AAcA,MAAa,mBAAoD;CAE/D,oBAAoB;EAClB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,sBAAsB;EACpB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,6BAA6B;EAC3B,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,oBAAoB;EAClB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CAGD,kBAAkB;EAChB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,sBAAsB;EACpB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CAGD,wBAAwB;EACtB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,0BAA0B;EACxB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CAGD,0BAA0B;EACxB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,4BAA4B;EAC1B,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,0BAA0B;EACxB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CAGD,sBAAsB;EACpB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,oBAAoB;EAClB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,mBAAmB;EACjB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,yBAAyB;EACvB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,2BAA2B;EACzB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CAGD,kBAAkB;EAChB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,mBAAmB;EACjB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CAGD,kBAAkB;EAChB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CAGD,wBAAwB;EACtB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,uBAAuB;EACrB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,0BAA0B;EACxB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,0BAA0B;EACxB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACD,0BAA0B;EACxB,OAAO;EACP,cAAc;EACd,iBAAiB;EACjB,gBAAgB;EAChB,eAAe;EAChB;CACF;;;;;;;;AASD,MAAa,aAAgC,OAAO,OAAO,OAAO,KAAK,iBAAiB,CAAC"}
|
|
@@ -27,7 +27,12 @@ const TOOL_REQUIREMENTS = {
|
|
|
27
27
|
contentrain_apply: {
|
|
28
28
|
projectRoot: true,
|
|
29
29
|
capabilities: ["sourceRead"]
|
|
30
|
-
}
|
|
30
|
+
},
|
|
31
|
+
contentrain_media_list: { media: true },
|
|
32
|
+
contentrain_media_get: { media: true },
|
|
33
|
+
contentrain_media_ingest: { media: true },
|
|
34
|
+
contentrain_media_update: { media: true },
|
|
35
|
+
contentrain_media_delete: { media: true }
|
|
31
36
|
};
|
|
32
37
|
/**
|
|
33
38
|
* Whether a tool can ever succeed for this provider + projectRoot pair.
|
|
@@ -39,9 +44,10 @@ function isToolAvailable(name, provider, projectRoot) {
|
|
|
39
44
|
const req = TOOL_REQUIREMENTS[name];
|
|
40
45
|
if (!req) return true;
|
|
41
46
|
if (req.projectRoot && !projectRoot) return false;
|
|
47
|
+
if (req.media && !provider.media) return false;
|
|
42
48
|
return (req.capabilities ?? []).every((cap) => provider.capabilities[cap]);
|
|
43
49
|
}
|
|
44
50
|
//#endregion
|
|
45
51
|
export { isToolAvailable as n, TOOL_REQUIREMENTS as t };
|
|
46
52
|
|
|
47
|
-
//# sourceMappingURL=availability-
|
|
53
|
+
//# sourceMappingURL=availability-sWWRz2W0.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"availability-sWWRz2W0.mjs","names":[],"sources":["../src/tools/availability.ts"],"sourcesContent":["import type { ProviderCapabilities } from '@contentrain/types'\n\n/**\n * Declarative availability requirements for capability-gated tools.\n *\n * This is the single source of truth `createServer` uses to decide which\n * tools to register for a given provider + projectRoot combination. Tools\n * absent from this map are always available. The requirements mirror the\n * call-time guards inside each tool handler (`capabilityError`) — those\n * guards remain as defense in depth, but a client talking to a remote\n * provider no longer sees tools that could never succeed in `tools/list`.\n *\n * `contentrain_validate` is intentionally NOT listed: read-only validate\n * works over any provider; only `fix: true` needs a local worktree and\n * keeps its call-time guard.\n */\nexport interface ToolRequirements {\n /** Tool needs a local project root on disk (worktree git transactions, IDE config, AST scans). */\n projectRoot?: boolean\n /** Provider capability flags that must all be `true`. */\n capabilities?: readonly (keyof ProviderCapabilities)[]\n /** Tool needs the provider's optional media facet (`RepoProvider.media`). */\n media?: boolean\n}\n\nexport const TOOL_REQUIREMENTS: Readonly<Record<string, ToolRequirements>> = {\n contentrain_init: { projectRoot: true },\n contentrain_scaffold: { projectRoot: true },\n contentrain_doctor: { projectRoot: true },\n contentrain_bulk: { projectRoot: true },\n contentrain_submit: { projectRoot: true, capabilities: ['localWorktree', 'pushRemote'] },\n contentrain_merge: { projectRoot: true, capabilities: ['localWorktree'] },\n contentrain_branch_list: { projectRoot: true, capabilities: ['localWorktree'] },\n contentrain_branch_delete: { projectRoot: true, capabilities: ['localWorktree'] },\n contentrain_scan: { projectRoot: true, capabilities: ['astScan'] },\n // Registration requires the extract path (sourceRead); reuse mode\n // additionally needs sourceWrite, which stays a call-time check because\n // it depends on the `mode` input.\n contentrain_apply: { projectRoot: true, capabilities: ['sourceRead'] },\n // Media tools exist only where the provider exposes a media stack\n // (Studio MCP Cloud). Local and plain remote providers never list them.\n contentrain_media_list: { media: true },\n contentrain_media_get: { media: true },\n contentrain_media_ingest: { media: true },\n contentrain_media_update: { media: true },\n contentrain_media_delete: { media: true },\n}\n\n/**\n * Whether a tool can ever succeed for this provider + projectRoot pair.\n * Used by `createServer` to filter registration; also exported for\n * embedders (e.g. Studio) that want to reason about the effective tool\n * surface without spinning up a server.\n */\nexport function isToolAvailable(\n name: string,\n provider: { capabilities: ProviderCapabilities, media?: unknown },\n projectRoot: string | undefined,\n): boolean {\n const req = TOOL_REQUIREMENTS[name]\n if (!req) return true\n if (req.projectRoot && !projectRoot) return false\n if (req.media && !provider.media) return false\n return (req.capabilities ?? []).every(cap => provider.capabilities[cap])\n}\n"],"mappings":";AAyBA,MAAa,oBAAgE;CAC3E,kBAAkB,EAAE,aAAa,MAAM;CACvC,sBAAsB,EAAE,aAAa,MAAM;CAC3C,oBAAoB,EAAE,aAAa,MAAM;CACzC,kBAAkB,EAAE,aAAa,MAAM;CACvC,oBAAoB;EAAE,aAAa;EAAM,cAAc,CAAC,iBAAiB,aAAa;EAAE;CACxF,mBAAmB;EAAE,aAAa;EAAM,cAAc,CAAC,gBAAgB;EAAE;CACzE,yBAAyB;EAAE,aAAa;EAAM,cAAc,CAAC,gBAAgB;EAAE;CAC/E,2BAA2B;EAAE,aAAa;EAAM,cAAc,CAAC,gBAAgB;EAAE;CACjF,kBAAkB;EAAE,aAAa;EAAM,cAAc,CAAC,UAAU;EAAE;CAIlE,mBAAmB;EAAE,aAAa;EAAM,cAAc,CAAC,aAAa;EAAE;CAGtE,wBAAwB,EAAE,OAAO,MAAM;CACvC,uBAAuB,EAAE,OAAO,MAAM;CACtC,0BAA0B,EAAE,OAAO,MAAM;CACzC,0BAA0B,EAAE,OAAO,MAAM;CACzC,0BAA0B,EAAE,OAAO,MAAM;CAC1C;;;;;;;AAQD,SAAgB,gBACd,MACA,UACA,aACS;CACT,MAAM,MAAM,kBAAkB;AAC9B,KAAI,CAAC,IAAK,QAAO;AACjB,KAAI,IAAI,eAAe,CAAC,YAAa,QAAO;AAC5C,KAAI,IAAI,SAAS,CAAC,SAAS,MAAO,QAAO;AACzC,SAAQ,IAAI,gBAAgB,EAAE,EAAE,OAAM,QAAO,SAAS,aAAa,KAAK"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as RepoReader } from "./index-DDX-qYNw.mjs";
|
|
2
2
|
import { ContentrainConfig, LocaleStrategy, ModelDefinition, Vocabulary, parseMarkdownFrontmatter as parseFrontmatter, serializeMarkdownFrontmatter as serializeFrontmatter, validateEntryId as validateEntryId$1, validateLocale as validateLocale$1, validateSlug as validateSlug$1 } from "@contentrain/types";
|
|
3
3
|
|
|
4
4
|
//#region src/core/content-manager.d.ts
|
|
@@ -60,4 +60,4 @@ declare function readContent(projectRoot: string, model: ModelDefinition, opts:
|
|
|
60
60
|
}): Promise<unknown>;
|
|
61
61
|
//#endregion
|
|
62
62
|
export { writeContent as _, deleteContent as a, readContent as c, resolveLocaleStrategy as d, resolveMdFilePath as f, validateSlug$1 as g, validateLocale$1 as h, WriteResult as i, resolveContentDir as l, validateEntryId$1 as m, DeleteOpts as n, listContent as o, serializeFrontmatter as p, ListOpts as r, parseFrontmatter as s, ContentEntry as t, resolveJsonFilePath as u };
|
|
63
|
-
//# sourceMappingURL=content-manager-
|
|
63
|
+
//# sourceMappingURL=content-manager-DcmNwvmq.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-manager-
|
|
1
|
+
{"version":3,"file":"content-manager-DcmNwvmq.d.mts","names":[],"sources":["../src/core/content-manager.ts"],"mappings":";;;;iBAgBgB,iBAAA,CAAkB,WAAA,UAAqB,KAAA,EAAO,eAAA;AAAA,iBAO9C,qBAAA,CAAsB,KAAA,EAAO,eAAA,GAAkB,cAAA;;iBAK/C,mBAAA,CAAoB,GAAA,UAAa,KAAA,EAAO,eAAA,EAAiB,MAAA;;iBAczD,iBAAA,CAAkB,GAAA,UAAa,KAAA,EAAO,eAAA,EAAiB,MAAA,UAAgB,IAAA;AAAA,UAetE,YAAA;EACf,EAAA;EACA,IAAA;EACA,MAAA;EACA,IAAA,EAAM,MAAA;AAAA;AAAA,UAGS,WAAA;EACf,MAAA;EACA,EAAA;EACA,IAAA;EACA,MAAA;EACA,UAAA;AAAA;AAAA,UAGe,UAAA;EACf,EAAA;EACA,IAAA;EACA,MAAA;EACA,IAAA;AAAA;AAAA,UAGe,QAAA;EACf,MAAA;EACA,MAAA,GAAS,MAAA;EACT,OAAA;EACA,KAAA;EACA,MAAA;AAAA;AAAA,iBAsBoB,YAAA,CACpB,WAAA,UACA,KAAA,EAAO,eAAA,EACP,OAAA,EAAS,YAAA,IACT,MAAA,EAAQ,iBAAA,EACR,UAAA,GAAa,UAAA,UACZ,OAAA,CAAQ,WAAA;AAAA,iBAyIW,aAAA,CACpB,WAAA,UACA,KAAA,EAAO,eAAA,EACP,IAAA,EAAM,UAAA,GACL,OAAA;;;;;AApMH;;;;;;;;;;;iBAoUgB,WAAA,CACd,WAAA,UACA,KAAA,EAAO,eAAA,EACP,IAAA,EAAM,QAAA,EACN,MAAA,EAAQ,iBAAA,GACP,OAAA;AAAA,iBACa,WAAA,CACd,MAAA,EAAQ,UAAA,EACR,KAAA,EAAO,eAAA,EACP,IAAA,EAAM,QAAA,EACN,MAAA,EAAQ,iBAAA,GACP,OAAA;AAAA,iBA0QmB,WAAA,CACpB,WAAA,UACA,KAAA,EAAO,eAAA,EACP,IAAA;EAAQ,MAAA;EAAgB,OAAA;EAAkB,IAAA;AAAA,IACzC,OAAA"}
|
package/dist/core/config.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as writeContent, a as deleteContent, c as readContent, d as resolveLocaleStrategy, f as resolveMdFilePath, g as validateSlug, h as validateLocale, i as WriteResult, l as resolveContentDir, m as validateEntryId, n as DeleteOpts, o as listContent, p as serializeFrontmatter, r as ListOpts, s as parseFrontmatter, t as ContentEntry, u as resolveJsonFilePath } from "../content-manager-
|
|
1
|
+
import { _ as writeContent, a as deleteContent, c as readContent, d as resolveLocaleStrategy, f as resolveMdFilePath, g as validateSlug, h as validateLocale, i as WriteResult, l as resolveContentDir, m as validateEntryId, n as DeleteOpts, o as listContent, p as serializeFrontmatter, r as ListOpts, s as parseFrontmatter, t as ContentEntry, u as resolveJsonFilePath } from "../content-manager-DcmNwvmq.mjs";
|
|
2
2
|
export { ContentEntry, DeleteOpts, ListOpts, WriteResult, deleteContent, listContent, parseFrontmatter, readContent, resolveContentDir, resolveJsonFilePath, resolveLocaleStrategy, resolveMdFilePath, serializeFrontmatter, validateEntryId, validateLocale, validateSlug, writeContent };
|
package/dist/core/context.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as FileChange, c as
|
|
2
|
-
export { ApplyPlanInput, Branch, Commit, CommitAuthor, FileChange, FileDiff, LOCAL_CAPABILITIES, MergeResult, ProviderCapabilities, RepoProvider, RepoReader, RepoWriter };
|
|
1
|
+
import { _ as RepoReader, a as FileChange, c as MediaAsset, d as MediaListResult, f as MediaProvider, g as RepoProvider, h as ProviderCapabilities, i as CommitAuthor, l as MediaIngestInput, m as MergeResult, n as Branch, o as FileDiff, p as MediaUpdateInput, r as Commit, s as LOCAL_CAPABILITIES, t as ApplyPlanInput, u as MediaListOptions, v as RepoWriter } from "../../index-DDX-qYNw.mjs";
|
|
2
|
+
export { ApplyPlanInput, Branch, Commit, CommitAuthor, FileChange, FileDiff, LOCAL_CAPABILITIES, MediaAsset, MediaIngestInput, MediaListOptions, MediaListResult, MediaProvider, MediaUpdateInput, MergeResult, ProviderCapabilities, RepoProvider, RepoReader, RepoWriter };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as ContentEntry } from "../../content-manager-
|
|
1
|
+
import { _ as RepoReader, a as FileChange } from "../../index-DDX-qYNw.mjs";
|
|
2
|
+
import { t as ContentEntry } from "../../content-manager-DcmNwvmq.mjs";
|
|
3
3
|
import { ContentrainConfig, ModelDefinition, Vocabulary } from "@contentrain/types";
|
|
4
4
|
|
|
5
5
|
//#region src/core/ops/apply-to-worktree.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as RepoReader } from "../../index-DDX-qYNw.mjs";
|
|
2
2
|
import { EntryMeta, FieldDef, ModelDefinition, ValidationError, ValidationResult } from "@contentrain/types";
|
|
3
3
|
|
|
4
4
|
//#region src/core/validator/entry.d.ts
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { ApplyPlanInput, Branch, Commit, CommitAuthor, FileChange, FileDiff, LOCAL_CAPABILITIES, MediaAsset, MediaIngestInput, MediaListOptions, MediaListResult, MediaProvider, MediaUpdateInput, MergeResult, ProviderCapabilities as ProviderCapabilities$1, RepoProvider, RepoReader, RepoWriter } from "@contentrain/types";
|
|
2
|
+
export { RepoReader as _, FileChange as a, MediaAsset as c, MediaListResult as d, MediaProvider as f, RepoProvider as g, ProviderCapabilities$1 as h, CommitAuthor as i, MediaIngestInput as l, MergeResult as m, Branch as n, FileDiff as o, MediaUpdateInput as p, Commit as r, LOCAL_CAPABILITIES as s, ApplyPlanInput as t, MediaListOptions as u, RepoWriter as v };
|
package/dist/index.mjs
CHANGED
|
@@ -12,8 +12,8 @@ import "./id-DV_T9Ic8.mjs";
|
|
|
12
12
|
import "./transaction-qliKvBRL.mjs";
|
|
13
13
|
import "./local-BZEUWBoC.mjs";
|
|
14
14
|
import "./detect-wVSI9VuY.mjs";
|
|
15
|
-
import "./annotations-
|
|
16
|
-
import { n as createServer } from "./server-
|
|
15
|
+
import "./annotations-D3tlsF38.mjs";
|
|
16
|
+
import { n as createServer } from "./server-DtabGAY6.mjs";
|
|
17
17
|
import "./validator-8vaPxSba.mjs";
|
|
18
18
|
import "./scan-config-BGUflS8t.mjs";
|
|
19
19
|
import "./graph-builder-CRUX_8mA.mjs";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as RepoReader, g as RepoProvider, h as ProviderCapabilities, i as CommitAuthor, m as MergeResult, n as Branch, o as FileDiff, r as Commit, t as ApplyPlanInput } from "../../index-DDX-qYNw.mjs";
|
|
2
2
|
import { Octokit } from "@octokit/rest";
|
|
3
3
|
|
|
4
4
|
//#region src/providers/github/app-auth.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as RepoReader, g as RepoProvider, h as ProviderCapabilities, i as CommitAuthor, m as MergeResult, n as Branch, o as FileDiff, r as Commit, t as ApplyPlanInput } from "../../index-DDX-qYNw.mjs";
|
|
2
2
|
import { Gitlab } from "@gitbeaker/rest";
|
|
3
3
|
|
|
4
4
|
//#region src/providers/gitlab/capabilities.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as FileChange,
|
|
1
|
+
import { _ as RepoReader, a as FileChange, g as RepoProvider, h as ProviderCapabilities$1, i as CommitAuthor, m as MergeResult, n as Branch, o as FileDiff, r as Commit } from "../../index-DDX-qYNw.mjs";
|
|
2
2
|
import { SyncResult, WorkflowMode } from "@contentrain/types";
|
|
3
3
|
|
|
4
4
|
//#region src/providers/local/types.d.ts
|
|
@@ -11,8 +11,8 @@ import "../../id-DV_T9Ic8.mjs";
|
|
|
11
11
|
import "../../transaction-qliKvBRL.mjs";
|
|
12
12
|
import "../../local-BZEUWBoC.mjs";
|
|
13
13
|
import "../../detect-wVSI9VuY.mjs";
|
|
14
|
-
import "../../annotations-
|
|
15
|
-
import { n as createServer } from "../../server-
|
|
14
|
+
import "../../annotations-D3tlsF38.mjs";
|
|
15
|
+
import { n as createServer } from "../../server-DtabGAY6.mjs";
|
|
16
16
|
import "../../validator-8vaPxSba.mjs";
|
|
17
17
|
import "../../scan-config-BGUflS8t.mjs";
|
|
18
18
|
import "../../graph-builder-CRUX_8mA.mjs";
|
|
@@ -8,9 +8,9 @@ import { n as readContext } from "./context-CYN__o3Q.mjs";
|
|
|
8
8
|
import { a as deleteRemoteBranch, c as pruneMergedRemoteBranches, i as cleanupMergedBranches, n as checkBranchHealth, s as listRemoteCrBranches } from "./branch-lifecycle-D7tXOE4f.mjs";
|
|
9
9
|
import { i as mergeBranch, n as createTransaction, r as ensureContentBranch, t as buildBranchName } from "./transaction-qliKvBRL.mjs";
|
|
10
10
|
import { n as isMerged, t as LocalProvider } from "./local-BZEUWBoC.mjs";
|
|
11
|
-
import { n as isToolAvailable, t as TOOL_REQUIREMENTS } from "./availability-
|
|
11
|
+
import { n as isToolAvailable, t as TOOL_REQUIREMENTS } from "./availability-sWWRz2W0.mjs";
|
|
12
12
|
import { t as detectStack } from "./detect-wVSI9VuY.mjs";
|
|
13
|
-
import { t as TOOL_ANNOTATIONS } from "./annotations-
|
|
13
|
+
import { t as TOOL_ANNOTATIONS } from "./annotations-D3tlsF38.mjs";
|
|
14
14
|
import { n as listTemplates, t as getTemplate } from "./templates-D6EllixQ.mjs";
|
|
15
15
|
import { t as validateProject } from "./validator-8vaPxSba.mjs";
|
|
16
16
|
import { t as OverlayReader } from "./overlay-reader-BOb105gS.mjs";
|
|
@@ -2368,8 +2368,137 @@ function registerDoctorTools(server, _provider, projectRoot) {
|
|
|
2368
2368
|
});
|
|
2369
2369
|
}
|
|
2370
2370
|
//#endregion
|
|
2371
|
+
//#region src/tools/media.ts
|
|
2372
|
+
/**
|
|
2373
|
+
* Media tools — a deterministic passthrough to the provider's optional
|
|
2374
|
+
* media facet (`RepoProvider.media`). Registration is capability-aware:
|
|
2375
|
+
* `createServer` skips all five tools when the provider has no media
|
|
2376
|
+
* stack, so the guard below is defense in depth only.
|
|
2377
|
+
*
|
|
2378
|
+
* The facet closes the discovery loop for external agents: list assets →
|
|
2379
|
+
* pick a `media/...` path → reference it via `contentrain_content_save`
|
|
2380
|
+
* (which normalizes it to an absolute delivery URL when `mediaBaseUrl`
|
|
2381
|
+
* is set). Ingest is URL-based — MCP has no binary channel — and the
|
|
2382
|
+
* provider implementation owns SSRF/MIME/size policy for the fetch.
|
|
2383
|
+
*/
|
|
2384
|
+
function mediaUnavailable(tool) {
|
|
2385
|
+
return {
|
|
2386
|
+
content: [{
|
|
2387
|
+
type: "text",
|
|
2388
|
+
text: JSON.stringify({
|
|
2389
|
+
error: `${tool} requires a provider with a media stack.`,
|
|
2390
|
+
capability_required: "media",
|
|
2391
|
+
hint: "Media tools are available when MCP is driven by a media-capable provider (e.g. Studio MCP Cloud). Local and plain git providers do not expose one."
|
|
2392
|
+
})
|
|
2393
|
+
}],
|
|
2394
|
+
isError: true
|
|
2395
|
+
};
|
|
2396
|
+
}
|
|
2397
|
+
function mediaError(error, stage) {
|
|
2398
|
+
return {
|
|
2399
|
+
content: [{
|
|
2400
|
+
type: "text",
|
|
2401
|
+
text: JSON.stringify({ ...normalizeOperationError(error, stage) })
|
|
2402
|
+
}],
|
|
2403
|
+
isError: true
|
|
2404
|
+
};
|
|
2405
|
+
}
|
|
2406
|
+
function ok(payload) {
|
|
2407
|
+
return { content: [{
|
|
2408
|
+
type: "text",
|
|
2409
|
+
text: JSON.stringify(payload)
|
|
2410
|
+
}] };
|
|
2411
|
+
}
|
|
2412
|
+
function registerMediaTools(server, provider, _projectRoot) {
|
|
2413
|
+
server.tool("contentrain_media_list", "List media assets from the provider media stack. Returns storage paths (media/...) usable in media/image/file fields via contentrain_content_save, plus delivery URLs when available. Supports search, tag filter, and cursor pagination.", {
|
|
2414
|
+
search: z.string().optional().describe("Substring match on filename/path/alt"),
|
|
2415
|
+
tag: z.string().optional().describe("Only assets carrying this tag"),
|
|
2416
|
+
limit: z.number().int().min(1).max(100).optional().describe("Page size. Default: provider-defined"),
|
|
2417
|
+
cursor: z.string().optional().describe("Opaque cursor from a previous response")
|
|
2418
|
+
}, TOOL_ANNOTATIONS["contentrain_media_list"], async (input) => {
|
|
2419
|
+
if (!provider.media) return mediaUnavailable("contentrain_media_list");
|
|
2420
|
+
try {
|
|
2421
|
+
const result = await provider.media.list(input);
|
|
2422
|
+
return ok({
|
|
2423
|
+
assets: result.assets,
|
|
2424
|
+
next_cursor: result.nextCursor,
|
|
2425
|
+
total: result.total
|
|
2426
|
+
});
|
|
2427
|
+
} catch (error) {
|
|
2428
|
+
return mediaError(error, "media_list");
|
|
2429
|
+
}
|
|
2430
|
+
});
|
|
2431
|
+
server.tool("contentrain_media_get", "Get a single media asset by id, including its storage path, delivery URL, and metadata.", { id: z.string().describe("Asset id (from contentrain_media_list)") }, TOOL_ANNOTATIONS["contentrain_media_get"], async (input) => {
|
|
2432
|
+
if (!provider.media) return mediaUnavailable("contentrain_media_get");
|
|
2433
|
+
try {
|
|
2434
|
+
const asset = await provider.media.get(input.id);
|
|
2435
|
+
if (!asset) return {
|
|
2436
|
+
content: [{
|
|
2437
|
+
type: "text",
|
|
2438
|
+
text: JSON.stringify({
|
|
2439
|
+
error: `Media asset not found: ${input.id}`,
|
|
2440
|
+
hint: "Use contentrain_media_list to discover asset ids."
|
|
2441
|
+
})
|
|
2442
|
+
}],
|
|
2443
|
+
isError: true
|
|
2444
|
+
};
|
|
2445
|
+
return ok({ asset });
|
|
2446
|
+
} catch (error) {
|
|
2447
|
+
return mediaError(error, "media_get");
|
|
2448
|
+
}
|
|
2449
|
+
});
|
|
2450
|
+
server.tool("contentrain_media_ingest", "Ingest a media asset from a source URL. The provider fetches the URL server-side under its own SSRF/MIME/size policy and stores the asset in the media stack. Returns the stored asset with its media/... path.", {
|
|
2451
|
+
url: z.string().url().describe("Source URL to fetch server-side"),
|
|
2452
|
+
filename: z.string().optional().describe("Target filename override"),
|
|
2453
|
+
alt: z.string().optional().describe("Alt text for the asset"),
|
|
2454
|
+
tags: z.array(z.string()).max(20).optional().describe("Tags to attach")
|
|
2455
|
+
}, TOOL_ANNOTATIONS["contentrain_media_ingest"], async (input) => {
|
|
2456
|
+
if (!provider.media) return mediaUnavailable("contentrain_media_ingest");
|
|
2457
|
+
try {
|
|
2458
|
+
return ok({
|
|
2459
|
+
status: "ingested",
|
|
2460
|
+
asset: await provider.media.ingest(input)
|
|
2461
|
+
});
|
|
2462
|
+
} catch (error) {
|
|
2463
|
+
return mediaError(error, "media_ingest");
|
|
2464
|
+
}
|
|
2465
|
+
});
|
|
2466
|
+
server.tool("contentrain_media_update", "Update metadata (alt text, tags, filename) of an existing media asset. Does not touch the binary.", {
|
|
2467
|
+
id: z.string().describe("Asset id to update"),
|
|
2468
|
+
alt: z.string().optional().describe("New alt text"),
|
|
2469
|
+
tags: z.array(z.string()).max(20).optional().describe("Replacement tag list"),
|
|
2470
|
+
filename: z.string().optional().describe("New filename")
|
|
2471
|
+
}, TOOL_ANNOTATIONS["contentrain_media_update"], async (input) => {
|
|
2472
|
+
if (!provider.media) return mediaUnavailable("contentrain_media_update");
|
|
2473
|
+
try {
|
|
2474
|
+
const { id, ...patch } = input;
|
|
2475
|
+
return ok({
|
|
2476
|
+
status: "updated",
|
|
2477
|
+
asset: await provider.media.update(id, patch)
|
|
2478
|
+
});
|
|
2479
|
+
} catch (error) {
|
|
2480
|
+
return mediaError(error, "media_update");
|
|
2481
|
+
}
|
|
2482
|
+
});
|
|
2483
|
+
server.tool("contentrain_media_delete", "Delete a media asset from the media stack. Content entries referencing its path are NOT rewritten — check references before deleting.", {
|
|
2484
|
+
id: z.string().describe("Asset id to delete"),
|
|
2485
|
+
confirm: z.literal(true).describe("Must be true to confirm deletion")
|
|
2486
|
+
}, TOOL_ANNOTATIONS["contentrain_media_delete"], async (input) => {
|
|
2487
|
+
if (!provider.media) return mediaUnavailable("contentrain_media_delete");
|
|
2488
|
+
try {
|
|
2489
|
+
await provider.media.delete(input.id);
|
|
2490
|
+
return ok({
|
|
2491
|
+
status: "deleted",
|
|
2492
|
+
id: input.id
|
|
2493
|
+
});
|
|
2494
|
+
} catch (error) {
|
|
2495
|
+
return mediaError(error, "media_delete");
|
|
2496
|
+
}
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2499
|
+
//#endregion
|
|
2371
2500
|
//#region package.json
|
|
2372
|
-
var version = "1.
|
|
2501
|
+
var version = "1.10.0";
|
|
2373
2502
|
//#endregion
|
|
2374
2503
|
//#region src/server.ts
|
|
2375
2504
|
/**
|
|
@@ -2410,6 +2539,7 @@ function createServer(input) {
|
|
|
2410
2539
|
registerNormalizeTools(server, provider, projectRoot);
|
|
2411
2540
|
registerBulkTools(server, provider, projectRoot);
|
|
2412
2541
|
registerDoctorTools(server, provider, projectRoot);
|
|
2542
|
+
registerMediaTools(server, provider, projectRoot);
|
|
2413
2543
|
return server;
|
|
2414
2544
|
}
|
|
2415
2545
|
function resolveServerContext(input) {
|
|
@@ -2438,4 +2568,4 @@ function resolveServerContext(input) {
|
|
|
2438
2568
|
//#endregion
|
|
2439
2569
|
export { createServer as n, DEFAULT_INSTRUCTIONS as t };
|
|
2440
2570
|
|
|
2441
|
-
//# sourceMappingURL=server-
|
|
2571
|
+
//# sourceMappingURL=server-DtabGAY6.mjs.map
|