@mokoenterprises/mokossh-mcp 3.8.1 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mokogit/ISSUE_TEMPLATE/config.yml +4 -4
- package/.mokogit/ISSUE_TEMPLATE/feature_request.md +1 -1
- package/.mokogit/ISSUE_TEMPLATE/security.md +1 -1
- package/.mokogit/actions/resolve-source-dir/action.yml +1 -1
- package/.mokogit/workflows/apidocs.yml +6 -6
- package/.mokogit/workflows/auto-assign.yml +1 -1
- package/.mokogit/workflows/auto-dev-issue.yml +2 -2
- package/.mokogit/workflows/auto-release.yml +202 -33
- package/.mokogit/workflows/branch-cleanup.yml +3 -3
- package/.mokogit/workflows/ci-issue-reporter.yml +5 -5
- package/.mokogit/workflows/cleanup.yml +3 -3
- package/.mokogit/workflows/makefile-lint.yml +48 -17
- package/.mokogit/workflows/npm-build-test.yml +8 -8
- package/.mokogit/workflows/npm-sdk-check.yml +1 -1
- package/.mokogit/workflows/npm-tool-inventory.yml +2 -2
- package/.mokogit/workflows/pr-branch-check.yml +92 -92
- package/.mokogit/workflows/pre-release.yml +208 -15
- package/.mokogit/workflows/rc-revert.yml +3 -3
- package/AGENTS.md +3 -3
- package/CHANGELOG.md +1 -1
- package/CONTRIBUTING.md +6 -6
- package/Makefile +3 -2
- package/README.md +20 -20
- package/SECURITY.md +2 -2
- package/package.json +9 -8
- package/source/token-reader.js +1 -1
- package/tools/deploy.mjs +27 -0
- package/.mokogit/workflows/cascade.yml +0 -645
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# Copyright (C) 2026 Moko
|
|
1
|
+
# Copyright (C) 2026 Moko Enterprises <hello@mokoenterprises.us>
|
|
2
2
|
#
|
|
3
3
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
4
|
#
|
|
5
5
|
# FILE INFORMATION
|
|
6
6
|
# DEFGROUP: MokoGIT.Workflow
|
|
7
7
|
# INGROUP: MokoCLI.Release
|
|
8
|
-
# REPO: https://git.
|
|
8
|
+
# REPO: https://git.mokoenterprises.us/MokoEnterprises/Template-Generic
|
|
9
9
|
# PATH: /.mokogit/workflows/pre-release.yml
|
|
10
10
|
# VERSION: 07.15.00
|
|
11
11
|
# CHANGE (07.15.00): "Vendor PHP dependencies (build-time)" is no longer a silent no-op on the release runners. The step existed since 07.xx but EVERY vendored build was failing invisibly: the runners' php-cli ships WITHOUT ext-gd, so composer could not RESOLVE mpdf/mpdf at all ("mpdf/mpdf require ext-gd * -> it is missing from your system"), and the step's continue-on-error + `|| warning` fail-soft swallowed that into a green build — the zip then shipped WITHOUT admin/vendor while the component manifest lists <folder>vendor</folder>, so JInstaller aborts the ENTIRE package install on-site ("File does not exist [ROOT][TMP]/.../admin/vendor" → "Failed to copy administrator files"; reproduced on MokonyxCRMDCM + MokonyxCRM dev installs). Fix: (1) provision ext-gd when missing before resolving; (2) verify the package's CONFIGURED vendor-dir (composer config vendor-dir, e.g. admin/vendor) actually materialized autoload.php; (3) when vendoring fails for a package whose Joomla manifest ships <folder>vendor</folder>, FAIL the build loud (::error:: + exit 1, continue-on-error removed) — a broken artifact that bricks installs is strictly worse than a red build. Packages whose manifests do NOT reference vendor/ keep the old fail-soft warning, and repos with no sub-package composer.json are a clean no-op, so non-vendoring repos are 100% unaffected. PREVIOUS (07.14.00): #469 — gate the dev-channel version BUMP on whether the push touched the Makefile SRC_DIR. The former non-code/test paths-ignore denylist on the dev push trigger is REMOVED: a docs/workflow/sample/test-only push no longer skips the build, it now RUNS in no-bump "update the current rolling dev release in place" mode. A new step "Resolve SRC_DIR bump gate (#469)" (id: srcgate) mirrors auto-release.yml: (1) electron (file-detected) or opt-out vars.RELEASE_SRCDIR_GATE=off -> bypass/always-bump; (2) else SRC_DIR REQUIRED, missing -> fail loud; (3) else diff before..sha (HEAD^1 fallback) ∩ ${SRC_DIR}/ -> should_bump. The per-merge dev-base patch bump ("Advance dev base") is now gated on should_bump!='false', so a non-source push keeps the dev base PUT and the rest of the job re-issues the existing rolling dev release. Loop-safety unchanged (job if: still re-checks [skip ci]/[skip bump]). Fleet-wide release-semantics change. PREVIOUS (07.13.00): the dev-base-bump and checkout-fallback steps now name the per-run token env var GITHUB_TOKEN (was the misleadingly-named MOKOGIT_TOKEN; the VALUE was always ${{ github.token }}). Same-repo writes (the dev base bump) use the built-in per-run github.token with contents:write — NEVER the org MOKOGIT_TOKEN secret, which this workflow does not reference at all. Naming-only; no behavior change. (The earlier "it's an org secret" framing was wrong — MokoGIT#1721.) PREVIOUS (07.12.00): "Advance dev base (per-merge patch bump)" now FAILS the step (::error:: + exit 1) when release_bump_dev reports failure (0 version files stamped), instead of the old ::warning:: + exit 0. A stalled bump (e.g. a repo-side Contents-API HTTP 500 on release_bump_dev's temp-branch write) was silently re-cutting the SAME dev version on every merge — for ~10 merges on MokonyxTickets — so the Joomla update feed stayed at the installed version and NO update was ever offered, invisibly, because the step stayed green. Failing loud turns the pre-release RED so the stall is caught immediately. The GITHUB_TOKEN-unset and #1412 "already advanced" branches keep their graceful exit 0 (not failures). See MokoGIT#1721.
|
|
@@ -79,9 +79,20 @@ permissions:
|
|
|
79
79
|
pull-requests: write
|
|
80
80
|
|
|
81
81
|
env:
|
|
82
|
-
GIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.
|
|
82
|
+
GIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoenterprises.us' }}
|
|
83
83
|
GIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }}
|
|
84
84
|
GIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }}
|
|
85
|
+
# #546: PIN the mokocli version installed by "Setup MokoCLI tools" below. The
|
|
86
|
+
# install was UNPINNED (composer create-project ... mokoenterprises/mokocli with
|
|
87
|
+
# no constraint => latest every run), so a bad mokocli release silently breaks
|
|
88
|
+
# EVERY repo's release at build time. This single pin is the version both the
|
|
89
|
+
# install step AND any future bump reference. BUMP THIS DELIBERATELY — do not
|
|
90
|
+
# auto-roll. In particular it MUST be bumped by hand once MokoCLI #1120's
|
|
91
|
+
# installer-inline capability ships (folding inlineInstallerScriptBase() into
|
|
92
|
+
# release_package.php), which is gated behind MOKO_JOOMLA_INLINE; pair the bump
|
|
93
|
+
# with that flag so an un-updated mokocli is a no-op, not an error, for one
|
|
94
|
+
# release. Allow a per-repo override via vars.MOKOCLI_VERSION for pilots.
|
|
95
|
+
MOKOCLI_VERSION: ${{ vars.MOKOCLI_VERSION || '10.34.00' }}
|
|
85
96
|
|
|
86
97
|
jobs:
|
|
87
98
|
build:
|
|
@@ -156,7 +167,7 @@ jobs:
|
|
|
156
167
|
run: |
|
|
157
168
|
set -u
|
|
158
169
|
TOK="$(printf '%s' "$GITHUB_TOKEN" | tr -d '[:space:]')"; echo "::add-mask::$TOK"
|
|
159
|
-
SERVER="${GITHUB_SERVER_URL:-https://git.
|
|
170
|
+
SERVER="${GITHUB_SERVER_URL:-https://git.mokoenterprises.us}"
|
|
160
171
|
CLONE_URL="https://x-access-token:${TOK}@${SERVER#https://}/${GITHUB_REPOSITORY}.git"
|
|
161
172
|
REF="${BUILD_REF:-${GITHUB_SHA:-}}"
|
|
162
173
|
echo "Retrying full-history checkout of ${GITHUB_REPOSITORY}@${REF:-<HEAD>} into ${GITHUB_WORKSPACE}"
|
|
@@ -194,7 +205,7 @@ jobs:
|
|
|
194
205
|
# keeps the derived value out of logs (#1840). --global is required so the
|
|
195
206
|
# rewrite reaches the submodule fetch subprocesses.
|
|
196
207
|
TOK="$(printf '%s' "$GITHUB_TOKEN" | tr -d '[:space:]')"; echo "::add-mask::$TOK"
|
|
197
|
-
git config --global url."https://x-access-token:${TOK}@git.
|
|
208
|
+
git config --global url."https://x-access-token:${TOK}@git.mokoenterprises.us/".insteadOf "https://git.mokoenterprises.us/"
|
|
198
209
|
git submodule sync --recursive || true
|
|
199
210
|
# FAIL-OPEN (#430): the per-run Actions token is scoped to THIS repo, so a
|
|
200
211
|
# cross-repo submodule can return "Repository not found" and abort the whole
|
|
@@ -230,11 +241,16 @@ jobs:
|
|
|
230
241
|
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
|
|
231
242
|
fi
|
|
232
243
|
rm -rf /tmp/mokocli
|
|
233
|
-
REG='{"type":"composer","url":"https://git.
|
|
244
|
+
REG='{"type":"composer","url":"https://git.mokoenterprises.us/api/packages/MokoEnterprises/composer"}'
|
|
245
|
+
# #546: install the PINNED mokocli (env MOKOCLI_VERSION) rather than
|
|
246
|
+
# latest — an exact `name:version` constraint on composer create-project.
|
|
247
|
+
# Roll this forward deliberately (see the env-block note). /opt/mokocli
|
|
248
|
+
# stays the stale-tolerant FAILSAFE below if the pinned registry install
|
|
249
|
+
# fails.
|
|
234
250
|
if composer create-project --no-install --no-interaction --no-progress --quiet \
|
|
235
|
-
--repository="${REG}"
|
|
251
|
+
--repository="${REG}" "mokoenterprises/mokocli:${MOKOCLI_VERSION}" /tmp/mokocli >/dev/null 2>&1 \
|
|
236
252
|
&& [ -f /tmp/mokocli/cli/version_bump.php ]; then
|
|
237
|
-
echo "Installed mokocli fresh from the Composer registry (primary)"
|
|
253
|
+
echo "Installed mokocli ${MOKOCLI_VERSION} (pinned, #546) fresh from the Composer registry (primary)"
|
|
238
254
|
# #1671: registry-publish LAG race. The registry install "succeeds" but can
|
|
239
255
|
# serve the PREVIOUS package for ~tens of seconds after a MokoCLI release
|
|
240
256
|
# (publish finishes AFTER the release run reports success). Meanwhile the
|
|
@@ -453,6 +469,26 @@ jobs:
|
|
|
453
469
|
echo "::notice::Platform '$PLATFORM' eligible for pre-release (joomla_family=${IS_JOOMLA_FAMILY})"
|
|
454
470
|
fi
|
|
455
471
|
|
|
472
|
+
# -- Download-stub opt-in detection (#544) ---------------------------------
|
|
473
|
+
# ADDITIVE + GATED. An electron repo opts into the branded download-stub
|
|
474
|
+
# installer build by shipping BOTH tools/build-release.mjs (the combined
|
|
475
|
+
# build+publish driver) AND moko-installer.config.mjs (the stub config) at
|
|
476
|
+
# the repo root. When present, the stub build below REPLACES the factory
|
|
477
|
+
# electron-builder leg (they are mutually exclusive). A plain electron repo
|
|
478
|
+
# (electron-builder config but no stub files) keeps its existing
|
|
479
|
+
# vars.ELECTRON_CI_BUILD factory path; a non-electron repo sets is_stub=false
|
|
480
|
+
# and runs nothing new. Post-checkout (a job-level if: cannot see the tree).
|
|
481
|
+
- name: "Detect download-stub installer (opt-in, #544)"
|
|
482
|
+
id: stub
|
|
483
|
+
if: steps.eligibility.outputs.is_electron == 'true'
|
|
484
|
+
run: |
|
|
485
|
+
if [ -f tools/build-release.mjs ] && [ -f moko-installer.config.mjs ]; then
|
|
486
|
+
echo "is_stub=true" >> "$GITHUB_OUTPUT"
|
|
487
|
+
echo "download-stub opt-in detected (tools/build-release.mjs + moko-installer.config.mjs) -- stub build enabled, factory electron-builder leg disabled."
|
|
488
|
+
else
|
|
489
|
+
echo "is_stub=false" >> "$GITHUB_OUTPUT"
|
|
490
|
+
fi
|
|
491
|
+
|
|
456
492
|
- name: "Resolve SRC_DIR bump gate (#469)"
|
|
457
493
|
id: srcgate
|
|
458
494
|
if: steps.eligibility.outputs.proceed == 'true'
|
|
@@ -799,22 +835,126 @@ jobs:
|
|
|
799
835
|
--ssh-host "${{ vars.DEV_SSH_HOST }}" --ssh-port "${{ vars.DEV_SSH_PORT }}" \
|
|
800
836
|
--ssh-user "${{ vars.DEV_SSH_USERNAME }}" --ssh-key ~/.ssh/deploy_key
|
|
801
837
|
|
|
802
|
-
# -- Electron pre-release
|
|
838
|
+
# -- Electron download-stub pre-release (opt-in, #544) ----------------------
|
|
839
|
+
# When a repo opts into the branded download-stub (steps.stub.is_stub), build
|
|
840
|
+
# + publish the stub installer + payload via tools/build-release.mjs on the
|
|
841
|
+
# `release` runner (the job already runs there), MIRRORING MokoHub's proven
|
|
842
|
+
# custom-mokohub-build-installer.yml. build-release.mjs does its own publish,
|
|
843
|
+
# so this fully REPLACES the factory electron-builder leg below (mutually
|
|
844
|
+
# exclusive via the is_stub gate). Channel = the dispatch stability input
|
|
845
|
+
# (default development on a dev push). Runs only on a publish-eligible repo,
|
|
846
|
+
# so a releases-off repo bumps without building.
|
|
847
|
+
- name: "Setup Node (electron stub)"
|
|
848
|
+
if: steps.stub.outputs.is_stub == 'true' && steps.eligibility.outputs.proceed == 'true' && (steps.srcgate.outputs.should_bump == 'true' || github.event_name == 'workflow_dispatch')
|
|
849
|
+
uses: actions/setup-node@v4
|
|
850
|
+
with:
|
|
851
|
+
node-version: 24.18.1
|
|
852
|
+
- name: "Setup pnpm (electron stub)"
|
|
853
|
+
if: steps.stub.outputs.is_stub == 'true' && steps.eligibility.outputs.proceed == 'true' && (steps.srcgate.outputs.should_bump == 'true' || github.event_name == 'workflow_dispatch')
|
|
854
|
+
uses: pnpm/action-setup@v4
|
|
855
|
+
with:
|
|
856
|
+
version: 11.20.0
|
|
857
|
+
- name: "Provision Wine + Xvfb (stub build)"
|
|
858
|
+
if: steps.stub.outputs.is_stub == 'true' && steps.eligibility.outputs.proceed == 'true' && (steps.srcgate.outputs.should_bump == 'true' || github.event_name == 'workflow_dispatch')
|
|
859
|
+
env:
|
|
860
|
+
DEBIAN_FRONTEND: noninteractive
|
|
861
|
+
run: |
|
|
862
|
+
# electron-builder's portable/NSIS target runs the stub under Wine and
|
|
863
|
+
# needs 32-bit libs + an X display. Prefer a runner that already has
|
|
864
|
+
# wine+xvfb baked in (no network). Only apt-install when missing, and
|
|
865
|
+
# NEVER hang: every apt call is time-boxed + lock-tolerant and its output
|
|
866
|
+
# is surfaced (not swallowed), so a broken runner fails LOUD + FAST with an
|
|
867
|
+
# actionable message instead of the old unguarded apt-get update stalling
|
|
868
|
+
# ~32 min then dying blind (observed on moko-lab-01, run 149092).
|
|
869
|
+
set -x
|
|
870
|
+
if command -v wine >/dev/null 2>&1 && command -v xvfb-run >/dev/null 2>&1; then
|
|
871
|
+
echo "::notice::wine + xvfb already present on runner — skipping apt provisioning"
|
|
872
|
+
else
|
|
873
|
+
sudo dpkg --add-architecture i386 || true
|
|
874
|
+
sudo timeout 180 apt-get update -o Acquire::Retries=2 -o DPkg::Lock::Timeout=120 -q || echo "::warning::apt-get update failed/timed out — trying install against existing lists"
|
|
875
|
+
sudo timeout 480 apt-get install -y -q --no-install-recommends -o DPkg::Lock::Timeout=120 xvfb wine64 wine32 || sudo timeout 480 apt-get install -y -q --no-install-recommends -o DPkg::Lock::Timeout=120 xvfb wine || echo "::warning::wine/xvfb apt install failed"
|
|
876
|
+
fi
|
|
877
|
+
command -v xvfb-run >/dev/null 2>&1 || { echo "::error::xvfb-run missing after provisioning — the release runner needs xvfb preinstalled (CI cannot build the Windows stub without a virtual display)"; exit 1; }
|
|
878
|
+
command -v wine >/dev/null 2>&1 || { echo "::error::wine missing after provisioning — the release runner needs wine (i386) preinstalled (CI cannot build the Windows stub under Wine)"; exit 1; }
|
|
879
|
+
export WINEDEBUG=-all
|
|
880
|
+
xvfb-run -a wineboot --init || echo "::warning::wineboot --init returned nonzero (prefix may still be usable)"
|
|
881
|
+
- name: "Fetch moko-installer (file: dep sibling) [stub]"
|
|
882
|
+
if: steps.stub.outputs.is_stub == 'true' && steps.eligibility.outputs.proceed == 'true' && (steps.srcgate.outputs.should_bump == 'true' || github.event_name == 'workflow_dispatch')
|
|
883
|
+
env:
|
|
884
|
+
# github.token is scoped to THIS repo only, so it CANNOT clone the
|
|
885
|
+
# cross-repo private moko-installer ("Repository not found"). Use the
|
|
886
|
+
# org MOKOGIT_TOKEN secret (cross-repo read); fall back to github.token.
|
|
887
|
+
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
|
888
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
889
|
+
run: |
|
|
890
|
+
# @mokoenterprises/moko-installer is a `file:../moko-installer` dep
|
|
891
|
+
# (local-dev link); a fresh runner checkout has no sibling, so clone it
|
|
892
|
+
# here. Channel->branch: the pre-release channels are all pre-stable, so
|
|
893
|
+
# pull moko-installer's dev branch (stable only exists in auto-release.yml).
|
|
894
|
+
# TODO(#544): if moko-installer grows per-channel branches, map rc->rc etc.
|
|
895
|
+
TOK="$(printf '%s' "${MOKOGIT_TOKEN:-$GITHUB_TOKEN}" | tr -d '[:space:]')"; echo "::add-mask::$TOK"
|
|
896
|
+
SRV="${GITHUB_SERVER_URL:-https://git.mokoenterprises.us}"
|
|
897
|
+
rm -rf ../moko-installer
|
|
898
|
+
# #546 (MEDIUM credential-exposure): do NOT embed the token in the clone
|
|
899
|
+
# URL — that persists it in ../moko-installer/.git/config and exposes it in
|
|
900
|
+
# the runner process list. Pass it as a one-shot http.extraHeader instead
|
|
901
|
+
# (the URL carries NO token), then rewrite origin to the clean URL so no
|
|
902
|
+
# credential lingers in .git/config. An always() cleanup step below removes
|
|
903
|
+
# ../moko-installer entirely.
|
|
904
|
+
REPO_URL="https://${SRV#https://}/MokoEnterprises/moko-installer.git"
|
|
905
|
+
git -c http.extraHeader="Authorization: token ${TOK}" clone --depth 1 -b dev "$REPO_URL" ../moko-installer
|
|
906
|
+
git -C ../moko-installer remote set-url origin "$REPO_URL"
|
|
907
|
+
- name: "Install dependencies (stub)"
|
|
908
|
+
if: steps.stub.outputs.is_stub == 'true' && steps.eligibility.outputs.proceed == 'true' && (steps.srcgate.outputs.should_bump == 'true' || github.event_name == 'workflow_dispatch')
|
|
909
|
+
run: pnpm install --no-frozen-lockfile
|
|
910
|
+
- name: "Build + publish stub installer + payload (#544)"
|
|
911
|
+
if: steps.stub.outputs.is_stub == 'true' && steps.eligibility.outputs.proceed == 'true' && (steps.srcgate.outputs.should_bump == 'true' || github.event_name == 'workflow_dispatch')
|
|
912
|
+
env:
|
|
913
|
+
HUSKY: "0"
|
|
914
|
+
WINEDEBUG: "-all"
|
|
915
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
916
|
+
# Scoped write:issue token for the installer bug-report feature (#86);
|
|
917
|
+
# absent on repos without the secret -> build-release just leaves it unset.
|
|
918
|
+
MOKO_REPORT_TOKEN: ${{ secrets.MOKO_REPORT_TOKEN }}
|
|
919
|
+
run: |
|
|
920
|
+
# tools/build-release.mjs: electron-builder --win dir (payload) ->
|
|
921
|
+
# buildInstaller (download mode) -> stub exe + payload tar.gz -> upload
|
|
922
|
+
# both to the channel release. Wrapped in xvfb-run so the nested
|
|
923
|
+
# electron-builder portable/NSIS pass has a virtual display under Wine.
|
|
924
|
+
# Channel = the dispatch stability (development on a dev push). 30-min
|
|
925
|
+
# guard (SIGTERM, then SIGKILL +30s), short of the job timeout so a
|
|
926
|
+
# regression fails loudly, not as a silent kill.
|
|
927
|
+
CH="${{ inputs.stability || 'development' }}"
|
|
928
|
+
timeout -k 30 1800 xvfb-run -a node tools/build-release.mjs --channel "$CH" --publish \
|
|
929
|
+
|| { rc=$?; echo "::error::build-release.mjs exited $rc (124 = 30-min guard) — see electron-builder output above"; exit $rc; }
|
|
930
|
+
|
|
931
|
+
- name: "Cleanup moko-installer clone (#546)"
|
|
932
|
+
# #546: always() — remove the cloned sibling so no checkout (and its
|
|
933
|
+
# .git/config) lingers on the shared runner workspace, even if a stub step
|
|
934
|
+
# above failed. LITERAL if: always() (never a continue-on-error expression,
|
|
935
|
+
# which Gitea would discard the whole workflow over); independent step — no
|
|
936
|
+
# needs:+always() fan-in. Safe no-op when the clone never happened.
|
|
937
|
+
if: always()
|
|
938
|
+
run: rm -rf ../moko-installer
|
|
939
|
+
|
|
940
|
+
# -- Electron pre-release: FACTORY installers (Windows via Wine + Linux) ----
|
|
803
941
|
# No Windows/macOS runner: cross-build Windows with Wine on the Ubuntu
|
|
804
942
|
# `release` runner, build Linux natively, skip macOS. Gated on is_electron
|
|
805
|
-
# so non-electron pre-releases are 100% unaffected.
|
|
943
|
+
# so non-electron pre-releases are 100% unaffected. ALSO gated on
|
|
944
|
+
# is_stub != 'true' (#544): a stub-opted repo runs the stub leg above INSTEAD,
|
|
945
|
+
# so these two paths are mutually exclusive.
|
|
806
946
|
- name: "Setup Node (electron)"
|
|
807
|
-
if: steps.eligibility.outputs.proceed == 'true' && steps.eligibility.outputs.is_electron == 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
947
|
+
if: steps.eligibility.outputs.proceed == 'true' && steps.eligibility.outputs.is_electron == 'true' && steps.stub.outputs.is_stub != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
808
948
|
uses: actions/setup-node@v4
|
|
809
949
|
with:
|
|
810
950
|
node-version: 24.18.1
|
|
811
951
|
- name: "Setup pnpm (electron)"
|
|
812
|
-
if: steps.eligibility.outputs.proceed == 'true' && steps.eligibility.outputs.is_electron == 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
952
|
+
if: steps.eligibility.outputs.proceed == 'true' && steps.eligibility.outputs.is_electron == 'true' && steps.stub.outputs.is_stub != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
813
953
|
uses: pnpm/action-setup@v4
|
|
814
954
|
with:
|
|
815
955
|
version: 11.20.0
|
|
816
956
|
- name: "Build electron installers (Windows via Wine + Linux) [pre-release]"
|
|
817
|
-
if: steps.eligibility.outputs.publish == 'true' && steps.eligibility.outputs.is_electron == 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
957
|
+
if: steps.eligibility.outputs.publish == 'true' && steps.eligibility.outputs.is_electron == 'true' && steps.stub.outputs.is_stub != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
818
958
|
env:
|
|
819
959
|
HUSKY: "0"
|
|
820
960
|
run: |
|
|
@@ -853,7 +993,7 @@ jobs:
|
|
|
853
993
|
# and the build fails ("no driver could be loaded / $DISPLAY").
|
|
854
994
|
xvfb-run -a npx --no-install electron-builder --win --linux --publish never || xvfb-run -a npx electron-builder --win --linux --publish never
|
|
855
995
|
- name: "Attach electron installers (pre-release)"
|
|
856
|
-
if: steps.eligibility.outputs.publish == 'true' && steps.eligibility.outputs.is_electron == 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
996
|
+
if: steps.eligibility.outputs.publish == 'true' && steps.eligibility.outputs.is_electron == 'true' && steps.stub.outputs.is_stub != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
857
997
|
continue-on-error: true
|
|
858
998
|
run: |
|
|
859
999
|
API_BASE="${GIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
|
@@ -1138,6 +1278,59 @@ jobs:
|
|
|
1138
1278
|
--repo "${GIT_REPO}" --out "$RUNNER_TEMP" \
|
|
1139
1279
|
--stability "$STABILITY" --rolling
|
|
1140
1280
|
|
|
1281
|
+
- name: Deploy over SFTP to dev (generic, presence-gated)
|
|
1282
|
+
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/dev' && vars.SFTP_DEV_HOST != '' }}
|
|
1283
|
+
env:
|
|
1284
|
+
DEPLOY_KEY: ${{ secrets.SFTP_DEV_KEY }}
|
|
1285
|
+
KNOWN_HOSTS: ${{ vars.SFTP_DEV_KNOWN_HOSTS }}
|
|
1286
|
+
SSH_USER: ${{ vars.SFTP_DEV_USER }}
|
|
1287
|
+
SSH_HOST: ${{ vars.SFTP_DEV_HOST }}
|
|
1288
|
+
SSH_PORT: ${{ vars.SFTP_DEV_PORT }}
|
|
1289
|
+
DEST: ${{ vars.SFTP_DEV_PATH }}
|
|
1290
|
+
# expected parent prefix for $DEST; $DEST must live UNDER this. Set this
|
|
1291
|
+
# repo/org variable (e.g. "/home/<user>/" or the webroot parent) to arm the
|
|
1292
|
+
# guard. Left empty → guard allows any non-root $DEST (back-compat).
|
|
1293
|
+
DEST_PREFIX: ${{ vars.SFTP_DEV_PATH_PREFIX }}
|
|
1294
|
+
run: |
|
|
1295
|
+
set -euo pipefail
|
|
1296
|
+
# never leave the deploy key / known_hosts on a shared runner
|
|
1297
|
+
trap 'rm -f ~/.ssh/id_sftp_deploy ~/.ssh/known_hosts_sftp' EXIT
|
|
1298
|
+
[ -n "$DEST" ] && [ "$DEST" != "/" ] || { echo "SFTP_DEV_PATH empty/root; refusing"; exit 1; }
|
|
1299
|
+
# SECURITY: validate $DEST against an expected prefix so a mis-set variable
|
|
1300
|
+
# can never point the (atomic, but destructive) swap at an arbitrary path.
|
|
1301
|
+
case "$DEST" in
|
|
1302
|
+
*/../*|*/..) echo "SFTP_DEV_PATH contains '..'; refusing"; exit 1 ;;
|
|
1303
|
+
esac
|
|
1304
|
+
if [ -n "${DEST_PREFIX:-}" ]; then
|
|
1305
|
+
case "$DEST" in
|
|
1306
|
+
"$DEST_PREFIX"*) : ;;
|
|
1307
|
+
*) echo "SFTP_DEV_PATH ($DEST) not under SFTP_DEV_PATH_PREFIX ($DEST_PREFIX); refusing"; exit 1 ;;
|
|
1308
|
+
esac
|
|
1309
|
+
fi
|
|
1310
|
+
install -d -m 700 ~/.ssh
|
|
1311
|
+
install -m600 /dev/null ~/.ssh/id_sftp_deploy # 0600 before any bytes (no umask window)
|
|
1312
|
+
printf '%s\n' "$DEPLOY_KEY" > ~/.ssh/id_sftp_deploy; chmod 600 ~/.ssh/id_sftp_deploy
|
|
1313
|
+
printf '%s\n' "$KNOWN_HOSTS" > ~/.ssh/known_hosts_sftp; chmod 644 ~/.ssh/known_hosts_sftp
|
|
1314
|
+
SSH="ssh -i $HOME/.ssh/id_sftp_deploy -p ${SSH_PORT:-22} -o UserKnownHostsFile=$HOME/.ssh/known_hosts_sftp -o StrictHostKeyChecking=yes -o IdentitiesOnly=yes"
|
|
1315
|
+
# Extend excludes to credential/dotfiles so secrets in the working tree are
|
|
1316
|
+
# never shipped. FOLLOW-UP (#<issue>): replace this whole-tree tar with an
|
|
1317
|
+
# explicit allowlist of the built release artifact (dist/ or the packaged
|
|
1318
|
+
# zip) once the per-platform build-output path is wired through here.
|
|
1319
|
+
TAR_EXCLUDES="--exclude=.git --exclude=.mokogit --exclude=.github \
|
|
1320
|
+
--exclude='*.token' --exclude='*.token.json' \
|
|
1321
|
+
--exclude=.env --exclude='.env.*' --exclude=.npmrc --exclude=auth.json \
|
|
1322
|
+
--exclude='*.pem' --exclude='*.key' --exclude='*.p12' --exclude='*.pfx' \
|
|
1323
|
+
--exclude=.ssh --exclude=.netrc --exclude=.aws --exclude=.docker"
|
|
1324
|
+
# Deploy to a staging dir, then atomically swap — never rm -rf the live path.
|
|
1325
|
+
STAGE="${DEST%/}.stage.$$"
|
|
1326
|
+
BACKUP="${DEST%/}.prev.$$"
|
|
1327
|
+
$SSH "$SSH_USER@$SSH_HOST" "rm -rf \"$STAGE\" && mkdir -p \"$STAGE\""
|
|
1328
|
+
eval tar czf - $TAR_EXCLUDES . | $SSH "$SSH_USER@$SSH_HOST" "tar xzf - -C \"$STAGE\""
|
|
1329
|
+
$SSH "$SSH_USER@$SSH_HOST" "set -e; \
|
|
1330
|
+
if [ -e \"$DEST\" ]; then rm -rf \"$BACKUP\"; mv \"$DEST\" \"$BACKUP\"; fi; \
|
|
1331
|
+
mkdir -p \"\$(dirname \"$DEST\")\"; mv \"$STAGE\" \"$DEST\"; rm -rf \"$BACKUP\""
|
|
1332
|
+
echo "Deployed to dev: $SSH_HOST:$DEST"
|
|
1333
|
+
|
|
1141
1334
|
# updates.xml <downloadurl> is generated server-side by MokoGIT (the license
|
|
1142
1335
|
# server; being moved to MokoSuiteLicensing). It must reference the VERSIONED
|
|
1143
1336
|
# rolling asset (pkg_<ext>-<version>-dev.zip) that release_package.php now
|
|
@@ -1169,4 +1362,4 @@ jobs:
|
|
|
1169
1362
|
echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
|
|
1170
1363
|
echo "| Channel | ${STABILITY} |" >> $GITHUB_STEP_SUMMARY
|
|
1171
1364
|
echo "| Package | \`${ZIP_NAME}\` |" >> $GITHUB_STEP_SUMMARY
|
|
1172
|
-
echo "| SHA-256 | \`${SHA256:-n/a}\` |" >> $GITHUB_STEP_SUMMARY
|
|
1365
|
+
echo "| SHA-256 | \`${SHA256:-n/a}\` |" >> $GITHUB_STEP_SUMMARY
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# Copyright (C) 2026 Moko
|
|
1
|
+
# Copyright (C) 2026 Moko Enterprises <hello@mokoenterprises.us>
|
|
2
2
|
#
|
|
3
3
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
4
|
#
|
|
5
5
|
# FILE INFORMATION
|
|
6
6
|
# DEFGROUP: MokoGIT.Workflow
|
|
7
7
|
# INGROUP: MokoCLI.Universal
|
|
8
|
-
# REPO: https://git.
|
|
8
|
+
# REPO: https://git.mokoenterprises.us/MokoEnterprises/Template-Generic
|
|
9
9
|
# PATH: /.mokogit/workflows/rc-revert.yml
|
|
10
10
|
# VERSION: 09.23.00
|
|
11
11
|
# BRIEF: Rename rc/ branch back to dev/ when PR is closed without merge
|
|
@@ -36,7 +36,7 @@ jobs:
|
|
|
36
36
|
env:
|
|
37
37
|
BRANCH: ${{ github.event.pull_request.head.ref }}
|
|
38
38
|
REPO: ${{ github.repository }}
|
|
39
|
-
GIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.
|
|
39
|
+
GIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoenterprises.us' }}
|
|
40
40
|
TOKEN: ${{ github.token }}
|
|
41
41
|
run: |
|
|
42
42
|
set -euo pipefail
|
package/AGENTS.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
Copyright 2026 Moko
|
|
2
|
+
Copyright 2026 Moko Enterprises
|
|
3
3
|
SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
4
|
BRIEF: Shared AI-agent instruction source of truth for this repository.
|
|
5
5
|
This file is the single point of truth;
|
|
@@ -37,7 +37,7 @@ automation (fork of `mcp-ssh-manager`).
|
|
|
37
37
|
- Never commit `.claude/`, `.gemini/`, `.mokoai/`, `.mcp.json`, `TODO.md`, or
|
|
38
38
|
minified assets.
|
|
39
39
|
- Workflow / automation config lives under `.mokogit/`.
|
|
40
|
-
- Attribute all machine-authored commits with `Authored-by: Moko
|
|
40
|
+
- Attribute all machine-authored commits with `Authored-by: Moko Enterprises`.
|
|
41
41
|
- Follow the credential rules: never hardcode SSH keys, passwords, or hosts;
|
|
42
42
|
use `.env` (from `.env.example`) and `profiles/`.
|
|
43
|
-
- Standards: MokoCLI — https://git.
|
|
43
|
+
- Standards: MokoCLI — https://git.mokoenterprises.us/MokoEnterprises/mokocli/wiki/Home
|
package/CHANGELOG.md
CHANGED
|
@@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
10
10
|
## [3.6.1] - 2026-07-30
|
|
11
11
|
|
|
12
12
|
### Fixed
|
|
13
|
-
- `npx @mokoconsulting/mokossh-mcp` failing with "could not determine executable to run" under Node 24 / npm 11 ([#33](https://git.
|
|
13
|
+
- `npx @mokoconsulting/mokossh-mcp` failing with "could not determine executable to run" under Node 24 / npm 11 ([#33](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/issues/33)). The package declared multiple bins, none matching the package name, so npm 11's stricter `npx` refused to guess which to run. Added a package-name-matching `mokossh-mcp` bin (the existing `mokossh-mcp` and `ssh-manager` remain as aliases) so `npx @mokoconsulting/mokossh-mcp` resolves deterministically without needing `-p`.
|
|
14
14
|
|
|
15
15
|
## [3.5.0] --- 2026-07-22
|
|
16
16
|
|
package/CONTRIBUTING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Contributing to Moko
|
|
1
|
+
# Contributing to Moko Enterprises Projects
|
|
2
2
|
|
|
3
|
-
Thank you for your interest in contributing. All Moko
|
|
3
|
+
Thank you for your interest in contributing. All Moko Enterprises repositories follow this universal workflow and version policy.
|
|
4
4
|
|
|
5
5
|
## Branching Workflow
|
|
6
6
|
|
|
@@ -130,9 +130,9 @@ Files synced from other repos (with a `# REPO:` header) are not touched.
|
|
|
130
130
|
## Code Standards
|
|
131
131
|
|
|
132
132
|
- **PHP**: PSR-12, tabs for indentation
|
|
133
|
-
- **Copyright**: all files must include the Moko
|
|
133
|
+
- **Copyright**: all files must include the Moko Enterprises copyright header
|
|
134
134
|
- **License**: SPDX identifier `GPL-3.0-or-later` (or as specified per repo)
|
|
135
|
-
- **Attribution**: use `Authored-by: Moko
|
|
135
|
+
- **Attribution**: use `Authored-by: Moko Enterprises` in commits, not individual names
|
|
136
136
|
|
|
137
137
|
## Commit Messages
|
|
138
138
|
|
|
@@ -143,7 +143,7 @@ type(scope): short description
|
|
|
143
143
|
|
|
144
144
|
Optional body with context.
|
|
145
145
|
|
|
146
|
-
Authored-by: Moko
|
|
146
|
+
Authored-by: Moko Enterprises
|
|
147
147
|
```
|
|
148
148
|
|
|
149
149
|
Types: `feat`, `fix`, `chore`, `docs`, `style`, `refactor`, `test`, `ci`
|
|
@@ -158,4 +158,4 @@ Use the repository's issue tracker with the appropriate template.
|
|
|
158
158
|
|
|
159
159
|
---
|
|
160
160
|
|
|
161
|
-
*Moko
|
|
161
|
+
*Moko Enterprises <hello@mokoenterprises.us>*
|
package/Makefile
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# NPM / Node Project Makefile
|
|
2
|
-
# Copyright (C) 2026 Moko
|
|
2
|
+
# Copyright (C) 2026 Moko Enterprises <hello@mokoenterprises.us>
|
|
3
3
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
4
|
#
|
|
5
5
|
# Native build/test/lint/package logic for an npm package (incl. MCP servers). The
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
# Identity (auto-filled by workflow sync — the Makefile is the version source of truth)
|
|
11
11
|
# ==============================================================================
|
|
12
12
|
PROJECT_NAME := mcp-mokossh
|
|
13
|
-
|
|
13
|
+
DISPLAY_NAME := MokoSSH MCP
|
|
14
|
+
PROJECT_VERSION := 03.09.00
|
|
14
15
|
PLATFORM := npm
|
|
15
16
|
|
|
16
17
|
# ==============================================================================
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Model Context Protocol server for SSH remote server management -- execute comman
|
|
|
16
16
|
| **Tools** | 37 tools across 6 groups |
|
|
17
17
|
| **License** | MIT |
|
|
18
18
|
| **Upstream** | [bvisible/mcp-ssh-manager](https://github.com/bvisible/mcp-ssh-manager) v3.4.0 |
|
|
19
|
-
| **Platform** | [MokoGIT](https://git.
|
|
19
|
+
| **Platform** | [MokoGIT](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp) (primary) |
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
@@ -41,24 +41,24 @@ mokossh-mcp exposes 37 tools that let Claude Code manage remote servers over SSH
|
|
|
41
41
|
|
|
42
42
|
### Guides
|
|
43
43
|
|
|
44
|
-
- [Installation](https://git.
|
|
45
|
-
- [Deployment Guide](https://git.
|
|
46
|
-
- [Backup Guide](https://git.
|
|
44
|
+
- [Installation](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki/INSTALLATION) -- prerequisites, install steps, .env configuration, Claude Code registration, multi-server setup, troubleshooting
|
|
45
|
+
- [Deployment Guide](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki/DEPLOYMENT_GUIDE) -- deploying files to remote servers with permission handling
|
|
46
|
+
- [Backup Guide](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki/BACKUP_GUIDE) -- database and file backup/restore workflows
|
|
47
47
|
|
|
48
48
|
### Reference
|
|
49
49
|
|
|
50
|
-
- [API](https://git.
|
|
51
|
-
- [Architecture](https://git.
|
|
52
|
-
- [Tool Management](https://git.
|
|
50
|
+
- [API](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki/API) -- all 37 tools organized by group with descriptions and key parameters
|
|
51
|
+
- [Architecture](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki/ARCHITECTURE) -- source file map, component responsibilities, tool activation system, connection pooling, design decisions
|
|
52
|
+
- [Tool Management](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki/TOOL_MANAGEMENT) -- tool enablement configuration and the `ssh-manager tools` CLI
|
|
53
53
|
|
|
54
54
|
### Operations
|
|
55
55
|
|
|
56
|
-
- [Aliases and Hooks](https://git.
|
|
56
|
+
- [Aliases and Hooks](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki/ALIASES_AND_HOOKS) -- server aliases, command aliases, and automation hooks
|
|
57
57
|
|
|
58
58
|
### Marketing
|
|
59
59
|
|
|
60
|
-
- [SEO](https://git.
|
|
61
|
-
- [Social Media Announcement](https://git.
|
|
60
|
+
- [SEO](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki/SEO) -- search engine optimization notes
|
|
61
|
+
- [Social Media Announcement](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki/SOCIAL_MEDIA_ANNOUNCEMENT) -- launch announcement templates
|
|
62
62
|
|
|
63
63
|
---
|
|
64
64
|
|
|
@@ -66,13 +66,13 @@ mokossh-mcp exposes 37 tools that let Claude Code manage remote servers over SSH
|
|
|
66
66
|
|
|
67
67
|
| Repo | Purpose |
|
|
68
68
|
|------|---------|
|
|
69
|
-
| [deploy-mcp](https://git.
|
|
70
|
-
| [monitor-mcp](https://git.
|
|
71
|
-
| [backup-mcp](https://git.
|
|
69
|
+
| [deploy-mcp](https://git.mokoenterprises.us/MokoEnterprises/deploy-mcp/wiki) | Git-based deployment MCP |
|
|
70
|
+
| [monitor-mcp](https://git.mokoenterprises.us/MokoEnterprises/monitor-mcp/wiki) | Server and Grafana monitoring MCP |
|
|
71
|
+
| [backup-mcp](https://git.mokoenterprises.us/MokoEnterprises/backup-mcp/wiki) | Backup MCP with Akeeba integration |
|
|
72
72
|
|
|
73
73
|
---
|
|
74
74
|
|
|
75
|
-
> **[MokoCLI](https://git.
|
|
75
|
+
> **[MokoCLI](https://git.mokoenterprises.us/MokoEnterprises/mokocli)** -- enterprise CLI automation for all Moko Enterprises repositories.
|
|
76
76
|
|
|
77
77
|
---
|
|
78
78
|
|
|
@@ -99,12 +99,12 @@ npm install -g @mokoconsulting/mokossh-mcp
|
|
|
99
99
|
From source:
|
|
100
100
|
|
|
101
101
|
```bash
|
|
102
|
-
git clone https://git.
|
|
102
|
+
git clone https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp.git
|
|
103
103
|
cd mokossh-mcp
|
|
104
104
|
npm install
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
Configure your servers and credentials via a `.env` file — see the [Installation guide](https://git.
|
|
107
|
+
Configure your servers and credentials via a `.env` file — see the [Installation guide](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki/INSTALLATION) for prerequisites and multi-server setup.
|
|
108
108
|
|
|
109
109
|
## Usage
|
|
110
110
|
|
|
@@ -121,17 +121,17 @@ Register the server with an MCP client such as Claude Code by adding it to your
|
|
|
121
121
|
}
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
Once connected, the agent can call all 37 tools across the six groups (Core, Database, Backup, Monitoring, Deployment, Automation) to execute commands, transfer files, run database operations, create backups, monitor health, and automate DevOps workflows on remote servers. Tool enablement is managed with the `ssh-manager tools` CLI. See the [API reference](https://git.
|
|
124
|
+
Once connected, the agent can call all 37 tools across the six groups (Core, Database, Backup, Monitoring, Deployment, Automation) to execute commands, transfer files, run database operations, create backups, monitor health, and automate DevOps workflows on remote servers. Tool enablement is managed with the `ssh-manager tools` CLI. See the [API reference](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki/API) for every tool and its parameters.
|
|
125
125
|
|
|
126
126
|
---
|
|
127
127
|
|
|
128
128
|
## Documentation
|
|
129
129
|
|
|
130
|
-
Full documentation is available on the [Wiki](https://git.
|
|
130
|
+
Full documentation is available on the [Wiki](https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp/wiki).
|
|
131
131
|
|
|
132
132
|
## Contributing
|
|
133
133
|
|
|
134
|
-
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) and follow the [MokoStandards](https://git.
|
|
134
|
+
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) and follow the [MokoStandards](https://git.mokoenterprises.us/MokoEnterprises/mokocli/wiki/Home). See the wiki for development guidelines and contribution instructions.
|
|
135
135
|
|
|
136
136
|
## License
|
|
137
137
|
|
|
@@ -139,4 +139,4 @@ This project is licensed under the GNU General Public License v3.0 or later -- s
|
|
|
139
139
|
|
|
140
140
|
---
|
|
141
141
|
|
|
142
|
-
*[Moko
|
|
142
|
+
*[Moko Enterprises](https://mokoenterprises.us) -- [MokoCLI](https://git.mokoenterprises.us/MokoEnterprises/mokocli)*
|
package/SECURITY.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- Copyright (C) 2026 Moko
|
|
1
|
+
<!-- Copyright (C) 2026 Moko Enterprises <hello@mokoenterprises.us>
|
|
2
2
|
Based on mcp-ssh-manager by MCP SSH Manager Contributors (MIT License)
|
|
3
3
|
SPDX-License-Identifier: MIT
|
|
4
4
|
-->
|
|
@@ -128,7 +128,7 @@ reinstallation.
|
|
|
128
128
|
|
|
129
129
|
If you discover a security issue, please report it privately:
|
|
130
130
|
|
|
131
|
-
- Email: hello@
|
|
131
|
+
- Email: hello@mokoenterprises.us
|
|
132
132
|
- Do **not** open a public issue for security vulnerabilities.
|
|
133
133
|
|
|
134
134
|
We will acknowledge receipt within 48 hours and aim to release a fix
|
package/package.json
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mokoenterprises/mokossh-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.0",
|
|
4
4
|
"description": "MCP server for SSH remote server management — execute commands, transfer files, database operations, backups, health monitoring, and DevOps automation",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"mcp-mokossh": "
|
|
8
|
-
"mokossh-mcp": "
|
|
7
|
+
"mcp-mokossh": "dist/index.js",
|
|
8
|
+
"mokossh-mcp": "dist/index.js",
|
|
9
9
|
"ssh-manager": "cli/ssh-manager.js"
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
12
12
|
"scripts": {
|
|
13
13
|
"start": "node source/index.js",
|
|
14
14
|
"build": "esbuild source/index.js --bundle --platform=node --format=esm --target=node20 --packages=external --outfile=dist/index.js",
|
|
15
|
-
"test": "
|
|
15
|
+
"test": "echo \"(no tests)\"",
|
|
16
16
|
"test:profiles": "node tests/test-profiles.js",
|
|
17
17
|
"test:aliases": "node tests/test-command-aliases.js",
|
|
18
18
|
"test:hooks": "node tests/test-hooks.js",
|
|
19
19
|
"test:tools": "node tests/test-tool-registry.js",
|
|
20
20
|
"lint": "eslint source/*.js",
|
|
21
|
-
"format": "prettier --write 'source/**/*.js' 'tests/**/*.js'"
|
|
21
|
+
"format": "prettier --write 'source/**/*.js' 'tests/**/*.js'",
|
|
22
|
+
"deploy": "node tools/deploy.mjs"
|
|
22
23
|
},
|
|
23
24
|
"dependencies": {
|
|
24
25
|
"@iarna/toml": "^2.2.5",
|
|
@@ -39,11 +40,11 @@
|
|
|
39
40
|
"license": "MIT",
|
|
40
41
|
"author": "MCP SSH Manager Contributors",
|
|
41
42
|
"contributors": [
|
|
42
|
-
"Moko
|
|
43
|
+
"Moko Enterprises <hello@mokoenterprises.us>"
|
|
43
44
|
],
|
|
44
45
|
"repository": {
|
|
45
46
|
"type": "git",
|
|
46
|
-
"url": "https://git.
|
|
47
|
+
"url": "https://git.mokoenterprises.us/MokoEnterprises/mokossh-mcp.git"
|
|
47
48
|
},
|
|
48
49
|
"upstream": {
|
|
49
50
|
"url": "https://github.com/bvisible/mcp-ssh-manager",
|
package/source/token-reader.js
CHANGED
package/tools/deploy.mjs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Deploy this MCP server to ~/mcp/<name> (portable; creates the target if missing).
|
|
3
|
+
// Usage: npm run deploy -> ~/mcp/<pkgname minus -mcp>
|
|
4
|
+
// override: node tools/deploy.mjs <name> | MCP_DEPLOY_NAME=.. | MCP_DEPLOY_DIR=..
|
|
5
|
+
import { mkdirSync, cpSync, rmSync, existsSync, readFileSync } from 'node:fs';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { join, dirname, resolve } from 'node:path';
|
|
8
|
+
import { execSync } from 'node:child_process';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
11
|
+
const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
|
|
12
|
+
const base = (pkg.name || 'mcp-server').split('/').pop().replace(/-mcp$/, '');
|
|
13
|
+
const name = process.argv[2] || process.env.MCP_DEPLOY_NAME || base;
|
|
14
|
+
const mcpDir = process.env.MCP_DEPLOY_DIR || join(homedir(), 'mcp');
|
|
15
|
+
const dest = join(mcpDir, name);
|
|
16
|
+
console.log(`Deploy ${pkg.name}@${pkg.version} -> ${dest}`);
|
|
17
|
+
mkdirSync(dest, { recursive: true });
|
|
18
|
+
execSync('npm run build', { cwd: root, stdio: 'inherit' });
|
|
19
|
+
for (const item of ['dist', 'package.json', 'package-lock.json']) {
|
|
20
|
+
const src = join(root, item); if (!existsSync(src)) continue;
|
|
21
|
+
const to = join(dest, item);
|
|
22
|
+
if (existsSync(to) && item === 'dist') rmSync(to, { recursive: true, force: true });
|
|
23
|
+
cpSync(src, to, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
try { execSync('npm ci --omit=dev --no-audit --no-fund', { cwd: dest, stdio: 'inherit' }); }
|
|
26
|
+
catch { execSync('npm install --omit=dev --no-audit --no-fund', { cwd: dest, stdio: 'inherit' }); }
|
|
27
|
+
console.log(`OK deployed -> ${dest}`);
|