@mokoconsulting/mcp-windows 3.0.0 → 3.0.1

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.
@@ -10,9 +10,9 @@
10
10
  # VERSION: 05.00.00
11
11
  # BRIEF: Universal build & release � detects platform from manifest.xml
12
12
  #
13
- # +========================================================================+
13
+ # +=======================================================================+
14
14
  # | UNIVERSAL BUILD & RELEASE PIPELINE |
15
- # +========================================================================+
15
+ # +=======================================================================+
16
16
  # | |
17
17
  # | Reads manifest.xml (joomla|dolibarr|generic) to branch logic. |
18
18
  # | |
@@ -21,7 +21,7 @@
21
21
  # | dolibarr: mod*.class.php, update.txt, dev version reset |
22
22
  # | generic: README-only, no update stream |
23
23
  # | |
24
- # +========================================================================+
24
+ # +=======================================================================+
25
25
 
26
26
  name: "Universal: Build & Release"
27
27
 
@@ -51,7 +51,7 @@ permissions:
51
51
  contents: write
52
52
 
53
53
  jobs:
54
- # ── PR Opened → Rename branch to RC and build RC release ─────────────────────
54
+ # ── PR Opened → Rename branch to RC and build RC release ─────────────────────────
55
55
  promote-rc:
56
56
  name: Promote to RC
57
57
  runs-on: release
@@ -149,7 +149,7 @@ jobs:
149
149
  echo "## Promoted to Release Candidate" >> $GITHUB_STEP_SUMMARY
150
150
  echo "Branch renamed to rc, minor bump, RC release built" >> $GITHUB_STEP_SUMMARY
151
151
 
152
- # ── Merged PR → Build & Release (or promote RC to stable) ────────────────────
152
+ # ── Merged PR → Build & Release (or promote RC to stable) ─────────────────────────
153
153
  release:
154
154
  name: Build & Release Pipeline
155
155
  runs-on: release
@@ -241,11 +241,47 @@ jobs:
241
241
  VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//')
242
242
  [ -z "$VERSION" ] && VERSION="00.00.00" && echo "skip=true" >> "$GITHUB_OUTPUT"
243
243
  echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
244
- echo "tag=stable" >> "$GITHUB_OUTPUT"
245
- echo "release_tag=stable" >> "$GITHUB_OUTPUT"
244
+ PLATFORM="${{ steps.platform.outputs.platform }}"
245
+ if [[ "$PLATFORM" == joomla* ]]; then
246
+ echo "tag=stable" >> "$GITHUB_OUTPUT"
247
+ echo "release_tag=stable" >> "$GITHUB_OUTPUT"
248
+ else
249
+ echo "tag=v${VERSION}" >> "$GITHUB_OUTPUT"
250
+ echo "release_tag=v${VERSION}" >> "$GITHUB_OUTPUT"
251
+ fi
246
252
  echo "branch=main" >> "$GITHUB_OUTPUT"
247
253
  echo "Published version: ${VERSION}"
248
254
 
255
+ - name: "Create semver tag for non-Joomla repos"
256
+ id: semver
257
+ if: |
258
+ steps.version.outputs.skip != 'true' &&
259
+ !startsWith(steps.platform.outputs.platform, 'joomla')
260
+ run: |
261
+ VERSION="${{ steps.version.outputs.version }}"
262
+ API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
263
+ TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
264
+ SEMVER_TAG="v${VERSION}"
265
+
266
+ echo "Creating semver tag: ${SEMVER_TAG}"
267
+
268
+ # Create the git tag via API
269
+ HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" \
270
+ -X POST -H "Authorization: token ${TOKEN}" \
271
+ -H "Content-Type: application/json" \
272
+ "${API_BASE}/tags" \
273
+ -d "{\"tag_name\":\"${SEMVER_TAG}\",\"target\":\"main\",\"message\":\"Release ${VERSION}\"}" 2>/dev/null || echo "000")
274
+
275
+ if [ "$HTTP_CODE" = "201" ] || [ "$HTTP_CODE" = "200" ]; then
276
+ echo "Created semver tag: ${SEMVER_TAG}"
277
+ elif [ "$HTTP_CODE" = "409" ]; then
278
+ echo "Semver tag ${SEMVER_TAG} already exists (skipped)"
279
+ else
280
+ echo "::warning::Failed to create semver tag ${SEMVER_TAG} (HTTP ${HTTP_CODE})"
281
+ fi
282
+
283
+ echo "semver_tag=${SEMVER_TAG}" >> "$GITHUB_OUTPUT"
284
+
249
285
  - name: Update release notes and promote changelog
