minutes-mcp 0.25.2 → 0.25.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/dist/corpus-lease.js +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +52 -6
- package/dist/node-child.d.ts +10 -0
- package/dist/node-child.js +16 -0
- package/dist/secure-read.js +2 -1
- package/package.json +2 -2
package/dist/corpus-lease.js
CHANGED
|
@@ -5,6 +5,7 @@ import { lstat, mkdir, open, opendir, realpath, stat } from "node:fs/promises";
|
|
|
5
5
|
import { basename, dirname, extname, isAbsolute, join, relative } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { decodePolicyUtf8, fingerprintTextFileFromBoundParent, readTextFileWithRevisionFromBoundParent, writeOperatorDiagnostic, } from "./secure-read.js";
|
|
8
|
+
import { nodeChildEnvironment } from "./node-child.js";
|
|
8
9
|
const MAX_AUTHORIZATION_ATTEMPTS = 2;
|
|
9
10
|
const DEFAULT_FENCE_TIMEOUT_MS = 5_000;
|
|
10
11
|
const DEFAULT_AUTHORIZATION_TIMEOUT_MS = 15_000;
|
|
@@ -1431,7 +1432,7 @@ async function dispatchStableCorpusLease(root, operation, hooks = {}) {
|
|
|
1431
1432
|
detached: process.platform !== "win32",
|
|
1432
1433
|
stdio: ["pipe", "pipe", "pipe"],
|
|
1433
1434
|
windowsHide: true,
|
|
1434
|
-
env:
|
|
1435
|
+
env: nodeChildEnvironment(),
|
|
1435
1436
|
});
|
|
1436
1437
|
child.stderr?.resume();
|
|
1437
1438
|
let resolveTermination;
|
package/dist/index.d.ts
CHANGED
|
@@ -451,7 +451,8 @@ export type AgentTrustReadiness = {
|
|
|
451
451
|
qmd_retirement: "ready-clean" | "blocked";
|
|
452
452
|
remediation?: string;
|
|
453
453
|
};
|
|
454
|
-
export declare function
|
|
454
|
+
export declare function cliTooOldGuidance(installedVersion: string, minimumVersion?: string, platform?: NodeJS.Platform): string;
|
|
455
|
+
export declare function readAgentTrustReadiness(runner?: MinutesRunner, platform?: NodeJS.Platform): Promise<AgentTrustReadiness>;
|
|
455
456
|
export declare function requireAgentTrustReadiness(runner?: MinutesRunner): Promise<AgentTrustReadiness>;
|
|
456
457
|
export declare function afterAgentTrustReadiness<T>(operation: () => Promise<T>, runner?: MinutesRunner): Promise<T>;
|
|
457
458
|
export declare function afterRequiredCli<T>(operation: () => Promise<T>, cliProbe?: () => Promise<boolean>): Promise<T>;
|
package/dist/index.js
CHANGED
|
@@ -51,7 +51,8 @@ import { homedir } from "os";
|
|
|
51
51
|
import { parse as parseYaml } from "yaml";
|
|
52
52
|
import * as reader from "minutes-sdk";
|
|
53
53
|
import { canonicalizeRoot, expandHomeLikePath, readTextFileInDirectory, validatePathInDirectories, validatePathInDirectory, } from "./paths.js";
|
|
54
|
-
import { isCliCompatible } from "./version.js";
|
|
54
|
+
import { isCliCompatible, parseVersion } from "./version.js";
|
|
55
|
+
import { nodeChildEnvironment } from "./node-child.js";
|
|
55
56
|
import { hasFeature, probeCapabilitiesSync, } from "./capabilities.js";
|
|
56
57
|
import { downloadReleaseBinaryWithChecksum, extractZipWithPowerShell, } from "./autoInstall.js";
|
|
57
58
|
import { attachCaptureRelay, } from "./captureRelay.js";
|
|
@@ -1569,7 +1570,7 @@ const COPILOT_SUPPORTED = hasFeature(CLI_CAPABILITIES, "copilot_realtime");
|
|
|
1569
1570
|
// `./version.ts` (see issue #183). Hosted `.mcpb` bundles will run
|
|
1570
1571
|
// against CLIs with different minor/patch numbers within the same
|
|
1571
1572
|
// major; that is explicitly supported.
|
|
1572
|
-
const MCP_SERVER_VERSION = "0.25.
|
|
1573
|
+
const MCP_SERVER_VERSION = "0.25.3";
|
|
1573
1574
|
export function parseKnowledgeConfig(configContent) {
|
|
1574
1575
|
const knowledgeMatch = configContent.match(/\[knowledge\][\s\S]*?(?=\n\[|$)/);
|
|
1575
1576
|
if (!knowledgeMatch) {
|
|
@@ -2483,7 +2484,47 @@ export async function readKnowledgeStatusSnapshot(runner = runMinutes) {
|
|
|
2483
2484
|
}
|
|
2484
2485
|
return result;
|
|
2485
2486
|
}
|
|
2486
|
-
|
|
2487
|
+
const AGENT_READINESS_MIN_CLI_VERSION = "0.25.0";
|
|
2488
|
+
function isOlderVersion(installed, minimum) {
|
|
2489
|
+
const found = parseVersion(installed);
|
|
2490
|
+
const required = parseVersion(minimum);
|
|
2491
|
+
if (!found || !required)
|
|
2492
|
+
return false;
|
|
2493
|
+
if (found.major !== required.major)
|
|
2494
|
+
return found.major < required.major;
|
|
2495
|
+
if (found.minor !== required.minor)
|
|
2496
|
+
return found.minor < required.minor;
|
|
2497
|
+
return found.patch < required.patch;
|
|
2498
|
+
}
|
|
2499
|
+
function rejectedUnknownSubcommand(error, subcommand) {
|
|
2500
|
+
const diagnostic = [error?.stderr, error?.message]
|
|
2501
|
+
.filter((value) => typeof value === "string")
|
|
2502
|
+
.join("\n")
|
|
2503
|
+
.toLowerCase();
|
|
2504
|
+
return (diagnostic.includes(subcommand.toLowerCase()) &&
|
|
2505
|
+
/(?:unrecognized|unknown|invalid) subcommand/.test(diagnostic));
|
|
2506
|
+
}
|
|
2507
|
+
export function cliTooOldGuidance(installedVersion, minimumVersion = AGENT_READINESS_MIN_CLI_VERSION, platform = process.platform) {
|
|
2508
|
+
const update = platform === "darwin" || platform === "win32"
|
|
2509
|
+
? "Install the latest free Minutes desktop app from https://useminutes.app"
|
|
2510
|
+
: "Update the Minutes CLI from https://useminutes.app, or run `cargo install minutes-cli`";
|
|
2511
|
+
return (`The Minutes engine is too old for this extension (found v${installedVersion}; ` +
|
|
2512
|
+
`needs v${minimumVersion} or newer). ${update}, then restart this app.`);
|
|
2513
|
+
}
|
|
2514
|
+
async function oldCliReadinessGuidance(runner, platform) {
|
|
2515
|
+
try {
|
|
2516
|
+
const { stdout } = await runner(["--version"], 5000);
|
|
2517
|
+
const match = stdout.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
|
|
2518
|
+
if (!match || !isOlderVersion(match[0], AGENT_READINESS_MIN_CLI_VERSION)) {
|
|
2519
|
+
return null;
|
|
2520
|
+
}
|
|
2521
|
+
return cliTooOldGuidance(match[0], AGENT_READINESS_MIN_CLI_VERSION, platform);
|
|
2522
|
+
}
|
|
2523
|
+
catch {
|
|
2524
|
+
return null;
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
export async function readAgentTrustReadiness(runner = runMinutes, platform = process.platform) {
|
|
2487
2528
|
let stdout;
|
|
2488
2529
|
try {
|
|
2489
2530
|
({ stdout } = await runner(["agent-readiness", "--json"]));
|
|
@@ -2496,6 +2537,11 @@ export async function readAgentTrustReadiness(runner = runMinutes) {
|
|
|
2496
2537
|
// "could not be verified safely" and nothing to do about it (#774).
|
|
2497
2538
|
if (error?.cliMissing)
|
|
2498
2539
|
throw error;
|
|
2540
|
+
if (rejectedUnknownSubcommand(error, "agent-readiness")) {
|
|
2541
|
+
const guidance = await oldCliReadinessGuidance(runner, platform);
|
|
2542
|
+
if (guidance)
|
|
2543
|
+
throw new Error(guidance);
|
|
2544
|
+
}
|
|
2499
2545
|
throw new Error("Minutes agent readiness could not be verified safely.");
|
|
2500
2546
|
}
|
|
2501
2547
|
let result;
|
|
@@ -4854,7 +4900,7 @@ export async function runIsolatedMcpProcessAudio(filePath, allowedDirs, audioExt
|
|
|
4854
4900
|
child = spawn(helper.binary, helper.args, {
|
|
4855
4901
|
detached: true,
|
|
4856
4902
|
stdio: ["pipe", "pipe", "pipe", "pipe"],
|
|
4857
|
-
env: mcpCliChildEnv(),
|
|
4903
|
+
env: nodeChildEnvironment(mcpCliChildEnv()),
|
|
4858
4904
|
});
|
|
4859
4905
|
}
|
|
4860
4906
|
catch {
|
|
@@ -5657,7 +5703,7 @@ registerTool("stop_dictation", "Stop the current dictation session.", {}, { titl
|
|
|
5657
5703
|
};
|
|
5658
5704
|
});
|
|
5659
5705
|
// ── Tool: list_voices ────────────────────────────────────────
|
|
5660
|
-
registerTool("list_voices", "List
|
|
5706
|
+
registerTool("list_voices", "List active voice enrollments for speaker identification. Shows who has been enrolled, sample count, and model version.", {}, { title: "Voice Profiles", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }, async () => {
|
|
5661
5707
|
if (!(await isCliAvailable())) {
|
|
5662
5708
|
return { content: [{ type: "text", text: "Minutes CLI not available." }] };
|
|
5663
5709
|
}
|
|
@@ -5665,7 +5711,7 @@ registerTool("list_voices", "List enrolled voice profiles for speaker identifica
|
|
|
5665
5711
|
const profiles = parseJsonOutput(stdout);
|
|
5666
5712
|
if (!Array.isArray(profiles) || profiles.length === 0) {
|
|
5667
5713
|
return {
|
|
5668
|
-
content: [{ type: "text", text: "No voice profiles enrolled. The user can enroll with: minutes enroll" }],
|
|
5714
|
+
content: [{ type: "text", text: "No voice profiles enrolled. The user can enroll with: minutes voice enroll" }],
|
|
5669
5715
|
};
|
|
5670
5716
|
}
|
|
5671
5717
|
const lines = profiles.map((p) => `${p.name} — ${p.sample_count} samples, ${p.source} (${p.model_version})`);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment for a helper that must run as Node through process.execPath.
|
|
3
|
+
*
|
|
4
|
+
* Electron hosts such as Claude Desktop expose their app executable as
|
|
5
|
+
* process.execPath. Spawning that executable with a JavaScript file does not
|
|
6
|
+
* start Node unless ELECTRON_RUN_AS_NODE is set for the child. Keep the switch
|
|
7
|
+
* scoped to helpers whose argv is a Node program; ordinary Minutes CLI children
|
|
8
|
+
* must continue to receive their existing policy environment unchanged.
|
|
9
|
+
*/
|
|
10
|
+
export declare function nodeChildEnvironment(base?: NodeJS.ProcessEnv, electronVersion?: string | undefined): NodeJS.ProcessEnv;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment for a helper that must run as Node through process.execPath.
|
|
3
|
+
*
|
|
4
|
+
* Electron hosts such as Claude Desktop expose their app executable as
|
|
5
|
+
* process.execPath. Spawning that executable with a JavaScript file does not
|
|
6
|
+
* start Node unless ELECTRON_RUN_AS_NODE is set for the child. Keep the switch
|
|
7
|
+
* scoped to helpers whose argv is a Node program; ordinary Minutes CLI children
|
|
8
|
+
* must continue to receive their existing policy environment unchanged.
|
|
9
|
+
*/
|
|
10
|
+
export function nodeChildEnvironment(base = process.env, electronVersion = process.versions.electron) {
|
|
11
|
+
const environment = { ...base };
|
|
12
|
+
if (electronVersion) {
|
|
13
|
+
environment.ELECTRON_RUN_AS_NODE = "1";
|
|
14
|
+
}
|
|
15
|
+
return environment;
|
|
16
|
+
}
|
package/dist/secure-read.js
CHANGED
|
@@ -3,6 +3,7 @@ import { createHash } from "node:crypto";
|
|
|
3
3
|
import { lstatSync, realpathSync, statSync, } from "node:fs";
|
|
4
4
|
import { basename, dirname } from "path";
|
|
5
5
|
import { TextDecoder } from "node:util";
|
|
6
|
+
import { nodeChildEnvironment } from "./node-child.js";
|
|
6
7
|
/**
|
|
7
8
|
* Decode security-policy-bearing text without Unicode replacement.
|
|
8
9
|
*
|
|
@@ -353,7 +354,7 @@ class BoundParentReader {
|
|
|
353
354
|
});
|
|
354
355
|
this.child = spawn(process.execPath, ["-e", BOUND_READER_SOURCE], {
|
|
355
356
|
cwd: parent,
|
|
356
|
-
env: { ...process.env, MINUTES_BOUND_PARENT: parent },
|
|
357
|
+
env: nodeChildEnvironment({ ...process.env, MINUTES_BOUND_PARENT: parent }),
|
|
357
358
|
stdio: ["pipe", "pipe", "pipe"],
|
|
358
359
|
windowsHide: true,
|
|
359
360
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "minutes-mcp",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.3",
|
|
4
4
|
"description": "MCP server for minutes \u2014 conversation memory for AI assistants. Works with Claude Desktop, Mistral Vibe, Cursor, Windsurf, and any MCP client.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@modelcontextprotocol/ext-apps": "^1.6.0",
|
|
47
47
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
48
|
-
"minutes-sdk": "0.25.
|
|
48
|
+
"minutes-sdk": "0.25.3",
|
|
49
49
|
"yaml": "^2.8.3",
|
|
50
50
|
"zod": "^3.25 || ^4.0"
|
|
51
51
|
},
|