kennel 0.1.8 → 0.1.9
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 +36 -87
- package/bin/kennel-native.mjs +5 -0
- package/dist/cli/dispatch.js +25 -16
- package/dist/cli/usage.js +9 -3
- package/dist/deploy/cloudflare.js +10 -1
- package/dist/deploy/smoke-tests.d.ts +1 -0
- package/dist/deploy/smoke-tests.js +21 -0
- package/dist/deploy/vercel.d.ts +3 -0
- package/dist/deploy/vercel.js +67 -0
- package/dist/mcp/config.js +14 -0
- package/dist/mcp/function-source.js +3 -1
- package/dist/mcp/generate.js +3 -3
- package/dist/mcp/install-page.d.ts +12 -1
- package/dist/mcp/install-page.js +3 -358
- package/dist/notifications/email-worker.js +1 -1
- package/dist/publish/cloudflare-init.js +5 -2
- package/dist/publish/config.d.ts +1 -1
- package/dist/publish/config.js +3 -15
- package/dist/publish/vercel-init.d.ts +9 -0
- package/dist/publish/vercel-init.js +52 -0
- package/dist/site/dev.js +2 -4
- package/dist/site/extension.d.ts +8 -0
- package/dist/site/extension.js +114 -0
- package/dist/site/renderers.d.ts +61 -0
- package/dist/site/renderers.js +219 -0
- package/dist/site/viewer.d.ts +9 -0
- package/dist/site/viewer.js +192 -0
- package/dist/site/vitepress.d.ts +1 -21
- package/dist/site/vitepress.js +1 -66
- package/dist/sources/commands.d.ts +1 -0
- package/dist/sources/commands.js +88 -0
- package/package.json +8 -8
- package/web/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/web/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/web/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/web/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/web/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/web/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/web/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/web/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/web/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/web/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/web/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/web/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/web/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/web/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/web/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/web/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/web/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/web/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/web/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/web/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/web/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/web/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/web/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/web/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/web/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/web/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/web/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/web/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/web/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/web/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/web/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/web/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/web/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/web/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/web/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/web/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/web/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/web/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/web/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/web/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/web/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/web/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/web/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/web/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/web/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/web/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/web/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/web/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/web/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/web/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/web/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/web/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/web/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/web/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/web/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/web/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/web/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/web/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/web/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/web/assets/abnfDiagram-VRR7QNED-Dizo1F0V.js +1 -0
- package/web/assets/arc-CraBhW5A.js +1 -0
- package/web/assets/architectureDiagram-ZJ3FMSHR-DrcQCjV4.js +36 -0
- package/web/assets/blockDiagram-677ZJIJ3-iGvS8HCJ.js +132 -0
- package/web/assets/c4Diagram-LMCZKHZV-B9ueRzOf.js +10 -0
- package/web/assets/channel-DjVeob-k.js +1 -0
- package/web/assets/chunk-2Q5K7J3B-Dg02y5Go.js +1 -0
- package/web/assets/chunk-32BRIVSS-DHUNfpw6.js +1 -0
- package/web/assets/chunk-5VM5RSS4-B6XJu9sr.js +15 -0
- package/web/assets/chunk-EX3LRPZG-DywY4I3l.js +231 -0
- package/web/assets/chunk-JWPE2WC7-C9-XkXDg.js +1 -0
- package/web/assets/chunk-MOJQB5TN-CXQXOtY9.js +88 -0
- package/web/assets/chunk-RYQCIY6F-DJwv9114.js +1 -0
- package/web/assets/chunk-V7JOEXUC-_b44nhwN.js +206 -0
- package/web/assets/chunk-VR4S4FIN-B_bGSDri.js +1 -0
- package/web/assets/chunk-XXDRQBXY-Bf-JPvQi.js +1 -0
- package/web/assets/classDiagram-OUVF2IWQ-4Od2_pq4.js +1 -0
- package/web/assets/classDiagram-v2-EOCWNBFH-4Od2_pq4.js +1 -0
- package/web/assets/cose-bilkent-JH36ORCC-Bcssb1jB.js +1 -0
- package/web/assets/cynefin-VYW2F7L2-t9uGqnJ4.js +166 -0
- package/web/assets/cynefinDiagram-TSTJHNR4-D0RvbNfG.js +62 -0
- package/web/assets/cytoscape.esm-D3_iZ_3b.js +321 -0
- package/web/assets/dagre-VKFMJZFB-DmmlPxN_.js +4 -0
- package/web/assets/defaultLocale-C4B-KCzX.js +1 -0
- package/web/assets/diagram-FQU43EPY-DtDak7gR.js +3 -0
- package/web/assets/diagram-G47NLZAW-Cn07lZ4L.js +24 -0
- package/web/assets/diagram-NH7WQ7WH-BTD9-weZ.js +24 -0
- package/web/assets/diagram-OA4YK3LP-fjOdFedY.js +30 -0
- package/web/assets/diagram-WEI45ONY-DSBYO7Nc.js +41 -0
- package/web/assets/ebnfDiagram-CCIWWBDH-B8km6QWT.js +1 -0
- package/web/assets/erDiagram-Q63AITRT-CHs2HT-U.js +85 -0
- package/web/assets/flowDiagram-23GEKE2U-CxjQgYus.js +156 -0
- package/web/assets/ganttDiagram-NO4QXBWP-CHkGy5_G.js +292 -0
- package/web/assets/gitGraphDiagram-IHSO6WYX-BdtSK3Q5.js +106 -0
- package/web/assets/graph-BvS0Xx32.js +1 -0
- package/web/assets/index-BiSkqJri.css +1 -0
- package/web/assets/index-sG3Cxc28.js +697 -0
- package/web/assets/infoDiagram-FWYZ7A6U-B0feeRLu.js +2 -0
- package/web/assets/init-Gi6I4Gst.js +1 -0
- package/web/assets/ishikawaDiagram-FXEZZL3T-DGCSsJ4r.js +70 -0
- package/web/assets/journeyDiagram-5HDEW3XC-D9xtvo9Z.js +139 -0
- package/web/assets/kanban-definition-HUTT4EX6-BqVdsgmq.js +89 -0
- package/web/assets/layout-D4ui-CWC.js +1 -0
- package/web/assets/linear-BopdAHdJ.js +1 -0
- package/web/assets/map-7eTsl7HP.js +1 -0
- package/web/assets/mermaid.core-DWAi8MqL.js +308 -0
- package/web/assets/mindmap-definition-LN4V7U3C-CsV_gb2j.js +96 -0
- package/web/assets/ordinal-Cboi1Yqb.js +1 -0
- package/web/assets/pegDiagram-2B236MQR-BmDNuFL1.js +1 -0
- package/web/assets/pieDiagram-ENE6RG2P-CBPZlXZP.js +39 -0
- package/web/assets/quadrantDiagram-ABIIQ3AL-CbUemD3z.js +7 -0
- package/web/assets/railroadDiagram-RFXS5EU6-Cyp4W7Hm.js +1 -0
- package/web/assets/requirementDiagram-TGXJPOKE-Dz35_qtT.js +84 -0
- package/web/assets/sankeyDiagram-HTMAVEWB-biUDOCWc.js +40 -0
- package/web/assets/sequenceDiagram-DBY2YBRQ-Bk4X1-E4.js +162 -0
- package/web/assets/sizeCapture-X5ZJPWSS-CDPSVeoQ.js +1 -0
- package/web/assets/stateDiagram-2N3HPSRC-Cx_G_F7H.js +1 -0
- package/web/assets/stateDiagram-v2-6OUMAXLB-DG9cZ_-X.js +1 -0
- package/web/assets/swimlanes-5IMT3BWC-KfhGp3gJ.js +2 -0
- package/web/assets/swimlanesDiagram-G3AALYLV-Bj6WXCUy.js +8 -0
- package/web/assets/timeline-definition-FHXFAJF6-Dp6wlW_7.js +120 -0
- package/web/assets/vennDiagram-L72KCM5P-CjdOdrf1.js +34 -0
- package/web/assets/wardleyDiagram-EHGQE667-DYl5GkQs.js +78 -0
- package/web/assets/xychartDiagram-FW5EYKEG-rPJ1RPYD.js +7 -0
- package/web/index.html +14 -0
- package/dist/mcp/data.d.ts +0 -14
- package/dist/mcp/data.js +0 -120
- package/dist/schema/doctor.d.ts +0 -1
- package/dist/schema/doctor.js +0 -69
- package/dist/schema/documents.d.ts +0 -18
- package/dist/schema/documents.js +0 -127
- package/dist/schema/pointers.d.ts +0 -5
- package/dist/schema/pointers.js +0 -48
- package/dist/schema/types.d.ts +0 -36
- package/dist/schema/types.js +0 -1
- package/dist/schema/validation.d.ts +0 -8
- package/dist/schema/validation.js +0 -212
package/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
# Kennel CLI
|
|
1
|
+
# Kennel Platform CLI
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Kennel keeps structured folders easy to inspect and validate. It looks upward from the target path for the nearest `schema.json` or `_schema.json`, then validates schema-declared YAML files or Markdown frontmatter documents.
|
|
3
|
+
Publishing, MCP generation, and knowledge-source commands for Kennel workspaces. The compact schema validator has moved to the private [`raggle-ai/kennel-compact`](https://github.com/raggle-ai/kennel-compact) repository.
|
|
6
4
|
|
|
7
5
|
## Usage
|
|
8
6
|
|
|
@@ -12,43 +10,23 @@ npm test
|
|
|
12
10
|
node bin/kennel.mjs --help
|
|
13
11
|
```
|
|
14
12
|
|
|
15
|
-
Install
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm install /Users/andrew/Documents/GitHub/kennel/cli
|
|
19
|
-
kennel --help
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Install from npm after publication:
|
|
13
|
+
Install from npm:
|
|
23
14
|
|
|
24
15
|
```bash
|
|
25
16
|
npm install --global kennel
|
|
26
17
|
kennel --help
|
|
27
18
|
```
|
|
28
19
|
|
|
29
|
-
|
|
20
|
+
Run platform commands:
|
|
30
21
|
|
|
31
22
|
```bash
|
|
32
|
-
cd /Users/andrew/Documents/GitHub/kennel/cli
|
|
33
|
-
npm publish --access public --registry=https://registry.npmjs.org
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Run against folder schemas:
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
kennel schema clients/reapit
|
|
40
|
-
kennel validate clients
|
|
41
|
-
kennel validate projects
|
|
42
|
-
kennel validate partners
|
|
43
|
-
kennel doctor clients/reapit
|
|
44
23
|
kennel dev /Users/andrewmagu/src/cdp-index --config index.json
|
|
24
|
+
kennel mcp generate . --config index.json
|
|
45
25
|
kennel publish init cloudflare .
|
|
46
26
|
kennel deploy .
|
|
47
27
|
kennel dp .
|
|
48
28
|
```
|
|
49
29
|
|
|
50
|
-
Kennel does not create schemas or new records. Manage `schema.json` or `_schema.json` files and folder templates outside the CLI, then use Kennel to inspect and validate them.
|
|
51
|
-
|
|
52
30
|
`kennel publish init cloudflare` is the exception for deploy wiring: it scaffolds
|
|
53
31
|
a Cloudflare Worker email-code gate for an existing docs workspace by writing
|
|
54
32
|
`publication` in `raggle.json` by default, then writing generated Cloudflare
|
|
@@ -67,65 +45,6 @@ Kennel loads `CLOUDFLARE_API_TOKEN` from Doppler only for the publish command.
|
|
|
67
45
|
`kennel publish cloudflare` remains available when the provider should be
|
|
68
46
|
explicit.
|
|
69
47
|
|
|
70
|
-
## Folder Shape
|
|
71
|
-
|
|
72
|
-
```text
|
|
73
|
-
clients/
|
|
74
|
-
schema.json
|
|
75
|
-
example-client/
|
|
76
|
-
client.yml
|
|
77
|
-
people/
|
|
78
|
-
notes/
|
|
79
|
-
comms/
|
|
80
|
-
evidence/
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
The nearest parent `schema.json` or `_schema.json` owns the expected shape for folders below it. When both names exist in the same folder, `schema.json` is preferred.
|
|
84
|
-
|
|
85
|
-
`kennel validate` discovers files from the nearest schema's `x-kennel.documents` declaration. If a schema omits that declaration, Kennel keeps the compatibility default of `client.yml` and `index.md`.
|
|
86
|
-
|
|
87
|
-
Markdown files are validated using YAML frontmatter. YAML files are parsed as YAML.
|
|
88
|
-
|
|
89
|
-
## Folder Requirements
|
|
90
|
-
|
|
91
|
-
Schemas can include a Kennel-only extension for folder shape checks:
|
|
92
|
-
|
|
93
|
-
```json
|
|
94
|
-
{
|
|
95
|
-
"x-kennel": {
|
|
96
|
-
"documents": [
|
|
97
|
-
"client.yml",
|
|
98
|
-
{ "path": "index.md", "parser": "markdown-frontmatter" },
|
|
99
|
-
{ "glob": "*.yml", "parser": "yaml" }
|
|
100
|
-
],
|
|
101
|
-
"requiredDirectories": ["people", "notes", "comms", "evidence"],
|
|
102
|
-
"requiredFiles": ["README.md"],
|
|
103
|
-
"directoryContents": [
|
|
104
|
-
{
|
|
105
|
-
"path": "people",
|
|
106
|
-
"glob": "*.md",
|
|
107
|
-
"minFiles": 1,
|
|
108
|
-
"whenPointerMinItems": "/contacts"
|
|
109
|
-
}
|
|
110
|
-
],
|
|
111
|
-
"fileReferences": [
|
|
112
|
-
{
|
|
113
|
-
"pointer": "/contacts/*/path",
|
|
114
|
-
"required": true,
|
|
115
|
-
"whenPointerMinItems": "/contacts"
|
|
116
|
-
}
|
|
117
|
-
]
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
String document entries match a file name anywhere under the schema root. Object entries can use `path` or `glob` plus an optional parser.
|
|
123
|
-
|
|
124
|
-
`requiredDirectories` and `requiredFiles` are checked next to each validated document and by `kennel doctor`.
|
|
125
|
-
|
|
126
|
-
`directoryContents` checks that a sibling directory contains enough matching files. Use `whenPointerMinItems` to apply the rule only when an array in the document is non-empty, or `whenPointerIn` with `{ "pointer": "/client/status", "values": ["active-client"] }` to apply it for selected field values.
|
|
127
|
-
|
|
128
|
-
`fileReferences` checks that document path fields point to existing files under the same folder. It supports JSON pointers with `*` wildcards, such as `/contacts/*/path`.
|
|
129
48
|
|
|
130
49
|
## MCP Analytics
|
|
131
50
|
|
|
@@ -158,7 +77,7 @@ The Raggle provider uses the `raggle-otel` package and defaults to `RAGGLE_OTEL_
|
|
|
158
77
|
|
|
159
78
|
## MCP Repo Integrations
|
|
160
79
|
|
|
161
|
-
`kennel mcp generate` also emits an MCP server runtime
|
|
80
|
+
`kennel mcp generate` also emits an MCP server runtime from `@raggle-ai/kennel/mcp` with core tools for searching index docs and tracked repositories. The runtime additionally exposes repo integration tools that let an agent run basic GitHub or GitLab commands against a repository linked from the index registry (`repos/index.yaml`):
|
|
162
81
|
|
|
163
82
|
- `submit_repo_feature_request` — open a feature request issue on a tracked repo, submitted on behalf of a user.
|
|
164
83
|
- `list_repo_issues` — list recent issues on a tracked repo.
|
|
@@ -190,6 +109,36 @@ To let people supply their own GitHub or GitLab setup (custom token env, self-ho
|
|
|
190
109
|
|
|
191
110
|
`allowedRepos` is an optional allowlist of registry repo names; when omitted, every registry repo is available. Set `enabled: false` to disable the repo integration tools while keeping the rest of the MCP server active.
|
|
192
111
|
|
|
112
|
+
## MCP Tool Catalog Profiles
|
|
113
|
+
|
|
114
|
+
Large MCP servers can expose a small eager tool surface while keeping specialised tools discoverable. Add `mcp.toolCatalog` to select a default profile. Tools not selected as eager are deferred automatically; `search_index_tools`, `describe_index_tool`, and `call_index_tool` let an agent discover a deferred schema and invoke it through the catalog dispatcher.
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"mcp": {
|
|
119
|
+
"toolCatalog": {
|
|
120
|
+
"defaultProfile": "minimal",
|
|
121
|
+
"allowClientProfile": true,
|
|
122
|
+
"profiles": {
|
|
123
|
+
"minimal": {
|
|
124
|
+
"eagerTools": [
|
|
125
|
+
"search_index",
|
|
126
|
+
"search_index_tools",
|
|
127
|
+
"describe_index_tool",
|
|
128
|
+
"call_index_tool"
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
"complete": {
|
|
132
|
+
"eagerNamespaces": ["*"]
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
When `allowClientProfile` is enabled, an MCP client or gateway can select a configured view with the `x-kennel-mcp-profile` header. Profile selection only narrows catalog exposure: role checks and mutating-tool policy still run for direct and dispatched calls. If `toolCatalog` is omitted, the runtime retains the legacy behavior and lists every available tool.
|
|
141
|
+
|
|
193
142
|
Registry entries that should support issue creation need a `url` (and optionally `provider`):
|
|
194
143
|
|
|
195
144
|
```yaml
|
package/dist/cli/dispatch.js
CHANGED
|
@@ -1,51 +1,60 @@
|
|
|
1
|
-
import { deploy, publish } from '../deploy/cloudflare.js';
|
|
2
|
-
import { generateMcp } from '../mcp/generate.js';
|
|
3
|
-
import { doctor } from '../schema/doctor.js';
|
|
4
|
-
import { schemaFor, validateTarget } from '../schema/validation.js';
|
|
5
|
-
import { dev } from '../site/dev.js';
|
|
6
|
-
import { publishInitCloudflare } from '../publish/cloudflare-init.js';
|
|
7
1
|
import { usage } from './usage.js';
|
|
8
2
|
export async function dispatch(argv) {
|
|
9
3
|
const [, , command, ...args] = argv;
|
|
10
|
-
if (
|
|
4
|
+
if (command === '-h' || command === '--help') {
|
|
11
5
|
usage();
|
|
12
6
|
return;
|
|
13
7
|
}
|
|
14
|
-
if (command
|
|
15
|
-
|
|
8
|
+
if (!command) {
|
|
9
|
+
const { viewer } = await import('../site/viewer.js');
|
|
10
|
+
await viewer([]);
|
|
16
11
|
return;
|
|
17
12
|
}
|
|
18
|
-
if (command === '
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
if (command === 'doctor') {
|
|
23
|
-
doctor(args[0] ?? '.');
|
|
13
|
+
if (command === 'source') {
|
|
14
|
+
const { sourceCommand } = await import('../sources/commands.js');
|
|
15
|
+
sourceCommand(args);
|
|
24
16
|
return;
|
|
25
17
|
}
|
|
26
18
|
if (command === 'dev') {
|
|
19
|
+
const { dev } = await import('../site/dev.js');
|
|
27
20
|
dev(args);
|
|
28
21
|
return;
|
|
29
22
|
}
|
|
23
|
+
if (command === 'extension' && args[0] === 'install') {
|
|
24
|
+
const { extensionInstall } = await import('../site/extension.js');
|
|
25
|
+
await extensionInstall();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
30
28
|
if (command === 'mcp' && args[0] === 'generate') {
|
|
29
|
+
const { generateMcp } = await import('../mcp/generate.js');
|
|
31
30
|
await generateMcp(args.slice(1));
|
|
32
31
|
return;
|
|
33
32
|
}
|
|
34
33
|
if (command === 'publish' && args[0] === 'init' && args[1] === 'cloudflare') {
|
|
34
|
+
const { publishInitCloudflare } = await import('../publish/cloudflare-init.js');
|
|
35
35
|
publishInitCloudflare(args.slice(2));
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
|
+
if (command === 'publish' && args[0] === 'init' && args[1] === 'vercel') {
|
|
39
|
+
const { publishInitVercel } = await import('../publish/vercel-init.js');
|
|
40
|
+
publishInitVercel(args.slice(2));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
38
43
|
if (command === 'publish') {
|
|
44
|
+
const { publish } = await import('../deploy/cloudflare.js');
|
|
39
45
|
publish(args);
|
|
40
46
|
return;
|
|
41
47
|
}
|
|
42
48
|
if (command === 'deploy') {
|
|
49
|
+
const { deploy } = await import('../deploy/cloudflare.js');
|
|
43
50
|
deploy(args);
|
|
44
51
|
return;
|
|
45
52
|
}
|
|
46
53
|
if (command === 'dp') {
|
|
54
|
+
const { deploy } = await import('../deploy/cloudflare.js');
|
|
47
55
|
deploy(args);
|
|
48
56
|
return;
|
|
49
57
|
}
|
|
50
|
-
|
|
58
|
+
const { viewer } = await import('../site/viewer.js');
|
|
59
|
+
await viewer([command, ...args]);
|
|
51
60
|
}
|
package/dist/cli/usage.js
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
export function usage() {
|
|
2
2
|
console.log(`Usage:
|
|
3
|
-
kennel
|
|
4
|
-
kennel
|
|
5
|
-
kennel
|
|
3
|
+
kennel [folder] [--host <host>] [--port <port>] [--lan|--tailscale]
|
|
4
|
+
kennel source list [path] [--config <json-file>] [--json]
|
|
5
|
+
kennel source describe <id> [path] [--config <json-file>] [--json]
|
|
6
|
+
kennel source doctor [path] [--config <json-file>] [--json]
|
|
7
|
+
kennel source query <id> [path] [--config <json-file>] [--limit <n>] [--json]
|
|
8
|
+
kennel source snapshot [path] [--config <json-file>] [--json]
|
|
6
9
|
kennel dev [path] [--config <json-file>] [--port <port>] [--script <script>] [--dry-run] [-- <args...>]
|
|
10
|
+
kennel extension install
|
|
7
11
|
kennel mcp generate [path] [--config <json-file>] [--data-only|--function-only]
|
|
8
12
|
kennel publish init cloudflare [path] [--config <json-file>] [--force] [--hostname <hostname>]
|
|
13
|
+
kennel publish init vercel [path] [--config <json-file>] [--force] [--hostname <hostname>]
|
|
9
14
|
kennel publish [path] [--config <json-file>] [--dry-run] [--force] [--hostname <hostname>] [--test-email <email>] [--skip-test] [--use-doppler-token]
|
|
10
15
|
kennel publish cloudflare [path] [--config <json-file>] [--dry-run] [--force] [--hostname <hostname>] [--test-email <email>] [--skip-test] [--use-doppler-token]
|
|
16
|
+
kennel publish vercel [path] [--config <json-file>] [--dry-run] [--force] [--hostname <hostname>] [--skip-test]
|
|
11
17
|
kennel deploy [path] [--config <json-file>] [legacy alias for publish]
|
|
12
18
|
kennel dp [path] [--config <json-file>] [legacy alias for publish]
|
|
13
19
|
`);
|
|
@@ -4,13 +4,15 @@ import { existsSync } from 'node:fs';
|
|
|
4
4
|
import { relative } from 'node:path';
|
|
5
5
|
import { readJson } from '../shared/json.js';
|
|
6
6
|
import { localBin } from '../shared/package-manager.js';
|
|
7
|
+
import { projectConfigPath } from '../shared/project-config.js';
|
|
7
8
|
import { commandLine } from '../shared/process.js';
|
|
8
|
-
import { packageJsonPath, publishBuildCommand, publishTestUrl, publishWranglerArgs, publishWranglerCommand, publicationAccess, } from '../publish/config.js';
|
|
9
|
+
import { packageJsonPath, publishBuildCommand, publishTestUrl, publishWranglerArgs, publishWranglerCommand, publicationAccess, publicationConfig, } from '../publish/config.js';
|
|
9
10
|
import { publishInitCloudflare } from '../publish/cloudflare-init.js';
|
|
10
11
|
import { splitPublishArgs } from '../publish/options.js';
|
|
11
12
|
import { withCloudflareEnvironment } from './environment.js';
|
|
12
13
|
import { runAccessHttpTest, runHttpTest } from './smoke-tests.js';
|
|
13
14
|
import { syncTriggerDev } from './trigger-dev.js';
|
|
15
|
+
import { publishVercel } from './vercel.js';
|
|
14
16
|
export function runPublishCommand(root, child, options) {
|
|
15
17
|
console.log(commandLine(child.command, child.args));
|
|
16
18
|
if (options.dryRun)
|
|
@@ -84,6 +86,13 @@ export function publish(input) {
|
|
|
84
86
|
if (input[0] === 'cloudflare' || input[0] === 'cloudflare-workers') {
|
|
85
87
|
return publishCloudflare(input.slice(1));
|
|
86
88
|
}
|
|
89
|
+
if (input[0] === 'vercel')
|
|
90
|
+
return publishVercel(input.slice(1));
|
|
91
|
+
const options = splitPublishArgs(input);
|
|
92
|
+
const config = readJson(projectConfigPath(options.targetPath, options.configFile));
|
|
93
|
+
const provider = publicationConfig(config).provider;
|
|
94
|
+
if (provider === 'vercel')
|
|
95
|
+
return publishVercel(input);
|
|
87
96
|
return publishCloudflare(input);
|
|
88
97
|
}
|
|
89
98
|
export function deploy(input) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { PublishOptions } from '../publish/options.js';
|
|
2
2
|
export declare function runHttpTest(root: string, hostname: string, testEmail: string, options: PublishOptions): void;
|
|
3
|
+
export declare function runStaticHttpTest(root: string, hostname: string, options: PublishOptions): void;
|
|
3
4
|
export declare function runAccessHttpTest(root: string, hostname: string, options: PublishOptions): void;
|
|
@@ -47,6 +47,27 @@ export function runHttpTest(root, hostname, testEmail, options) {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
+
export function runStaticHttpTest(root, hostname, options) {
|
|
51
|
+
const baseUrl = publishTestUrl(hostname);
|
|
52
|
+
if (!baseUrl) {
|
|
53
|
+
console.log('skip test: no hostname configured');
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (!commandExists('curl')) {
|
|
57
|
+
console.log('skip test: curl is not available');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const rootTest = {
|
|
61
|
+
command: 'curl',
|
|
62
|
+
args: ['-fsS', '-H', 'Cache-Control: no-cache', baseUrl],
|
|
63
|
+
};
|
|
64
|
+
console.log(`${commandLine(rootTest.command, rootTest.args)} | returns 2xx`);
|
|
65
|
+
if (!options.dryRun) {
|
|
66
|
+
const result = spawnSync(rootTest.command, rootTest.args, { cwd: root, stdio: 'ignore' });
|
|
67
|
+
if (result.status !== 0)
|
|
68
|
+
throw new Error(`${baseUrl} did not return a successful response`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
50
71
|
export function runAccessHttpTest(root, hostname, options) {
|
|
51
72
|
const baseUrl = publishTestUrl(hostname);
|
|
52
73
|
if (!baseUrl) {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { readJson } from '../shared/json.js';
|
|
4
|
+
import { localBin } from '../shared/package-manager.js';
|
|
5
|
+
import { commandLine } from '../shared/process.js';
|
|
6
|
+
import { packageJsonPath, publicationConfig, publicationDomains, publishBuildCommand, publishTestUrl, } from '../publish/config.js';
|
|
7
|
+
import { splitPublishArgs } from '../publish/options.js';
|
|
8
|
+
import { publishInitVercel } from '../publish/vercel-init.js';
|
|
9
|
+
import { runStaticHttpTest } from './smoke-tests.js';
|
|
10
|
+
function runVercelCommand(root, child, options) {
|
|
11
|
+
console.log(commandLine(child.command, child.args));
|
|
12
|
+
if (options.dryRun)
|
|
13
|
+
return;
|
|
14
|
+
const result = spawnSync(child.command, child.args, {
|
|
15
|
+
cwd: root,
|
|
16
|
+
stdio: 'inherit',
|
|
17
|
+
env: process.env,
|
|
18
|
+
});
|
|
19
|
+
if (result.status !== 0)
|
|
20
|
+
process.exit(result.status ?? 1);
|
|
21
|
+
}
|
|
22
|
+
export function publishVercelCommand(root, projectName) {
|
|
23
|
+
const args = ['deploy', '--prod', '--yes', '--project', projectName];
|
|
24
|
+
const vercel = localBin(root, 'vercel');
|
|
25
|
+
if (vercel)
|
|
26
|
+
return { command: vercel, args };
|
|
27
|
+
return { command: 'npx', args: ['vercel', ...args] };
|
|
28
|
+
}
|
|
29
|
+
function vercelHostname(config, fallback) {
|
|
30
|
+
const publication = publicationConfig(config);
|
|
31
|
+
const domains = publicationDomains(config);
|
|
32
|
+
const hostname = fallback ||
|
|
33
|
+
domains.primary ||
|
|
34
|
+
publication.hostname ||
|
|
35
|
+
publication.domain ||
|
|
36
|
+
publication.url;
|
|
37
|
+
return typeof hostname === 'string' ? hostname : '';
|
|
38
|
+
}
|
|
39
|
+
export function publishVercel(input) {
|
|
40
|
+
const options = splitPublishArgs(input);
|
|
41
|
+
const setup = publishInitVercel([
|
|
42
|
+
'--force',
|
|
43
|
+
'--config',
|
|
44
|
+
options.configFile,
|
|
45
|
+
...(options.hostname ? ['--hostname', options.hostname] : []),
|
|
46
|
+
options.targetPath,
|
|
47
|
+
]);
|
|
48
|
+
const { root } = setup;
|
|
49
|
+
const packagePath = packageJsonPath(root);
|
|
50
|
+
if (!existsSync(packagePath))
|
|
51
|
+
throw new Error(`No package.json found next to ${setup.configPath}`);
|
|
52
|
+
const pkg = readJson(packagePath);
|
|
53
|
+
if (options.build)
|
|
54
|
+
runVercelCommand(root, publishBuildCommand(root, pkg), options);
|
|
55
|
+
const publication = publicationConfig(setup.config);
|
|
56
|
+
const projectName = typeof publication.projectName === 'string'
|
|
57
|
+
? publication.projectName
|
|
58
|
+
: 'kennel-docs';
|
|
59
|
+
if (options.deploy)
|
|
60
|
+
runVercelCommand(root, publishVercelCommand(root, projectName), options);
|
|
61
|
+
const hostname = vercelHostname(setup.config, setup.hostname);
|
|
62
|
+
if (hostname && !options.skipTest)
|
|
63
|
+
runStaticHttpTest(root, hostname, options);
|
|
64
|
+
const url = publishTestUrl(hostname);
|
|
65
|
+
if (url)
|
|
66
|
+
console.log(`url ${url}`);
|
|
67
|
+
}
|
package/dist/mcp/config.js
CHANGED
|
@@ -152,6 +152,18 @@ function toolPacks(config) {
|
|
|
152
152
|
return undefined;
|
|
153
153
|
return mcp.toolPacks;
|
|
154
154
|
}
|
|
155
|
+
function toolCatalog(config) {
|
|
156
|
+
const mcp = runtimeMcpConfig(config);
|
|
157
|
+
if (!isObject(mcp.toolCatalog))
|
|
158
|
+
return undefined;
|
|
159
|
+
return mcp.toolCatalog;
|
|
160
|
+
}
|
|
161
|
+
function docs(config) {
|
|
162
|
+
const mcp = runtimeMcpConfig(config);
|
|
163
|
+
if (!isObject(mcp.docs))
|
|
164
|
+
return undefined;
|
|
165
|
+
return mcp.docs;
|
|
166
|
+
}
|
|
155
167
|
export function serverConfig(config) {
|
|
156
168
|
const mcp = runtimeMcpConfig(config);
|
|
157
169
|
const serverName = String(mcp.serverName ?? config.name ?? 'index');
|
|
@@ -159,11 +171,13 @@ export function serverConfig(config) {
|
|
|
159
171
|
...(access(config) ? { access: access(config) } : {}),
|
|
160
172
|
...(isObject(mcp.analytics) ? { analytics: mcp.analytics } : {}),
|
|
161
173
|
...(isObject(mcp.conversationSnapshots) ? { conversationSnapshots: mcp.conversationSnapshots } : {}),
|
|
174
|
+
...(docs(config) ? { docs: docs(config) } : {}),
|
|
162
175
|
instructions: typeof mcp.instructions === 'string' && mcp.instructions.trim()
|
|
163
176
|
? mcp.instructions.trim()
|
|
164
177
|
: "Find relevant Index documents and repo entries for the user's topic. Use search_index_docs and search_index_repos for topic lookup, then read index://doc/{slug} or index://repo/{name} when more detail is needed.",
|
|
165
178
|
name: mcp.runtimeName ?? `${serverName}-mcp`,
|
|
166
179
|
...(repoIntegrations(config) ? { repoIntegrations: repoIntegrations(config) } : {}),
|
|
180
|
+
...(toolCatalog(config) ? { toolCatalog: toolCatalog(config) } : {}),
|
|
167
181
|
toolAliases: toolAliases(config),
|
|
168
182
|
...(toolPacks(config) ? { toolPacks: toolPacks(config) } : {}),
|
|
169
183
|
version: mcp.version ?? '1.0.0',
|
|
@@ -16,7 +16,7 @@ export function mcpFunctionSource(options) {
|
|
|
16
16
|
].join(', ')}];\n`
|
|
17
17
|
: '';
|
|
18
18
|
const customToolOption = customToolNames.length || toolModuleNames.length ? ', customTools' : '';
|
|
19
|
-
return `import { createMcpHttpHandler } from "@raggle-ai/kennel
|
|
19
|
+
return `import { createMcpHttpHandler } from "@raggle-ai/kennel/mcp";
|
|
20
20
|
import data from "./_generated/mcp-data.json";
|
|
21
21
|
${customToolImports ? `${customToolImports}\n` : ''}${toolModuleImports ? `${toolModuleImports}\n` : ''}
|
|
22
22
|
|
|
@@ -24,8 +24,10 @@ const serverConfig = ${JSON.stringify(options.serverConfig, null, 2)} as {
|
|
|
24
24
|
access?: Record<string, unknown>;
|
|
25
25
|
analytics?: Record<string, unknown>;
|
|
26
26
|
conversationSnapshots?: Record<string, unknown>;
|
|
27
|
+
docs?: Record<string, unknown>;
|
|
27
28
|
instructions: string;
|
|
28
29
|
name: string;
|
|
30
|
+
toolCatalog?: Record<string, unknown>;
|
|
29
31
|
toolAliases: Record<string, string>;
|
|
30
32
|
toolPacks?: Record<string, unknown>;
|
|
31
33
|
version: string;
|
package/dist/mcp/generate.js
CHANGED
|
@@ -22,11 +22,11 @@ export async function generateMcp(input) {
|
|
|
22
22
|
};
|
|
23
23
|
const agentDirectory = agentToolsDirectory(config);
|
|
24
24
|
const agentTools = agentDirectory ? collectAgentTools(root, agentDirectory) : [];
|
|
25
|
-
const { docs, health, repos } = collectMcpData(root, dataConfig);
|
|
25
|
+
const { docs, health, records, repos, sources } = collectMcpData(root, dataConfig);
|
|
26
26
|
const target = outputPath(root, config);
|
|
27
27
|
mkdirSync(dirname(target), { recursive: true });
|
|
28
|
-
writeMcpData(target, docs, repos, agentTools, health);
|
|
29
|
-
console.log(`ok ${relative(root, target)} (${docs.length} docs, ${repos.length} repos, ${agentTools.length} agent tools)`);
|
|
28
|
+
writeMcpData(target, docs, repos, agentTools, health, records, sources);
|
|
29
|
+
console.log(`ok ${relative(root, target)} (${docs.length} docs, ${repos.length} repos, ${agentTools.length} agent tools, ${records.length} records, ${sources.length} sources)`);
|
|
30
30
|
}
|
|
31
31
|
if (!options.dataOnly) {
|
|
32
32
|
const target = functionPath(root, config);
|
|
@@ -1 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import { installPageLink, installPageMarkdownPath, renderInstallPage } from '@raggle-ai/kennel-knowledge/install-page';
|
|
2
|
+
export { installPageLink, installPageMarkdownPath, renderInstallPage, };
|
|
3
|
+
export type InstallModel = {
|
|
4
|
+
description: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
installMarkdownUrl?: string;
|
|
7
|
+
protectedUrl?: string;
|
|
8
|
+
publicUrl: string;
|
|
9
|
+
serverName: string;
|
|
10
|
+
tools: string[];
|
|
11
|
+
};
|
|
12
|
+
export declare function writeInstallPage(root: string, config: Record<string, unknown>): string | undefined;
|