@lovinka/deployik-mcp 0.1.0 → 0.1.4
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 +35 -10
- package/dist/client/http.js +36 -0
- package/dist/client/http.js.map +1 -1
- package/dist/config/audit.js +12 -1
- package/dist/config/audit.js.map +1 -1
- package/dist/config/binding.js +85 -18
- package/dist/config/binding.js.map +1 -1
- package/dist/config/cache.js +9 -1
- package/dist/config/cache.js.map +1 -1
- package/dist/index.js +40 -1
- package/dist/index.js.map +1 -1
- package/dist/install-skill.js +50 -0
- package/dist/install-skill.js.map +1 -0
- package/dist/lib/normalize.js +60 -0
- package/dist/lib/normalize.js.map +1 -0
- package/dist/resolve/project.js +26 -6
- package/dist/resolve/project.js.map +1 -1
- package/dist/server.js +3 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/_helpers.js +5 -1
- package/dist/tools/_helpers.js.map +1 -1
- package/dist/tools/env.js +17 -12
- package/dist/tools/env.js.map +1 -1
- package/dist/tools/help.js +120 -0
- package/dist/tools/help.js.map +1 -1
- package/dist/tools/secrets.js +17 -12
- package/dist/tools/secrets.js.map +1 -1
- package/dist/tools/workflows.js +176 -24
- package/dist/tools/workflows.js.map +1 -1
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -28,10 +28,21 @@ For a VPN-only deployment, point `DEPLOYIK_URL` at any reachable host (`http://1
|
|
|
28
28
|
## What it does
|
|
29
29
|
|
|
30
30
|
- **~32 thin tools** — one per Deployik HTTP endpoint (projects, deployments, env vars, secrets, domains, auto-build, password protection, volumes, analytics, email, workspaces, tokens, GitHub).
|
|
31
|
-
- **
|
|
32
|
-
- **Bundled knowledge** — Deployik's how-to recipes ship as MCP prompts (`deployik_recipe_*`)
|
|
33
|
-
- **Repo binding** — `
|
|
31
|
+
- **12 workflow tools** — `setup_project_from_repo`, `deploy_project`, `set_secret`, `tail_latest_logs`, `debug_failed_deployment`, `get_project_health`, `init_in_repo`, `whats_my_url`, `whats_broken`, `redeploy`, and more.
|
|
32
|
+
- **Bundled knowledge** — Deployik's how-to recipes ship as MCP prompts (`deployik_recipe_*`), plus three tools: `list_recipes`, `get_recipe(topic)`, and **`find_help(question)`** which routes free-form English ("where do I set the Stripe key for the live site?") to the right recipe automatically.
|
|
33
|
+
- **Repo binding** — first call inside a git repo with a unique-match `origin` auto-writes `.deployik.json` (committed, just project + workspace + schema URL) and gitignores the private `.deployik/` directory. Self-healing `.gitignore`.
|
|
34
34
|
- **Tiered safety** — destructive operations require `confirm: true`; production-touching operations also require `confirm_name: <project>`. Every destructive call is logged to `.deployik/audit.log`.
|
|
35
|
+
- **Loose English** — `prod` / `live` / `staging` / `dev` / `both` / `everywhere` all normalize to the right scope automatically.
|
|
36
|
+
|
|
37
|
+
## Also: install the Deployik skill into Claude Code
|
|
38
|
+
|
|
39
|
+
For Claude Code users who want the recipes available via `/skills` (independent of any MCP tool call):
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx -y @lovinka/deployik-mcp install-skill
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This copies `SKILL.md` + `click-paths.md` + `api-actions.md` into `~/.claude/skills/deployik-howto/`. Add `--yes` to skip the confirmation prompt. Run it any time you upgrade the package to refresh the recipes.
|
|
35
46
|
|
|
36
47
|
## Local development
|
|
37
48
|
|
|
@@ -46,14 +57,28 @@ Test against a local Deployik dev server with `DEPLOYIK_URL=http://127.0.0.1:808
|
|
|
46
57
|
|
|
47
58
|
## Files written on the host
|
|
48
59
|
|
|
49
|
-
|
|
60
|
+
Project ↔ repo state is split into two layers — **public** (commit it) and
|
|
61
|
+
**private** (gitignored, per developer):
|
|
50
62
|
|
|
51
63
|
```
|
|
52
|
-
|
|
53
|
-
├──
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
└──
|
|
64
|
+
<repo-root>/
|
|
65
|
+
├── .deployik.json PUBLIC, commit this. Just { project, workspace, $schema }.
|
|
66
|
+
│ Teammates pulling your repo immediately know which
|
|
67
|
+
│ Deployik project this folder deploys to.
|
|
68
|
+
└── .deployik/ PRIVATE. Auto-added to .gitignore (and re-added on every
|
|
69
|
+
MCP call if a teammate clobbers the .gitignore line).
|
|
70
|
+
├── cache.json Project + workspace list (1h TTL).
|
|
71
|
+
├── token Optional token fallback (mode 0600) — only used if
|
|
72
|
+
DEPLOYIK_TOKEN env var is unset.
|
|
73
|
+
└── audit.log Append-only ledger of destructive calls (secret values
|
|
74
|
+
redacted automatically).
|
|
57
75
|
```
|
|
58
76
|
|
|
59
|
-
|
|
77
|
+
**Automatic binding**: the first time you run any tool inside a git repo whose
|
|
78
|
+
`origin` remote uniquely matches one Deployik project, the MCP writes
|
|
79
|
+
`.deployik.json` silently — no explicit setup needed. If multiple projects
|
|
80
|
+
deploy the same repo (monorepos with several Deployik apps), the MCP returns a
|
|
81
|
+
friendly "which one?" with the candidate slugs.
|
|
82
|
+
|
|
83
|
+
**Manual binding** (also fine): "deployik bind this repo to forge-kpmg" → the
|
|
84
|
+
AI calls `init_in_repo({ project: "forge-kpmg" })` and writes `.deployik.json`.
|
package/dist/client/http.js
CHANGED
|
@@ -13,6 +13,29 @@ export class DeployikClient {
|
|
|
13
13
|
this.userAgent = opts.userAgent ?? "deployik-mcp/0.1.0";
|
|
14
14
|
}
|
|
15
15
|
async request(path, opts = {}) {
|
|
16
|
+
// Transient 5xx (commonly SQLITE_BUSY on the Deployik server during a live
|
|
17
|
+
// build pipeline) are auto-retried with exponential backoff. Idempotent
|
|
18
|
+
// methods (GET, PUT, DELETE) and the env/secret upsert POST endpoints are
|
|
19
|
+
// safe to retry — they all use ON CONFLICT or full-set replacement.
|
|
20
|
+
const method = opts.method ?? "GET";
|
|
21
|
+
const maxAttempts = retryableMethod(method, path) ? 4 : 1;
|
|
22
|
+
let lastErr;
|
|
23
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
24
|
+
try {
|
|
25
|
+
return await this.requestOnce(path, opts);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
if (err instanceof ApiError && err.status >= 500 && err.status < 600 && attempt < maxAttempts) {
|
|
29
|
+
lastErr = err;
|
|
30
|
+
await sleep(Math.min(150 * 2 ** (attempt - 1), 1500));
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
throw err;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
throw lastErr;
|
|
37
|
+
}
|
|
38
|
+
async requestOnce(path, opts) {
|
|
16
39
|
const url = this.buildUrl(path, opts.query);
|
|
17
40
|
const headers = {
|
|
18
41
|
Authorization: `Bearer ${this.token}`,
|
|
@@ -103,4 +126,17 @@ export class DeployikClient {
|
|
|
103
126
|
return `${this.baseUrl}/api/deployments/${encodeURIComponent(deploymentId)}/screenshot`;
|
|
104
127
|
}
|
|
105
128
|
}
|
|
129
|
+
function retryableMethod(method, path) {
|
|
130
|
+
// GET / PUT / DELETE are HTTP-idempotent.
|
|
131
|
+
if (method === "GET" || method === "PUT" || method === "DELETE")
|
|
132
|
+
return true;
|
|
133
|
+
// The Deployik env/secret single-upsert POST endpoints are application-level
|
|
134
|
+
// idempotent (UPSERT with ON CONFLICT) so retrying a transient 5xx is safe.
|
|
135
|
+
if (method === "POST" && /\/env\b|\/secrets\b/.test(path) && !path.endsWith("/test-smtp"))
|
|
136
|
+
return true;
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
function sleep(ms) {
|
|
140
|
+
return new Promise((res) => setTimeout(res, ms));
|
|
141
|
+
}
|
|
106
142
|
//# sourceMappingURL=http.js.map
|
package/dist/client/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/client/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAqBtD,MAAM,OAAO,cAAc;IAChB,OAAO,CAAS;IACR,KAAK,CAAS;IACd,SAAS,CAAS;IAClB,SAAS,CAAe;IACxB,SAAS,CAAS;IAEnC,YAAY,IAA2B;QACrC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,oBAAoB,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,OAAO,CAAI,IAAY,EAAE,OAAuB,EAAE;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,OAAO,GAA2B;YACtC,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;YACrC,MAAM,EAAE,kBAAkB;YAC1B,YAAY,EAAE,IAAI,CAAC,SAAS;SAC7B,CAAC;QACF,MAAM,IAAI,GAAgB;YACxB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;YAC5B,OAAO;SACR,CAAC;QACF,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC7C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACrE,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;QAEhC,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACtD,MAAM,IAAI,QAAQ,CAAC;oBACjB,MAAM,EAAE,CAAC;oBACT,QAAQ,EAAE,IAAI;oBACd,IAAI,EAAE,IAAI;oBACV,OAAO,EAAE,2BAA2B,IAAI,CAAC,SAAS,OAAO,IAAI,EAAE;oBAC/D,IAAI,EAAE,qHAAqH;iBAC5H,CAAC,CAAC;YACL,CAAC;YACD,MAAM,IAAI,QAAQ,CAAC;gBACjB,MAAM,EAAE,CAAC;gBACT,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,yBAAyB,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE;gBACnE,IAAI,EAAE,yEAAyE;aAChF,CAAC,CAAC;QACL,CAAC;QACD,YAAY,CAAC,OAAO,CAAC,CAAC;QAEtB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,MAAM,GAAY,IAAI,CAAC;QAC3B,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,GAAG,IAAI,CAAC;YAChB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,+DAA+D;YACjE,CAAC;YACD,MAAM,MAAM,GACV,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAK,MAAkC,CAAC,KAAK,CAAC;gBACnF,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAK,MAAkC,CAAC,OAAO,CAAC;gBACrF,IAAI;gBACJ,mBAAmB,QAAQ,CAAC,MAAM,GAAG,CAAC;YACxC,MAAM,IAAI,QAAQ,CAAC;gBACjB,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;gBACvB,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;aAC3C,CAAC,CAAC;QACL,CAAC;QAED,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,SAAc,CAAC;QAC3C,OAAO,MAAW,CAAC;IACrB,CAAC;IAED,QAAQ,CAAC,IAAY,EAAE,KAA+B;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QAC5D,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,UAAU,EAAE,EAAE,CAAC;QACnG,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI;gBAAE,SAAS;YAC5C,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3B,CAAC;QACD,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACrC,CAAC;IAED,wDAAwD;IACxD,aAAa,CAAC,YAAoB;QAChC,OAAO,GAAG,IAAI,CAAC,OAAO,oBAAoB,kBAAkB,CAAC,YAAY,CAAC,aAAa,CAAC;IAC1F,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/client/http.ts"],"names":[],"mappings":"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"}
|
package/dist/config/audit.js
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { appendFileSync, mkdirSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { ensureGitignore } from "./binding.js";
|
|
4
|
+
function reaffirmGitignore(stateDir) {
|
|
5
|
+
// The state dir lives at <cwd>/.deployik — the cwd is its parent.
|
|
6
|
+
try {
|
|
7
|
+
ensureGitignore(dirname(stateDir));
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
// best-effort; never block the write
|
|
11
|
+
}
|
|
12
|
+
}
|
|
3
13
|
const AUDIT_FILE = "audit.log";
|
|
4
14
|
const SECRET_KEYS = new Set([
|
|
5
15
|
"value",
|
|
@@ -34,6 +44,7 @@ export function redact(args) {
|
|
|
34
44
|
export function appendAudit(stateDir, entry) {
|
|
35
45
|
try {
|
|
36
46
|
mkdirSync(stateDir, { recursive: true });
|
|
47
|
+
reaffirmGitignore(stateDir);
|
|
37
48
|
appendFileSync(join(stateDir, AUDIT_FILE), `${JSON.stringify(entry)}\n`, "utf8");
|
|
38
49
|
}
|
|
39
50
|
catch {
|
package/dist/config/audit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/config/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/config/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,SAAS,iBAAiB,CAAC,QAAgB;IACzC,kEAAkE;IAClE,IAAI,CAAC;QACH,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;IACvC,CAAC;AACH,CAAC;AAYD,MAAM,UAAU,GAAG,WAAW,CAAC;AAE/B,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IAC1B,OAAO;IACP,QAAQ;IACR,UAAU;IACV,OAAO;IACP,sBAAsB;IACtB,eAAe;IACf,gBAAgB;CACjB,CAAC,CAAC;AAEH,MAAM,UAAU,MAAM,CAAC,IAA6B;IAClD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACvB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1C,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,CAAC;iBAAM,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC3B,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;YACjB,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAA4B,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,KAAiB;IAC7D,IAAI,CAAC;QACH,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC5B,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;IACzD,CAAC;AACH,CAAC"}
|
package/dist/config/binding.js
CHANGED
|
@@ -1,30 +1,75 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
|
-
const
|
|
3
|
+
const PUBLIC_FILE = ".deployik.json";
|
|
4
|
+
const PUBLIC_SCHEMA = "https://lovinka.com/schemas/deployik.json";
|
|
4
5
|
const GITIGNORE_LINE = ".deployik/";
|
|
5
|
-
export function
|
|
6
|
-
return join(
|
|
6
|
+
export function publicConfigPath(cwd) {
|
|
7
|
+
return join(cwd, PUBLIC_FILE);
|
|
7
8
|
}
|
|
8
|
-
export function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
export function legacyBindingPath(stateDir) {
|
|
10
|
+
return join(stateDir, "binding.json");
|
|
11
|
+
}
|
|
12
|
+
export function readBinding(stateDir, cwd) {
|
|
13
|
+
// Prefer the public, committed config at repo root.
|
|
14
|
+
if (cwd) {
|
|
15
|
+
const publicPath = publicConfigPath(cwd);
|
|
16
|
+
if (existsSync(publicPath)) {
|
|
17
|
+
try {
|
|
18
|
+
const raw = readFileSync(publicPath, "utf8");
|
|
19
|
+
const parsed = JSON.parse(raw);
|
|
20
|
+
if (parsed && typeof parsed.project === "string") {
|
|
21
|
+
return {
|
|
22
|
+
project: parsed.project,
|
|
23
|
+
workspace: parsed.workspace,
|
|
24
|
+
defaultEnvironment: parsed.defaultEnvironment,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// fall through to legacy
|
|
30
|
+
}
|
|
31
|
+
}
|
|
18
32
|
}
|
|
19
|
-
|
|
20
|
-
|
|
33
|
+
// Fallback: legacy private binding for repos that bound under the old layout.
|
|
34
|
+
const legacy = legacyBindingPath(stateDir);
|
|
35
|
+
if (existsSync(legacy)) {
|
|
36
|
+
try {
|
|
37
|
+
const raw = readFileSync(legacy, "utf8");
|
|
38
|
+
const parsed = JSON.parse(raw);
|
|
39
|
+
if (!parsed || typeof parsed.project !== "string")
|
|
40
|
+
return undefined;
|
|
41
|
+
return parsed;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
21
46
|
}
|
|
47
|
+
return undefined;
|
|
22
48
|
}
|
|
23
|
-
export function writeBinding(stateDir, binding) {
|
|
49
|
+
export function writeBinding(stateDir, cwd, binding) {
|
|
50
|
+
// Always write to the public, committed file.
|
|
51
|
+
const payload = {
|
|
52
|
+
$schema: PUBLIC_SCHEMA,
|
|
53
|
+
project: binding.project,
|
|
54
|
+
...(binding.workspace ? { workspace: binding.workspace } : {}),
|
|
55
|
+
...(binding.defaultEnvironment ? { defaultEnvironment: binding.defaultEnvironment } : {}),
|
|
56
|
+
};
|
|
57
|
+
writeFileSync(publicConfigPath(cwd), `${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
|
58
|
+
// Always (re-)ensure the gitignore protects the private dir, even if the
|
|
59
|
+
// .deployik.json itself is committed. Cheap, defensive — if a teammate
|
|
60
|
+
// dropped the line, the next MCP call patches it back.
|
|
61
|
+
ensureGitignore(cwd);
|
|
62
|
+
// Make sure the private state dir exists so cache.json / token / audit.log
|
|
63
|
+
// have a home, but don't touch the legacy binding file — that stays for
|
|
64
|
+
// backwards compat only.
|
|
24
65
|
mkdirSync(stateDir, { recursive: true });
|
|
25
|
-
writeFileSync(bindingPath(stateDir), `${JSON.stringify(binding, null, 2)}\n`, "utf8");
|
|
26
66
|
}
|
|
27
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* Append `.deployik/` to .gitignore if absent. Idempotent. Returns true if a
|
|
69
|
+
* line was added. Called on every binding write so the protection is
|
|
70
|
+
* self-healing (teammate edits, merge conflicts, manual deletes — all fixed
|
|
71
|
+
* silently next time anything touches `.deployik/`).
|
|
72
|
+
*/
|
|
28
73
|
export function ensureGitignore(cwd) {
|
|
29
74
|
const gitignorePath = join(cwd, ".gitignore");
|
|
30
75
|
if (!existsSync(dirname(gitignorePath)))
|
|
@@ -41,4 +86,26 @@ export function ensureGitignore(cwd) {
|
|
|
41
86
|
appendFileSync(gitignorePath, `${prefix}${GITIGNORE_LINE}\n`, "utf8");
|
|
42
87
|
return true;
|
|
43
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Verify the public config is sane. Used by `show_binding`-style tools to
|
|
91
|
+
* surface schema issues that would otherwise look like "binding missing".
|
|
92
|
+
*/
|
|
93
|
+
export function validatePublicConfig(cwd) {
|
|
94
|
+
const path = publicConfigPath(cwd);
|
|
95
|
+
if (!existsSync(path))
|
|
96
|
+
return { ok: false, reason: "missing" };
|
|
97
|
+
try {
|
|
98
|
+
const raw = readFileSync(path, "utf8");
|
|
99
|
+
const parsed = JSON.parse(raw);
|
|
100
|
+
if (!parsed || typeof parsed !== "object")
|
|
101
|
+
return { ok: false, reason: "not an object" };
|
|
102
|
+
if (typeof parsed.project !== "string" || parsed.project.length === 0) {
|
|
103
|
+
return { ok: false, reason: "missing 'project' string" };
|
|
104
|
+
}
|
|
105
|
+
return { ok: true };
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
return { ok: false, reason: `parse error: ${err.message}` };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
44
111
|
//# sourceMappingURL=binding.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../../src/config/binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC7F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../../src/config/binding.ts"],"names":[],"mappings":"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"}
|
package/dist/config/cache.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { ensureGitignore } from "./binding.js";
|
|
3
4
|
const CACHE_FILE = "cache.json";
|
|
4
5
|
const DEFAULT_TTL_SECONDS = 60 * 60; // 1h
|
|
5
6
|
export function cachePath(stateDir) {
|
|
@@ -22,6 +23,13 @@ export function readCache(stateDir) {
|
|
|
22
23
|
}
|
|
23
24
|
export function writeCache(stateDir, data) {
|
|
24
25
|
mkdirSync(stateDir, { recursive: true });
|
|
26
|
+
// Self-heal .gitignore on every cache write — cheap, defensive.
|
|
27
|
+
try {
|
|
28
|
+
ensureGitignore(dirname(stateDir));
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// best-effort
|
|
32
|
+
}
|
|
25
33
|
const full = {
|
|
26
34
|
version: 1,
|
|
27
35
|
fetchedAt: new Date().toISOString(),
|
package/dist/config/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/config/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/config/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAyB/C,MAAM,UAAU,GAAG,YAAY,CAAC;AAChC,MAAM,mBAAmB,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK;AAE1C,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,OAAO,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;QAC5C,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,IAAuF;IAClI,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,gEAAgE;IAChE,IAAI,CAAC;QACH,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;IACD,MAAM,IAAI,GAAc;QACtB,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,mBAAmB;QAClD,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC;IACF,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACjF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAA4B;IACvD,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;AACxD,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,12 +2,51 @@
|
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
import { buildServer } from "./server.js";
|
|
4
4
|
import { ConfigError } from "./config/env.js";
|
|
5
|
+
import { installSkill } from "./install-skill.js";
|
|
6
|
+
import { VERSION } from "./version.js";
|
|
7
|
+
const HELP = `deployik-mcp ${VERSION}
|
|
8
|
+
|
|
9
|
+
USAGE
|
|
10
|
+
deployik-mcp Start the MCP server over stdio (default).
|
|
11
|
+
deployik-mcp install-skill Copy the bundled Deployik how-to recipes to
|
|
12
|
+
~/.claude/skills/deployik-howto/ so Claude
|
|
13
|
+
Code surfaces them as a regular skill.
|
|
14
|
+
Pass --yes / -y to skip the confirmation.
|
|
15
|
+
deployik-mcp --help, -h Show this message.
|
|
16
|
+
deployik-mcp --version, -v Print version and exit.
|
|
17
|
+
|
|
18
|
+
ENVIRONMENT
|
|
19
|
+
DEPLOYIK_URL Base URL of your Deployik instance
|
|
20
|
+
(e.g. https://deployik.lovinka.com).
|
|
21
|
+
DEPLOYIK_TOKEN Personal Access Token (dpk_...). If unset,
|
|
22
|
+
falls back to ./.deployik/token if present.
|
|
23
|
+
DEPLOYIK_TIMEOUT_MS Per-request timeout in ms (default 30000).
|
|
24
|
+
`;
|
|
5
25
|
async function main() {
|
|
26
|
+
const argv = process.argv.slice(2);
|
|
27
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
28
|
+
process.stdout.write(HELP);
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
if (argv.includes("--version") || argv.includes("-v")) {
|
|
32
|
+
process.stdout.write(`${VERSION}\n`);
|
|
33
|
+
process.exit(0);
|
|
34
|
+
}
|
|
35
|
+
const sub = argv[0];
|
|
36
|
+
if (sub === "install-skill") {
|
|
37
|
+
const yes = argv.includes("--yes") || argv.includes("-y");
|
|
38
|
+
const code = await installSkill({ yes });
|
|
39
|
+
process.exit(code);
|
|
40
|
+
}
|
|
41
|
+
if (sub && !sub.startsWith("-")) {
|
|
42
|
+
process.stderr.write(`Unknown subcommand: ${sub}\nRun \`deployik-mcp --help\` for usage.\n`);
|
|
43
|
+
process.exit(2);
|
|
44
|
+
}
|
|
6
45
|
try {
|
|
7
46
|
const { server } = buildServer();
|
|
8
47
|
const transport = new StdioServerTransport();
|
|
9
48
|
await server.connect(transport);
|
|
10
|
-
process.stderr.write(
|
|
49
|
+
process.stderr.write(`deployik-mcp ${VERSION} ready (stdio)\n`);
|
|
11
50
|
}
|
|
12
51
|
catch (err) {
|
|
13
52
|
if (err instanceof ConfigError) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,IAAI,GAAG,gBAAgB,OAAO;;;;;;;;;;;;;;;;;CAiBnC,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,GAAG,KAAK,eAAe,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,GAAG,4CAA4C,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,OAAO,kBAAkB,CAAC,CAAC;IAClE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;YAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAkB,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// `deployik-mcp install-skill` — write the bundled Deployik knowledge into
|
|
2
|
+
// Claude Code's skills directory so the same recipes the MCP serves are also
|
|
3
|
+
// available as a regular `/skills/deployik-howto` skill that fires
|
|
4
|
+
// independently of any MCP tool call (e.g. when the user is reading a doc and
|
|
5
|
+
// types `/skills`).
|
|
6
|
+
//
|
|
7
|
+
// Idempotent. Asks for confirmation unless --yes is passed.
|
|
8
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
9
|
+
import { homedir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { createInterface } from "node:readline";
|
|
12
|
+
import { RECIPE_FILES } from "./knowledge/recipes.generated.js";
|
|
13
|
+
export async function installSkill(opts) {
|
|
14
|
+
const base = opts.destBase ?? join(homedir(), ".claude", "skills");
|
|
15
|
+
const target = join(base, "deployik-howto");
|
|
16
|
+
if (!RECIPE_FILES.length) {
|
|
17
|
+
process.stderr.write(`No bundled recipes found in this build.\n`);
|
|
18
|
+
return 1;
|
|
19
|
+
}
|
|
20
|
+
process.stdout.write(`This will write ${RECIPE_FILES.length} files to:\n ${target}\n`);
|
|
21
|
+
for (const f of RECIPE_FILES)
|
|
22
|
+
process.stdout.write(` - ${f.file}\n`);
|
|
23
|
+
if (existsSync(target)) {
|
|
24
|
+
process.stdout.write(`\nNote: '${target}' already exists. Files will be overwritten.\n`);
|
|
25
|
+
}
|
|
26
|
+
if (!opts.yes) {
|
|
27
|
+
const ok = await promptYesNo("\nProceed? [y/N] ");
|
|
28
|
+
if (!ok) {
|
|
29
|
+
process.stdout.write("Aborted. To skip the prompt next time, pass --yes.\n");
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
mkdirSync(target, { recursive: true });
|
|
34
|
+
for (const f of RECIPE_FILES) {
|
|
35
|
+
writeFileSync(join(target, f.file), f.content, "utf8");
|
|
36
|
+
}
|
|
37
|
+
process.stdout.write(`\n✓ Installed Deployik skill to ${target}\n`);
|
|
38
|
+
process.stdout.write(` Test it: in Claude Code, type /skills and look for 'deployik-howto'.\n`);
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
function promptYesNo(prompt) {
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
44
|
+
rl.question(prompt, (answer) => {
|
|
45
|
+
rl.close();
|
|
46
|
+
resolve(/^y(es)?$/i.test(answer.trim()));
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=install-skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-skill.js","sourceRoot":"","sources":["../src/install-skill.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAC7E,mEAAmE;AACnE,8EAA8E;AAC9E,oBAAoB;AACpB,EAAE;AACF,4DAA4D;AAE5D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAOhE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAiB;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IACnE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAE5C,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAClE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,YAAY,CAAC,MAAM,iBAAiB,MAAM,IAAI,CAAC,CAAC;IACxF,KAAK,MAAM,CAAC,IAAI,YAAY;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;IAEtE,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM,gDAAgD,CAAC,CAAC;IAC3F,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACd,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC,mBAAmB,CAAC,CAAC;QAClD,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC7E,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC7B,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,MAAM,IAAI,CAAC,CAAC;IACpE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAC;IACjG,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7E,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAC7B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Normalize user-friendly English inputs into the strict values the Deployik
|
|
2
|
+
// backend expects. Non-technical users say "prod", "live", "main site" — the
|
|
3
|
+
// AI relays those literally. Match them charitably here so a single tool call
|
|
4
|
+
// works without a clarifying round-trip.
|
|
5
|
+
const ENV_ALIASES = {
|
|
6
|
+
production: "production",
|
|
7
|
+
prod: "production",
|
|
8
|
+
live: "production",
|
|
9
|
+
"live site": "production",
|
|
10
|
+
"main site": "production",
|
|
11
|
+
main: "production",
|
|
12
|
+
release: "production",
|
|
13
|
+
public: "production",
|
|
14
|
+
preview: "preview",
|
|
15
|
+
prev: "preview",
|
|
16
|
+
staging: "preview",
|
|
17
|
+
stage: "preview",
|
|
18
|
+
dev: "preview",
|
|
19
|
+
development: "preview",
|
|
20
|
+
test: "preview",
|
|
21
|
+
testing: "preview",
|
|
22
|
+
draft: "preview",
|
|
23
|
+
};
|
|
24
|
+
const SCOPE_ALIASES = {
|
|
25
|
+
...ENV_ALIASES,
|
|
26
|
+
shared: "shared",
|
|
27
|
+
both: "shared",
|
|
28
|
+
all: "shared",
|
|
29
|
+
everywhere: "shared",
|
|
30
|
+
common: "shared",
|
|
31
|
+
global: "shared",
|
|
32
|
+
};
|
|
33
|
+
export function normalizeEnvironment(input) {
|
|
34
|
+
if (!input)
|
|
35
|
+
return undefined;
|
|
36
|
+
const key = input.toLowerCase().trim();
|
|
37
|
+
return ENV_ALIASES[key];
|
|
38
|
+
}
|
|
39
|
+
export function normalizeScope(input) {
|
|
40
|
+
if (!input)
|
|
41
|
+
return undefined;
|
|
42
|
+
const key = input.toLowerCase().trim();
|
|
43
|
+
return SCOPE_ALIASES[key];
|
|
44
|
+
}
|
|
45
|
+
/** When the AI passes a fuzzy environment we want to honor it; throw if no match. */
|
|
46
|
+
export function requireEnvironment(input) {
|
|
47
|
+
const normalized = normalizeEnvironment(input);
|
|
48
|
+
if (!normalized) {
|
|
49
|
+
throw new Error(`Unknown environment '${input}'. Use 'preview' (test / staging / dev) or 'production' (live / public).`);
|
|
50
|
+
}
|
|
51
|
+
return normalized;
|
|
52
|
+
}
|
|
53
|
+
export function requireScope(input) {
|
|
54
|
+
const normalized = normalizeScope(input);
|
|
55
|
+
if (!normalized) {
|
|
56
|
+
throw new Error(`Unknown scope '${input}'. Use 'shared' (both environments), 'preview' (test only), or 'production' (live only).`);
|
|
57
|
+
}
|
|
58
|
+
return normalized;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=normalize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/lib/normalize.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,yCAAyC;AAKzC,MAAM,WAAW,GAAgC;IAC/C,UAAU,EAAE,YAAY;IACxB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,YAAY;IACzB,WAAW,EAAE,YAAY;IACzB,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,SAAS;IAChB,GAAG,EAAE,SAAS;IACd,WAAW,EAAE,SAAS;IACtB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,MAAM,aAAa,GAAkC;IACnD,GAAG,WAAW;IACd,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,QAAQ;IACd,GAAG,EAAE,QAAQ;IACb,UAAU,EAAE,QAAQ;IACpB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;CACjB,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,KAAyB;IAC5D,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IACvC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAyB;IACtD,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IACvC,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,MAAM,UAAU,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,wBAAwB,KAAK,0EAA0E,CACxG,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,kBAAkB,KAAK,0FAA0F,CAClH,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
package/dist/resolve/project.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
|
-
import { readBinding } from "../config/binding.js";
|
|
2
|
+
import { readBinding, writeBinding } from "../config/binding.js";
|
|
3
3
|
import { readCache, writeCache, isCacheFresh } from "../config/cache.js";
|
|
4
4
|
export class ResolveError extends Error {
|
|
5
5
|
hint;
|
|
@@ -24,19 +24,39 @@ export async function resolveProject(ctx, input = {}) {
|
|
|
24
24
|
return { project: match, source: "slug" };
|
|
25
25
|
throw new ResolveError(`No project named '${input.project}' is visible to this token${input.workspace ? ` in workspace '${input.workspace}'` : ""}.`, "Call `list_projects` to see what this token can reach.");
|
|
26
26
|
}
|
|
27
|
-
// 3. binding file
|
|
28
|
-
const binding = readBinding(ctx.stateDir);
|
|
27
|
+
// 3. binding file (public .deployik.json or legacy .deployik/binding.json)
|
|
28
|
+
const binding = readBinding(ctx.stateDir, ctx.cwd);
|
|
29
29
|
if (binding?.project) {
|
|
30
30
|
const match = matchProjectByName(projects, binding.project, binding.workspace);
|
|
31
31
|
if (match)
|
|
32
32
|
return { project: match, source: "binding" };
|
|
33
33
|
}
|
|
34
|
-
// 4. git remote → cached project lookup
|
|
34
|
+
// 4. git remote → cached project lookup, AUTO-BIND if a single unambiguous match
|
|
35
35
|
const remote = readGitRemote(ctx.cwd);
|
|
36
36
|
if (remote) {
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
37
|
+
const matches = projects.filter((p) => p.github_owner.toLowerCase() === remote.owner.toLowerCase() && p.github_repo.toLowerCase() === remote.repo.toLowerCase());
|
|
38
|
+
if (matches.length === 1) {
|
|
39
|
+
const match = matches[0];
|
|
40
|
+
// Self-bind: write .deployik.json so the next call resolves via the
|
|
41
|
+
// binding (cheaper) and so teammates pulling this repo inherit the
|
|
42
|
+
// mapping. Best-effort — never block resolution.
|
|
43
|
+
try {
|
|
44
|
+
writeBinding(ctx.stateDir, ctx.cwd, {
|
|
45
|
+
project: match.name,
|
|
46
|
+
workspace: match.organization_name ?? match.organization_id,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// ignore — fall through to returning the match anyway
|
|
51
|
+
}
|
|
39
52
|
return { project: match, source: "git_remote" };
|
|
53
|
+
}
|
|
54
|
+
// Multiple repos share the same github_owner/github_repo (e.g. several
|
|
55
|
+
// projects deploying different apps from one monorepo) — too ambiguous to
|
|
56
|
+
// auto-bind, but still surface the candidates to help the AI/user.
|
|
57
|
+
if (matches.length > 1) {
|
|
58
|
+
throw new ResolveError(`This repo (${remote.owner}/${remote.repo}) maps to ${matches.length} Deployik projects: ${matches.map((m) => m.name).join(", ")}.`, "Pass `project: <slug>` to disambiguate, or run `init_in_repo` with the slug you want bound.");
|
|
59
|
+
}
|
|
40
60
|
}
|
|
41
61
|
// 5. single project visible
|
|
42
62
|
if (projects.length === 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/resolve/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/resolve/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAsB,MAAM,oBAAoB,CAAC;AAuB7F,MAAM,OAAO,YAAa,SAAQ,KAAK;IACQ;IAA7C,YAAY,OAAe,EAAkB,IAAY;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QAD4B,SAAI,GAAJ,IAAI,CAAQ;QAEvD,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAmB,EAAE,QAAsB,EAAE;IAChF,iBAAiB;IACjB,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAU,aAAa,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACvG,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,uBAAuB;IACvB,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IAE1C,mBAAmB;IACnB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3E,IAAI,KAAK;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACrD,MAAM,IAAI,YAAY,CACpB,qBAAqB,KAAK,CAAC,OAAO,6BAA6B,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAC7H,wDAAwD,CACzD,CAAC;IACJ,CAAC;IAED,2EAA2E;IAC3E,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACnD,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAC/E,IAAI,KAAK;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC1D,CAAC;IAED,iFAAiF;IACjF,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAC7B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAChI,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;YAC1B,oEAAoE;YACpE,mEAAmE;YACnE,iDAAiD;YACjD,IAAI,CAAC;gBACH,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,EAAE;oBAClC,OAAO,EAAE,KAAK,CAAC,IAAI;oBACnB,SAAS,EAAE,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,eAAe;iBAC5D,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,sDAAsD;YACxD,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;QAClD,CAAC;QACD,uEAAuE;QACvE,0EAA0E;QAC1E,mEAAmE;QACnE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,YAAY,CACpB,cAAc,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,aAAa,OAAO,CAAC,MAAM,uBAAuB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EACnI,6FAA6F,CAC9F,CAAC;QACJ,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC/D,CAAC;IAED,MAAM,IAAI,YAAY,CACpB,uDAAuD,EACvD,uGAAuG,CACxG,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAmB;IACrD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAY,WAAW,CAAC,CAAC;IAClE,MAAM,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAClC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAmB,EAAE,QAAmB;IACzE,kEAAkE;IAClE,IAAI,UAAU,GAAmB,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC;YACH,UAAU,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAiB,gBAAgB,CAAC,CAAC;QAC1E,CAAC;QAAC,MAAM,CAAC;YACP,UAAU,GAAG,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC5C,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,QAAQ;gBACzB,aAAa,EAAE,CAAC;gBAChB,UAAU,EAAE,EAAE;gBACd,UAAU,EAAE,EAAE;aACf,CAAC,CAAC,IAAI,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;SAAM,CAAC;QACN,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3C,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,KAAK;YAClB,eAAe,EAAE,QAAQ;YACzB,aAAa,EAAE,CAAC;YAChB,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,EAAE;SACf,CAAC,CAAC,CAAC;IACN,CAAC;IAED,MAAM,MAAM,GAAoB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,SAAS,EAAE,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,eAAe;QACnD,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,WAAW,EAAE,CAAC,CAAC,WAAW;KAC3B,CAAC,CAAC,CAAC;IAEJ,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE;QACvB,QAAQ,EAAE,MAAM;QAChB,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7E,QAAQ,EAAE,QAAQ,EAAE,QAAQ;KAC7B,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAmB,EAAE,IAAY,EAAE,SAAkB;IAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,CAAC;IAC3E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC,CAAC,CAAE,CAAC;IAC7C,IAAI,CAAC,SAAS;QAAE,OAAO,OAAO,CAAC,CAAC,CAAE,CAAC;IACnC,MAAM,EAAE,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC;IACzH,OAAO,OAAO,IAAI,OAAO,CAAC,CAAC,CAAE,CAAC;AAChC,CAAC;AAOD,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,2BAA2B,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzH,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,uEAAuE;IACvE,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACzE,IAAI,GAAG;QAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,CAAC;IAClD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IACnF,IAAI,KAAK;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC;IACxD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -3,17 +3,18 @@ import { DeployikClient } from "./client/http.js";
|
|
|
3
3
|
import { loadEnv } from "./config/env.js";
|
|
4
4
|
import { registerKnowledgePrompts } from "./knowledge/prompts.js";
|
|
5
5
|
import { registerAllTools } from "./tools/index.js";
|
|
6
|
+
import { VERSION } from "./version.js";
|
|
6
7
|
export function buildServer(env = process.env, cwd = process.cwd()) {
|
|
7
8
|
const cfg = loadEnv(env, cwd);
|
|
8
9
|
const client = new DeployikClient({
|
|
9
10
|
baseUrl: cfg.baseUrl,
|
|
10
11
|
token: cfg.token,
|
|
11
12
|
timeoutMs: cfg.timeoutMs,
|
|
12
|
-
userAgent:
|
|
13
|
+
userAgent: `deployik-mcp/${VERSION}`,
|
|
13
14
|
});
|
|
14
15
|
const server = new McpServer({
|
|
15
16
|
name: "deployik",
|
|
16
|
-
version:
|
|
17
|
+
version: VERSION,
|
|
17
18
|
}, {
|
|
18
19
|
capabilities: {
|
|
19
20
|
tools: {},
|