250
286
  run: |
251
287
  API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
@@ -0,0 +1,76 @@
1
+ # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
2
+ # SPDX-License-Identifier: GPL-3.0-or-later
3
+
4
+ name: "Publish to Composer"
5
+
6
+ on:
7
+ push:
8
+ tags:
9
+ - 'v*'
10
+ - '[0-9]*.[0-9]*.[0-9]*'
11
+ release:
12
+ types: [published]
13
+ workflow_dispatch:
14
+
15
+ env:
16
+ GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
17
+
18
+ jobs:
19
+ publish:
20
+ name: Publish Package
21
+ runs-on: ubuntu-latest
22
+ if: >-
23
+ !contains(github.event.head_commit.message, '[skip ci]') &&
24
+ !contains(github.event.head_commit.message, '[skip publish]')
25
+ steps:
26
+ - name: Checkout
27
+ uses: actions/checkout@v4
28
+
29
+ - name: Setup PHP
30
+ run: |
31
+ if ! command -v php &> /dev/null; then
32
+ sudo apt-get update -qq
33
+ sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1
34
+ fi
35
+
36
+ - name: Install dependencies
37
+ run: composer install --no-dev --no-interaction --prefer-dist --quiet
38
+
39
+ - name: Determine version
40
+ id: version
41
+ run: |
42
+ VERSION=$(php -r "echo json_decode(file_get_contents('composer.json'))->version;")
43
+ echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
44
+ echo "Package version: ${VERSION}"
45
+
46
+ # Gitea Composer Registry — auto-publishes from tags
47
+ # The tag push itself registers the package at:
48
+ # https://git.mokoconsulting.tech/api/packages/MokoConsulting/composer
49
+ - name: Verify Gitea registry
50
+ run: |
51
+ echo "Gitea Composer registry auto-publishes from tags."
52
+ echo "Package available at: ${GITEA_URL}/api/packages/MokoConsulting/composer"
53
+ echo "Install: composer require mokoconsulting/mokocli"
54
+
55
+ # Packagist — notify of new version
56
+ - name: Notify Packagist
57
+ if: secrets.PACKAGIST_TOKEN != ''
58
+ run: |
59
+ VERSION="${{ steps.version.outputs.version }}"
60
+ echo "Notifying Packagist of version ${VERSION}..."
61
+ curl -sf -X POST \
62
+ -H "Content-Type: application/json" \
63
+ -d '{"repository":{"url":"https://git.mokoconsulting.tech/MokoConsulting/mokocli"}}' \
64
+ "https://packagist.org/api/update-package?username=mokoconsulting&apiToken=${{ secrets.PACKAGIST_TOKEN }}" \
65
+ && echo "Packagist notified" \
66
+ || echo "::warning::Packagist notification failed (package may not be registered yet)"
67
+
68
+ - name: Summary
69
+ run: |
70
+ VERSION="${{ steps.version.outputs.version }}"
71
+ echo "## Composer Package Published" >> $GITHUB_STEP_SUMMARY
72
+ echo "" >> $GITHUB_STEP_SUMMARY
73
+ echo "| Registry | Status |" >> $GITHUB_STEP_SUMMARY
74
+ echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY
75
+ echo "| Gitea | \`composer require mokoconsulting/mokocli:${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
76
+ echo "| Packagist | \`composer require mokoconsulting/mokocli\` |" >> $GITHUB_STEP_SUMMARY
@@ -88,8 +88,20 @@ jobs:
88
88
  php ${MOKO_CLI}/platform_detect.php --path . --github-output 2>/dev/null || true
89
89
  php ${MOKO_CLI}/manifest_read.php --path . --github-output
90
90
 
91
+ - name: Check platform eligibility (Joomla only)
92
+ id: eligibility
93
+ run: |
94
+ PLATFORM="${{ steps.platform.outputs.platform }}"
95
+ if [[ "$PLATFORM" == joomla* ]] || [[ "$PLATFORM" == "joomla" ]]; then
96
+ echo "proceed=true" >> "$GITHUB_OUTPUT"
97
+ else
98
+ echo "proceed=false" >> "$GITHUB_OUTPUT"
99
+ echo "::notice::Platform '$PLATFORM' — non-Joomla, skipping pre-release auto-bump"
100
+ fi
101
+
91
102
  - name: Resolve metadata and bump version
