@mokoconsulting/mcp-mokosuite 1.0.0 → 1.1.0-dev.372
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/workflows/auto-bump.yml +8 -0
- package/.mokogit/workflows/auto-release.yml +184 -71
- package/.mokogit/workflows/cascade-dev.yml +128 -60
- package/.mokogit/workflows/changelog-validation.yml +41 -25
- package/.mokogit/workflows/ci-issue-reporter.yml +1 -1
- package/.mokogit/workflows/cleanup.yml +3 -3
- package/.mokogit/workflows/custom-workflow-sync-trigger.yml +83 -0
- package/.mokogit/workflows/issue-branch.yml +1 -1
- package/.mokogit/workflows/npm-build-test.yml +103 -19
- package/.mokogit/workflows/npm-prerelease.yml +174 -0
- package/.mokogit/workflows/npm-publish.yml +44 -17
- package/.mokogit/workflows/pr-check.yml +181 -53
- package/.mokogit/workflows/pre-release.yml +174 -35
- package/.mokogit/workflows/rc-revert.yml +1 -1
- package/.mokogit/workflows/version-set.yml +4 -4
- package/AGENTS.md +39 -0
- package/CHANGELOG.md +46 -10
- package/dist/index.js +28 -1
- package/docs/API.md +54 -45
- package/package.json +1 -1
- package/src/index.ts +59 -1
- package/.mokogit/workflows/ci-generic.yml +0 -203
- package/.mokogit/workflows/repo-health.yml +0 -700
- package/.mokogit/workflows/standards-compliance.yml +0 -2507
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -25,6 +25,9 @@ import type { ApiConfig, ApiResponse } from './types.js';
|
|
|
25
25
|
/** Base path for MokoSuiteClient Web Services (appended after /api/index.php). */
|
|
26
26
|
const MSC = '/v1/mokosuiteclient';
|
|
27
27
|
|
|
28
|
+
/** Base path for MokoSuiteExtensions (store) Web Services (appended after /api/index.php). */
|
|
29
|
+
const MSE = '/v1/mokosuiteextensions';
|
|
30
|
+
|
|
28
31
|
let config: ApiConfig;
|
|
29
32
|
|
|
30
33
|
function clientFor(connection?: string): ApiClient {
|
|
@@ -64,7 +67,7 @@ function requireConfirm(confirm: boolean): { content: Array<{ type: 'text'; text
|
|
|
64
67
|
|
|
65
68
|
const server = new McpServer({
|
|
66
69
|
name: 'mcp-mokosuite',
|
|
67
|
-
version: '1.
|
|
70
|
+
version: '1.1.0',
|
|
68
71
|
});
|
|
69
72
|
|
|
70
73
|
// ════════════════════════════════════════════════════════════════════════
|
|
@@ -322,6 +325,61 @@ server.tool(
|
|
|
322
325
|
},
|
|
323
326
|
);
|
|
324
327
|
|
|
328
|
+
// ════════════════════════════════════════════════════════════════════════
|
|
329
|
+
// LAYER 1 — Extensions Store (MokoSuiteExtensions)
|
|
330
|
+
// ════════════════════════════════════════════════════════════════════════
|
|
331
|
+
|
|
332
|
+
server.tool(
|
|
333
|
+
'store_catalog_list',
|
|
334
|
+
'List the products available in the MokoSuite Extensions store catalog for a site.',
|
|
335
|
+
{ ...ConnectionParam },
|
|
336
|
+
async ({ connection }) => formatResponse(await clientFor(connection).get(`${MSE}/catalog`)),
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
server.tool(
|
|
340
|
+
'store_catalog_get',
|
|
341
|
+
'Get a single MokoSuite Extensions store product by its catalog id.',
|
|
342
|
+
{
|
|
343
|
+
id: z.number().describe('Catalog product id'),
|
|
344
|
+
...ConnectionParam,
|
|
345
|
+
},
|
|
346
|
+
async ({ id, connection }) => formatResponse(await clientFor(connection).get(`${MSE}/catalog/${id}`)),
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
server.tool(
|
|
350
|
+
'store_install',
|
|
351
|
+
'Install a MokoSuite Extensions store product on a site by its catalog id.',
|
|
352
|
+
{
|
|
353
|
+
id: z.number().describe('Catalog product id to install'),
|
|
354
|
+
...ConnectionParam,
|
|
355
|
+
},
|
|
356
|
+
async ({ id, connection }) => formatResponse(await clientFor(connection).post(`${MSE}/catalog/${id}/install`)),
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
server.tool(
|
|
360
|
+
'store_update',
|
|
361
|
+
'Update an installed MokoSuite Extensions store product on a site by its catalog id.',
|
|
362
|
+
{
|
|
363
|
+
id: z.number().describe('Catalog product id to update'),
|
|
364
|
+
...ConnectionParam,
|
|
365
|
+
},
|
|
366
|
+
async ({ id, connection }) => formatResponse(await clientFor(connection).post(`${MSE}/catalog/${id}/update`)),
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
server.tool(
|
|
370
|
+
'store_uninstall',
|
|
371
|
+
'Uninstall a MokoSuite Extensions store product from a site by its catalog id. Destructive — requires `confirm: true`.',
|
|
372
|
+
{
|
|
373
|
+
id: z.number().describe('Catalog product id to uninstall'),
|
|
374
|
+
confirm: z.boolean().describe('Must be true — uninstalling removes the product from the target site'),
|
|
375
|
+
...ConnectionParam,
|
|
376
|
+
},
|
|
377
|
+
async ({ id, confirm, connection }) => {
|
|
378
|
+
if (!confirm) return text('Refused: set `confirm: true` to uninstall this store product.');
|
|
379
|
+
return formatResponse(await clientFor(connection).post(`${MSE}/catalog/${id}/uninstall`));
|
|
380
|
+
},
|
|
381
|
+
);
|
|
382
|
+
|
|
325
383
|
// ── Start Server ────────────────────────────────────────────────────────
|
|
326
384
|
|
|
327
385
|
async function main(): Promise<void> {
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
2
|
-
#
|
|
3
|
-
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
-
#
|
|
5
|
-
# FILE INFORMATION
|
|
6
|
-
# DEFGROUP: MokoGIT.Workflow
|
|
7
|
-
# INGROUP: MokoCLI.CI
|
|
8
|
-
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
|
9
|
-
# PATH: /.mokogit/workflows/ci-generic.yml
|
|
10
|
-
# VERSION: 01.00.00
|
|
11
|
-
# BRIEF: CI pipeline — lint, validate, and test for generic projects (PHP + Node.js)
|
|
12
|
-
|
|
13
|
-
name: "Generic: Project CI"
|
|
14
|
-
|
|
15
|
-
on:
|
|
16
|
-
pull_request:
|
|
17
|
-
branches:
|
|
18
|
-
- main
|
|
19
|
-
- dev
|
|
20
|
-
- dev/**
|
|
21
|
-
- rc/**
|
|
22
|
-
workflow_dispatch:
|
|
23
|
-
|
|
24
|
-
permissions:
|
|
25
|
-
contents: read
|
|
26
|
-
|
|
27
|
-
env:
|
|
28
|
-
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
29
|
-
|
|
30
|
-
jobs:
|
|
31
|
-
# ── Lint & Validate ───────────────────────────────────────────────────
|
|
32
|
-
lint:
|
|
33
|
-
name: Lint & Validate
|
|
34
|
-
runs-on: ubuntu-latest
|
|
35
|
-
# Skip on template repos (Template-*) — they hold placeholder scaffolding, not buildable source.
|
|
36
|
-
if: ${{ !startsWith(github.event.repository.name, 'Template-') }}
|
|
37
|
-
|
|
38
|
-
steps:
|
|
39
|
-
- name: Checkout
|
|
40
|
-
uses: actions/checkout@v4
|
|
41
|
-
|
|
42
|
-
- name: Detect toolchain
|
|
43
|
-
id: detect
|
|
44
|
-
run: |
|
|
45
|
-
HAS_PHP=false
|
|
46
|
-
HAS_NODE=false
|
|
47
|
-
[ -f "composer.json" ] && HAS_PHP=true
|
|
48
|
-
[ -f "package.json" ] && HAS_NODE=true
|
|
49
|
-
echo "has_php=$HAS_PHP" >> "$GITHUB_OUTPUT"
|
|
50
|
-
echo "has_node=$HAS_NODE" >> "$GITHUB_OUTPUT"
|
|
51
|
-
echo "Toolchain: PHP=$HAS_PHP Node=$HAS_NODE"
|
|
52
|
-
|
|
53
|
-
- name: Setup PHP
|
|
54
|
-
if: steps.detect.outputs.has_php == 'true'
|
|
55
|
-
run: |
|
|
56
|
-
if ! command -v php &> /dev/null; then
|
|
57
|
-
sudo apt-get update -qq
|
|
58
|
-
sudo apt-get install -y -qq php-cli php-mbstring php-xml >/dev/null 2>&1
|
|
59
|
-
fi
|
|
60
|
-
php -v
|
|
61
|
-
|
|
62
|
-
- name: Setup Node.js
|
|
63
|
-
if: steps.detect.outputs.has_node == 'true'
|
|
64
|
-
uses: actions/setup-node@v4
|
|
65
|
-
with:
|
|
66
|
-
node-version: '20'
|
|
67
|
-
|
|
68
|
-
- name: Install PHP dependencies
|
|
69
|
-
if: steps.detect.outputs.has_php == 'true'
|
|
70
|
-
run: |
|
|
71
|
-
if [ -f "composer.json" ]; then
|
|
72
|
-
composer install --no-interaction --prefer-dist --quiet 2>/dev/null || true
|
|
73
|
-
fi
|
|
74
|
-
|
|
75
|
-
- name: Install Node.js dependencies
|
|
76
|
-
if: steps.detect.outputs.has_node == 'true'
|
|
77
|
-
run: |
|
|
78
|
-
if [ -f "package.json" ]; then
|
|
79
|
-
npm ci --quiet 2>/dev/null || npm install --quiet 2>/dev/null || true
|
|
80
|
-
fi
|
|
81
|
-
|
|
82
|
-
- name: PHP syntax check
|
|
83
|
-
if: steps.detect.outputs.has_php == 'true'
|
|
84
|
-
run: |
|
|
85
|
-
ERRORS=0
|
|
86
|
-
while IFS= read -r -d '' file; do
|
|
87
|
-
if ! php -l "$file" 2>&1 | grep -q "No syntax errors"; then
|
|
88
|
-
echo "::error file=${file}::PHP syntax error"
|
|
89
|
-
ERRORS=$((ERRORS + 1))
|
|
90
|
-
fi
|
|
91
|
-
done < <(find . -name "*.php" -not -path "./.git/*" -not -path "./vendor/*" -not -path "./node_modules/*" -print0)
|
|
92
|
-
|
|
93
|
-
echo "## PHP Lint" >> $GITHUB_STEP_SUMMARY
|
|
94
|
-
if [ "$ERRORS" -eq 0 ]; then
|
|
95
|
-
echo "All PHP files passed syntax check." >> $GITHUB_STEP_SUMMARY
|
|
96
|
-
else
|
|
97
|
-
echo "${ERRORS} file(s) with syntax errors." >> $GITHUB_STEP_SUMMARY
|
|
98
|
-
exit 1
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
- name: TypeScript/JavaScript lint
|
|
102
|
-
if: steps.detect.outputs.has_node == 'true'
|
|
103
|
-
run: |
|
|
104
|
-
if [ -f "node_modules/.bin/eslint" ]; then
|
|
105
|
-
npx eslint src/ --quiet 2>&1 || { echo "::error::ESLint errors found"; exit 1; }
|
|
106
|
-
echo "## ESLint" >> $GITHUB_STEP_SUMMARY
|
|
107
|
-
echo "All files passed ESLint." >> $GITHUB_STEP_SUMMARY
|
|
108
|
-
elif [ -f ".eslintrc.json" ] || [ -f ".eslintrc.js" ] || [ -f "eslint.config.js" ]; then
|
|
109
|
-
echo "::warning::ESLint config found but eslint not installed"
|
|
110
|
-
else
|
|
111
|
-
echo "No ESLint configured — skipping"
|
|
112
|
-
fi
|
|
113
|
-
|
|
114
|
-
- name: TypeScript compile check
|
|
115
|
-
if: steps.detect.outputs.has_node == 'true'
|
|
116
|
-
run: |
|
|
117
|
-
if [ -f "tsconfig.json" ] && [ -f "node_modules/.bin/tsc" ]; then
|
|
118
|
-
npx tsc --noEmit 2>&1 || { echo "::error::TypeScript compilation errors"; exit 1; }
|
|
119
|
-
echo "## TypeScript" >> $GITHUB_STEP_SUMMARY
|
|
120
|
-
echo "TypeScript compilation passed." >> $GITHUB_STEP_SUMMARY
|
|
121
|
-
fi
|
|
122
|
-
|
|
123
|
-
- name: PHPStan static analysis
|
|
124
|
-
if: steps.detect.outputs.has_php == 'true'
|
|
125
|
-
run: |
|
|
126
|
-
if [ -f "phpstan.neon" ] && [ -f "vendor/bin/phpstan" ]; then
|
|
127
|
-
vendor/bin/phpstan analyse --no-progress 2>&1 || { echo "::warning::PHPStan found issues"; }
|
|
128
|
-
fi
|
|
129
|
-
|
|
130
|
-
# ── Tests ─────────────────────────────────────────────────────────────
|
|
131
|
-
test:
|
|
132
|
-
name: Tests
|
|
133
|
-
runs-on: ubuntu-latest
|
|
134
|
-
# Independent job (no `needs: lint`): the MokoGIT Actions scheduler does not
|
|
135
|
-
# offer the dependent 2nd job of a needs-chain to runners, so it stalls in
|
|
136
|
-
# "waiting" and is reaped by ABANDONED_JOB_TIMEOUT. Guard template repos
|
|
137
|
-
# directly (same condition lint uses) instead of gating on lint's result.
|
|
138
|
-
if: ${{ !startsWith(github.event.repository.name, 'Template-') }}
|
|
139
|
-
|
|
140
|
-
steps:
|
|
141
|
-
- name: Checkout
|
|
142
|
-
uses: actions/checkout@v4
|
|
143
|
-
|
|
144
|
-
- name: Detect toolchain
|
|
145
|
-
id: detect
|
|
146
|
-
run: |
|
|
147
|
-
HAS_PHP=false
|
|
148
|
-
HAS_NODE=false
|
|
149
|
-
[ -f "composer.json" ] && HAS_PHP=true
|
|
150
|
-
[ -f "package.json" ] && HAS_NODE=true
|
|
151
|
-
echo "has_php=$HAS_PHP" >> "$GITHUB_OUTPUT"
|
|
152
|
-
echo "has_node=$HAS_NODE" >> "$GITHUB_OUTPUT"
|
|
153
|
-
|
|
154
|
-
- name: Setup PHP
|
|
155
|
-
if: steps.detect.outputs.has_php == 'true'
|
|
156
|
-
run: |
|
|
157
|
-
if ! command -v php &> /dev/null; then
|
|
158
|
-
sudo apt-get update -qq
|
|
159
|
-
sudo apt-get install -y -qq php-cli php-mbstring php-xml >/dev/null 2>&1
|
|
160
|
-
fi
|
|
161
|
-
|
|
162
|
-
- name: Setup Node.js
|
|
163
|
-
if: steps.detect.outputs.has_node == 'true'
|
|
164
|
-
uses: actions/setup-node@v4
|
|
165
|
-
with:
|
|
166
|
-
node-version: '20'
|
|
167
|
-
|
|
168
|
-
- name: Install dependencies
|
|
169
|
-
run: |
|
|
170
|
-
[ -f "composer.json" ] && composer install --no-interaction --prefer-dist --quiet 2>/dev/null || true
|
|
171
|
-
[ -f "package.json" ] && { npm ci --quiet 2>/dev/null || npm install --quiet 2>/dev/null || true; } || true
|
|
172
|
-
|
|
173
|
-
- name: Run PHP tests
|
|
174
|
-
if: steps.detect.outputs.has_php == 'true'
|
|
175
|
-
run: |
|
|
176
|
-
if [ -f "vendor/bin/phpunit" ]; then
|
|
177
|
-
vendor/bin/phpunit --testdox 2>&1
|
|
178
|
-
echo "## PHPUnit" >> $GITHUB_STEP_SUMMARY
|
|
179
|
-
echo "Tests passed." >> $GITHUB_STEP_SUMMARY
|
|
180
|
-
elif [ -f "phpunit.xml" ] || [ -f "phpunit.xml.dist" ]; then
|
|
181
|
-
echo "::warning::PHPUnit config found but phpunit not installed"
|
|
182
|
-
else
|
|
183
|
-
echo "No PHPUnit configured — skipping"
|
|
184
|
-
fi
|
|
185
|
-
|
|
186
|
-
- name: Run Node.js tests
|
|
187
|
-
if: steps.detect.outputs.has_node == 'true'
|
|
188
|
-
run: |
|
|
189
|
-
if jq -e '.scripts.test' package.json > /dev/null 2>&1; then
|
|
190
|
-
npm test 2>&1
|
|
191
|
-
echo "## Node.js Tests" >> $GITHUB_STEP_SUMMARY
|
|
192
|
-
echo "Tests passed." >> $GITHUB_STEP_SUMMARY
|
|
193
|
-
else
|
|
194
|
-
echo "No test script in package.json — skipping"
|
|
195
|
-
fi
|
|
196
|
-
|
|
197
|
-
- name: Build check
|
|
198
|
-
run: |
|
|
199
|
-
if [ -f "Makefile" ]; then
|
|
200
|
-
make build 2>&1 || echo "::warning::Build failed or not configured"
|
|
201
|
-
elif [ -f "package.json" ] && jq -e '.scripts.build' package.json > /dev/null 2>&1; then
|
|
202
|
-
npm run build 2>&1 || echo "::warning::Build failed"
|
|
203
|
-
fi
|