@studiometa/forge-mcp 0.4.6 → 0.4.8

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.
@@ -2,7 +2,7 @@ import { readFileSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { HttpClient, isForgeApiError } from "@studiometa/forge-api";
5
- import { RESOURCES, activateCertificate, createAuditLogger, createBackupConfig, createCertificate, createCommand, createDaemon, createDatabase, createDatabaseUser, createFirewallRule, createMonitor, createNginxTemplate, createRecipe, createRedirectRule, createScheduledJob, createSecurityRule, createServer, createSite, createSshKey, deleteBackupConfig, deleteCertificate, deleteDaemon, deleteDatabase, deleteDatabaseUser, deleteFirewallRule, deleteMonitor, deleteNginxTemplate, deleteRecipe, deleteRedirectRule, deleteScheduledJob, deleteSecurityRule, deleteServer, deleteSite, deleteSshKey, deploySiteAndWait, getBackupConfig, getCertificate, getCommand, getDaemon, getDaemonLog, getDatabase, getDatabaseUser, getDeploymentLog, getDeploymentScript, getEnv, getFirewallRule, getMonitor, getNginxConfig, getNginxTemplate, getRecipe, getRedirectRule, getScheduledJob, getSecurityRule, getServer, getSite, getSshKey, getUser, listBackupConfigs, listCommands, listDaemons, listDatabaseUsers, listDatabases, listDeployments, listFirewallRules, listMonitors, listNginxTemplates, listRecipes, listRedirectRules, listScheduledJobs, listSecurityRules, listServers, listServices, listSites, listSshKeys, rebootServer, resolveServers, resolveSites, restartDaemon, restartService, runRecipe, updateBackupConfig, updateDaemon, updateDatabaseUser, updateDeploymentScript, updateEnv, updateNginxConfig, updateNginxTemplate, updateRecipe, updateSecurityRule, updateSite } from "@studiometa/forge-core";
5
+ import { PHP_CONFIG_TYPES, RESOURCES, activateCertificate, createAuditLogger, createBackupConfig, createCertificate, createCommand, createDaemon, createDatabase, createDatabaseUser, createFirewallRule, createMonitor, createNginxTemplate, createRecipe, createRedirectRule, createScheduledJob, createSecurityRule, createServer, createSite, createSshKey, deleteBackupConfig, deleteCertificate, deleteDaemon, deleteDatabase, deleteDatabaseUser, deleteFirewallRule, deleteMonitor, deleteNginxTemplate, deleteRecipe, deleteRedirectRule, deleteScheduledJob, deleteSecurityRule, deleteServer, deleteSite, deleteSshKey, deploySiteAndWait, disablePhpOpcache, enablePhpOpcache, getBackupConfig, getCertificate, getCommand, getDaemon, getDaemonLog, getDatabase, getDatabaseUser, getDeploymentLog, getDeploymentScript, getEnv, getFirewallRule, getMonitor, getNginxConfig, getNginxTemplate, getPhpConfig, getPhpMaxExecutionTime, getPhpMaxUploadSize, getPhpOpcache, getPhpVersion, getRecipe, getRedirectRule, getScheduledJob, getSecurityRule, getServer, getSite, getSshKey, getUser, listBackupConfigs, listCommands, listDaemons, listDatabaseUsers, listDatabases, listDeployments, listFirewallRules, listMonitors, listNginxTemplates, listPhpVersions, listRecipes, listRedirectRules, listScheduledJobs, listSecurityRules, listServers, listServices, listSites, listSshKeys, rebootServer, resolveServers, resolveSites, restartDaemon, restartService, runRecipe, updateBackupConfig, updateDaemon, updateDatabaseUser, updateDeploymentScript, updateEnv, updateNginxConfig, updateNginxTemplate, updatePhpConfig, updatePhpMaxExecutionTime, updatePhpMaxUploadSize, updateRecipe, updateSecurityRule, updateSite } from "@studiometa/forge-core";
6
6
  //#region src/instructions.ts
7
7
  /**
8
8
  * MCP Server Instructions
@@ -153,6 +153,54 @@ function _getStandardProps(context) {
153
153
  };
154
154
  }
155
155
  /**
156
+ * Joins multiple `expects` values with the given separator.
157
+ *
158
+ * @param values The `expects` values.
159
+ * @param separator The separator.
160
+ *
161
+ * @returns The joined `expects` property.
162
+ *
163
+ * @internal
164
+ */
165
+ /* @__NO_SIDE_EFFECTS__ */
166
+ function _joinExpects(values$1, separator) {
167
+ const list = [...new Set(values$1)];
168
+ if (list.length > 1) return `(${list.join(` ${separator} `)})`;
169
+ return list[0] ?? "never";
170
+ }
171
+ /* @__NO_SIDE_EFFECTS__ */
172
+ function integer(message$1) {
173
+ return {
174
+ kind: "validation",
175
+ type: "integer",
176
+ reference: integer,
177
+ async: false,
178
+ expects: null,
179
+ requirement: Number.isInteger,
180
+ message: message$1,
181
+ "~run"(dataset, config$1) {
182
+ if (dataset.typed && !this.requirement(dataset.value)) _addIssue(this, "integer", dataset, config$1);
183
+ return dataset;
184
+ }
185
+ };
186
+ }
187
+ /* @__NO_SIDE_EFFECTS__ */
188
+ function minValue(requirement, message$1) {
189
+ return {
190
+ kind: "validation",
191
+ type: "min_value",
192
+ reference: minValue,
193
+ async: false,
194
+ expects: `>=${requirement instanceof Date ? requirement.toJSON() : /* @__PURE__ */ _stringify(requirement)}`,
195
+ requirement,
196
+ message: message$1,
197
+ "~run"(dataset, config$1) {
198
+ if (dataset.typed && !(dataset.value >= this.requirement)) _addIssue(this, "value", dataset, config$1, { received: dataset.value instanceof Date ? dataset.value.toJSON() : /* @__PURE__ */ _stringify(dataset.value) });
199
+ return dataset;
200
+ }
201
+ };
202
+ }
203
+ /**
156
204
  * Returns the fallback value of the schema.
157
205
  *
158
206
  * @param schema The schema to get it from.
@@ -227,6 +275,45 @@ function array(item, message$1) {
227
275
  };
228
276
  }
229
277
  /* @__NO_SIDE_EFFECTS__ */
278
+ function boolean(message$1) {
279
+ return {
280
+ kind: "schema",
281
+ type: "boolean",
282
+ reference: boolean,
283
+ expects: "boolean",
284
+ async: false,
285
+ message: message$1,
286
+ get "~standard"() {
287
+ return /* @__PURE__ */ _getStandardProps(this);
288
+ },
289
+ "~run"(dataset, config$1) {
290
+ if (typeof dataset.value === "boolean") dataset.typed = true;
291
+ else _addIssue(this, "type", dataset, config$1);
292
+ return dataset;
293
+ }
294
+ };
295
+ }
296
+ /* @__NO_SIDE_EFFECTS__ */
297
+ function literal(literal_, message$1) {
298
+ return {
299
+ kind: "schema",
300
+ type: "literal",
301
+ reference: literal,
302
+ expects: /* @__PURE__ */ _stringify(literal_),
303
+ async: false,
304
+ literal: literal_,
305
+ message: message$1,
306
+ get "~standard"() {
307
+ return /* @__PURE__ */ _getStandardProps(this);
308
+ },
309
+ "~run"(dataset, config$1) {
310
+ if (dataset.value === this.literal) dataset.typed = true;
311
+ else _addIssue(this, "type", dataset, config$1);
312
+ return dataset;
313
+ }
314
+ };
315
+ }
316
+ /* @__NO_SIDE_EFFECTS__ */
230
317
  function nullable(wrapped, default_) {
231
318
  return {
232
319
  kind: "schema",
@@ -361,6 +448,26 @@ function optional(wrapped, default_) {
361
448
  };
362
449
  }
363
450
  /* @__NO_SIDE_EFFECTS__ */
451
+ function picklist(options, message$1) {
452
+ return {
453
+ kind: "schema",
454
+ type: "picklist",
455
+ reference: picklist,
456
+ expects: /* @__PURE__ */ _joinExpects(options.map(_stringify), "|"),
457
+ async: false,
458
+ options,
459
+ message: message$1,
460
+ get "~standard"() {
461
+ return /* @__PURE__ */ _getStandardProps(this);
462
+ },
463
+ "~run"(dataset, config$1) {
464
+ if (this.options.includes(dataset.value)) dataset.typed = true;
465
+ else _addIssue(this, "type", dataset, config$1);
466
+ return dataset;
467
+ }
468
+ };
469
+ }
470
+ /* @__NO_SIDE_EFFECTS__ */
364
471
  function string(message$1) {
365
472
  return {
366
473
  kind: "schema",
@@ -401,6 +508,96 @@ function unknown() {
401
508
  }
402
509
  };
403
510
  }
511
+ /* @__NO_SIDE_EFFECTS__ */
512
+ function variant(key, options, message$1) {
513
+ return {
514
+ kind: "schema",
515
+ type: "variant",
516
+ reference: variant,
517
+ expects: "Object",
518
+ async: false,
519
+ key,
520
+ options,
521
+ message: message$1,
522
+ get "~standard"() {
523
+ return /* @__PURE__ */ _getStandardProps(this);
524
+ },
525
+ "~run"(dataset, config$1) {
526
+ const input = dataset.value;
527
+ if (input && typeof input === "object") {
528
+ let outputDataset;
529
+ let maxDiscriminatorPriority = 0;
530
+ let invalidDiscriminatorKey = this.key;
531
+ let expectedDiscriminators = [];
532
+ const parseOptions = (variant$1, allKeys) => {
533
+ for (const schema of variant$1.options) {
534
+ if (schema.type === "variant") parseOptions(schema, new Set(allKeys).add(schema.key));
535
+ else {
536
+ let keysAreValid = true;
537
+ let currentPriority = 0;
538
+ for (const currentKey of allKeys) {
539
+ const discriminatorSchema = schema.entries[currentKey];
540
+ if (currentKey in input ? discriminatorSchema["~run"]({
541
+ typed: false,
542
+ value: input[currentKey]
543
+ }, { abortEarly: true }).issues : discriminatorSchema.type !== "exact_optional" && discriminatorSchema.type !== "optional" && discriminatorSchema.type !== "nullish") {
544
+ keysAreValid = false;
545
+ if (invalidDiscriminatorKey !== currentKey && (maxDiscriminatorPriority < currentPriority || maxDiscriminatorPriority === currentPriority && currentKey in input && !(invalidDiscriminatorKey in input))) {
546
+ maxDiscriminatorPriority = currentPriority;
547
+ invalidDiscriminatorKey = currentKey;
548
+ expectedDiscriminators = [];
549
+ }
550
+ if (invalidDiscriminatorKey === currentKey) expectedDiscriminators.push(schema.entries[currentKey].expects);
551
+ break;
552
+ }
553
+ currentPriority++;
554
+ }
555
+ if (keysAreValid) {
556
+ const optionDataset = schema["~run"]({ value: input }, config$1);
557
+ if (!outputDataset || !outputDataset.typed && optionDataset.typed) outputDataset = optionDataset;
558
+ }
559
+ }
560
+ if (outputDataset && !outputDataset.issues) break;
561
+ }
562
+ };
563
+ parseOptions(this, /* @__PURE__ */ new Set([this.key]));
564
+ if (outputDataset) return outputDataset;
565
+ _addIssue(this, "type", dataset, config$1, {
566
+ input: input[invalidDiscriminatorKey],
567
+ expected: /* @__PURE__ */ _joinExpects(expectedDiscriminators, "|"),
568
+ path: [{
569
+ type: "object",
570
+ origin: "value",
571
+ input,
572
+ key: invalidDiscriminatorKey,
573
+ value: input[invalidDiscriminatorKey]
574
+ }]
575
+ });
576
+ } else _addIssue(this, "type", dataset, config$1);
577
+ return dataset;
578
+ }
579
+ };
580
+ }
581
+ /* @__NO_SIDE_EFFECTS__ */
582
+ function pipe(...pipe$1) {
583
+ return {
584
+ ...pipe$1[0],
585
+ pipe: pipe$1,
586
+ get "~standard"() {
587
+ return /* @__PURE__ */ _getStandardProps(this);
588
+ },
589
+ "~run"(dataset, config$1) {
590
+ for (const item of pipe$1) if (item.kind !== "metadata") {
591
+ if (dataset.issues && (item.kind === "schema" || item.kind === "transformation")) {
592
+ dataset.typed = false;
593
+ break;
594
+ }
595
+ if (!dataset.issues || !config$1.abortEarly && !config$1.abortPipeEarly) dataset = item["~run"](dataset, config$1);
596
+ }
597
+ return dataset;
598
+ }
599
+ };
600
+ }
404
601
  /**
405
602
  * Parses an unknown input based on a schema.
406
603
  *
@@ -762,6 +959,20 @@ function formatServiceList(services) {
762
959
  });
763
960
  return `${services.length} service(s):\n${lines.join("\n")}`;
764
961
  }
962
+ /**
963
+ * Format a list of installed PHP versions.
964
+ */
965
+ function formatPhpVersionList(versions) {
966
+ if (versions.length === 0) return "No PHP versions found.";
967
+ const lines = versions.map((v) => `• PHP ${v.version} (ID: ${v.id}) — ${v.status}`);
968
+ return `${versions.length} PHP version(s):\n${lines.join("\n")}`;
969
+ }
970
+ /**
971
+ * Format a single PHP version.
972
+ */
973
+ function formatPhpVersion(version) {
974
+ return `PHP ${version.version} (ID: ${version.id})\nBinary: ${version.binary_name}\nStatus: ${version.status}`;
975
+ }
765
976
  //#endregion
766
977
  //#region src/errors.ts
767
978
  /**
@@ -1106,6 +1317,22 @@ var TOOLS = [{
1106
1317
  enum: [...READ_ACTIONS],
1107
1318
  description: "Read action to perform. Use \"help\" for resource documentation."
1108
1319
  },
1320
+ setting: {
1321
+ type: "string",
1322
+ description: "PHP setting to read (php get): version, config, max-upload-size, max-execution-time, opcache"
1323
+ },
1324
+ version: {
1325
+ type: "string",
1326
+ description: "PHP version ID or version (e.g. \"8.3\", \"php83\") for php get"
1327
+ },
1328
+ type: {
1329
+ type: "string",
1330
+ description: "PHP configuration file for php get setting=config: cli, fpm, pool"
1331
+ },
1332
+ user: {
1333
+ type: "string",
1334
+ description: "FPM pool user for php get setting=config type=pool (optional)"
1335
+ },
1109
1336
  operations: {
1110
1337
  type: "array",
1111
1338
  description: "Array of operations for batch execution (max 10). Each operation needs resource, action, and any additional params.",
@@ -1171,7 +1398,7 @@ var TOOLS = [{
1171
1398
  },
1172
1399
  type: {
1173
1400
  type: "string",
1174
- description: "Resource type (e.g. app, web, worker for servers; mysql, postgres for databases; disk_usage, used_memory for monitors)"
1401
+ description: "Resource type (e.g. app, web, worker for servers; mysql, postgres for databases; disk_usage, used_memory for monitors; cli, fpm, pool for php configs)"
1175
1402
  },
1176
1403
  domain: {
1177
1404
  type: "string",
@@ -1183,7 +1410,7 @@ var TOOLS = [{
1183
1410
  },
1184
1411
  content: {
1185
1412
  type: "string",
1186
- description: "Content body for env variables, nginx config, or deployment script updates"
1413
+ description: "Content body for env variables, nginx config, deployment script or PHP config updates"
1187
1414
  },
1188
1415
  command: {
1189
1416
  type: "string",
@@ -1191,7 +1418,7 @@ var TOOLS = [{
1191
1418
  },
1192
1419
  user: {
1193
1420
  type: "string",
1194
- description: "Unix user to run as (daemons, scheduled jobs; e.g. forge, root)"
1421
+ description: "Unix user to run as (daemons, scheduled jobs; e.g. forge, root), or the FPM pool user (php config type=pool)"
1195
1422
  },
1196
1423
  port: {
1197
1424
  type: ["string", "number"],
@@ -1249,7 +1476,19 @@ var TOOLS = [{
1249
1476
  },
1250
1477
  version: {
1251
1478
  type: "string",
1252
- description: "PHP version required when restarting the php service (e.g. php83)"
1479
+ description: "PHP version: required when restarting the php service (e.g. php83); version ID or version (e.g. \"8.3\") for php update setting=config"
1480
+ },
1481
+ setting: {
1482
+ type: "string",
1483
+ description: "PHP setting to write (php update): config, max-upload-size, max-execution-time, opcache"
1484
+ },
1485
+ value: {
1486
+ type: "number",
1487
+ description: "Integer for php update: megabytes for max-upload-size, seconds for max-execution-time"
1488
+ },
1489
+ enabled: {
1490
+ type: "boolean",
1491
+ description: "For php update setting=opcache: true enables OPcache, false disables it"
1253
1492
  }
1254
1493
  },
1255
1494
  required: ["resource", "action"]
@@ -2623,6 +2862,86 @@ var RESOURCE_HELP = {
2623
2862
  }
2624
2863
  ]
2625
2864
  },
2865
+ php: {
2866
+ description: "Manage PHP on a server: installed versions, cli/fpm/pool configuration files, max upload size, max execution time and OPcache",
2867
+ scope: "server (requires server_id)",
2868
+ actions: {
2869
+ list: "List installed PHP versions (with their IDs)",
2870
+ get: "Read one setting: version, config, max-upload-size, max-execution-time or opcache",
2871
+ update: "Write one setting: config (replaces the whole file), max-upload-size, max-execution-time or opcache"
2872
+ },
2873
+ fields: {
2874
+ setting: "What to read or write: version, config, max-upload-size, max-execution-time, opcache",
2875
+ version: "PHP version ID, or a version such as \"8.3\", \"php83\" or \"php8.3\" (for setting=version and setting=config)",
2876
+ type: "Configuration file for setting=config: cli, fpm or pool",
2877
+ user: "Unix user of the FPM pool (optional, type=pool only)",
2878
+ content: "Full configuration file content (update setting=config)",
2879
+ value: "Integer for update: megabytes for max-upload-size, seconds for max-execution-time",
2880
+ enabled: "Boolean for update setting=opcache: true enables, false disables"
2881
+ },
2882
+ examples: [
2883
+ {
2884
+ description: "List installed PHP versions",
2885
+ params: {
2886
+ resource: "php",
2887
+ action: "list",
2888
+ server_id: "123"
2889
+ }
2890
+ },
2891
+ {
2892
+ description: "Read the FPM php.ini of PHP 8.3",
2893
+ params: {
2894
+ resource: "php",
2895
+ action: "get",
2896
+ server_id: "123",
2897
+ setting: "config",
2898
+ version: "8.3",
2899
+ type: "fpm"
2900
+ }
2901
+ },
2902
+ {
2903
+ description: "Replace the CLI php.ini of PHP 8.3",
2904
+ params: {
2905
+ resource: "php",
2906
+ action: "update",
2907
+ server_id: "123",
2908
+ setting: "config",
2909
+ version: "8.3",
2910
+ type: "cli",
2911
+ content: "memory_limit = 512M\n..."
2912
+ }
2913
+ },
2914
+ {
2915
+ description: "Set the max upload size to 128 MB",
2916
+ params: {
2917
+ resource: "php",
2918
+ action: "update",
2919
+ server_id: "123",
2920
+ setting: "max-upload-size",
2921
+ value: 128
2922
+ }
2923
+ },
2924
+ {
2925
+ description: "Read the OPcache status",
2926
+ params: {
2927
+ resource: "php",
2928
+ action: "get",
2929
+ server_id: "123",
2930
+ setting: "opcache"
2931
+ }
2932
+ },
2933
+ {
2934
+ description: "Enable OPcache",
2935
+ params: {
2936
+ resource: "php",
2937
+ action: "update",
2938
+ server_id: "123",
2939
+ setting: "opcache",
2940
+ enabled: true
2941
+ }
2942
+ }
2943
+ ]
2944
+ },
2626
2945
  "firewall-rules": {
2627
2946
  description: "Manage UFW firewall rules on a server",
2628
2947
  scope: "server (requires server_id)",
@@ -3155,6 +3474,138 @@ var handleNginxTemplates = createResourceHandler({
3155
3474
  }
3156
3475
  });
3157
3476
  //#endregion
3477
+ //#region src/handlers/php.ts
3478
+ var configFields = {
3479
+ server_id: /* @__PURE__ */ string(),
3480
+ setting: /* @__PURE__ */ literal("config"),
3481
+ version: /* @__PURE__ */ string(),
3482
+ type: /* @__PURE__ */ picklist(PHP_CONFIG_TYPES),
3483
+ user: /* @__PURE__ */ optional(/* @__PURE__ */ string())
3484
+ };
3485
+ /**
3486
+ * Read one PHP setting. Scalar settings are wrapped in an object for JSON output.
3487
+ */
3488
+ async function getPhpSetting(options, ctx) {
3489
+ const { server_id } = options;
3490
+ switch (options.setting) {
3491
+ case "version": return getPhpVersion({
3492
+ server_id,
3493
+ version: options.version
3494
+ }, ctx);
3495
+ case "config": return getPhpConfig({
3496
+ server_id,
3497
+ version: options.version,
3498
+ type: options.type,
3499
+ user: options.user
3500
+ }, ctx);
3501
+ case "max-upload-size": return { data: { max_upload_size: (await getPhpMaxUploadSize({ server_id }, ctx)).data } };
3502
+ case "max-execution-time": return { data: { max_execution_time: (await getPhpMaxExecutionTime({ server_id }, ctx)).data } };
3503
+ default: return { data: { opcache_enabled: (await getPhpOpcache({ server_id }, ctx)).data } };
3504
+ }
3505
+ }
3506
+ /**
3507
+ * Write one PHP setting.
3508
+ */
3509
+ function updatePhpSetting(options, ctx) {
3510
+ const { server_id } = options;
3511
+ switch (options.setting) {
3512
+ case "config": return updatePhpConfig({
3513
+ server_id,
3514
+ version: options.version,
3515
+ type: options.type,
3516
+ content: options.content,
3517
+ user: options.user
3518
+ }, ctx);
3519
+ case "max-upload-size": return updatePhpMaxUploadSize({
3520
+ server_id,
3521
+ size: options.value
3522
+ }, ctx);
3523
+ case "max-execution-time": return updatePhpMaxExecutionTime({
3524
+ server_id,
3525
+ seconds: options.value
3526
+ }, ctx);
3527
+ default: return options.enabled ? enablePhpOpcache({ server_id }, ctx) : disablePhpOpcache({ server_id }, ctx);
3528
+ }
3529
+ }
3530
+ /**
3531
+ * Format the result of a `get` for compact output.
3532
+ */
3533
+ function formatGet(data, args) {
3534
+ switch (args.setting) {
3535
+ case "version": return formatPhpVersion(data);
3536
+ case "config": return `PHP ${String(args.type)} configuration:\n${String(data)}`;
3537
+ case "max-upload-size": return `PHP max upload size: ${data.max_upload_size} MB`;
3538
+ case "max-execution-time": return `PHP max execution time: ${data.max_execution_time} seconds`;
3539
+ default: return `OPcache is ${data.opcache_enabled ? "enabled" : "disabled"}.`;
3540
+ }
3541
+ }
3542
+ /**
3543
+ * Format the confirmation of an `update`.
3544
+ */
3545
+ function formatUpdate(args) {
3546
+ switch (args.setting) {
3547
+ case "config": return `PHP ${String(args.type)} configuration updated.`;
3548
+ case "max-upload-size": return `PHP max upload size set to ${String(args.value)} MB.`;
3549
+ case "max-execution-time": return `PHP max execution time set to ${String(args.value)} seconds.`;
3550
+ default: return `OPcache ${args.enabled ? "enabled" : "disabled"}.`;
3551
+ }
3552
+ }
3553
+ var handlePhp = createResourceHandler({
3554
+ resource: "php",
3555
+ actions: [
3556
+ "list",
3557
+ "get",
3558
+ "update"
3559
+ ],
3560
+ inputSchemas: {
3561
+ list: /* @__PURE__ */ object({ server_id: /* @__PURE__ */ string() }),
3562
+ get: /* @__PURE__ */ variant("setting", [
3563
+ /* @__PURE__ */ object({
3564
+ server_id: /* @__PURE__ */ string(),
3565
+ setting: /* @__PURE__ */ literal("version"),
3566
+ version: /* @__PURE__ */ string()
3567
+ }),
3568
+ /* @__PURE__ */ object(configFields),
3569
+ /* @__PURE__ */ object({
3570
+ server_id: /* @__PURE__ */ string(),
3571
+ setting: /* @__PURE__ */ picklist([
3572
+ "max-upload-size",
3573
+ "max-execution-time",
3574
+ "opcache"
3575
+ ])
3576
+ })
3577
+ ]),
3578
+ update: /* @__PURE__ */ variant("setting", [
3579
+ /* @__PURE__ */ object({
3580
+ ...configFields,
3581
+ content: /* @__PURE__ */ string()
3582
+ }),
3583
+ /* @__PURE__ */ object({
3584
+ server_id: /* @__PURE__ */ string(),
3585
+ setting: /* @__PURE__ */ picklist(["max-upload-size", "max-execution-time"]),
3586
+ value: /* @__PURE__ */ pipe(/* @__PURE__ */ number(), /* @__PURE__ */ integer(), /* @__PURE__ */ minValue(0))
3587
+ }),
3588
+ /* @__PURE__ */ object({
3589
+ server_id: /* @__PURE__ */ string(),
3590
+ setting: /* @__PURE__ */ literal("opcache"),
3591
+ enabled: /* @__PURE__ */ boolean()
3592
+ })
3593
+ ])
3594
+ },
3595
+ executors: {
3596
+ list: listPhpVersions,
3597
+ get: getPhpSetting,
3598
+ update: updatePhpSetting
3599
+ },
3600
+ formatResult: (action, data, args) => {
3601
+ switch (action) {
3602
+ case "list": return formatPhpVersionList(data);
3603
+ case "get": return formatGet(data, args);
3604
+ default: return formatUpdate(args);
3605
+ }
3606
+ }
3607
+ });
3608
+ //#endregion
3158
3609
  //#region src/handlers/recipes.ts
3159
3610
  var handleRecipes = createResourceHandler({
3160
3611
  resource: "recipes",
@@ -3595,6 +4046,19 @@ var RESOURCE_SCHEMAS = {
3595
4046
  restart: ["server_id", "service"]
3596
4047
  }
3597
4048
  },
4049
+ php: {
4050
+ actions: [
4051
+ "list",
4052
+ "get",
4053
+ "update"
4054
+ ],
4055
+ scope: "server",
4056
+ required: {
4057
+ list: ["server_id"],
4058
+ get: ["server_id", "setting"],
4059
+ update: ["server_id", "setting"]
4060
+ }
4061
+ },
3598
4062
  "firewall-rules": {
3599
4063
  actions: [
3600
4064
  "list",
@@ -4501,6 +4965,7 @@ function routeToHandler(resource, action, args, ctx) {
4501
4965
  case "commands": return handleCommands(action, args, ctx);
4502
4966
  case "scheduled-jobs": return handleScheduledJobs(action, args, ctx);
4503
4967
  case "services": return handleServices(action, args, ctx);
4968
+ case "php": return handlePhp(action, args, ctx);
4504
4969
  case "user": return handleUser(action, args, ctx);
4505
4970
  case "batch": return handleBatch(action, args, ctx, routeToHandler);
4506
4971
  /* v8 ignore next 6 -- all valid resources are handled above; unreachable in practice */
@@ -4590,8 +5055,8 @@ async function executeToolWithCredentials(name, args, credentials) {
4590
5055
  }
4591
5056
  //#endregion
4592
5057
  //#region src/version.ts
4593
- var VERSION = "0.4.6";
5058
+ var VERSION = "0.4.8";
4594
5059
  //#endregion
4595
5060
  export { INSTRUCTIONS as a, getTools as i, executeToolWithCredentials as n, STDIO_ONLY_TOOLS as r, VERSION as t };
4596
5061
 
4597
- //# sourceMappingURL=version-BS77BDou.js.map
5062
+ //# sourceMappingURL=version-Cc6wPkZg.js.map