@lovinka/deployik-mcp 0.1.4 → 0.1.6
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 +46 -14
- package/dist/index.js +99 -15
- package/dist/index.js.map +1 -1
- package/dist/install-mcp.js +133 -0
- package/dist/install-mcp.js.map +1 -0
- package/dist/install-skill.js +48 -24
- package/dist/install-skill.js.map +1 -1
- package/dist/install.js +80 -0
- package/dist/install.js.map +1 -0
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,9 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
MCP server for [Deployik](https://github.com/lefteq/lovinka-deployik). Lets any MCP-aware AI drive Deployik end-to-end — create projects, set secrets, trigger deployments, debug failed builds, manage domains — without touching the dashboard.
|
|
4
4
|
|
|
5
|
-
## Install (one-shot
|
|
5
|
+
## Install (one-shot, no JSON editing)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npx -y @lovinka/deployik-mcp install
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Prompts for your Deployik URL and Personal Access Token, then:
|
|
12
|
+
|
|
13
|
+
- Registers the `deployik` MCP server in `~/.claude.json` (Claude Code) **and** the Claude Desktop config (if installed) so every project + every window can use it.
|
|
14
|
+
- Copies the Deployik how-to recipes into `~/.claude/skills/deployik-howto/` so `/skills` surfaces them.
|
|
15
|
+
- Backs up any pre-existing config to `<path>.bak.<timestamp>` before merging.
|
|
16
|
+
|
|
17
|
+
Restart Claude Code / Claude Desktop afterwards.
|
|
18
|
+
|
|
19
|
+
### Scopes
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Global (recommended) — once installed, available everywhere
|
|
23
|
+
npx -y @lovinka/deployik-mcp install --global
|
|
24
|
+
|
|
25
|
+
# Local — writes <cwd>/.mcp.json + <cwd>/.claude/skills/
|
|
26
|
+
# MCP only fires when Claude is opened in this folder
|
|
27
|
+
npx -y @lovinka/deployik-mcp install --local
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Non-interactive
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx -y @lovinka/deployik-mcp install \
|
|
34
|
+
--yes \
|
|
35
|
+
--url=https://deployik.lovinka.com \
|
|
36
|
+
--token=dpk_xxx
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or set `DEPLOYIK_URL` / `DEPLOYIK_TOKEN` env vars and pass `--yes`.
|
|
40
|
+
|
|
41
|
+
### Granular subcommands
|
|
42
|
+
|
|
43
|
+
| Command | What it does |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `install` | MCP registration + skill files (default) |
|
|
46
|
+
| `install-mcp` | MCP registration only |
|
|
47
|
+
| `install-skill` | Skill files only |
|
|
48
|
+
| `uninstall` | Removes the `deployik` MCP entry from every Claude config |
|
|
49
|
+
|
|
50
|
+
### Manual install (if you prefer to edit JSON yourself)
|
|
8
51
|
|
|
9
52
|
```json
|
|
10
53
|
{
|
|
@@ -21,9 +64,7 @@ Add to your MCP client config (Claude Desktop, Claude Code, etc.):
|
|
|
21
64
|
}
|
|
22
65
|
```
|
|
23
66
|
|
|
24
|
-
Get a token at **Account → Access tokens** in Deployik. The token is shown once on creation; copy it then.
|
|
25
|
-
|
|
26
|
-
For a VPN-only deployment, point `DEPLOYIK_URL` at any reachable host (`http://10.x.x.x:8080`, `https://deployik.internal`, etc.).
|
|
67
|
+
Get a token at **Account → Access tokens** in Deployik. The token is shown once on creation; copy it then. For a VPN-only deployment, point `DEPLOYIK_URL` at any reachable host (`http://10.x.x.x:8080`, `https://deployik.internal`, etc.).
|
|
27
68
|
|
|
28
69
|
## What it does
|
|
29
70
|
|
|
@@ -34,15 +75,6 @@ For a VPN-only deployment, point `DEPLOYIK_URL` at any reachable host (`http://1
|
|
|
34
75
|
- **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
76
|
- **Loose English** — `prod` / `live` / `staging` / `dev` / `both` / `everywhere` all normalize to the right scope automatically.
|
|
36
77
|
|
|
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.
|
|
46
78
|
|
|
47
79
|
## Local development
|
|
48
80
|
|
package/dist/index.js
CHANGED
|
@@ -3,25 +3,78 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
3
3
|
import { buildServer } from "./server.js";
|
|
4
4
|
import { ConfigError } from "./config/env.js";
|
|
5
5
|
import { installSkill } from "./install-skill.js";
|
|
6
|
+
import { installMcp, uninstallMcp } from "./install-mcp.js";
|
|
7
|
+
import { installAll } from "./install.js";
|
|
6
8
|
import { VERSION } from "./version.js";
|
|
7
9
|
const HELP = `deployik-mcp ${VERSION}
|
|
8
10
|
|
|
9
11
|
USAGE
|
|
10
|
-
deployik-mcp
|
|
11
|
-
deployik-mcp install
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
deployik-mcp
|
|
16
|
-
|
|
12
|
+
deployik-mcp Start the MCP server over stdio (default).
|
|
13
|
+
deployik-mcp install Register the MCP server in Claude config
|
|
14
|
+
AND copy the bundled skill (recommended).
|
|
15
|
+
deployik-mcp install-mcp Only register the MCP server in Claude config.
|
|
16
|
+
deployik-mcp install-skill Only copy the Deployik skill files.
|
|
17
|
+
deployik-mcp uninstall Remove the 'deployik' MCP server entry from
|
|
18
|
+
every Claude config it lives in.
|
|
19
|
+
deployik-mcp --help, -h Show this message.
|
|
20
|
+
deployik-mcp --version, -v Print version and exit.
|
|
21
|
+
|
|
22
|
+
SCOPES (default: --global)
|
|
23
|
+
--global Install to user-level Claude configs:
|
|
24
|
+
• ~/.claude.json (Claude Code)
|
|
25
|
+
• ~/Library/Application Support/… (Claude Desktop, mac)
|
|
26
|
+
• %APPDATA%/Claude/… (Claude Desktop, win)
|
|
27
|
+
• ~/.config/Claude/… (Claude Desktop, linux)
|
|
28
|
+
Once installed, every project + every
|
|
29
|
+
Claude window has the deployik tools.
|
|
30
|
+
--local Install to the current project only:
|
|
31
|
+
• <cwd>/.mcp.json
|
|
32
|
+
• <cwd>/.claude/skills/deployik-howto/
|
|
33
|
+
|
|
34
|
+
FLAGS
|
|
35
|
+
--yes, -y Skip confirmation prompts (use defaults).
|
|
36
|
+
--url=<url> Deployik URL (default: https://deployik.lovinka.com).
|
|
37
|
+
--token=<dpk_...> Personal Access Token. Required for install
|
|
38
|
+
unless DEPLOYIK_TOKEN env var is set.
|
|
17
39
|
|
|
18
40
|
ENVIRONMENT
|
|
19
|
-
DEPLOYIK_URL
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
41
|
+
DEPLOYIK_URL Used as the URL default when not passed.
|
|
42
|
+
DEPLOYIK_TOKEN Used as the token default when not passed.
|
|
43
|
+
DEPLOYIK_TIMEOUT_MS Per-request timeout in ms (default 30000).
|
|
44
|
+
|
|
45
|
+
EXAMPLES
|
|
46
|
+
npx -y @lovinka/deployik-mcp install
|
|
47
|
+
Interactive global install: prompts for URL + token, writes Claude
|
|
48
|
+
Code + Claude Desktop configs, copies skill files.
|
|
49
|
+
|
|
50
|
+
npx -y @lovinka/deployik-mcp install --yes --token=dpk_xxx
|
|
51
|
+
Non-interactive global install with default URL.
|
|
52
|
+
|
|
53
|
+
npx -y @lovinka/deployik-mcp install --local --token=dpk_xxx
|
|
54
|
+
Project-scoped install: writes .mcp.json + .claude/skills/ in cwd.
|
|
55
|
+
|
|
56
|
+
npx -y @lovinka/deployik-mcp uninstall
|
|
57
|
+
Removes the 'deployik' MCP server entry from every global Claude config.
|
|
24
58
|
`;
|
|
59
|
+
function parseFlags(argv) {
|
|
60
|
+
let scope = "global";
|
|
61
|
+
let yes = false;
|
|
62
|
+
let url;
|
|
63
|
+
let token;
|
|
64
|
+
for (const arg of argv) {
|
|
65
|
+
if (arg === "--global")
|
|
66
|
+
scope = "global";
|
|
67
|
+
else if (arg === "--local")
|
|
68
|
+
scope = "local";
|
|
69
|
+
else if (arg === "--yes" || arg === "-y")
|
|
70
|
+
yes = true;
|
|
71
|
+
else if (arg.startsWith("--url="))
|
|
72
|
+
url = arg.slice("--url=".length);
|
|
73
|
+
else if (arg.startsWith("--token="))
|
|
74
|
+
token = arg.slice("--token=".length);
|
|
75
|
+
}
|
|
76
|
+
return { scope, yes, url, token };
|
|
77
|
+
}
|
|
25
78
|
async function main() {
|
|
26
79
|
const argv = process.argv.slice(2);
|
|
27
80
|
if (argv.includes("--help") || argv.includes("-h")) {
|
|
@@ -33,13 +86,40 @@ async function main() {
|
|
|
33
86
|
process.exit(0);
|
|
34
87
|
}
|
|
35
88
|
const sub = argv[0];
|
|
89
|
+
const rest = argv.slice(1);
|
|
90
|
+
if (sub === "install") {
|
|
91
|
+
const flags = parseFlags(rest);
|
|
92
|
+
const code = await installAll(flags);
|
|
93
|
+
process.exit(code);
|
|
94
|
+
}
|
|
95
|
+
if (sub === "install-mcp") {
|
|
96
|
+
const flags = parseFlags(rest);
|
|
97
|
+
const code = await installAll({ ...flags, skipSkill: true });
|
|
98
|
+
process.exit(code);
|
|
99
|
+
}
|
|
36
100
|
if (sub === "install-skill") {
|
|
37
|
-
const
|
|
38
|
-
const code = await installSkill({ yes });
|
|
101
|
+
const flags = parseFlags(rest);
|
|
102
|
+
const code = await installSkill({ scope: flags.scope, yes: flags.yes });
|
|
39
103
|
process.exit(code);
|
|
40
104
|
}
|
|
105
|
+
if (sub === "uninstall") {
|
|
106
|
+
const flags = parseFlags(rest);
|
|
107
|
+
const res = uninstallMcp({ scope: flags.scope });
|
|
108
|
+
for (const w of res.written)
|
|
109
|
+
process.stdout.write(` ✓ removed from ${w.path}${w.backupPath ? ` (backup → ${w.backupPath})` : ""}\n`);
|
|
110
|
+
for (const s of res.skipped)
|
|
111
|
+
process.stdout.write(` · ${s.path} — ${s.reason}\n`);
|
|
112
|
+
if (res.written.length === 0)
|
|
113
|
+
process.stdout.write(`Nothing removed.\n`);
|
|
114
|
+
process.exit(0);
|
|
115
|
+
}
|
|
41
116
|
if (sub && !sub.startsWith("-")) {
|
|
42
|
-
process.stderr.write(`Unknown subcommand: ${sub}
|
|
117
|
+
process.stderr.write(`Unknown subcommand: ${sub} (this build is @lovinka/deployik-mcp ${VERSION}).\n` +
|
|
118
|
+
`Run \`deployik-mcp --help\` for usage.\n` +
|
|
119
|
+
`\nIf you expected this subcommand to exist, your npx cache may be serving\n` +
|
|
120
|
+
`an old version. Force a refresh with one of:\n` +
|
|
121
|
+
` npx -y @lovinka/deployik-mcp@latest ${sub}\n` +
|
|
122
|
+
` rm -rf ~/.npm/_npx && npx -y @lovinka/deployik-mcp ${sub}\n`);
|
|
43
123
|
process.exit(2);
|
|
44
124
|
}
|
|
45
125
|
try {
|
|
@@ -57,5 +137,9 @@ async function main() {
|
|
|
57
137
|
process.exit(1);
|
|
58
138
|
}
|
|
59
139
|
}
|
|
140
|
+
// `installMcp` is exported from a sibling module for programmatic use; the
|
|
141
|
+
// re-export here keeps the published `dist/index.js` self-contained for
|
|
142
|
+
// scripts that prefer requiring the entry point.
|
|
143
|
+
export { installMcp };
|
|
60
144
|
main();
|
|
61
145
|
//# sourceMappingURL=index.js.map
|
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;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,IAAI,GAAG,gBAAgB,OAAO
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Register the @lovinka/deployik-mcp server in Claude's MCP config so users
|
|
2
|
+
// don't have to hand-edit JSON. Supports two scopes:
|
|
3
|
+
//
|
|
4
|
+
// global — Claude Code's user-level `~/.claude.json` (always) and, if
|
|
5
|
+
// present, Claude Desktop's platform-specific config file. This is
|
|
6
|
+
// the recommended path because once it's set the MCP server is
|
|
7
|
+
// available in every project + every Claude window.
|
|
8
|
+
//
|
|
9
|
+
// local — Project-level `.mcp.json` in the current directory. Newer
|
|
10
|
+
// Claude Code versions auto-pick this up. Useful for a repo where
|
|
11
|
+
// you want to commit a per-project MCP config (e.g. pointed at a
|
|
12
|
+
// preview instance of Deployik).
|
|
13
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from "node:fs";
|
|
14
|
+
import { homedir, platform } from "node:os";
|
|
15
|
+
import { dirname, join, resolve } from "node:path";
|
|
16
|
+
function makeEntry(spec, url, token) {
|
|
17
|
+
return {
|
|
18
|
+
type: "stdio",
|
|
19
|
+
command: "npx",
|
|
20
|
+
args: ["-y", spec],
|
|
21
|
+
env: {
|
|
22
|
+
DEPLOYIK_URL: url,
|
|
23
|
+
DEPLOYIK_TOKEN: token,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The set of config files we know how to write for a given scope. For
|
|
29
|
+
* `global`, we try every install target and include the ones whose parent
|
|
30
|
+
* directory exists (so we don't materialise a Claude Desktop directory on a
|
|
31
|
+
* machine that doesn't have it installed).
|
|
32
|
+
*/
|
|
33
|
+
function targetsFor(scope, cwd) {
|
|
34
|
+
if (scope === "local") {
|
|
35
|
+
return [{ path: resolve(cwd, ".mcp.json"), mustExistDir: false, label: "project .mcp.json" }];
|
|
36
|
+
}
|
|
37
|
+
const home = homedir();
|
|
38
|
+
const out = [
|
|
39
|
+
{ path: join(home, ".claude.json"), mustExistDir: false, label: "Claude Code (~/.claude.json)" },
|
|
40
|
+
];
|
|
41
|
+
if (platform() === "darwin") {
|
|
42
|
+
out.push({
|
|
43
|
+
path: join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json"),
|
|
44
|
+
mustExistDir: true,
|
|
45
|
+
label: "Claude Desktop (macOS)",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
else if (platform() === "win32") {
|
|
49
|
+
const appdata = process.env.APPDATA || join(home, "AppData", "Roaming");
|
|
50
|
+
out.push({
|
|
51
|
+
path: join(appdata, "Claude", "claude_desktop_config.json"),
|
|
52
|
+
mustExistDir: true,
|
|
53
|
+
label: "Claude Desktop (Windows)",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
out.push({
|
|
58
|
+
path: join(home, ".config", "Claude", "claude_desktop_config.json"),
|
|
59
|
+
mustExistDir: true,
|
|
60
|
+
label: "Claude Desktop (Linux)",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
function readConfig(path) {
|
|
66
|
+
if (!existsSync(path))
|
|
67
|
+
return undefined;
|
|
68
|
+
try {
|
|
69
|
+
const raw = readFileSync(path, "utf8").trim();
|
|
70
|
+
if (!raw)
|
|
71
|
+
return {};
|
|
72
|
+
return JSON.parse(raw);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
throw new Error(`Failed to parse ${path} — refusing to overwrite. (${err.message})`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function backup(path) {
|
|
79
|
+
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
80
|
+
const bak = `${path}.bak.${ts}`;
|
|
81
|
+
copyFileSync(path, bak);
|
|
82
|
+
return bak;
|
|
83
|
+
}
|
|
84
|
+
export function installMcp(opts) {
|
|
85
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
86
|
+
const name = opts.name ?? "deployik";
|
|
87
|
+
const spec = opts.packageSpec ?? "@lovinka/deployik-mcp";
|
|
88
|
+
const entry = makeEntry(spec, opts.url, opts.token);
|
|
89
|
+
const result = { written: [], skipped: [] };
|
|
90
|
+
for (const target of targetsFor(opts.scope, cwd)) {
|
|
91
|
+
if (target.mustExistDir && !existsSync(dirname(target.path))) {
|
|
92
|
+
result.skipped.push({ path: target.path, reason: `parent dir not found (${target.label} not installed?)` });
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const existing = readConfig(target.path);
|
|
96
|
+
const created = !existsSync(target.path);
|
|
97
|
+
let backupPath;
|
|
98
|
+
if (existing && existsSync(target.path)) {
|
|
99
|
+
backupPath = backup(target.path);
|
|
100
|
+
}
|
|
101
|
+
const next = existing ?? {};
|
|
102
|
+
next.mcpServers = { ...(next.mcpServers ?? {}), [name]: entry };
|
|
103
|
+
mkdirSync(dirname(target.path), { recursive: true });
|
|
104
|
+
writeFileSync(target.path, JSON.stringify(next, null, 2) + "\n", "utf8");
|
|
105
|
+
result.written.push({ path: target.path, created, backupPath });
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
/** Symmetric uninstall — removes the named mcpServers entry from every target. */
|
|
110
|
+
export function uninstallMcp(opts) {
|
|
111
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
112
|
+
const name = opts.name ?? "deployik";
|
|
113
|
+
const result = { written: [], skipped: [] };
|
|
114
|
+
for (const target of targetsFor(opts.scope, cwd)) {
|
|
115
|
+
if (!existsSync(target.path)) {
|
|
116
|
+
result.skipped.push({ path: target.path, reason: "not present" });
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const config = readConfig(target.path);
|
|
120
|
+
if (!config?.mcpServers || !(name in config.mcpServers)) {
|
|
121
|
+
result.skipped.push({ path: target.path, reason: `no '${name}' entry` });
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const backupPath = backup(target.path);
|
|
125
|
+
const remaining = { ...config.mcpServers };
|
|
126
|
+
delete remaining[name];
|
|
127
|
+
config.mcpServers = remaining;
|
|
128
|
+
writeFileSync(target.path, JSON.stringify(config, null, 2) + "\n", "utf8");
|
|
129
|
+
result.written.push({ path: target.path, created: false, backupPath });
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=install-mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-mcp.js","sourceRoot":"","sources":["../src/install-mcp.ts"],"names":[],"mappings":"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"}
|
package/dist/install-skill.js
CHANGED
|
@@ -1,49 +1,73 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// independently of any MCP tool call (e.g. when the user is reading a doc and
|
|
5
|
-
// types `/skills`).
|
|
1
|
+
// Copy the bundled Deployik knowledge into Claude's skills directory so the
|
|
2
|
+
// same recipes the MCP serves are also available as a regular skill (fires
|
|
3
|
+
// from `/skills` independently of any MCP tool call).
|
|
6
4
|
//
|
|
7
|
-
//
|
|
5
|
+
// Scope:
|
|
6
|
+
// global → ~/.claude/skills/deployik-howto/ (default)
|
|
7
|
+
// local → <cwd>/.claude/skills/deployik-howto/ (per-project)
|
|
8
8
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { homedir } from "node:os";
|
|
10
|
-
import { join } from "node:path";
|
|
10
|
+
import { join, resolve } from "node:path";
|
|
11
11
|
import { createInterface } from "node:readline";
|
|
12
12
|
import { RECIPE_FILES } from "./knowledge/recipes.generated.js";
|
|
13
|
+
export function skillTargetDir(scope, cwd, destBase) {
|
|
14
|
+
if (destBase)
|
|
15
|
+
return resolve(destBase, "deployik-howto");
|
|
16
|
+
if (scope === "local")
|
|
17
|
+
return resolve(cwd, ".claude", "skills", "deployik-howto");
|
|
18
|
+
return join(homedir(), ".claude", "skills", "deployik-howto");
|
|
19
|
+
}
|
|
13
20
|
export async function installSkill(opts) {
|
|
14
|
-
const
|
|
15
|
-
|
|
21
|
+
const result = await installSkillResult(opts);
|
|
22
|
+
if (result === null)
|
|
23
|
+
return 0;
|
|
24
|
+
process.stdout.write(`\n✓ Installed Deployik skill to ${result.target}\n`);
|
|
25
|
+
process.stdout.write(` Test it: in Claude Code, type /skills and look for 'deployik-howto'.\n`);
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
export async function installSkillResult(opts) {
|
|
29
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
30
|
+
const target = skillTargetDir(opts.scope, cwd, opts.destBase);
|
|
16
31
|
if (!RECIPE_FILES.length) {
|
|
17
32
|
process.stderr.write(`No bundled recipes found in this build.\n`);
|
|
18
|
-
return
|
|
33
|
+
return null;
|
|
19
34
|
}
|
|
20
|
-
process.stdout.write(`
|
|
35
|
+
process.stdout.write(`Skill files (${opts.scope}) → ${target}\n`);
|
|
21
36
|
for (const f of RECIPE_FILES)
|
|
22
37
|
process.stdout.write(` - ${f.file}\n`);
|
|
23
|
-
|
|
24
|
-
|
|
38
|
+
const alreadyExisted = existsSync(target);
|
|
39
|
+
if (alreadyExisted) {
|
|
40
|
+
process.stdout.write(`Note: '${target}' already exists. Files will be overwritten.\n`);
|
|
25
41
|
}
|
|
26
42
|
if (!opts.yes) {
|
|
27
|
-
const ok = await promptYesNo("
|
|
43
|
+
const ok = await promptYesNo("Proceed with skill install? [y/N] ");
|
|
28
44
|
if (!ok) {
|
|
29
|
-
process.stdout.write("
|
|
30
|
-
return
|
|
45
|
+
process.stdout.write("Skipped skill install.\n");
|
|
46
|
+
return null;
|
|
31
47
|
}
|
|
32
48
|
}
|
|
33
49
|
mkdirSync(target, { recursive: true });
|
|
34
|
-
for (const f of RECIPE_FILES)
|
|
50
|
+
for (const f of RECIPE_FILES)
|
|
35
51
|
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;
|
|
52
|
+
return { target, files: RECIPE_FILES.map((f) => f.file), alreadyExisted };
|
|
40
53
|
}
|
|
41
|
-
function promptYesNo(prompt) {
|
|
42
|
-
return new Promise((
|
|
54
|
+
export function promptYesNo(prompt) {
|
|
55
|
+
return new Promise((resolveFn) => {
|
|
43
56
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
44
57
|
rl.question(prompt, (answer) => {
|
|
45
58
|
rl.close();
|
|
46
|
-
|
|
59
|
+
resolveFn(/^y(es)?$/i.test(answer.trim()));
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
export function prompt(message, defaultValue) {
|
|
64
|
+
return new Promise((resolveFn) => {
|
|
65
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
66
|
+
const suffix = defaultValue ? ` [${defaultValue}]` : "";
|
|
67
|
+
rl.question(`${message}${suffix}: `, (answer) => {
|
|
68
|
+
rl.close();
|
|
69
|
+
const trimmed = answer.trim();
|
|
70
|
+
resolveFn(trimmed || defaultValue || "");
|
|
47
71
|
});
|
|
48
72
|
});
|
|
49
73
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-skill.js","sourceRoot":"","sources":["../src/install-skill.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,
|
|
1
|
+
{"version":3,"file":"install-skill.js","sourceRoot":"","sources":["../src/install-skill.ts"],"names":[],"mappings":"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"}
|
package/dist/install.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// One-shot installer: registers the @lovinka/deployik-mcp MCP server in
|
|
2
|
+
// Claude's config AND copies the bundled Deployik skill into Claude's skills
|
|
3
|
+
// directory. Default scope is GLOBAL (recommended) — once installed, every
|
|
4
|
+
// project + every Claude window can use the deployik tools.
|
|
5
|
+
import { installMcp } from "./install-mcp.js";
|
|
6
|
+
import { installSkillResult, prompt, promptYesNo } from "./install-skill.js";
|
|
7
|
+
const DEFAULT_URL = "https://deployik.lovinka.com";
|
|
8
|
+
export async function installAll(opts) {
|
|
9
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
10
|
+
const scope = opts.scope;
|
|
11
|
+
process.stdout.write(`\n=== Installing @lovinka/deployik-mcp (${scope}) ===\n\n`);
|
|
12
|
+
// Resolve URL + token
|
|
13
|
+
let url = opts.url ?? process.env.DEPLOYIK_URL ?? "";
|
|
14
|
+
let token = opts.token ?? process.env.DEPLOYIK_TOKEN ?? "";
|
|
15
|
+
if (!opts.skipMcp) {
|
|
16
|
+
if (!opts.yes) {
|
|
17
|
+
if (!url)
|
|
18
|
+
url = await prompt("Deployik URL", DEFAULT_URL);
|
|
19
|
+
if (!token)
|
|
20
|
+
token = await prompt("Personal Access Token (dpk_…)");
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
if (!url)
|
|
24
|
+
url = DEFAULT_URL;
|
|
25
|
+
}
|
|
26
|
+
if (!token) {
|
|
27
|
+
process.stderr.write(`\nERROR: DEPLOYIK_TOKEN missing.\nPass --token=<dpk_...> or set DEPLOYIK_TOKEN env var.\n` +
|
|
28
|
+
`Get a token at: Account → Access tokens in your Deployik dashboard.\n`);
|
|
29
|
+
return 2;
|
|
30
|
+
}
|
|
31
|
+
if (!url)
|
|
32
|
+
url = DEFAULT_URL;
|
|
33
|
+
}
|
|
34
|
+
// Confirmation
|
|
35
|
+
if (!opts.yes) {
|
|
36
|
+
process.stdout.write(`\nAbout to perform:\n`);
|
|
37
|
+
if (!opts.skipMcp)
|
|
38
|
+
process.stdout.write(` • Register MCP server 'deployik' (${scope}) pointing at ${url}\n`);
|
|
39
|
+
if (!opts.skipSkill)
|
|
40
|
+
process.stdout.write(` • Copy Deployik skill files (${scope})\n`);
|
|
41
|
+
process.stdout.write(`\n`);
|
|
42
|
+
const ok = await promptYesNo("Proceed? [y/N] ");
|
|
43
|
+
if (!ok) {
|
|
44
|
+
process.stdout.write("Aborted.\n");
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// 1. MCP registration
|
|
49
|
+
if (!opts.skipMcp) {
|
|
50
|
+
process.stdout.write(`\n--- MCP server registration ---\n`);
|
|
51
|
+
const res = installMcp({ scope, url, token, cwd });
|
|
52
|
+
for (const w of res.written) {
|
|
53
|
+
process.stdout.write(` ✓ ${w.created ? "created" : "updated"} ${w.path}${w.backupPath ? ` (backup → ${w.backupPath})` : ""}\n`);
|
|
54
|
+
}
|
|
55
|
+
for (const s of res.skipped) {
|
|
56
|
+
process.stdout.write(` · skipped ${s.path} (${s.reason})\n`);
|
|
57
|
+
}
|
|
58
|
+
if (res.written.length === 0) {
|
|
59
|
+
process.stderr.write(` ! no MCP config targets were writable — nothing changed.\n`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 2. Skill files
|
|
63
|
+
if (!opts.skipSkill) {
|
|
64
|
+
process.stdout.write(`\n--- Skill files ---\n`);
|
|
65
|
+
const r = await installSkillResult({ scope, yes: true, cwd });
|
|
66
|
+
if (r) {
|
|
67
|
+
process.stdout.write(` ✓ wrote ${r.files.length} files to ${r.target}${r.alreadyExisted ? " (overwrote existing)" : ""}\n`);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
process.stdout.write(` · skill install was skipped\n`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
process.stdout.write(`\nDone. Restart Claude Code / Claude Desktop to pick up the new MCP server.\n`);
|
|
74
|
+
if (scope === "local") {
|
|
75
|
+
process.stdout.write(`\nNote: with --local scope, the .mcp.json and .claude/skills/deployik-howto/ are written into\n` +
|
|
76
|
+
`the current directory. The MCP server only fires when Claude is opened in this folder.\n`);
|
|
77
|
+
}
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|
package/dist/version.js
CHANGED
package/package.json
CHANGED