moodle-cli 0.7.0-alpha.2 → 0.7.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/moodle.js +93 -12
- package/dist/worker/worker.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -174,7 +174,7 @@ moodle mcp bridge
|
|
|
174
174
|
|
|
175
175
|
The default client connection uses `moodle mcp bridge`, which keeps the Bearer token out of client configuration. Use `moodle mcp connect CLIENT --mode remote` for clients that support authenticated remote MCP headers.
|
|
176
176
|
|
|
177
|
-
Alpha version `0.7.0-alpha.
|
|
177
|
+
Alpha version `0.7.0-alpha.3` supports MCP `2026-07-28` and a stateless compatibility lane for `2025-11-25` clients.
|
|
178
178
|
|
|
179
179
|
### Configuration
|
|
180
180
|
|
package/dist/moodle.js
CHANGED
|
@@ -3700,7 +3700,7 @@ function escapeXml(value) {
|
|
|
3700
3700
|
}
|
|
3701
3701
|
|
|
3702
3702
|
// src/version.ts
|
|
3703
|
-
var VERSION = "0.7.0-alpha.
|
|
3703
|
+
var VERSION = "0.7.0-alpha.3";
|
|
3704
3704
|
|
|
3705
3705
|
// src/forum.ts
|
|
3706
3706
|
function parseDiscussionReference(value) {
|
|
@@ -4519,6 +4519,61 @@ import { chmod as chmod3, mkdir as mkdir5, readFile as readFile4, rename as rena
|
|
|
4519
4519
|
import { homedir as homedir6 } from "os";
|
|
4520
4520
|
import { dirname as dirname5, join as join6, win32 as windowsPath } from "path";
|
|
4521
4521
|
var SERVICE = "moodle-cli-mcp";
|
|
4522
|
+
var MACOS_KEYCHAIN_SCRIPT = `
|
|
4523
|
+
ObjC.import("Foundation")
|
|
4524
|
+
ObjC.import("Security")
|
|
4525
|
+
|
|
4526
|
+
function main() {
|
|
4527
|
+
const input = $.NSFileHandle.fileHandleWithStandardInput.readDataToEndOfFile
|
|
4528
|
+
const text = $.NSString.alloc.initWithDataEncoding(input, $.NSUTF8StringEncoding)
|
|
4529
|
+
const payload = JSON.parse(ObjC.unwrap(text))
|
|
4530
|
+
const keys = {
|
|
4531
|
+
class: "class",
|
|
4532
|
+
genericPassword: "genp",
|
|
4533
|
+
service: "svce",
|
|
4534
|
+
account: "acct",
|
|
4535
|
+
valueData: "v_Data",
|
|
4536
|
+
returnData: "r_Data",
|
|
4537
|
+
}
|
|
4538
|
+
const query = $.NSMutableDictionary.alloc.init
|
|
4539
|
+
query.setObjectForKey(keys.genericPassword, keys.class)
|
|
4540
|
+
query.setObjectForKey(payload.service, keys.service)
|
|
4541
|
+
query.setObjectForKey(payload.profile, keys.account)
|
|
4542
|
+
|
|
4543
|
+
if (payload.operation === "read") {
|
|
4544
|
+
query.setObjectForKey(true, keys.returnData)
|
|
4545
|
+
const result = $()
|
|
4546
|
+
const status = Number($.SecItemCopyMatching(query, result))
|
|
4547
|
+
if (status === -25300) return
|
|
4548
|
+
if (status !== 0) throw new Error("Keychain read failed: " + status)
|
|
4549
|
+
$.NSFileHandle.fileHandleWithStandardOutput.writeData(result)
|
|
4550
|
+
return
|
|
4551
|
+
}
|
|
4552
|
+
|
|
4553
|
+
if (payload.operation === "write") {
|
|
4554
|
+
const value = $(payload.credentials).dataUsingEncoding($.NSUTF8StringEncoding)
|
|
4555
|
+
const attributes = $.NSMutableDictionary.alloc.init
|
|
4556
|
+
attributes.setObjectForKey(value, keys.valueData)
|
|
4557
|
+
let status = Number($.SecItemUpdate(query, attributes))
|
|
4558
|
+
if (status === -25300) {
|
|
4559
|
+
query.setObjectForKey(value, keys.valueData)
|
|
4560
|
+
status = Number($.SecItemAdd(query, null))
|
|
4561
|
+
}
|
|
4562
|
+
if (status !== 0) throw new Error("Keychain write failed: " + status)
|
|
4563
|
+
return
|
|
4564
|
+
}
|
|
4565
|
+
|
|
4566
|
+
if (payload.operation === "delete") {
|
|
4567
|
+
const status = Number($.SecItemDelete(query))
|
|
4568
|
+
if (status !== 0 && status !== -25300) throw new Error("Keychain delete failed: " + status)
|
|
4569
|
+
return
|
|
4570
|
+
}
|
|
4571
|
+
|
|
4572
|
+
throw new Error("Unsupported Keychain operation")
|
|
4573
|
+
}
|
|
4574
|
+
|
|
4575
|
+
main()
|
|
4576
|
+
`;
|
|
4522
4577
|
var WINDOWS_CREDENTIAL_READ = `
|
|
4523
4578
|
$ErrorActionPreference = "Stop"
|
|
4524
4579
|
[Console]::InputEncoding = [Text.UTF8Encoding]::new($false)
|
|
@@ -4623,24 +4678,30 @@ var MacOSKeychainCredentialBackend = class {
|
|
|
4623
4678
|
name = "macOS Login Keychain";
|
|
4624
4679
|
async read(profile) {
|
|
4625
4680
|
try {
|
|
4626
|
-
const result = await this.runner.run(
|
|
4627
|
-
|
|
4681
|
+
const result = await this.runner.run(
|
|
4682
|
+
"osascript",
|
|
4683
|
+
["-l", "JavaScript", "-e", MACOS_KEYCHAIN_SCRIPT],
|
|
4684
|
+
macosKeychainInput("read", profile)
|
|
4685
|
+
);
|
|
4686
|
+
const value = result.stdout.trim();
|
|
4687
|
+
if (value) {
|
|
4688
|
+
return parseCredentials(value);
|
|
4689
|
+
}
|
|
4690
|
+
await this.deleteEmptyLegacyEntry(profile);
|
|
4691
|
+
return null;
|
|
4628
4692
|
} catch (error) {
|
|
4629
4693
|
if (commandNotFound(error)) {
|
|
4630
4694
|
throw new CredentialBackendUnavailableError(this.name, error);
|
|
4631
4695
|
}
|
|
4632
|
-
if (commandExitCode(error) === 44) {
|
|
4633
|
-
return null;
|
|
4634
|
-
}
|
|
4635
4696
|
throw error;
|
|
4636
4697
|
}
|
|
4637
4698
|
}
|
|
4638
4699
|
async write(profile, credentials) {
|
|
4639
4700
|
try {
|
|
4640
4701
|
await this.runner.run(
|
|
4641
|
-
"
|
|
4642
|
-
["
|
|
4643
|
-
|
|
4702
|
+
"osascript",
|
|
4703
|
+
["-l", "JavaScript", "-e", MACOS_KEYCHAIN_SCRIPT],
|
|
4704
|
+
macosKeychainInput("write", profile, credentials)
|
|
4644
4705
|
);
|
|
4645
4706
|
} catch (error) {
|
|
4646
4707
|
if (commandNotFound(error)) {
|
|
@@ -4651,14 +4712,26 @@ var MacOSKeychainCredentialBackend = class {
|
|
|
4651
4712
|
}
|
|
4652
4713
|
async delete(profile) {
|
|
4653
4714
|
try {
|
|
4654
|
-
await this.runner.run(
|
|
4715
|
+
await this.runner.run(
|
|
4716
|
+
"osascript",
|
|
4717
|
+
["-l", "JavaScript", "-e", MACOS_KEYCHAIN_SCRIPT],
|
|
4718
|
+
macosKeychainInput("delete", profile)
|
|
4719
|
+
);
|
|
4655
4720
|
} catch (error) {
|
|
4656
4721
|
if (commandNotFound(error)) {
|
|
4657
4722
|
throw new CredentialBackendUnavailableError(this.name, error);
|
|
4658
4723
|
}
|
|
4659
|
-
|
|
4660
|
-
|
|
4724
|
+
throw error;
|
|
4725
|
+
}
|
|
4726
|
+
}
|
|
4727
|
+
async deleteEmptyLegacyEntry(profile) {
|
|
4728
|
+
try {
|
|
4729
|
+
await this.runner.run("security", ["delete-generic-password", "-s", SERVICE, "-a", profile]);
|
|
4730
|
+
} catch (error) {
|
|
4731
|
+
if (commandNotFound(error) || commandExitCode(error) === 44) {
|
|
4732
|
+
return;
|
|
4661
4733
|
}
|
|
4734
|
+
throw error;
|
|
4662
4735
|
}
|
|
4663
4736
|
}
|
|
4664
4737
|
};
|
|
@@ -4883,6 +4956,14 @@ function parseCredentials(value) {
|
|
|
4883
4956
|
function powershellArgs(script) {
|
|
4884
4957
|
return ["-NoProfile", "-NonInteractive", "-Command", script];
|
|
4885
4958
|
}
|
|
4959
|
+
function macosKeychainInput(operation, profile, credentials) {
|
|
4960
|
+
return JSON.stringify({
|
|
4961
|
+
operation,
|
|
4962
|
+
service: SERVICE,
|
|
4963
|
+
profile,
|
|
4964
|
+
...credentials ? { credentials: JSON.stringify(credentials) } : {}
|
|
4965
|
+
});
|
|
4966
|
+
}
|
|
4886
4967
|
function windowsCredentialInput(profile, credentials) {
|
|
4887
4968
|
return JSON.stringify({
|
|
4888
4969
|
service: SERVICE,
|
package/dist/worker/worker.js
CHANGED