92
103
  id: meta
104
+ if: steps.eligibility.outputs.proceed == 'true'
93
105
  run: |
94
106
  # Auto-detect stability from branch name on push, or use input on dispatch
95
107
  if [ "${{ github.event_name }}" = "push" ]; then
@@ -166,6 +178,7 @@ jobs:
166
178
 
167
179
  - name: Create release
168
180
  id: release
181
+ if: steps.eligibility.outputs.proceed == 'true'
169
182
  run: |
170
183
  TAG="${{ steps.meta.outputs.tag }}"
171
184
  VERSION="${{ steps.meta.outputs.version }}"
@@ -176,6 +189,7 @@ jobs:
176
189
  --repo "${GITEA_REPO}" --branch "${{ github.ref_name }}" --prerelease
177
190
 
178
191
  - name: Update release notes from CHANGELOG.md
192
+ if: steps.eligibility.outputs.proceed == 'true'
179
193
  run: |
180
194
  TAG="${{ steps.meta.outputs.tag }}"
181
195
  VERSION="${{ steps.meta.outputs.version }}"
@@ -212,6 +226,7 @@ jobs:
212
226
 
213
227
  - name: Build package and upload
214
228
  id: package
229
+ if: steps.eligibility.outputs.proceed == 'true'
215
230
  run: |
216
231
  VERSION="${{ steps.meta.outputs.version }}"
217
232
  TAG="${{ steps.meta.outputs.tag }}"
@@ -225,6 +240,7 @@ jobs:
225
240
  # No need to build, commit, or sync updates.xml from workflows
226
241
 
227
242
  - name: "Delete lesser pre-release channels (cascade)"
243
+ if: steps.eligibility.outputs.proceed == 'true'
228
244
  continue-on-error: true
229
245
  run: |
230
246
  API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mokoconsulting/mcp-windows",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "MCP server for Windows desktop system operations",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,237 +0,0 @@
