@contentrain/mcp 1.2.1 → 1.4.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 +93 -25
- package/dist/annotations-Clhbw2lh.mjs +126 -0
- package/dist/annotations-Clhbw2lh.mjs.map +1 -0
- package/dist/{apply-manager-BkPMfpsN.mjs → apply-manager-D5ym5Jba.mjs} +7 -7
- package/dist/{apply-manager-BkPMfpsN.mjs.map → apply-manager-D5ym5Jba.mjs.map} +1 -1
- package/dist/{astro-parser-BJ-54JGe.mjs → astro-parser-B-nLl0zE.mjs} +3 -3
- package/dist/{astro-parser-BJ-54JGe.mjs.map → astro-parser-B-nLl0zE.mjs.map} +1 -1
- package/dist/{branch-lifecycle-wGJg25LT.mjs → branch-lifecycle-CFVpTpNT.mjs} +33 -3
- package/dist/{branch-lifecycle-wGJg25LT.mjs.map → branch-lifecycle-CFVpTpNT.mjs.map} +1 -1
- package/dist/{compiler-rIC4ETHv.mjs → compiler-k4yttlzM.mjs} +2 -2
- package/dist/{compiler-rIC4ETHv.mjs.map → compiler-k4yttlzM.mjs.map} +1 -1
- package/dist/{compiler-sfc.cjs-BbD04rn_.mjs → compiler-sfc.cjs-D0d_OicF.mjs} +2 -2
- package/dist/{compiler-sfc.cjs-BbD04rn_.mjs.map → compiler-sfc.cjs-D0d_OicF.mjs.map} +1 -1
- package/dist/config-BIl5Ybj0.mjs +40 -0
- package/dist/config-BIl5Ybj0.mjs.map +1 -0
- package/dist/content-manager-DqDLSNQ-.d.mts +63 -0
- package/dist/content-manager-DqDLSNQ-.d.mts.map +1 -0
- package/dist/context-J0OU9Nfp.mjs +102 -0
- package/dist/context-J0OU9Nfp.mjs.map +1 -0
- package/dist/contracts-DfL0BfrD.mjs +2 -0
- package/dist/core/apply-manager.mjs +10 -10
- package/dist/core/config.d.mts +13 -0
- package/dist/core/config.d.mts.map +1 -1
- package/dist/core/config.mjs +2 -3
- package/dist/core/content-manager.d.mts +2 -45
- package/dist/core/content-manager.mjs +3 -4
- package/dist/core/context.d.mts +32 -2
- package/dist/core/context.d.mts.map +1 -1
- package/dist/core/context.mjs +7 -7
- package/dist/core/contracts/index.d.mts +2 -0
- package/dist/core/contracts/index.mjs +2 -0
- package/dist/core/doctor.d.mts +76 -0
- package/dist/core/doctor.d.mts.map +1 -0
- package/dist/core/doctor.mjs +8 -0
- package/dist/core/graph-builder.mjs +3 -4
- package/dist/core/meta-manager.mjs +2 -3
- package/dist/core/model-manager.d.mts +34 -1
- package/dist/core/model-manager.d.mts.map +1 -1
- package/dist/core/model-manager.mjs +3 -4
- package/dist/core/ops/index.d.mts +137 -0
- package/dist/core/ops/index.d.mts.map +1 -0
- package/dist/core/ops/index.mjs +4 -0
- package/dist/core/overlay-reader.d.mts +42 -0
- package/dist/core/overlay-reader.d.mts.map +1 -0
- package/dist/core/overlay-reader.mjs +2 -0
- package/dist/core/scan-config.mjs +2 -3
- package/dist/core/scanner.mjs +4 -5
- package/dist/core/validator/index.d.mts +129 -0
- package/dist/core/validator/index.d.mts.map +1 -0
- package/dist/core/validator/index.mjs +6 -0
- package/dist/{detect-DinOQAmK.mjs → detect-DL9mFmaS.mjs} +2 -2
- package/dist/{detect-DinOQAmK.mjs.map → detect-DL9mFmaS.mjs.map} +1 -1
- package/dist/doctor-CgBoT6h1.mjs +338 -0
- package/dist/doctor-CgBoT6h1.mjs.map +1 -0
- package/dist/{fs-BnIQ4dKj.mjs → fs-DLbVB-Ek.mjs} +2 -2
- package/dist/fs-DLbVB-Ek.mjs.map +1 -0
- package/dist/git/branch-lifecycle.d.mts +30 -1
- package/dist/git/branch-lifecycle.d.mts.map +1 -1
- package/dist/git/branch-lifecycle.mjs +4 -5
- package/dist/git/transaction.d.mts +2 -2
- package/dist/git/transaction.d.mts.map +1 -1
- package/dist/git/transaction.mjs +8 -8
- package/dist/{graph-builder-tM7zj-SX.mjs → graph-builder-DXv2JEp-.mjs} +3 -3
- package/dist/{graph-builder-tM7zj-SX.mjs.map → graph-builder-DXv2JEp-.mjs.map} +1 -1
- package/dist/{id-DV_T9Ic8.mjs → id-CIO9s0x_.mjs} +1 -1
- package/dist/{id-DV_T9Ic8.mjs.map → id-CIO9s0x_.mjs.map} +1 -1
- package/dist/index-D0wQJSgs.d.mts +2 -0
- package/dist/index.mjs +22 -17
- package/dist/index.mjs.map +1 -1
- package/dist/local-DvP4Y4T-.mjs +182 -0
- package/dist/local-DvP4Y4T-.mjs.map +1 -0
- package/dist/{meta-manager--0IwAPCl.mjs → meta-manager-C900rEyG.mjs} +2 -2
- package/dist/{meta-manager--0IwAPCl.mjs.map → meta-manager-C900rEyG.mjs.map} +1 -1
- package/dist/{model-manager-DW_fOGRM.mjs → model-manager-BhLsUgaB.mjs} +241 -49
- package/dist/model-manager-BhLsUgaB.mjs.map +1 -0
- package/dist/{node-Cbq5eR5i.mjs → node-DN9hZeil.mjs} +1 -1
- package/dist/{node-Cbq5eR5i.mjs.map → node-DN9hZeil.mjs.map} +1 -1
- package/dist/ops-DjEWi5Wa.mjs +486 -0
- package/dist/ops-DjEWi5Wa.mjs.map +1 -0
- package/dist/overlay-reader-DOdyDRIv.mjs +74 -0
- package/dist/overlay-reader-DOdyDRIv.mjs.map +1 -0
- package/dist/paths-C3xNyc7z.mjs +52 -0
- package/dist/paths-C3xNyc7z.mjs.map +1 -0
- package/dist/paths-CYl5vCBD.mjs +54 -0
- package/dist/paths-CYl5vCBD.mjs.map +1 -0
- package/dist/providers/github/index.d.mts +201 -0
- package/dist/providers/github/index.d.mts.map +1 -0
- package/dist/providers/github/index.mjs +494 -0
- package/dist/providers/github/index.mjs.map +1 -0
- package/dist/providers/gitlab/index.d.mts +158 -0
- package/dist/providers/gitlab/index.d.mts.map +1 -0
- package/dist/providers/gitlab/index.mjs +361 -0
- package/dist/providers/gitlab/index.mjs.map +1 -0
- package/dist/providers/local/index.d.mts +106 -0
- package/dist/providers/local/index.d.mts.map +1 -0
- package/dist/providers/local/index.mjs +12 -0
- package/dist/{scan-config-QgnJ1-52.mjs → scan-config-jC6XmiqF.mjs} +2 -2
- package/dist/{scan-config-QgnJ1-52.mjs.map → scan-config-jC6XmiqF.mjs.map} +1 -1
- package/dist/{scanner-DUoXnmtI.mjs → scanner-DKMwc03k.mjs} +7 -7
- package/dist/{scanner-DUoXnmtI.mjs.map → scanner-DKMwc03k.mjs.map} +1 -1
- package/dist/serialization-B1CEzR4H.mjs +2 -0
- package/dist/server/http/index.d.mts +107 -0
- package/dist/server/http/index.d.mts.map +1 -0
- package/dist/server/http/index.mjs +248 -0
- package/dist/server/http/index.mjs.map +1 -0
- package/dist/{server-Dtq8vqbK.mjs → server-BkhhtEE2.mjs} +486 -355
- package/dist/server-BkhhtEE2.mjs.map +1 -0
- package/dist/server-WqGx6ait.d.mts +50 -0
- package/dist/server-WqGx6ait.d.mts.map +1 -0
- package/dist/server.d.mts +2 -7
- package/dist/server.mjs +22 -17
- package/dist/{source-map-generator-DpO-ejrt.mjs → source-map-generator-BWDva49I.mjs} +1 -1
- package/dist/{source-map-generator-DpO-ejrt.mjs.map → source-map-generator-BWDva49I.mjs.map} +1 -1
- package/dist/{svelte-parser-1bBcMx3T.mjs → svelte-parser-Dr9mmZuk.mjs} +3 -3
- package/dist/{svelte-parser-1bBcMx3T.mjs.map → svelte-parser-Dr9mmZuk.mjs.map} +1 -1
- package/dist/templates/index.mjs +1 -1
- package/dist/{templates-bRPzYq4M.mjs → templates-VrLVqfe5.mjs} +1 -1
- package/dist/{templates-bRPzYq4M.mjs.map → templates-VrLVqfe5.mjs.map} +1 -1
- package/dist/testing/conformance.d.mts +59 -0
- package/dist/testing/conformance.d.mts.map +1 -0
- package/dist/testing/conformance.mjs +59 -0
- package/dist/testing/conformance.mjs.map +1 -0
- package/dist/tools/annotations.d.mts +24 -0
- package/dist/tools/annotations.d.mts.map +1 -0
- package/dist/tools/annotations.mjs +2 -0
- package/dist/{transaction-C_Pvux78.mjs → transaction-DgkNgWSI.mjs} +61 -32
- package/dist/transaction-DgkNgWSI.mjs.map +1 -0
- package/dist/tsx-parser-BOMZE_yQ.mjs +2 -0
- package/dist/{tsx-parser-BWiMGAIR.mjs → tsx-parser-CQc6nr-o.mjs} +1 -1
- package/dist/{tsx-parser-BWiMGAIR.mjs.map → tsx-parser-CQc6nr-o.mjs.map} +1 -1
- package/dist/util/detect.mjs +2 -3
- package/dist/util/fs.mjs +1 -2
- package/dist/util/id.mjs +1 -1
- package/dist/validator-B0nNRFeU.mjs +906 -0
- package/dist/validator-B0nNRFeU.mjs.map +1 -0
- package/dist/{vue-parser-DTPTN3Yb.mjs → vue-parser-COgjArqv.mjs} +3 -3
- package/dist/{vue-parser-DTPTN3Yb.mjs.map → vue-parser-COgjArqv.mjs.map} +1 -1
- package/package.json +82 -23
- package/testing/conformance/01-new-collection-entry/expected/.contentrain/config.json +15 -0
- package/testing/conformance/01-new-collection-entry/expected/.contentrain/content/blog/blog/en.json +6 -0
- package/testing/conformance/01-new-collection-entry/expected/.contentrain/context.json +22 -0
- package/testing/conformance/01-new-collection-entry/expected/.contentrain/meta/blog/en.json +7 -0
- package/testing/conformance/01-new-collection-entry/expected/.contentrain/models/blog.json +16 -0
- package/testing/conformance/01-new-collection-entry/scenario.json +19 -0
- package/testing/conformance/01-new-collection-entry/setup/.contentrain/config.json +15 -0
- package/testing/conformance/01-new-collection-entry/setup/.contentrain/models/blog.json +16 -0
- package/testing/conformance/02-new-singleton/expected/.contentrain/config.json +15 -0
- package/testing/conformance/02-new-singleton/expected/.contentrain/content/marketing/hero/en.json +4 -0
- package/testing/conformance/02-new-singleton/expected/.contentrain/context.json +22 -0
- package/testing/conformance/02-new-singleton/expected/.contentrain/meta/hero/en.json +5 -0
- package/testing/conformance/02-new-singleton/expected/.contentrain/models/hero.json +16 -0
- package/testing/conformance/02-new-singleton/scenario.json +18 -0
- package/testing/conformance/02-new-singleton/setup/.contentrain/config.json +15 -0
- package/testing/conformance/02-new-singleton/setup/.contentrain/models/hero.json +16 -0
- package/testing/conformance/03-new-dictionary/expected/.contentrain/config.json +15 -0
- package/testing/conformance/03-new-dictionary/expected/.contentrain/content/marketing/ui-strings/en.json +5 -0
- package/testing/conformance/03-new-dictionary/expected/.contentrain/context.json +22 -0
- package/testing/conformance/03-new-dictionary/expected/.contentrain/meta/ui-strings/en.json +5 -0
- package/testing/conformance/03-new-dictionary/expected/.contentrain/models/ui-strings.json +7 -0
- package/testing/conformance/03-new-dictionary/scenario.json +19 -0
- package/testing/conformance/03-new-dictionary/setup/.contentrain/config.json +15 -0
- package/testing/conformance/03-new-dictionary/setup/.contentrain/models/ui-strings.json +7 -0
- package/testing/conformance/README.md +77 -0
- package/testing/conformance/scenarios.json +36 -0
- package/dist/config-B5kc2oeV.mjs +0 -27
- package/dist/config-B5kc2oeV.mjs.map +0 -1
- package/dist/context-DIDt_TxX.mjs +0 -46
- package/dist/context-DIDt_TxX.mjs.map +0 -1
- package/dist/core/content-manager.d.mts.map +0 -1
- package/dist/core/validator.d.mts +0 -23
- package/dist/core/validator.d.mts.map +0 -1
- package/dist/core/validator.mjs +0 -7
- package/dist/fs-BnIQ4dKj.mjs.map +0 -1
- package/dist/model-manager-DW_fOGRM.mjs.map +0 -1
- package/dist/serializer-CnHTtmc1.mjs +0 -2
- package/dist/server-Dtq8vqbK.mjs.map +0 -1
- package/dist/server.d.mts.map +0 -1
- package/dist/transaction-C_Pvux78.mjs.map +0 -1
- package/dist/tsx-parser-BFLv292Y.mjs +0 -2
- package/dist/util/serializer.d.mts +0 -2
- package/dist/util/serializer.mjs +0 -2
- package/dist/validator-SQYUV2JP.mjs +0 -581
- package/dist/validator-SQYUV2JP.mjs.map +0 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//#region src/providers/shared/errors.ts
|
|
2
|
+
/**
|
|
3
|
+
* Unified "is this a 404?" helper for API-backed providers.
|
|
4
|
+
*
|
|
5
|
+
* Two common error shapes in the provider SDKs we use:
|
|
6
|
+
*
|
|
7
|
+
* - **Octokit** (`@octokit/rest`) — rejects with an `Error` that has a
|
|
8
|
+
* top-level `.status` number set to the HTTP status code.
|
|
9
|
+
* - **Gitbeaker** (`@gitbeaker/rest`) — rejects with a plain `Error` whose
|
|
10
|
+
* `.cause` includes `{ response: { status } }`.
|
|
11
|
+
*
|
|
12
|
+
* Both forms converge on `404` meaning "resource missing", so we check
|
|
13
|
+
* both shapes strictly. We deliberately do NOT fall back to substring
|
|
14
|
+
* matching on the error message — that leniency can silently mask other
|
|
15
|
+
* 404-like errors (forbidden repo, deleted project, rate limits) and
|
|
16
|
+
* produce the wrong answer. If either SDK ever stops populating the
|
|
17
|
+
* status field on a legitimate 404, the regression will surface in tests
|
|
18
|
+
* rather than being papered over at the reader layer.
|
|
19
|
+
*/
|
|
20
|
+
function isNotFoundError(error) {
|
|
21
|
+
if (typeof error !== "object" || error === null) return false;
|
|
22
|
+
if (error.status === 404) return true;
|
|
23
|
+
return error.cause?.response?.status === 404;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/providers/shared/paths.ts
|
|
27
|
+
/**
|
|
28
|
+
* Normalise an optional contentRoot — strip leading/trailing slashes,
|
|
29
|
+
* treat `''`, `/` and `undefined` as "no prefix". Used by API-backed
|
|
30
|
+
* providers (GitHub, GitLab, future Bitbucket) to anchor content-relative
|
|
31
|
+
* paths against a repo subdirectory when Contentrain lives under a
|
|
32
|
+
* monorepo path like `apps/web/.contentrain/`.
|
|
33
|
+
*/
|
|
34
|
+
function normaliseContentRoot(raw) {
|
|
35
|
+
if (!raw || raw === "/" || raw === "") return "";
|
|
36
|
+
return raw.replace(/^\/+|\/+$/g, "");
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve a content-root-relative path to a repo-relative path. The result
|
|
40
|
+
* always uses forward slashes and has no leading slash — the form every
|
|
41
|
+
* REST git API consumes for `file_path` / `path` query parameters and the
|
|
42
|
+
* Git Data API tree entries.
|
|
43
|
+
*/
|
|
44
|
+
function resolveRepoPath(contentRoot, relativePath) {
|
|
45
|
+
const prefix = normaliseContentRoot(contentRoot);
|
|
46
|
+
const cleanPath = relativePath.replace(/^\/+/, "");
|
|
47
|
+
return prefix ? `${prefix}/${cleanPath}` : cleanPath;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { isNotFoundError as n, resolveRepoPath as t };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=paths-C3xNyc7z.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths-C3xNyc7z.mjs","names":[],"sources":["../src/providers/shared/errors.ts","../src/providers/shared/paths.ts"],"sourcesContent":["/**\n * Unified \"is this a 404?\" helper for API-backed providers.\n *\n * Two common error shapes in the provider SDKs we use:\n *\n * - **Octokit** (`@octokit/rest`) — rejects with an `Error` that has a\n * top-level `.status` number set to the HTTP status code.\n * - **Gitbeaker** (`@gitbeaker/rest`) — rejects with a plain `Error` whose\n * `.cause` includes `{ response: { status } }`.\n *\n * Both forms converge on `404` meaning \"resource missing\", so we check\n * both shapes strictly. We deliberately do NOT fall back to substring\n * matching on the error message — that leniency can silently mask other\n * 404-like errors (forbidden repo, deleted project, rate limits) and\n * produce the wrong answer. If either SDK ever stops populating the\n * status field on a legitimate 404, the regression will surface in tests\n * rather than being papered over at the reader layer.\n */\nexport function isNotFoundError(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) return false\n const direct = (error as { status?: number }).status\n if (direct === 404) return true\n const nested = (error as { cause?: { response?: { status?: number } } }).cause?.response?.status\n return nested === 404\n}\n","/**\n * Normalise an optional contentRoot — strip leading/trailing slashes,\n * treat `''`, `/` and `undefined` as \"no prefix\". Used by API-backed\n * providers (GitHub, GitLab, future Bitbucket) to anchor content-relative\n * paths against a repo subdirectory when Contentrain lives under a\n * monorepo path like `apps/web/.contentrain/`.\n */\nexport function normaliseContentRoot(raw?: string): string {\n if (!raw || raw === '/' || raw === '') return ''\n return raw.replace(/^\\/+|\\/+$/g, '')\n}\n\n/**\n * Resolve a content-root-relative path to a repo-relative path. The result\n * always uses forward slashes and has no leading slash — the form every\n * REST git API consumes for `file_path` / `path` query parameters and the\n * Git Data API tree entries.\n */\nexport function resolveRepoPath(contentRoot: string | undefined, relativePath: string): string {\n const prefix = normaliseContentRoot(contentRoot)\n const cleanPath = relativePath.replace(/^\\/+/, '')\n return prefix ? `${prefix}/${cleanPath}` : cleanPath\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,SAAgB,gBAAgB,OAAyB;AACvD,KAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AAExD,KADgB,MAA8B,WAC/B,IAAK,QAAO;AAE3B,QADgB,MAAyD,OAAO,UAAU,WACxE;;;;;;;;;;;AChBpB,SAAgB,qBAAqB,KAAsB;AACzD,KAAI,CAAC,OAAO,QAAQ,OAAO,QAAQ,GAAI,QAAO;AAC9C,QAAO,IAAI,QAAQ,cAAc,GAAG;;;;;;;;AAStC,SAAgB,gBAAgB,aAAiC,cAA8B;CAC7F,MAAM,SAAS,qBAAqB,YAAY;CAChD,MAAM,YAAY,aAAa,QAAQ,QAAQ,GAAG;AAClD,QAAO,SAAS,GAAG,OAAO,GAAG,cAAc"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
//#region src/core/ops/paths.ts
|
|
2
|
+
/**
|
|
3
|
+
* Content-root-relative path helpers for plan-API consumers.
|
|
4
|
+
*
|
|
5
|
+
* These mirror the logic inside `core/content-manager.ts:resolveJsonFilePath`
|
|
6
|
+
* but return forward-slash relative strings suitable for `FileChange.path`.
|
|
7
|
+
* Providers are responsible for resolving these against their backing store
|
|
8
|
+
* (worktree on disk for LocalProvider, git tree path for GitHubProvider, ...).
|
|
9
|
+
*
|
|
10
|
+
* Kept inline to `core/ops/` for now; when Faz 2 finishes migrating every op
|
|
11
|
+
* the legacy absolute-path helpers in `core/content-manager.ts` and
|
|
12
|
+
* `core/meta-manager.ts` will call into these (or be replaced entirely).
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Content-root-relative content directory for a model (forward-slash paths).
|
|
16
|
+
* Mirrors `resolveContentDir` with an empty `projectRoot`, so reader-backed
|
|
17
|
+
* callers and plan-API consumers share the same path resolution.
|
|
18
|
+
*/
|
|
19
|
+
function contentDirPath(model) {
|
|
20
|
+
if (model.content_path) return model.content_path;
|
|
21
|
+
return `.contentrain/content/${model.domain}/${model.id}`;
|
|
22
|
+
}
|
|
23
|
+
function contentDir(model) {
|
|
24
|
+
return contentDirPath(model);
|
|
25
|
+
}
|
|
26
|
+
function contentFilePath(model, locale) {
|
|
27
|
+
const dir = contentDir(model);
|
|
28
|
+
if (!model.i18n) return `${dir}/data.json`;
|
|
29
|
+
switch (model.locale_strategy ?? "file") {
|
|
30
|
+
case "suffix": return `${dir}/${model.id}.${locale}.json`;
|
|
31
|
+
case "directory": return `${dir}/${locale}/${model.id}.json`;
|
|
32
|
+
case "none": return `${dir}/${model.id}.json`;
|
|
33
|
+
default: return `${dir}/${locale}.json`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function documentFilePath(model, locale, slug) {
|
|
37
|
+
const dir = contentDir(model);
|
|
38
|
+
if (!model.i18n) return `${dir}/${slug}.md`;
|
|
39
|
+
switch (model.locale_strategy ?? "file") {
|
|
40
|
+
case "suffix": return `${dir}/${slug}.${locale}.md`;
|
|
41
|
+
case "directory": return `${dir}/${locale}/${slug}.md`;
|
|
42
|
+
case "none": return `${dir}/${slug}.md`;
|
|
43
|
+
default: return `${dir}/${slug}/${locale}.md`;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function metaFilePath(model, locale, slug) {
|
|
47
|
+
const base = `.contentrain/meta/${model.id}`;
|
|
48
|
+
if (model.kind === "document" && slug) return `${base}/${slug}/${locale}.json`;
|
|
49
|
+
return `${base}/${locale}.json`;
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { metaFilePath as i, contentFilePath as n, documentFilePath as r, contentDirPath as t };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=paths-CYl5vCBD.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths-CYl5vCBD.mjs","names":[],"sources":["../src/core/ops/paths.ts"],"sourcesContent":["import type { ModelDefinition } from '@contentrain/types'\n\n/**\n * Content-root-relative path helpers for plan-API consumers.\n *\n * These mirror the logic inside `core/content-manager.ts:resolveJsonFilePath`\n * but return forward-slash relative strings suitable for `FileChange.path`.\n * Providers are responsible for resolving these against their backing store\n * (worktree on disk for LocalProvider, git tree path for GitHubProvider, ...).\n *\n * Kept inline to `core/ops/` for now; when Faz 2 finishes migrating every op\n * the legacy absolute-path helpers in `core/content-manager.ts` and\n * `core/meta-manager.ts` will call into these (or be replaced entirely).\n */\n\n/**\n * Content-root-relative content directory for a model (forward-slash paths).\n * Mirrors `resolveContentDir` with an empty `projectRoot`, so reader-backed\n * callers and plan-API consumers share the same path resolution.\n */\nexport function contentDirPath(\n model: Pick<ModelDefinition, 'domain' | 'id' | 'content_path'>,\n): string {\n if (model.content_path) return model.content_path\n return `.contentrain/content/${model.domain}/${model.id}`\n}\n\nfunction contentDir(model: Pick<ModelDefinition, 'domain' | 'id' | 'content_path'>): string {\n return contentDirPath(model)\n}\n\nexport function contentFilePath(\n model: Pick<ModelDefinition, 'id' | 'kind' | 'domain' | 'i18n' | 'content_path' | 'locale_strategy'>,\n locale: string,\n): string {\n const dir = contentDir(model)\n if (!model.i18n) return `${dir}/data.json`\n const strategy = model.locale_strategy ?? 'file'\n switch (strategy) {\n case 'suffix': return `${dir}/${model.id}.${locale}.json`\n case 'directory': return `${dir}/${locale}/${model.id}.json`\n case 'none': return `${dir}/${model.id}.json`\n default: return `${dir}/${locale}.json`\n }\n}\n\nexport function documentFilePath(\n model: Pick<ModelDefinition, 'id' | 'domain' | 'i18n' | 'content_path' | 'locale_strategy'>,\n locale: string,\n slug: string,\n): string {\n const dir = contentDir(model)\n if (!model.i18n) return `${dir}/${slug}.md`\n const strategy = model.locale_strategy ?? 'file'\n switch (strategy) {\n case 'suffix': return `${dir}/${slug}.${locale}.md`\n case 'directory': return `${dir}/${locale}/${slug}.md`\n case 'none': return `${dir}/${slug}.md`\n default: return `${dir}/${slug}/${locale}.md`\n }\n}\n\nexport function metaFilePath(\n model: Pick<ModelDefinition, 'id' | 'kind'>,\n locale: string,\n slug?: string,\n): string {\n const base = `.contentrain/meta/${model.id}`\n if (model.kind === 'document' && slug) {\n return `${base}/${slug}/${locale}.json`\n }\n return `${base}/${locale}.json`\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoBA,SAAgB,eACd,OACQ;AACR,KAAI,MAAM,aAAc,QAAO,MAAM;AACrC,QAAO,wBAAwB,MAAM,OAAO,GAAG,MAAM;;AAGvD,SAAS,WAAW,OAAwE;AAC1F,QAAO,eAAe,MAAM;;AAG9B,SAAgB,gBACd,OACA,QACQ;CACR,MAAM,MAAM,WAAW,MAAM;AAC7B,KAAI,CAAC,MAAM,KAAM,QAAO,GAAG,IAAI;AAE/B,SADiB,MAAM,mBAAmB,QAC1C;EACE,KAAK,SAAU,QAAO,GAAG,IAAI,GAAG,MAAM,GAAG,GAAG,OAAO;EACnD,KAAK,YAAa,QAAO,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG;EACtD,KAAK,OAAQ,QAAO,GAAG,IAAI,GAAG,MAAM,GAAG;EACvC,QAAS,QAAO,GAAG,IAAI,GAAG,OAAO;;;AAIrC,SAAgB,iBACd,OACA,QACA,MACQ;CACR,MAAM,MAAM,WAAW,MAAM;AAC7B,KAAI,CAAC,MAAM,KAAM,QAAO,GAAG,IAAI,GAAG,KAAK;AAEvC,SADiB,MAAM,mBAAmB,QAC1C;EACE,KAAK,SAAU,QAAO,GAAG,IAAI,GAAG,KAAK,GAAG,OAAO;EAC/C,KAAK,YAAa,QAAO,GAAG,IAAI,GAAG,OAAO,GAAG,KAAK;EAClD,KAAK,OAAQ,QAAO,GAAG,IAAI,GAAG,KAAK;EACnC,QAAS,QAAO,GAAG,IAAI,GAAG,KAAK,GAAG,OAAO;;;AAI7C,SAAgB,aACd,OACA,QACA,MACQ;CACR,MAAM,OAAO,qBAAqB,MAAM;AACxC,KAAI,MAAM,SAAS,cAAc,KAC/B,QAAO,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO;AAEnC,QAAO,GAAG,KAAK,GAAG,OAAO"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { c as MergeResult, d as RepoReader, i as CommitAuthor, l as ProviderCapabilities, n as Branch, o as FileDiff, r as Commit, t as ApplyPlanInput, u as RepoProvider } from "../../index-D0wQJSgs.mjs";
|
|
2
|
+
import { Octokit } from "@octokit/rest";
|
|
3
|
+
|
|
4
|
+
//#region src/providers/github/app-auth.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* GitHub App authentication helpers.
|
|
7
|
+
*
|
|
8
|
+
* Two entry points:
|
|
9
|
+
*
|
|
10
|
+
* - {@link signAppJwt} — mint a short-lived (10 min) GitHub App JWT from
|
|
11
|
+
* `appId` + `privateKey`. Used to authenticate app-level endpoints
|
|
12
|
+
* (listing installations, creating installation tokens).
|
|
13
|
+
*
|
|
14
|
+
* - {@link exchangeInstallationToken} — exchange an app JWT for a
|
|
15
|
+
* per-installation access token that can be passed straight to
|
|
16
|
+
* `Octokit({ auth: token })`. Installation tokens last ~1 hour and
|
|
17
|
+
* must be refreshed.
|
|
18
|
+
*
|
|
19
|
+
* Both helpers are pure — they never import `@octokit/rest` or
|
|
20
|
+
* `@octokit/auth-app`. Callers that want auto-refresh behaviour should
|
|
21
|
+
* either wire `@octokit/auth-app` as the `authStrategy` when constructing
|
|
22
|
+
* their own Octokit (see the embedding guide), or call
|
|
23
|
+
* `exchangeInstallationToken` on their own schedule.
|
|
24
|
+
*/
|
|
25
|
+
interface AppAuthConfig {
|
|
26
|
+
/** GitHub App ID (numeric, from the app's settings page). */
|
|
27
|
+
appId: number;
|
|
28
|
+
/** PEM-encoded private key — the contents of the `.pem` the app issued. */
|
|
29
|
+
privateKey: string;
|
|
30
|
+
/** Installation the token should be scoped to. */
|
|
31
|
+
installationId: number;
|
|
32
|
+
}
|
|
33
|
+
interface InstallationTokenResult {
|
|
34
|
+
/** Opaque bearer token — pass to `new Octokit({ auth: token })`. */
|
|
35
|
+
token: string;
|
|
36
|
+
/** ISO 8601 expiry. Installation tokens expire after ~1 hour. */
|
|
37
|
+
expiresAt: string;
|
|
38
|
+
}
|
|
39
|
+
declare function signAppJwt(config: Pick<AppAuthConfig, 'appId' | 'privateKey'>): string;
|
|
40
|
+
/**
|
|
41
|
+
* Exchange an App JWT for an installation-scoped access token by calling
|
|
42
|
+
* GitHub's `POST /app/installations/{id}/access_tokens` endpoint.
|
|
43
|
+
*
|
|
44
|
+
* Uses `fetch` (Node ≥22 has it native) so the helper stays dependency-
|
|
45
|
+
* free. Throws on non-2xx responses with the GitHub-returned message.
|
|
46
|
+
*/
|
|
47
|
+
declare function exchangeInstallationToken(config: AppAuthConfig, opts?: {
|
|
48
|
+
baseUrl?: string;
|
|
49
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
50
|
+
}): Promise<InstallationTokenResult>;
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/providers/github/capabilities.d.ts
|
|
53
|
+
/**
|
|
54
|
+
* Capability set for GitHubProvider.
|
|
55
|
+
*
|
|
56
|
+
* GitHub over the Git Data API has no working tree, so local worktree
|
|
57
|
+
* features, source-file access and AST scans are unavailable. Push /
|
|
58
|
+
* PR operations are free because every commit goes straight to the
|
|
59
|
+
* remote. Branch protection detection uses the Repos API.
|
|
60
|
+
*
|
|
61
|
+
* Tools that require `astScan`, `sourceRead` or `sourceWrite` must
|
|
62
|
+
* gracefully reject (with `capability_required`) when running against
|
|
63
|
+
* a GitHubProvider — this is the mechanism behind phase 6's normalize
|
|
64
|
+
* capability-gate.
|
|
65
|
+
*/
|
|
66
|
+
declare const GITHUB_CAPABILITIES: ProviderCapabilities;
|
|
67
|
+
//#endregion
|
|
68
|
+
//#region src/providers/github/client.d.ts
|
|
69
|
+
/**
|
|
70
|
+
* GitHubClient — a typed alias for an `@octokit/rest` instance.
|
|
71
|
+
*
|
|
72
|
+
* We rely on the peer-installed `@octokit/rest` for its types only; the
|
|
73
|
+
* provider code never imports Octokit eagerly. Consumers install it
|
|
74
|
+
* themselves via the optional peer dependency; the factory in
|
|
75
|
+
* `factory.ts` `await import()`s Octokit at runtime so the rest of MCP
|
|
76
|
+
* stays usable without it.
|
|
77
|
+
*/
|
|
78
|
+
type GitHubClient = Octokit;
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/providers/github/types.d.ts
|
|
81
|
+
/**
|
|
82
|
+
* A reference to a GitHub repository.
|
|
83
|
+
*
|
|
84
|
+
* `contentRoot` is the repo-relative directory prefix where Contentrain
|
|
85
|
+
* content lives. For a flat content repo it stays `''`; for a monorepo
|
|
86
|
+
* where Contentrain is embedded (e.g. `apps/web/.contentrain/`) it holds
|
|
87
|
+
* that prefix. All reader/writer paths are joined against it.
|
|
88
|
+
*/
|
|
89
|
+
interface RepoRef {
|
|
90
|
+
owner: string;
|
|
91
|
+
name: string;
|
|
92
|
+
contentRoot?: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Authentication options for the GitHub provider.
|
|
96
|
+
*
|
|
97
|
+
* - `pat` — a personal access token or fine-grained PAT. Simplest for
|
|
98
|
+
* self-hosted MCP or CI runners. Phase 5.1 ships with this mode only.
|
|
99
|
+
* - `app` — GitHub App installation auth (JWT + installation token
|
|
100
|
+
* exchange). Planned for Phase 5.2; see `.internal/refactor/
|
|
101
|
+
* 02-studio-handoff.md` S6 for how Studio's hosted MCP plugs in.
|
|
102
|
+
*/
|
|
103
|
+
type GitHubAuth = {
|
|
104
|
+
type: 'pat';
|
|
105
|
+
token: string;
|
|
106
|
+
} | {
|
|
107
|
+
type: 'app';
|
|
108
|
+
appId: number;
|
|
109
|
+
privateKey: string;
|
|
110
|
+
installationId: number;
|
|
111
|
+
};
|
|
112
|
+
/** Default author used when a call does not provide one. */
|
|
113
|
+
declare const DEFAULT_GITHUB_AUTHOR: CommitAuthor;
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/providers/github/provider.d.ts
|
|
116
|
+
/**
|
|
117
|
+
* GitHubProvider — `RepoProvider` backed by the Octokit-driven GitHub
|
|
118
|
+
* REST + Git Data APIs.
|
|
119
|
+
*
|
|
120
|
+
* The provider is transport-agnostic; it only talks to an `Octokit`
|
|
121
|
+
* instance passed into the constructor. The `createGitHubProvider`
|
|
122
|
+
* helper in `factory.ts` wraps the dynamic import so consumers never
|
|
123
|
+
* have to touch Octokit directly.
|
|
124
|
+
*/
|
|
125
|
+
declare class GitHubProvider implements RepoProvider {
|
|
126
|
+
private readonly client;
|
|
127
|
+
readonly repo: RepoRef;
|
|
128
|
+
readonly capabilities: ProviderCapabilities;
|
|
129
|
+
private readonly reader;
|
|
130
|
+
constructor(client: GitHubClient, repo: RepoRef);
|
|
131
|
+
readFile(path: string, ref?: string): Promise<string>;
|
|
132
|
+
listDirectory(path: string, ref?: string): Promise<string[]>;
|
|
133
|
+
fileExists(path: string, ref?: string): Promise<boolean>;
|
|
134
|
+
applyPlan(input: ApplyPlanInput): Promise<Commit>;
|
|
135
|
+
listBranches(prefix?: string): Promise<Branch[]>;
|
|
136
|
+
createBranch(name: string, fromRef?: string): Promise<void>;
|
|
137
|
+
deleteBranch(name: string): Promise<void>;
|
|
138
|
+
getBranchDiff(branch: string, base?: string): Promise<FileDiff[]>;
|
|
139
|
+
mergeBranch(branch: string, into: string): Promise<MergeResult>;
|
|
140
|
+
isMerged(branch: string, into?: string): Promise<boolean>;
|
|
141
|
+
getDefaultBranch(): Promise<string>;
|
|
142
|
+
}
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region src/providers/github/factory.d.ts
|
|
145
|
+
/**
|
|
146
|
+
* Create an Octokit-backed `GitHubClient` from an auth configuration.
|
|
147
|
+
*
|
|
148
|
+
* The `@octokit/rest` module is imported dynamically so it stays a pure
|
|
149
|
+
* optional peer dependency — self-hosted MCP on stdio can run without
|
|
150
|
+
* it. If the module is not installed, the import throws with a helpful
|
|
151
|
+
* hint pointing the operator at the peer dependency.
|
|
152
|
+
*
|
|
153
|
+
* Two auth modes:
|
|
154
|
+
*
|
|
155
|
+
* - `pat` — personal access token or fine-grained PAT. Simplest for
|
|
156
|
+
* self-hosted MCP or CI runners.
|
|
157
|
+
* - `app` — GitHub App installation auth. The factory mints a short-
|
|
158
|
+
* lived JWT, exchanges it for an installation token via
|
|
159
|
+
* `exchangeInstallationToken`, and instantiates Octokit with the
|
|
160
|
+
* resulting bearer. The returned token expires in ~1 hour; callers
|
|
161
|
+
* that need auto-refresh should instead inject their own Octokit
|
|
162
|
+
* built with `@octokit/auth-app`'s auth strategy and construct
|
|
163
|
+
* `GitHubProvider` directly. See the embedding guide for trade-offs.
|
|
164
|
+
*/
|
|
165
|
+
declare function createGitHubClient(auth: GitHubAuth): Promise<GitHubClient>;
|
|
166
|
+
/**
|
|
167
|
+
* Factory for the full provider — instantiates an Octokit client and
|
|
168
|
+
* wraps it in a `GitHubProvider`. Consumers who already hold an Octokit
|
|
169
|
+
* instance (HTTP server injecting shared clients, tests, etc.) should
|
|
170
|
+
* instantiate `GitHubProvider` directly instead.
|
|
171
|
+
*/
|
|
172
|
+
declare function createGitHubProvider(opts: {
|
|
173
|
+
auth: GitHubAuth;
|
|
174
|
+
repo: RepoRef;
|
|
175
|
+
}): Promise<GitHubProvider>;
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region src/providers/github/reader.d.ts
|
|
178
|
+
/**
|
|
179
|
+
* GitHubReader — `RepoReader` backed by the GitHub Repos + Git Data APIs.
|
|
180
|
+
*
|
|
181
|
+
* Reads pass through `repos.getContent`; directories return a list of
|
|
182
|
+
* names, files return decoded UTF-8 text. Files larger than ~1 MB are
|
|
183
|
+
* fetched by blob SHA through `git.getBlob` because `getContent` omits
|
|
184
|
+
* the body in that case.
|
|
185
|
+
*
|
|
186
|
+
* `ref` is forwarded verbatim and may be a branch name, tag name or
|
|
187
|
+
* commit SHA. When omitted, GitHub resolves to the repository's default
|
|
188
|
+
* branch — which is usually wrong for Contentrain flows, so callers
|
|
189
|
+
* should always pass the explicit `contentrain` tracking branch.
|
|
190
|
+
*/
|
|
191
|
+
declare class GitHubReader implements RepoReader {
|
|
192
|
+
private readonly client;
|
|
193
|
+
private readonly repo;
|
|
194
|
+
constructor(client: GitHubClient, repo: RepoRef);
|
|
195
|
+
readFile(path: string, ref?: string): Promise<string>;
|
|
196
|
+
listDirectory(path: string, ref?: string): Promise<string[]>;
|
|
197
|
+
fileExists(path: string, ref?: string): Promise<boolean>;
|
|
198
|
+
}
|
|
199
|
+
//#endregion
|
|
200
|
+
export { type AppAuthConfig, DEFAULT_GITHUB_AUTHOR, GITHUB_CAPABILITIES, type GitHubAuth, type GitHubClient, GitHubProvider, GitHubReader, type InstallationTokenResult, type RepoRef, createGitHubClient, createGitHubProvider, exchangeInstallationToken, signAppJwt };
|
|
201
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/providers/github/app-auth.ts","../../../src/providers/github/capabilities.ts","../../../src/providers/github/client.ts","../../../src/providers/github/types.ts","../../../src/providers/github/provider.ts","../../../src/providers/github/factory.ts","../../../src/providers/github/reader.ts"],"mappings":";;;;;;;;AAuBA;;;;;;;;;AASA;;;;;AAkBA;;UA3BiB,aAAA;EA2BsB;EAzBrC,KAAA;EAyBsC;EAvBtC,UAAA;EAuB4E;EArB5E,cAAA;AAAA;AAAA,UAGe,uBAAA;;EAEf,KAAA;EA4C6C;EA1C7C,SAAA;AAAA;AAAA,iBAcc,UAAA,CAAW,MAAA,EAAQ,IAAA,CAAK,aAAA;;;;;;;;iBA0BlB,yBAAA,CACpB,MAAA,EAAQ,aAAA,EACR,IAAA;EAAQ,OAAA;EAAkB,SAAA,UAAmB,UAAA,CAAW,KAAA;AAAA,IACvD,OAAA,CAAQ,uBAAA;;;;;;AAxDX;;;;;;;;;AASA;cCjBa,mBAAA,EAAqB,oBAAA;;;;;;ADQlC;;;;;;KEZY,YAAA,GAAe,OAAA;;;;;;AFY3B;;;;;UGbiB,OAAA;EACf,KAAA;EACA,IAAA;EACA,WAAA;AAAA;;;;;AHqCF;;;;;KGzBY,UAAA;EACN,IAAA;EAAa,KAAA;AAAA;EAEb,IAAA;EACA,KAAA;EACA,UAAA;EACA,cAAA;AAAA;;cAIO,qBAAA,EAAuB,YAAA;;;;AHZpC;;;;;;;;cIUa,cAAA,YAA0B,YAAA;EAAA,iBAKlB,MAAA;EAAA,SACD,IAAA,EAAM,OAAA;EAAA,SALf,YAAA,EAAc,oBAAA;EAAA,iBACN,MAAA;cAGE,MAAA,EAAQ,YAAA,EACT,IAAA,EAAM,OAAA;EAKxB,QAAA,CAAS,IAAA,UAAc,GAAA,YAAe,OAAA;EAGtC,aAAA,CAAc,IAAA,UAAc,GAAA,YAAe,OAAA;EAG3C,UAAA,CAAW,IAAA,UAAc,GAAA,YAAe,OAAA;EAIxC,SAAA,CAAU,KAAA,EAAO,cAAA,GAAiB,OAAA,CAAQ,MAAA;EAI1C,YAAA,CAAa,MAAA,YAAkB,OAAA,CAAQ,MAAA;EAGvC,YAAA,CAAa,IAAA,UAAc,OAAA,YAAmB,OAAA;EAI9C,YAAA,CAAa,IAAA,WAAe,OAAA;EAG5B,aAAA,CAAc,MAAA,UAAgB,IAAA,YAAgB,OAAA,CAAQ,QAAA;EAItD,WAAA,CAAY,MAAA,UAAgB,IAAA,WAAe,OAAA,CAAQ,WAAA;EAGnD,QAAA,CAAS,MAAA,UAAgB,IAAA,YAAgB,OAAA;EAIzC,gBAAA,CAAA,GAAoB,OAAA;AAAA;;;;AJxDtB;;;;;;;;;AASA;;;;;AAkBA;;;;;iBKzBsB,kBAAA,CAAmB,IAAA,EAAM,UAAA,GAAa,OAAA,CAAQ,YAAA;;;;ALmDpE;;;iBKhBsB,oBAAA,CAAqB,IAAA;EAAQ,IAAA,EAAM,UAAA;EAAY,IAAA,EAAM,OAAA;AAAA,IAAY,OAAA,CAAQ,cAAA;;;;ALrC/F;;;;;;;;;AASA;;;cMda,YAAA,YAAwB,UAAA;EAAA,iBAEhB,MAAA;EAAA,iBACA,IAAA;cADA,MAAA,EAAQ,YAAA,EACR,IAAA,EAAM,OAAA;EAGnB,QAAA,CAAS,IAAA,UAAc,GAAA,YAAe,OAAA;EAmCtC,aAAA,CAAc,IAAA,UAAc,GAAA,YAAe,OAAA;EAkB3C,UAAA,CAAW,IAAA,UAAc,GAAA,YAAe,OAAA;AAAA"}
|