1
- #!/usr/bin/env bash
2
- # ============================================================================
3
- # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
4
- #
5
- # SPDX-License-Identifier: GPL-3.0-or-later
6
- #
7
- # FILE INFORMATION
8
- # DEFGROUP: Automation.CI
9
- # INGROUP: moko-platform.Automation
10
- # REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
11
- # PATH: /automation/ci-issue-reporter.sh
12
- # VERSION: 09.23.00
13
- # BRIEF: Creates or updates a Gitea issue when a CI gate fails.
14
- # Deduplicates by searching open issues with the "ci-auto" label
15
- # whose title matches the gate. If a matching issue exists, a comment
16
- # is appended instead of opening a duplicate.
17
- # ============================================================================
18
-
19
- set -euo pipefail
20
-
21
- # ── Defaults ────────────────────────────────────────────────────────────────
22
- GITEA_URL="${GITEA_URL:-https://git.mokoconsulting.tech}"
23
- GITEA_TOKEN="${GITEA_TOKEN:-}"
24
- REPO="${GITHUB_REPOSITORY:-}"
25
- RUN_URL="${GITHUB_SERVER_URL:-${GITEA_URL}}/${REPO}/actions/runs/${GITHUB_RUN_ID:-0}"
26
- LABEL_NAME="ci-auto"
27
- LABEL_COLOR="#e11d48"
28
-
29
- GATE=""
30
- DETAILS=""
31
- SEVERITY="error"
32
- WORKFLOW=""
33
-
34
- # ── Parse arguments ─────────────────────────────────────────────────────────
35
- usage() {
36
- cat <<EOF
37
- Usage: ci-issue-reporter.sh --gate NAME --details TEXT [OPTIONS]
38
-
39
- Required:
40
- --gate CI gate name (e.g. "Code Quality", "Self-Health")
41
- --details Human-readable failure description
42
-
43
- Optional:
44
- --severity "error" (default) or "warning"
45
- --workflow Workflow name for the issue title
46
- --repo owner/repo (default: \$GITHUB_REPOSITORY)
47
- --run-url URL to the CI run (auto-detected from env)
48
- --token Gitea API token (default: \$GITEA_TOKEN)
49
- --url Gitea base URL (default: \$GITEA_URL)
50
- EOF
51
- exit 1
52
- }
53
-
54
- while [[ $# -gt 0 ]]; do
55
- case "$1" in
56
- --gate) GATE="$2"; shift 2 ;;
57
- --details) DETAILS="$2"; shift 2 ;;
58
- --severity) SEVERITY="$2"; shift 2 ;;
59
- --workflow) WORKFLOW="$2"; shift 2 ;;
60
- --repo) REPO="$2"; shift 2 ;;
61
- --run-url) RUN_URL="$2"; shift 2 ;;
62
- --token) GITEA_TOKEN="$2"; shift 2 ;;
63
- --url) GITEA_URL="$2"; shift 2 ;;
64
- -h|--help) usage ;;
65
- *) echo "Unknown option: $1"; usage ;;
66
- esac
67
- done
68
-
69
- [[ -z "$GATE" ]] && { echo "ERROR: --gate is required"; usage; }
70
- [[ -z "$DETAILS" ]] && { echo "ERROR: --details is required"; usage; }
71
- [[ -z "$GITEA_TOKEN" ]] && { echo "ERROR: GITEA_TOKEN not set"; exit 1; }
72
- [[ -z "$REPO" ]] && { echo "ERROR: GITHUB_REPOSITORY not set"; exit 1; }
73
-
74
- API="${GITEA_URL}/api/v1/repos/${REPO}"
75
-
76
- # ── Build title ─────────────────────────────────────────────────────────────
77
- if [[ -n "$WORKFLOW" ]]; then
78
- TITLE="[CI] ${WORKFLOW}: ${GATE} failed"
79
- else
80
- TITLE="[CI] ${GATE} failed"
81
- fi
82
-
83
- # ── Ensure label exists ─────────────────────────────────────────────────────
84
- ensure_label() {
85
- local exists
86
- exists=$(curl -sf -o /dev/null -w '%{http_code}' \
87
- -H "Authorization: token ${GITEA_TOKEN}" \
88
- "${API}/labels" 2>/dev/null || echo "000")
89
-
90
- if [[ "$exists" == "200" ]]; then
91
- # Check if label already exists
92
- local found
93
- found=$(curl -sf \
94
- -H "Authorization: token ${GITEA_TOKEN}" \
95
- "${API}/labels" 2>/dev/null \
96
- | grep -o "\"name\":\"${LABEL_NAME}\"" || true)
97
-
98
- if [[ -z "$found" ]]; then
99
- curl -sf -X POST \
100
- -H "Authorization: token ${GITEA_TOKEN}" \
101
- -H "Content-Type: application/json" \
102
- "${API}/labels" \
103
- -d "{\"name\":\"${LABEL_NAME}\",\"color\":\"${LABEL_COLOR}\",\"description\":\"Auto-created by CI issue reporter\"}" \
104
- > /dev/null 2>&1 || true
105
- fi
106
- fi
107
- }
108
-
109
- # ── Search for existing open issue ──────────────────────────────────────────
110
- find_existing_issue() {
111
- # URL-encode the gate name for the query
112
- local query
113
- query=$(printf '%s' "[CI] ${GATE}" | sed 's/ /%20/g; s/\[/%5B/g; s/\]/%5D/g')
114
-
115
- local response
116
- response=$(curl -sf \
117
- -H "Authorization: token ${GITEA_TOKEN}" \
118
- "${API}/issues?type=issues&state=open&labels=${LABEL_NAME}&q=${query}&limit=5" \
119
- 2>/dev/null || echo "[]")
120
-
121
- # Extract the first matching issue number
122
- echo "$response" \
123
- | grep -oP '"number":\s*\K[0-9]+' \
124
- | head -1
125
- }
126
-
127
- # ── Build issue body ────────────────────────────────────────────────────────
128
- build_body() {
129
- local severity_badge
130
- if [[ "$SEVERITY" == "error" ]]; then
131
- severity_badge="**Severity:** Error"
132
- else
133
- severity_badge="**Severity:** Warning"
134
- fi
135
-
136
- cat <<BODY
137
- ## CI Gate Failure: ${GATE}
138
-
139
- ${severity_badge}
140
- **Workflow:** ${WORKFLOW:-unknown}
141
- **Branch:** ${GITHUB_REF_NAME:-unknown}
142
- **Commit:** \`${GITHUB_SHA:0:8}\`
143
- **Run:** [View CI run](${RUN_URL})
144
-
145
- ### Details
146
-
147
- ${DETAILS}
148
-
149
- ### Resolution
150
-
151
- Fix the issue described above and push a new commit. This issue will be closed automatically when the gate passes, or can be closed manually.
152
-
153
- ---
154
- *Auto-created by [ci-issue-reporter](${GITEA_URL}/${REPO}/src/branch/main/automation/ci-issue-reporter.sh)*
155
- BODY
156
- }
157
-
158
- # ── Build comment body (for existing issues) ────────────────────────────────
159
- build_comment() {
160
- cat <<COMMENT
161
- ### CI failure recurrence
162
-
163
- **Branch:** ${GITHUB_REF_NAME:-unknown}
164
- **Commit:** \`${GITHUB_SHA:0:8}\`
165
- **Run:** [View CI run](${RUN_URL})
166
-
167
- ${DETAILS}
168
- COMMENT
169
- }
170
-
171
- # ── Main ────────────────────────────────────────────────────────────────────
172
- ensure_label
173
-
174
- EXISTING=$(find_existing_issue)
175
-
176
- if [[ -n "$EXISTING" ]]; then
177
- # Append comment to existing issue
178
- COMMENT_BODY=$(build_comment)
179
- COMMENT_JSON=$(printf '%s' "$COMMENT_BODY" | python3 -c "
180
- import sys, json
181
- print(json.dumps({'body': sys.stdin.read()}))" 2>/dev/null)
182
-
183
- HTTP=$(curl -sf -o /dev/null -w '%{http_code}' -X POST \
184
- -H "Authorization: token ${GITEA_TOKEN}" \
185
- -H "Content-Type: application/json" \
186
- "${API}/issues/${EXISTING}/comments" \
187
- -d "${COMMENT_JSON}" 2>/dev/null || echo "000")
188
-
189
- if [[ "$HTTP" == "201" ]]; then
190
- echo "Commented on existing issue #${EXISTING}"
191
- else
192
- echo "WARNING: Failed to comment on issue #${EXISTING} (HTTP ${HTTP})"
193
- fi
194
- else
195
- # Create new issue
196
- ISSUE_BODY=$(build_body)
197
- ISSUE_JSON=$(python3 -c "
198
- import sys, json
199
- body = sys.stdin.read()
200
- print(json.dumps({
201
- 'title': sys.argv[1],
202
- 'body': body,
203
- 'labels': []
204
- }))" "$TITLE" <<< "$ISSUE_BODY" 2>/dev/null)
205
-
206
- # Create the issue
207
- RESPONSE=$(curl -sf -X POST \
208
- -H "Authorization: token ${GITEA_TOKEN}" \
209
- -H "Content-Type: application/json" \
210
- "${API}/issues" \
211
- -d "${ISSUE_JSON}" 2>/dev/null || echo "{}")
212
-
213
- ISSUE_NUM=$(echo "$RESPONSE" | grep -oP '"number":\s*\K[0-9]+' | head -1)
214
-
215
- if [[ -n "$ISSUE_NUM" ]]; then
216
- # Apply label (separate call — more reliable across Gitea versions)
217
- LABEL_ID=$(curl -sf \
218
- -H "Authorization: token ${GITEA_TOKEN}" \
219
- "${API}/labels" 2>/dev/null \
220
- | grep -oP "\"id\":\s*\K[0-9]+(?=[^}]*\"name\":\s*\"${LABEL_NAME}\")" \
221
- | head -1 || true)
222
-
223
- if [[ -n "$LABEL_ID" ]]; then
224
- curl -sf -X POST \
225
- -H "Authorization: token ${GITEA_TOKEN}" \
226
- -H "Content-Type: application/json" \
227
- "${API}/issues/${ISSUE_NUM}/labels" \
228
- -d "{\"labels\":[${LABEL_ID}]}" \
229
- > /dev/null 2>&1 || true
230
- fi
231
-
232
- echo "Created issue #${ISSUE_NUM}: ${TITLE}"
233
- else
234
- echo "WARNING: Failed to create issue"
235
- echo "Response: ${RESPONSE}"
236
- fi
237
- fi
package/scripts/setup.mjs DELETED
@@ -1,123 +0,0 @@
1
- #!/usr/bin/env node
2
- /* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
3
- *
4
- * This file is part of a Moko Consulting project.
5
- *
6
- * SPDX-License-Identifier: GPL-3.0-or-later
7
- *
8
- * FILE INFORMATION
9
- * DEFGROUP: mcp_windows.Scripts
10
- * INGROUP: mcp_windows
11
- * REPO: https://git.mokoconsulting.tech/MokoConsulting/mcp_windows
12
- * PATH: /scripts/setup.mjs
13
- * VERSION: 01.00.00
14
- * BRIEF: Interactive setup — prompts for API connection details and writes config
15
- */
16
-
17
- import { createInterface } from 'node:readline/promises';
18
- import { readFile, writeFile } from 'node:fs/promises';
19
- import { resolve } from 'node:path';
20
- import { homedir } from 'node:os';
21
-
22
- // ── Customize these ─────────────────────────────────────────────────────
23
- const PROJECT_NAME = 'mcp_windows';
24
- const CONFIG_PATH = resolve(homedir(), `.${PROJECT_NAME}.json`);
25
- const API_LABEL = 'Windows Desktop'; // e.g. "Dolibarr", "Joomla"
26
- const AUTH_FIELD = 'apiKey'; // field name in config
27
- const AUTH_PROMPT = 'API key'; // what to ask the user for
28
- // ────────────────────────────────────────────────────────────────────────
29
-
30
- const rl = createInterface({ input: process.stdin, output: process.stdout });
31
-
32
- async function prompt(question, defaultValue) {
33
- const suffix = defaultValue ? ` [${defaultValue}]` : '';
34
- const answer = await rl.question(`${question}${suffix}: `);
35
- return answer.trim() || defaultValue || '';
36
- }
37
-
38
- async function promptRequired(question) {
39
- let answer = '';
40
- while (!answer) {
41
- answer = (await rl.question(`${question}: `)).trim();
42
- if (!answer) {
43
- console.log(' This field is required.');
44
- }
45
- }
46
- return answer;
47
- }
48
-
49
- async function main() {
50
- console.log('');
51
- console.log(`=== ${PROJECT_NAME} Setup ===`);
52
- console.log('');
53
- console.log('This will create your configuration file at:');
54
- console.log(` ${CONFIG_PATH}`);
55
- console.log('');
56
-
57
- let existing = null;
58
- try {
59
- const raw = await readFile(CONFIG_PATH, 'utf-8');
60
- existing = JSON.parse(raw);
61
- console.log('Existing config found. You can add a new connection or overwrite.');
62
- console.log(` Current connections: ${Object.keys(existing.connections).join(', ')}`);
63
- console.log('');
64
- } catch {
65
- // No existing config
66
- }
67
-
68
- const connectionName = await prompt('Connection name', 'production');
69
- const baseUrl = await promptRequired(`${API_LABEL} URL (e.g. https://api.example.com)`);
70
- const authValue = await promptRequired(`${API_LABEL} ${AUTH_PROMPT}`);
71
-
72
- const cleanUrl = baseUrl.replace(/\/+$/, '');
73
-
74
- const insecureAnswer = await prompt('Skip TLS verification for self-signed certs? (y/N)', 'N');
75
- const insecure = insecureAnswer.toLowerCase() === 'y';
76
-
77
- const connection = { baseUrl: cleanUrl, [AUTH_FIELD]: authValue };
78
- if (insecure) {
79
- connection.insecure = true;
80
- }
81
-
82
- let config;
83
- if (existing) {
84
- config = existing;
85
- config.connections[connectionName] = connection;
86
- const setDefault = await prompt(`Set "${connectionName}" as default connection? (y/N)`, 'N');
87
- if (setDefault.toLowerCase() === 'y') {
88
- config.defaultConnection = connectionName;
89
- }
90
- } else {
91
- config = {
92
- defaultConnection: connectionName,
93
- connections: {
94
- [connectionName]: connection,
95
- },
96
- };
97
- }
98
-
99
- await writeFile(CONFIG_PATH, JSON.stringify(config, null, '\t') + '\n', 'utf-8');
100
-
101
- console.log('');
102
- console.log(`Config written to ${CONFIG_PATH}`);
103
- console.log(` Connection "${connectionName}" configured for ${cleanUrl}`);
104
- console.log('');
105
-
106
- const addAnother = await prompt('Add another connection? (y/N)', 'N');
107
- if (addAnother.toLowerCase() === 'y') {
108
- rl.close();
109
- const { execFileSync } = await import('node:child_process');
110
- execFileSync('node', [new URL(import.meta.url).pathname], { stdio: 'inherit' });
111
- return;
112
- }
113
-
114
- console.log('Setup complete. You can now use the MCP server.');
115
- console.log('');
116
- rl.close();
117
- }
118
-
119
- main().catch((err) => {
120
- console.error(`Setup failed: ${err.message}`);
121
- rl.close();
122
- process.exit(1);
123
- });