@costgate/momentum-mcp 0.2.1 → 0.2.2
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 +2 -2
- package/momentum-mcp.mjs +430 -93
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ MOMENTUM_TOKEN=mom_agent_xxx \
|
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
整条命令不用自己拼 —— 在 Momentum 的「设置 › Agent」里签发令牌时会直接给出,
|
|
12
|
-
默认用 `@latest`,发新版不用改配置;想固定某一版时把 latest 换成版本号(当前是 0.2.
|
|
12
|
+
默认用 `@latest`,发新版不用改配置;想固定某一版时把 latest 换成版本号(当前是 0.2.2)。
|
|
13
13
|
|
|
14
14
|
| 环境变量 | 必填 | 说明 |
|
|
15
15
|
|---|---|---|
|
|
@@ -18,4 +18,4 @@ MOMENTUM_TOKEN=mom_agent_xxx \
|
|
|
18
18
|
| `MOMENTUM_CF_ACCESS_CLIENT_ID` | 否 | 部署在 Cloudflare Access 后面时才需要 |
|
|
19
19
|
| `MOMENTUM_CF_ACCESS_CLIENT_SECRET` | 否 | 同上 |
|
|
20
20
|
|
|
21
|
-
版本 0.2.
|
|
21
|
+
版本 0.2.2。客户端和服务端版本不一致时,启动日志(stderr)会明确警告。
|
package/momentum-mcp.mjs
CHANGED
|
@@ -7195,7 +7195,7 @@ var require_dist = __commonJS({
|
|
|
7195
7195
|
}
|
|
7196
7196
|
});
|
|
7197
7197
|
|
|
7198
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
7198
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
7199
7199
|
import process2 from "node:process";
|
|
7200
7200
|
|
|
7201
7201
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/core/core.js
|
|
@@ -11699,7 +11699,7 @@ function preprocess(fn, schema) {
|
|
|
11699
11699
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/classic/external.js
|
|
11700
11700
|
config(en_default());
|
|
11701
11701
|
|
|
11702
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
11702
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
11703
11703
|
var LATEST_PROTOCOL_VERSION = "2025-11-25";
|
|
11704
11704
|
var SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"];
|
|
11705
11705
|
var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
|
|
@@ -13230,7 +13230,7 @@ var UrlElicitationRequiredError = class extends McpError {
|
|
|
13230
13230
|
}
|
|
13231
13231
|
};
|
|
13232
13232
|
|
|
13233
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
13233
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
|
|
13234
13234
|
var STDIO_DEFAULT_MAX_BUFFER_SIZE = 10 * 1024 * 1024;
|
|
13235
13235
|
var ReadBuffer = class {
|
|
13236
13236
|
constructor(options) {
|
|
@@ -13267,7 +13267,7 @@ function serializeMessage(message) {
|
|
|
13267
13267
|
return JSON.stringify(message) + "\n";
|
|
13268
13268
|
}
|
|
13269
13269
|
|
|
13270
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
13270
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
13271
13271
|
var StdioServerTransport = class {
|
|
13272
13272
|
constructor(_stdin = process2.stdin, _stdout = process2.stdout, options) {
|
|
13273
13273
|
this._stdin = _stdin;
|
|
@@ -15339,7 +15339,7 @@ var allowErrorProps = SuperJSON.allowErrorProps;
|
|
|
15339
15339
|
|
|
15340
15340
|
// src/version.ts
|
|
15341
15341
|
var UNKNOWN = "unknown";
|
|
15342
|
-
var MCP_VERSION = true ? "0.2.
|
|
15342
|
+
var MCP_VERSION = true ? "0.2.2" : versionFromRepo();
|
|
15343
15343
|
var CLIENT_HEADER = `momentum-mcp/${MCP_VERSION}`;
|
|
15344
15344
|
function compareVersions(a, b) {
|
|
15345
15345
|
const parse4 = (v) => {
|
|
@@ -19477,7 +19477,7 @@ function object2(shape, params) {
|
|
|
19477
19477
|
return new ZodMiniObject(def);
|
|
19478
19478
|
}
|
|
19479
19479
|
|
|
19480
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
19480
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
|
|
19481
19481
|
function isZ4Schema(s) {
|
|
19482
19482
|
const schema = s;
|
|
19483
19483
|
return !!schema._zod;
|
|
@@ -19637,7 +19637,7 @@ function getLiteralValue(schema) {
|
|
|
19637
19637
|
return void 0;
|
|
19638
19638
|
}
|
|
19639
19639
|
|
|
19640
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
19640
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
|
|
19641
19641
|
function isTerminal(status) {
|
|
19642
19642
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
19643
19643
|
}
|
|
@@ -20926,7 +20926,7 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
20926
20926
|
return combined;
|
|
20927
20927
|
};
|
|
20928
20928
|
|
|
20929
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
20929
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
|
|
20930
20930
|
function mapMiniTarget(t) {
|
|
20931
20931
|
if (!t)
|
|
20932
20932
|
return "draft-7";
|
|
@@ -20968,7 +20968,7 @@ function parseWithCompat(schema, data) {
|
|
|
20968
20968
|
return result.data;
|
|
20969
20969
|
}
|
|
20970
20970
|
|
|
20971
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
20971
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
|
|
20972
20972
|
var DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
|
|
20973
20973
|
var Protocol = class {
|
|
20974
20974
|
constructor(_options) {
|
|
@@ -21009,9 +21009,6 @@ var Protocol = class {
|
|
|
21009
21009
|
this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
|
|
21010
21010
|
const handleTaskResult = async () => {
|
|
21011
21011
|
const taskId = request.params.taskId;
|
|
21012
|
-
if (!await this._taskStore.getTask(taskId, extra.sessionId)) {
|
|
21013
|
-
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
|
|
21014
|
-
}
|
|
21015
21012
|
if (this._taskMessageQueue) {
|
|
21016
21013
|
let queuedMessage;
|
|
21017
21014
|
while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
|
|
@@ -21042,12 +21039,12 @@ var Protocol = class {
|
|
|
21042
21039
|
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
|
|
21043
21040
|
}
|
|
21044
21041
|
if (!isTerminal(task.status)) {
|
|
21045
|
-
await this._waitForTaskUpdate(taskId, extra.signal
|
|
21042
|
+
await this._waitForTaskUpdate(taskId, extra.signal);
|
|
21046
21043
|
return await handleTaskResult();
|
|
21047
21044
|
}
|
|
21048
21045
|
if (isTerminal(task.status)) {
|
|
21049
21046
|
const result = await this._taskStore.getTaskResult(taskId, extra.sessionId);
|
|
21050
|
-
this._clearTaskQueue(taskId
|
|
21047
|
+
this._clearTaskQueue(taskId);
|
|
21051
21048
|
return {
|
|
21052
21049
|
...result,
|
|
21053
21050
|
_meta: {
|
|
@@ -21084,7 +21081,7 @@ var Protocol = class {
|
|
|
21084
21081
|
throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
|
|
21085
21082
|
}
|
|
21086
21083
|
await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
|
|
21087
|
-
this._clearTaskQueue(request.params.taskId
|
|
21084
|
+
this._clearTaskQueue(request.params.taskId);
|
|
21088
21085
|
const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
|
|
21089
21086
|
if (!cancelledTask) {
|
|
21090
21087
|
throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
|
|
@@ -21212,19 +21209,6 @@ var Protocol = class {
|
|
|
21212
21209
|
const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
|
|
21213
21210
|
const capturedTransport = this._transport;
|
|
21214
21211
|
const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
|
|
21215
|
-
const sessionId = capturedTransport?.sessionId;
|
|
21216
|
-
const store = this._taskStore;
|
|
21217
|
-
let relatedTaskFound = true;
|
|
21218
|
-
let relatedTaskLookup;
|
|
21219
|
-
if (relatedTaskId && store && this._taskMessageQueue && sessionId !== void 0) {
|
|
21220
|
-
relatedTaskFound = false;
|
|
21221
|
-
relatedTaskLookup = (async () => {
|
|
21222
|
-
if (!await store.getTask(relatedTaskId, sessionId)) {
|
|
21223
|
-
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`);
|
|
21224
|
-
}
|
|
21225
|
-
relatedTaskFound = true;
|
|
21226
|
-
})();
|
|
21227
|
-
}
|
|
21228
21212
|
if (handler === void 0) {
|
|
21229
21213
|
const errorResponse = {
|
|
21230
21214
|
jsonrpc: "2.0",
|
|
@@ -21234,10 +21218,7 @@ var Protocol = class {
|
|
|
21234
21218
|
message: "Method not found"
|
|
21235
21219
|
}
|
|
21236
21220
|
};
|
|
21237
|
-
if (relatedTaskId &&
|
|
21238
|
-
const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() };
|
|
21239
|
-
relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error2) => this._onerror(new Error(`Failed to send an error response: ${error2}`)));
|
|
21240
|
-
} else if (relatedTaskId && this._taskMessageQueue) {
|
|
21221
|
+
if (relatedTaskId && this._taskMessageQueue) {
|
|
21241
21222
|
this._enqueueTaskMessage(relatedTaskId, {
|
|
21242
21223
|
type: "error",
|
|
21243
21224
|
message: errorResponse,
|
|
@@ -21288,10 +21269,7 @@ var Protocol = class {
|
|
|
21288
21269
|
closeSSEStream: extra?.closeSSEStream,
|
|
21289
21270
|
closeStandaloneSSEStream: extra?.closeStandaloneSSEStream
|
|
21290
21271
|
};
|
|
21291
|
-
|
|
21292
|
-
if (relatedTaskLookup && abortController.signal.aborted) {
|
|
21293
|
-
throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
|
|
21294
|
-
}
|
|
21272
|
+
Promise.resolve().then(() => {
|
|
21295
21273
|
if (taskCreationParams) {
|
|
21296
21274
|
this.assertTaskHandlerCapability(request.method);
|
|
21297
21275
|
}
|
|
@@ -21326,7 +21304,7 @@ var Protocol = class {
|
|
|
21326
21304
|
...error2["data"] !== void 0 && { data: error2["data"] }
|
|
21327
21305
|
}
|
|
21328
21306
|
};
|
|
21329
|
-
if (relatedTaskId && this._taskMessageQueue
|
|
21307
|
+
if (relatedTaskId && this._taskMessageQueue) {
|
|
21330
21308
|
await this._enqueueTaskMessage(relatedTaskId, {
|
|
21331
21309
|
type: "error",
|
|
21332
21310
|
message: errorResponse,
|
|
@@ -21806,7 +21784,7 @@ var Protocol = class {
|
|
|
21806
21784
|
throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
|
|
21807
21785
|
}
|
|
21808
21786
|
const maxQueueSize = this._options?.maxTaskQueueSize;
|
|
21809
|
-
await this._taskMessageQueue.enqueue(taskId, message, sessionId
|
|
21787
|
+
await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
|
|
21810
21788
|
}
|
|
21811
21789
|
/**
|
|
21812
21790
|
* Clears the message queue for a task and rejects any pending request resolvers.
|
|
@@ -21835,13 +21813,12 @@ var Protocol = class {
|
|
|
21835
21813
|
* Uses polling to check for updates at the task's configured poll interval.
|
|
21836
21814
|
* @param taskId The task ID to wait for
|
|
21837
21815
|
* @param signal Abort signal to cancel the wait
|
|
21838
|
-
* @param sessionId Session of the request that waits, passed to the task store
|
|
21839
21816
|
* @returns Promise that resolves when an update occurs or rejects if aborted
|
|
21840
21817
|
*/
|
|
21841
|
-
async _waitForTaskUpdate(taskId, signal
|
|
21818
|
+
async _waitForTaskUpdate(taskId, signal) {
|
|
21842
21819
|
let interval = this._options?.defaultTaskPollInterval ?? 1e3;
|
|
21843
21820
|
try {
|
|
21844
|
-
const task = await this._taskStore?.getTask(taskId
|
|
21821
|
+
const task = await this._taskStore?.getTask(taskId);
|
|
21845
21822
|
if (task?.pollInterval) {
|
|
21846
21823
|
interval = task.pollInterval;
|
|
21847
21824
|
}
|
|
@@ -21945,7 +21922,7 @@ function mergeCapabilities(base, additional) {
|
|
|
21945
21922
|
return result;
|
|
21946
21923
|
}
|
|
21947
21924
|
|
|
21948
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
21925
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
|
|
21949
21926
|
var import_ajv = __toESM(require_ajv(), 1);
|
|
21950
21927
|
var import_ajv_formats = __toESM(require_dist(), 1);
|
|
21951
21928
|
function createDefaultAjvInstance() {
|
|
@@ -22013,7 +21990,7 @@ var AjvJsonSchemaValidator = class {
|
|
|
22013
21990
|
}
|
|
22014
21991
|
};
|
|
22015
21992
|
|
|
22016
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
21993
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
|
|
22017
21994
|
var ExperimentalServerTasks = class {
|
|
22018
21995
|
constructor(_server) {
|
|
22019
21996
|
this._server = _server;
|
|
@@ -22226,7 +22203,7 @@ var ExperimentalServerTasks = class {
|
|
|
22226
22203
|
}
|
|
22227
22204
|
};
|
|
22228
22205
|
|
|
22229
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
22206
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
|
|
22230
22207
|
function assertToolsCallTaskCapability(requests, method, entityName) {
|
|
22231
22208
|
if (!requests) {
|
|
22232
22209
|
throw new Error(`${entityName} does not support task creation (required for ${method})`);
|
|
@@ -22261,7 +22238,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
|
|
|
22261
22238
|
}
|
|
22262
22239
|
}
|
|
22263
22240
|
|
|
22264
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
22241
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
|
|
22265
22242
|
var Server = class extends Protocol {
|
|
22266
22243
|
/**
|
|
22267
22244
|
* Initializes this server with the given name and version information.
|
|
@@ -22632,7 +22609,7 @@ var Server = class extends Protocol {
|
|
|
22632
22609
|
}
|
|
22633
22610
|
};
|
|
22634
22611
|
|
|
22635
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
22612
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
|
|
22636
22613
|
var COMPLETABLE_SYMBOL = Symbol.for("mcp.completable");
|
|
22637
22614
|
function isCompletable(schema) {
|
|
22638
22615
|
return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
|
|
@@ -22646,7 +22623,229 @@ var McpZodTypeKind;
|
|
|
22646
22623
|
McpZodTypeKind2["Completable"] = "McpCompletable";
|
|
22647
22624
|
})(McpZodTypeKind || (McpZodTypeKind = {}));
|
|
22648
22625
|
|
|
22649
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
22626
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/uriTemplate.js
|
|
22627
|
+
var MAX_TEMPLATE_LENGTH = 1e6;
|
|
22628
|
+
var MAX_VARIABLE_LENGTH = 1e6;
|
|
22629
|
+
var MAX_TEMPLATE_EXPRESSIONS = 1e4;
|
|
22630
|
+
var MAX_REGEX_LENGTH = 1e6;
|
|
22631
|
+
var UriTemplate = class _UriTemplate {
|
|
22632
|
+
/**
|
|
22633
|
+
* Returns true if the given string contains any URI template expressions.
|
|
22634
|
+
* A template expression is a sequence of characters enclosed in curly braces,
|
|
22635
|
+
* like {foo} or {?bar}.
|
|
22636
|
+
*/
|
|
22637
|
+
static isTemplate(str) {
|
|
22638
|
+
return /\{[^}\s]+\}/.test(str);
|
|
22639
|
+
}
|
|
22640
|
+
static validateLength(str, max, context) {
|
|
22641
|
+
if (str.length > max) {
|
|
22642
|
+
throw new Error(`${context} exceeds maximum length of ${max} characters (got ${str.length})`);
|
|
22643
|
+
}
|
|
22644
|
+
}
|
|
22645
|
+
get variableNames() {
|
|
22646
|
+
return this.parts.flatMap((part) => typeof part === "string" ? [] : part.names);
|
|
22647
|
+
}
|
|
22648
|
+
constructor(template) {
|
|
22649
|
+
_UriTemplate.validateLength(template, MAX_TEMPLATE_LENGTH, "Template");
|
|
22650
|
+
this.template = template;
|
|
22651
|
+
this.parts = this.parse(template);
|
|
22652
|
+
}
|
|
22653
|
+
toString() {
|
|
22654
|
+
return this.template;
|
|
22655
|
+
}
|
|
22656
|
+
parse(template) {
|
|
22657
|
+
const parts = [];
|
|
22658
|
+
let currentText = "";
|
|
22659
|
+
let i = 0;
|
|
22660
|
+
let expressionCount = 0;
|
|
22661
|
+
while (i < template.length) {
|
|
22662
|
+
if (template[i] === "{") {
|
|
22663
|
+
if (currentText) {
|
|
22664
|
+
parts.push(currentText);
|
|
22665
|
+
currentText = "";
|
|
22666
|
+
}
|
|
22667
|
+
const end = template.indexOf("}", i);
|
|
22668
|
+
if (end === -1)
|
|
22669
|
+
throw new Error("Unclosed template expression");
|
|
22670
|
+
expressionCount++;
|
|
22671
|
+
if (expressionCount > MAX_TEMPLATE_EXPRESSIONS) {
|
|
22672
|
+
throw new Error(`Template contains too many expressions (max ${MAX_TEMPLATE_EXPRESSIONS})`);
|
|
22673
|
+
}
|
|
22674
|
+
const expr = template.slice(i + 1, end);
|
|
22675
|
+
const operator = this.getOperator(expr);
|
|
22676
|
+
const exploded = expr.includes("*");
|
|
22677
|
+
const names = this.getNames(expr);
|
|
22678
|
+
const name = names[0];
|
|
22679
|
+
for (const name2 of names) {
|
|
22680
|
+
_UriTemplate.validateLength(name2, MAX_VARIABLE_LENGTH, "Variable name");
|
|
22681
|
+
}
|
|
22682
|
+
parts.push({ name, operator, names, exploded });
|
|
22683
|
+
i = end + 1;
|
|
22684
|
+
} else {
|
|
22685
|
+
currentText += template[i];
|
|
22686
|
+
i++;
|
|
22687
|
+
}
|
|
22688
|
+
}
|
|
22689
|
+
if (currentText) {
|
|
22690
|
+
parts.push(currentText);
|
|
22691
|
+
}
|
|
22692
|
+
return parts;
|
|
22693
|
+
}
|
|
22694
|
+
getOperator(expr) {
|
|
22695
|
+
const operators = ["+", "#", ".", "/", "?", "&"];
|
|
22696
|
+
return operators.find((op) => expr.startsWith(op)) || "";
|
|
22697
|
+
}
|
|
22698
|
+
getNames(expr) {
|
|
22699
|
+
const operator = this.getOperator(expr);
|
|
22700
|
+
return expr.slice(operator.length).split(",").map((name) => name.replace("*", "").trim()).filter((name) => name.length > 0);
|
|
22701
|
+
}
|
|
22702
|
+
encodeValue(value, operator) {
|
|
22703
|
+
_UriTemplate.validateLength(value, MAX_VARIABLE_LENGTH, "Variable value");
|
|
22704
|
+
if (operator === "+" || operator === "#") {
|
|
22705
|
+
return encodeURI(value);
|
|
22706
|
+
}
|
|
22707
|
+
return encodeURIComponent(value);
|
|
22708
|
+
}
|
|
22709
|
+
expandPart(part, variables) {
|
|
22710
|
+
if (part.operator === "?" || part.operator === "&") {
|
|
22711
|
+
const pairs = part.names.map((name) => {
|
|
22712
|
+
const value2 = variables[name];
|
|
22713
|
+
if (value2 === void 0)
|
|
22714
|
+
return "";
|
|
22715
|
+
const encoded2 = Array.isArray(value2) ? value2.map((v) => this.encodeValue(v, part.operator)).join(",") : this.encodeValue(value2.toString(), part.operator);
|
|
22716
|
+
return `${name}=${encoded2}`;
|
|
22717
|
+
}).filter((pair) => pair.length > 0);
|
|
22718
|
+
if (pairs.length === 0)
|
|
22719
|
+
return "";
|
|
22720
|
+
const separator = part.operator === "?" ? "?" : "&";
|
|
22721
|
+
return separator + pairs.join("&");
|
|
22722
|
+
}
|
|
22723
|
+
if (part.names.length > 1) {
|
|
22724
|
+
const values2 = part.names.map((name) => variables[name]).filter((v) => v !== void 0);
|
|
22725
|
+
if (values2.length === 0)
|
|
22726
|
+
return "";
|
|
22727
|
+
return values2.map((v) => Array.isArray(v) ? v[0] : v).join(",");
|
|
22728
|
+
}
|
|
22729
|
+
const value = variables[part.name];
|
|
22730
|
+
if (value === void 0)
|
|
22731
|
+
return "";
|
|
22732
|
+
const values = Array.isArray(value) ? value : [value];
|
|
22733
|
+
const encoded = values.map((v) => this.encodeValue(v, part.operator));
|
|
22734
|
+
switch (part.operator) {
|
|
22735
|
+
case "":
|
|
22736
|
+
return encoded.join(",");
|
|
22737
|
+
case "+":
|
|
22738
|
+
return encoded.join(",");
|
|
22739
|
+
case "#":
|
|
22740
|
+
return "#" + encoded.join(",");
|
|
22741
|
+
case ".":
|
|
22742
|
+
return "." + encoded.join(".");
|
|
22743
|
+
case "/":
|
|
22744
|
+
return "/" + encoded.join("/");
|
|
22745
|
+
default:
|
|
22746
|
+
return encoded.join(",");
|
|
22747
|
+
}
|
|
22748
|
+
}
|
|
22749
|
+
expand(variables) {
|
|
22750
|
+
let result = "";
|
|
22751
|
+
let hasQueryParam = false;
|
|
22752
|
+
for (const part of this.parts) {
|
|
22753
|
+
if (typeof part === "string") {
|
|
22754
|
+
result += part;
|
|
22755
|
+
continue;
|
|
22756
|
+
}
|
|
22757
|
+
const expanded = this.expandPart(part, variables);
|
|
22758
|
+
if (!expanded)
|
|
22759
|
+
continue;
|
|
22760
|
+
if ((part.operator === "?" || part.operator === "&") && hasQueryParam) {
|
|
22761
|
+
result += expanded.replace("?", "&");
|
|
22762
|
+
} else {
|
|
22763
|
+
result += expanded;
|
|
22764
|
+
}
|
|
22765
|
+
if (part.operator === "?" || part.operator === "&") {
|
|
22766
|
+
hasQueryParam = true;
|
|
22767
|
+
}
|
|
22768
|
+
}
|
|
22769
|
+
return result;
|
|
22770
|
+
}
|
|
22771
|
+
escapeRegExp(str) {
|
|
22772
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
22773
|
+
}
|
|
22774
|
+
partToRegExp(part) {
|
|
22775
|
+
const patterns = [];
|
|
22776
|
+
for (const name2 of part.names) {
|
|
22777
|
+
_UriTemplate.validateLength(name2, MAX_VARIABLE_LENGTH, "Variable name");
|
|
22778
|
+
}
|
|
22779
|
+
if (part.operator === "?" || part.operator === "&") {
|
|
22780
|
+
for (let i = 0; i < part.names.length; i++) {
|
|
22781
|
+
const name2 = part.names[i];
|
|
22782
|
+
const prefix = i === 0 ? "\\" + part.operator : "&";
|
|
22783
|
+
patterns.push({
|
|
22784
|
+
pattern: prefix + this.escapeRegExp(name2) + "=([^&]+)",
|
|
22785
|
+
name: name2
|
|
22786
|
+
});
|
|
22787
|
+
}
|
|
22788
|
+
return patterns;
|
|
22789
|
+
}
|
|
22790
|
+
let pattern;
|
|
22791
|
+
const name = part.name;
|
|
22792
|
+
switch (part.operator) {
|
|
22793
|
+
case "":
|
|
22794
|
+
pattern = part.exploded ? "([^/,]+(?:,[^/,]+)*)" : "([^/,]+)";
|
|
22795
|
+
break;
|
|
22796
|
+
case "+":
|
|
22797
|
+
case "#":
|
|
22798
|
+
pattern = "(.+)";
|
|
22799
|
+
break;
|
|
22800
|
+
case ".":
|
|
22801
|
+
pattern = "\\.([^/,]+)";
|
|
22802
|
+
break;
|
|
22803
|
+
case "/":
|
|
22804
|
+
pattern = "/" + (part.exploded ? "([^/,]+(?:,[^/,]+)*)" : "([^/,]+)");
|
|
22805
|
+
break;
|
|
22806
|
+
default:
|
|
22807
|
+
pattern = "([^/]+)";
|
|
22808
|
+
}
|
|
22809
|
+
patterns.push({ pattern, name });
|
|
22810
|
+
return patterns;
|
|
22811
|
+
}
|
|
22812
|
+
match(uri) {
|
|
22813
|
+
_UriTemplate.validateLength(uri, MAX_TEMPLATE_LENGTH, "URI");
|
|
22814
|
+
let pattern = "^";
|
|
22815
|
+
const names = [];
|
|
22816
|
+
for (const part of this.parts) {
|
|
22817
|
+
if (typeof part === "string") {
|
|
22818
|
+
pattern += this.escapeRegExp(part);
|
|
22819
|
+
} else {
|
|
22820
|
+
const patterns = this.partToRegExp(part);
|
|
22821
|
+
for (const { pattern: partPattern, name } of patterns) {
|
|
22822
|
+
pattern += partPattern;
|
|
22823
|
+
names.push({ name, exploded: part.exploded });
|
|
22824
|
+
}
|
|
22825
|
+
}
|
|
22826
|
+
}
|
|
22827
|
+
pattern += "$";
|
|
22828
|
+
_UriTemplate.validateLength(pattern, MAX_REGEX_LENGTH, "Generated regex pattern");
|
|
22829
|
+
const regex = new RegExp(pattern);
|
|
22830
|
+
const match = uri.match(regex);
|
|
22831
|
+
if (!match)
|
|
22832
|
+
return null;
|
|
22833
|
+
const result = {};
|
|
22834
|
+
for (let i = 0; i < names.length; i++) {
|
|
22835
|
+
const { name, exploded } = names[i];
|
|
22836
|
+
const value = match[i + 1];
|
|
22837
|
+
const cleanName = name.replace("*", "");
|
|
22838
|
+
if (exploded && value.includes(",")) {
|
|
22839
|
+
result[cleanName] = value.split(",");
|
|
22840
|
+
} else {
|
|
22841
|
+
result[cleanName] = value;
|
|
22842
|
+
}
|
|
22843
|
+
}
|
|
22844
|
+
return result;
|
|
22845
|
+
}
|
|
22846
|
+
};
|
|
22847
|
+
|
|
22848
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
|
|
22650
22849
|
var TOOL_NAME_REGEX = /^[A-Za-z0-9._-]{1,128}$/;
|
|
22651
22850
|
function validateToolName(name) {
|
|
22652
22851
|
const warnings = [];
|
|
@@ -22704,7 +22903,7 @@ function validateAndWarnToolName(name) {
|
|
|
22704
22903
|
return result.isValid;
|
|
22705
22904
|
}
|
|
22706
22905
|
|
|
22707
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
22906
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
|
|
22708
22907
|
var ExperimentalMcpServerTasks = class {
|
|
22709
22908
|
constructor(_mcpServer) {
|
|
22710
22909
|
this._mcpServer = _mcpServer;
|
|
@@ -22719,43 +22918,7 @@ var ExperimentalMcpServerTasks = class {
|
|
|
22719
22918
|
}
|
|
22720
22919
|
};
|
|
22721
22920
|
|
|
22722
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
22723
|
-
function toolInputElementCount(value, max) {
|
|
22724
|
-
let count = 0;
|
|
22725
|
-
const stack = [value];
|
|
22726
|
-
while (stack.length > 0) {
|
|
22727
|
-
const node = stack.pop();
|
|
22728
|
-
if (node === null || typeof node !== "object")
|
|
22729
|
-
continue;
|
|
22730
|
-
if (Array.isArray(node)) {
|
|
22731
|
-
for (const child of node) {
|
|
22732
|
-
if (++count > max)
|
|
22733
|
-
return count;
|
|
22734
|
-
if (child !== null && typeof child === "object")
|
|
22735
|
-
stack.push(child);
|
|
22736
|
-
}
|
|
22737
|
-
} else {
|
|
22738
|
-
for (const key in node) {
|
|
22739
|
-
if (!Object.prototype.hasOwnProperty.call(node, key))
|
|
22740
|
-
continue;
|
|
22741
|
-
if (++count > max)
|
|
22742
|
-
return count;
|
|
22743
|
-
const child = node[key];
|
|
22744
|
-
if (child !== null && typeof child === "object")
|
|
22745
|
-
stack.push(child);
|
|
22746
|
-
}
|
|
22747
|
-
}
|
|
22748
|
-
}
|
|
22749
|
-
return count;
|
|
22750
|
-
}
|
|
22751
|
-
function resolveMaxToolInputElements(value) {
|
|
22752
|
-
if (value === void 0 || value === Infinity)
|
|
22753
|
-
return void 0;
|
|
22754
|
-
if (typeof value !== "number" || Number.isNaN(value) || value < 1) {
|
|
22755
|
-
throw new RangeError(`maxToolInputElements must be a number of at least 1, or Infinity, got ${String(value)}`);
|
|
22756
|
-
}
|
|
22757
|
-
return value;
|
|
22758
|
-
}
|
|
22921
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
|
|
22759
22922
|
var McpServer = class {
|
|
22760
22923
|
constructor(serverInfo, options) {
|
|
22761
22924
|
this._registeredResources = {};
|
|
@@ -22767,7 +22930,6 @@ var McpServer = class {
|
|
|
22767
22930
|
this._resourceHandlersInitialized = false;
|
|
22768
22931
|
this._promptHandlersInitialized = false;
|
|
22769
22932
|
this.server = new Server(serverInfo, options);
|
|
22770
|
-
this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements);
|
|
22771
22933
|
}
|
|
22772
22934
|
/**
|
|
22773
22935
|
* Access experimental features.
|
|
@@ -22898,15 +23060,12 @@ var McpServer = class {
|
|
|
22898
23060
|
* Validates tool input arguments against the tool's input schema.
|
|
22899
23061
|
*/
|
|
22900
23062
|
async validateToolInput(tool, args, toolName) {
|
|
22901
|
-
if (this._maxToolInputElements !== void 0 && toolInputElementCount(args, this._maxToolInputElements) > this._maxToolInputElements) {
|
|
22902
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for tool ${toolName}: arguments contain more than the maximum of ${this._maxToolInputElements} elements`);
|
|
22903
|
-
}
|
|
22904
23063
|
if (!tool.inputSchema) {
|
|
22905
23064
|
return void 0;
|
|
22906
23065
|
}
|
|
22907
23066
|
const inputObj = normalizeObjectSchema(tool.inputSchema);
|
|
22908
23067
|
const schemaToParse = inputObj ?? tool.inputSchema;
|
|
22909
|
-
const parseResult = await safeParseAsync3(schemaToParse, args
|
|
23068
|
+
const parseResult = await safeParseAsync3(schemaToParse, args);
|
|
22910
23069
|
if (!parseResult.success) {
|
|
22911
23070
|
const error2 = "error" in parseResult ? parseResult.error : "Unknown error";
|
|
22912
23071
|
const errorMessage = getParseErrorMessage(error2);
|
|
@@ -23144,7 +23303,7 @@ var McpServer = class {
|
|
|
23144
23303
|
}
|
|
23145
23304
|
if (prompt.argsSchema) {
|
|
23146
23305
|
const argsObj = normalizeObjectSchema(prompt.argsSchema);
|
|
23147
|
-
const parseResult = await safeParseAsync3(argsObj, request.params.arguments
|
|
23306
|
+
const parseResult = await safeParseAsync3(argsObj, request.params.arguments);
|
|
23148
23307
|
if (!parseResult.success) {
|
|
23149
23308
|
const error2 = "error" in parseResult ? parseResult.error : "Unknown error";
|
|
23150
23309
|
const errorMessage = getParseErrorMessage(error2);
|
|
@@ -23475,6 +23634,30 @@ var McpServer = class {
|
|
|
23475
23634
|
}
|
|
23476
23635
|
}
|
|
23477
23636
|
};
|
|
23637
|
+
var ResourceTemplate = class {
|
|
23638
|
+
constructor(uriTemplate, _callbacks) {
|
|
23639
|
+
this._callbacks = _callbacks;
|
|
23640
|
+
this._uriTemplate = typeof uriTemplate === "string" ? new UriTemplate(uriTemplate) : uriTemplate;
|
|
23641
|
+
}
|
|
23642
|
+
/**
|
|
23643
|
+
* Gets the URI template pattern.
|
|
23644
|
+
*/
|
|
23645
|
+
get uriTemplate() {
|
|
23646
|
+
return this._uriTemplate;
|
|
23647
|
+
}
|
|
23648
|
+
/**
|
|
23649
|
+
* Gets the list callback, if one was provided.
|
|
23650
|
+
*/
|
|
23651
|
+
get listCallback() {
|
|
23652
|
+
return this._callbacks.list;
|
|
23653
|
+
}
|
|
23654
|
+
/**
|
|
23655
|
+
* Gets the callback for completing a specific URI template variable, if one was provided.
|
|
23656
|
+
*/
|
|
23657
|
+
completeCallback(variable) {
|
|
23658
|
+
return this._callbacks.complete?.[variable];
|
|
23659
|
+
}
|
|
23660
|
+
};
|
|
23478
23661
|
var EMPTY_OBJECT_JSON_SCHEMA = {
|
|
23479
23662
|
type: "object",
|
|
23480
23663
|
properties: {}
|
|
@@ -23551,6 +23734,68 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
23551
23734
|
}
|
|
23552
23735
|
};
|
|
23553
23736
|
|
|
23737
|
+
// src/prompts.ts
|
|
23738
|
+
var TASK_ARG = external_exports.string().min(1).describe("\u4EFB\u52A1\u7F16\u53F7\uFF0C\u5982 MOM-12");
|
|
23739
|
+
var user = (lines) => [
|
|
23740
|
+
{ role: "user", content: { type: "text", text: lines.filter((l) => typeof l === "string").join("\n") } }
|
|
23741
|
+
];
|
|
23742
|
+
function createPrompts(profile = "work") {
|
|
23743
|
+
const canDigest = profile === "full";
|
|
23744
|
+
return [
|
|
23745
|
+
{
|
|
23746
|
+
name: "start_task",
|
|
23747
|
+
title: "\u5F00\u59CB\u505A\u4EFB\u52A1",
|
|
23748
|
+
description: "\u9886\u53D6\u4E00\u4E2A Momentum \u4EFB\u52A1\u5E76\u6309\u56E2\u961F\u6D41\u7A0B\u5F00\u5DE5\uFF1A\u8BFB\u4E0A\u4E0B\u6587\u3001\u8BB2\u6E05\u65B9\u6848\u3001\u52A8\u624B\u3001\u5173\u952E\u8282\u70B9\u7559\u8BC4\u8BBA\u3002",
|
|
23749
|
+
argsSchema: { task: TASK_ARG, note: external_exports.string().optional().describe("\u8FD9\u6B21\u8981\u505A\u4EC0\u4E48\u3001\u6709\u4EC0\u4E48\u989D\u5916\u8981\u6C42") },
|
|
23750
|
+
render: ({ task, note }) => user([
|
|
23751
|
+
`\u8BF7\u5F00\u59CB\u505A Momentum \u4EFB\u52A1 ${task}\u3002`,
|
|
23752
|
+
"",
|
|
23753
|
+
`1. \u76F4\u63A5\u8C03 begin_task("${task}")\uFF1A\u5B83\u4E00\u6B21\u5B8C\u6210\u89E3\u6790\u7F16\u53F7\u3001\u5F00\u8FD0\u884C\u3001\u9886\u53D6\u5E76\u8FD4\u56DE\u7D27\u51D1\u4E0A\u4E0B\u6587\uFF0C\u4E0D\u5FC5\u5148 whoami / get_task\u3002\u5FC3\u8DF3\u81EA\u52A8\u7EED\u7EA6\u3002`,
|
|
23754
|
+
"2. \u8BFB\u4E0A\u4E0B\u6587\uFF1A\u63CF\u8FF0\u3001\u9A8C\u6536\u6807\u51C6\uFF08\u8BB0\u4E0B specVersion\uFF0C\u4EA4\u4ED8\u65F6\u8981\u7528\uFF09\u3001\u4F9D\u8D56\u3001\u5DF2\u6709\u51B3\u5B9A\u3001\u5F85\u7B54\u95EE\u9898\u548C\u6700\u65B0\u4EA4\u4ED8\u3002\u88AB\u4F9D\u8D56\u5361\u4F4F\u3001\u6216\u6709\u963B\u585E\u95EE\u9898\u6CA1\u7B54\u65F6\uFF0C\u5148\u505C\u4E0B\u6765\u544A\u8BC9\u6211\u3002",
|
|
23755
|
+
"3. \u52A8\u624B\u524D\u5148\u7528\u5927\u767D\u8BDD\u8BB2\u6E05\u6253\u7B97\u600E\u4E48\u505A\u3001\u6BCF\u6761\u9A8C\u6536\u6807\u51C6\u6253\u7B97\u600E\u4E48\u9A8C\u8BC1\uFF1B\u65B9\u6848\u503C\u5F97\u7559\u6863\u5C31\u7528 update_task_plan \u5199\u8FDB\u6267\u884C\u7EC6\u5316\u3002",
|
|
23756
|
+
"4. \u5F00\u59CB\u5E72\u6D3B\u3002\u7F3A\u4FE1\u606F\u5148\u95EE\u6211\uFF1B\u6211\u7B54\u4E0D\u4E86\u3001\u8981\u56E2\u961F\u62CD\u677F\u7684\u624D\u7528 ask_question\u3002\u5173\u952E\u8282\u70B9\u7528 comment_on_task \u5199\u4E00\u6761\u77ED\u8FDB\u5C55\uFF08\u5148\u7ED3\u8BBA\u3001\u518D\u8981\u70B9\uFF09\u3002",
|
|
23757
|
+
"5. \u505A\u5B8C\u6309\u300C\u5199\u4EA4\u4ED8\u8BF4\u660E\u300D\uFF08write_delivery\uFF09\u7684\u8981\u6C42\u8C03 finish_task_work \u63D0\u4EA4\u4EA4\u4ED8\u5E76\u79FB\u5230\u8BC4\u5BA1\u3002",
|
|
23758
|
+
note && "",
|
|
23759
|
+
note && `\u8865\u5145\u8981\u6C42\uFF1A${note}`
|
|
23760
|
+
])
|
|
23761
|
+
},
|
|
23762
|
+
{
|
|
23763
|
+
name: "digest_discussion",
|
|
23764
|
+
title: "\u6574\u7406\u8BA8\u8BBA\u6210\u63D0\u6848",
|
|
23765
|
+
description: "\u628A\u5F53\u524D\u4F1A\u8BDD\u91CC\u7684\u8BA8\u8BBA\u6574\u7406\u6210\u4EFB\u52A1\u7684\u4FEE\u6539\u63D0\u6848\uFF1A\u62CD\u677F\u7684\u51B3\u5B9A\u3001\u5F85\u7B54\u95EE\u9898\u3001\u8BF4\u660E\u4E0E\u9A8C\u6536\u6807\u51C6\u7684\u6539\u52A8\u3002",
|
|
23766
|
+
argsSchema: { task: TASK_ARG, focus: external_exports.string().optional().describe("\u53EA\u6574\u7406\u8BA8\u8BBA\u91CC\u7684\u54EA\u4E00\u90E8\u5206") },
|
|
23767
|
+
render: ({ task, focus }) => user([
|
|
23768
|
+
`\u628A\u6211\u4EEC\u8FD9\u6BB5\u8BA8\u8BBA\u6574\u7406\u6210\u4EFB\u52A1 ${task} \u7684\u4FEE\u6539\u63D0\u6848\u3002`,
|
|
23769
|
+
focus && `\u53EA\u6574\u7406\u8FD9\u90E8\u5206\uFF1A${focus}`,
|
|
23770
|
+
"",
|
|
23771
|
+
`1. \u5148\u8C03 get_task_context("${task}") \u770B\u5F53\u524D\u8BF4\u660E\u3001\u7248\u672C\u53F7 specVersion\u3001\u5DF2\u6709\u51B3\u5B9A\u548C\u5F85\u7B54\u95EE\u9898\uFF0C\u5DF2\u6709\u7684\u4E0D\u8981\u91CD\u590D\u3002`,
|
|
23772
|
+
"2. \u4ECE\u8BA8\u8BBA\u91CC\u63D0\u53D6\u4E09\u7C7B\u4E1C\u897F\uFF1A",
|
|
23773
|
+
" - \u5DF2\u7ECF\u62CD\u677F\u7684\u51B3\u5B9A\uFF1A\u4E00\u6761\u53EA\u8BF4\u4E00\u4EF6\u4E8B\uFF0C\u5199\u6E05\u7406\u7531\uFF1B",
|
|
23774
|
+
" - \u8FD8\u6CA1\u6709\u7B54\u6848\u7684\u95EE\u9898\uFF1A\u6807\u51FA\u54EA\u4E9B\u4F1A\u5361\u4F4F\u8FDB\u5EA6\uFF1B",
|
|
23775
|
+
" - \u63CF\u8FF0\u6216\u9A8C\u6536\u6807\u51C6\u8981\u600E\u4E48\u6539\uFF1A\u9A8C\u6536\u6807\u51C6\u6BCF\u6761\u53EF\u6838\u5BF9\uFF0C\u4FDD\u7559\u539F\u6709\u7684 id\u3002",
|
|
23776
|
+
" \u8BA8\u8BBA\u4E2D\u7684\u8BBE\u60F3\u3001\u53EA\u6709\u6211\u4E00\u65B9\u63D0\u8FC7\u7684\u60F3\u6CD5\u4E0D\u7B97\u51B3\u5B9A\uFF0C\u4E0D\u80FD\u81EA\u884C\u8BA4\u5B9A\u3002",
|
|
23777
|
+
"3. \u5148\u628A\u8349\u7A3F\u7528\u5927\u767D\u8BDD\u5217\u7ED9\u6211\u8FC7\u76EE\uFF0C\u6211\u786E\u8BA4\u540E\u518D\u63D0\u4EA4\u3002",
|
|
23778
|
+
canDigest ? "4. \u786E\u8BA4\u540E\u8C03 propose_digest\uFF0Cspec_change.expected_version \u586B\u7B2C 1 \u6B65\u8BFB\u5230\u7684 specVersion\u3002\u5B83\u662F\u4E00\u6761\u5F85\u4EBA\u786E\u8BA4\u7684\u63D0\u6848\uFF1A\u63A5\u53D7\u540E\u4E00\u6B21\u751F\u6548\u3001\u8BF4\u660E\u5F62\u6210\u65B0\u7248\u672C\uFF0C\u5728\u90A3\u4E4B\u524D\u4EFB\u52A1\u6CA1\u6709\u4EFB\u4F55\u6539\u52A8\u3002" : "4. \u5F53\u524D\u5DE5\u5177\u6863\uFF08work\uFF09\u6CA1\u6709 propose_digest\uFF1A\u786E\u8BA4\u540E\u628A\u51B3\u5B9A\u548C\u8BF4\u660E\u6539\u52A8\u7528 comment_on_task \u8BB0\u5230\u4EFB\u52A1\u4E0B\uFF0C\u963B\u585E\u95EE\u9898\u7528 ask_question \u63D0\u51FA\u6765\uFF1B\u5E76\u63D0\u9192\u6211\u8BF4\u660E\u672C\u8EAB\u8981\u5728 Momentum \u754C\u9762\u91CC\u6539\uFF0C\u6216\u628A MOMENTUM_TOOL_PROFILE \u8BBE\u6210 full \u540E\u518D\u63D0\u4EA4\u63D0\u6848\u3002"
|
|
23779
|
+
])
|
|
23780
|
+
},
|
|
23781
|
+
{
|
|
23782
|
+
name: "write_delivery",
|
|
23783
|
+
title: "\u5199\u4EA4\u4ED8\u8BF4\u660E",
|
|
23784
|
+
description: "\u6309\u4EFB\u52A1\u8BF4\u660E\u9010\u6761\u8986\u76D6\u9A8C\u6536\u6807\u51C6\uFF0C\u5199\u597D\u4EA4\u4ED8\u8BF4\u660E\u5E76\u8C03 finish_task_work \u63D0\u4EA4\u3001\u79FB\u5230\u8BC4\u5BA1\u3002",
|
|
23785
|
+
argsSchema: { task: TASK_ARG },
|
|
23786
|
+
render: ({ task }) => user([
|
|
23787
|
+
`\u4E3A\u4EFB\u52A1 ${task} \u5199\u4EA4\u4ED8\u8BF4\u660E\u5E76\u63D0\u4EA4\u3002`,
|
|
23788
|
+
"",
|
|
23789
|
+
`1. \u624B\u4E0A\u6CA1\u6709\u9A8C\u6536\u6807\u51C6\u548C specVersion \u65F6\u5148\u8C03 get_task_context("${task}")\u3002based_on_spec_version \u586B\u4F60\u5B9E\u9645\u5BF9\u7167\u7684\u90A3\u4E2A\u7248\u672C\uFF1B\u5F00\u5DE5\u540E\u8BF4\u660E\u5347\u8FC7\u7248\uFF0C\u5148\u5BF9\u7167\u65B0\u7248\u672C\u770B\u8FD8\u5DEE\u4EC0\u4E48\u3002`,
|
|
23790
|
+
"2. summary \u5199\u7ED9\u4EFB\u52A1\u6307\u6D3E\u7684\u4EBA\u770B\uFF1A\u5927\u767D\u8BDD\u8BB2\u505A\u4E86\u4EC0\u4E48\u3001\u5173\u952E\u53D6\u820D\u3001\u5BF9\u4F7F\u7528\u8005\u7684\u5F71\u54CD\uFF1B\u6D41\u7A0B\u6216\u6A21\u5757\u5173\u7CFB\u7528 mermaid \u753B\u51FA\u6765\u3002\u5DE5\u7A0B\u5E08\u591A\u8BB2\u5B9E\u73B0\u53D6\u820D\uFF0C\u5176\u4ED6\u4EBA\u53EA\u8BB2\u7ED3\u679C\u3002",
|
|
23791
|
+
"3. results \u9010\u6761\u8986\u76D6\u6BCF\u4E2A\u9A8C\u6536\u6807\u51C6\uFF08criterionId \u7528\u8BF4\u660E\u91CC\u7684 id\uFF09\uFF1Aoutcome \u53EA\u7528 passed / failed / unverified\uFF0Cevidence \u5199\u522B\u4EBA\u80FD\u6838\u5BF9\u7684\u8BC1\u636E\uFF08\u6D4B\u8BD5\u540D\u3001\u547D\u4EE4\u8F93\u51FA\u3001\u94FE\u63A5\uFF09\u3002\u6CA1\u6709\u771F\u6B63\u9A8C\u8BC1\u8FC7\u7684\u6807 unverified\uFF0C\u4E0D\u8981\u731C\u3002",
|
|
23792
|
+
"4. artifacts \u653E PR\u3001\u6587\u6863\u7B49\u94FE\u63A5\uFF1B\u6CA1\u505A\u5B8C\u7684\u5199\u8FDB remaining_work\uFF1B\u63A5\u624B\u7684\u4EBA\u9700\u8981\u77E5\u9053\u7684\u5199\u8FDB handoff\u3002",
|
|
23793
|
+
"5. \u8C03 finish_task_work \u63D0\u4EA4\uFF1Aidempotency_key \u53D6\u4E00\u4E2A\u7A33\u5B9A\u7684\u503C\uFF0C\u67D0\u4E00\u6B65\u5931\u8D25\u65F6\u7528\u76F8\u540C\u53C2\u6570\u91CD\u8BD5\u3002\u4EFB\u52A1\u4F1A\u8FDB\u8BC4\u5BA1\uFF0C\u8BC4\u5BA1\u901A\u8FC7\u524D\u4E0D\u7B97\u5B8C\u6210\u3002"
|
|
23794
|
+
])
|
|
23795
|
+
}
|
|
23796
|
+
];
|
|
23797
|
+
}
|
|
23798
|
+
|
|
23554
23799
|
// ../../packages/core/src/task-schemas.ts
|
|
23555
23800
|
var markdownSchema = external_exports.string().max(2e5);
|
|
23556
23801
|
var httpUrl = external_exports.string().url().max(2e3).refine((url) => /^https?:\/\//i.test(url), "\u53EA\u652F\u6301 HTTP(S) \u94FE\u63A5");
|
|
@@ -23601,11 +23846,13 @@ var RunHeartbeats = class {
|
|
|
23601
23846
|
lastRunOfTask = /* @__PURE__ */ new Map();
|
|
23602
23847
|
pending = [];
|
|
23603
23848
|
timer = null;
|
|
23849
|
+
closed = false;
|
|
23604
23850
|
intervalMs;
|
|
23605
23851
|
leaseSeconds;
|
|
23606
23852
|
log;
|
|
23607
23853
|
/** 开始替这次运行续约。expectClaim = 它手上应当有领取,续不上要告诉模型 */
|
|
23608
23854
|
track(runId, taskId, expectClaim = false) {
|
|
23855
|
+
if (this.closed) return;
|
|
23609
23856
|
this.runs.set(runId, { taskId, expectClaim });
|
|
23610
23857
|
if (taskId) this.lastRunOfTask.set(taskId, runId);
|
|
23611
23858
|
if (!this.timer) {
|
|
@@ -23628,6 +23875,10 @@ var RunHeartbeats = class {
|
|
|
23628
23875
|
has(runId) {
|
|
23629
23876
|
return this.runs.has(runId);
|
|
23630
23877
|
}
|
|
23878
|
+
/** 正在续约的运行数 */
|
|
23879
|
+
get size() {
|
|
23880
|
+
return this.runs.size;
|
|
23881
|
+
}
|
|
23631
23882
|
/** 取走攒下的提醒。每条只给模型看一次 */
|
|
23632
23883
|
drainNotices() {
|
|
23633
23884
|
return this.pending.splice(0);
|
|
@@ -23636,6 +23887,15 @@ var RunHeartbeats = class {
|
|
|
23636
23887
|
if (this.timer) clearInterval(this.timer);
|
|
23637
23888
|
this.timer = null;
|
|
23638
23889
|
}
|
|
23890
|
+
/**
|
|
23891
|
+
* 永久停掉:之后再 track 也不会续约。远程会话(http.ts)结束时用 —— 会话关掉的那一刻
|
|
23892
|
+
* 可能还有一个 begin_task 在路上,它回来时的 track 不能把一个已经没人的会话重新续活
|
|
23893
|
+
*/
|
|
23894
|
+
close() {
|
|
23895
|
+
this.closed = true;
|
|
23896
|
+
this.runs.clear();
|
|
23897
|
+
this.stop();
|
|
23898
|
+
}
|
|
23639
23899
|
/** 给所有在跟的运行各发一次心跳。定时器调它,测试也直接调它 */
|
|
23640
23900
|
async tick() {
|
|
23641
23901
|
await Promise.all([...this.runs].map(([runId, run2]) => this.beatOne(runId, run2)));
|
|
@@ -23977,6 +24237,14 @@ var BEGIN_OUTPUT = external_exports.object({
|
|
|
23977
24237
|
context: CONTEXT_SCHEMA.optional(),
|
|
23978
24238
|
proposalId: external_exports.string().optional()
|
|
23979
24239
|
}).passthrough();
|
|
24240
|
+
var NAMED = external_exports.object({ id: external_exports.string(), name: external_exports.string() }).passthrough();
|
|
24241
|
+
var WHOAMI_OUTPUT = external_exports.object({
|
|
24242
|
+
kind: external_exports.enum(["agent", "human"]),
|
|
24243
|
+
actorId: external_exports.string().nullable(),
|
|
24244
|
+
orgId: external_exports.string().nullable(),
|
|
24245
|
+
agent: NAMED.optional(),
|
|
24246
|
+
instance: NAMED.optional()
|
|
24247
|
+
}).passthrough();
|
|
23980
24248
|
var PAGE_OUTPUT = external_exports.object({ items: external_exports.array(external_exports.unknown()) }).passthrough();
|
|
23981
24249
|
var TASKS_OUTPUT = external_exports.object({ items: external_exports.array(external_exports.object(TASK_FIELDS).passthrough()) }).passthrough();
|
|
23982
24250
|
var BROWSE_OUTCOME = external_exports.enum(["ok", "no_projects", "no_match", "project_unavailable", "failed"]);
|
|
@@ -23986,7 +24254,7 @@ var BROWSE_OUTPUT = external_exports.object({
|
|
|
23986
24254
|
items: external_exports.array(external_exports.unknown()),
|
|
23987
24255
|
nextOffset: external_exports.number().nullable()
|
|
23988
24256
|
}).passthrough();
|
|
23989
|
-
var READ = { readOnlyHint: true, openWorldHint: false };
|
|
24257
|
+
var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
23990
24258
|
var write = (destructiveHint, idempotentHint) => ({
|
|
23991
24259
|
readOnlyHint: false,
|
|
23992
24260
|
destructiveHint,
|
|
@@ -24010,7 +24278,7 @@ var TOOL_META = {
|
|
|
24010
24278
|
list_task_deliveries: { annotations: READ, outputSchema: PAGE_OUTPUT },
|
|
24011
24279
|
poll_events: { annotations: READ, outputSchema: PAGE_OUTPUT },
|
|
24012
24280
|
current_cycle: { annotations: READ },
|
|
24013
|
-
whoami: { annotations: READ },
|
|
24281
|
+
whoami: { annotations: READ, outputSchema: WHOAMI_OUTPUT },
|
|
24014
24282
|
// 开工 / 收尾:重复调用沿用同一次运行、交付按 idempotency_key 去重
|
|
24015
24283
|
begin_task: { annotations: write(false, true), outputSchema: BEGIN_OUTPUT },
|
|
24016
24284
|
finish_task_work: { annotations: write(false, true), outputSchema: FINISH_OUTPUT },
|
|
@@ -25381,6 +25649,52 @@ function explain(err) {
|
|
|
25381
25649
|
return `\u5931\u8D25\uFF1A${message}`;
|
|
25382
25650
|
}
|
|
25383
25651
|
|
|
25652
|
+
// src/resources.ts
|
|
25653
|
+
var SPEC_URI = (key, version2) => `momentum://task/${encodeURIComponent(key)}/spec${version2 === void 0 ? "" : `/${version2}`}`;
|
|
25654
|
+
var UUID2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
25655
|
+
function renderSpec(key, spec, current) {
|
|
25656
|
+
const at = spec.createdAt instanceof Date ? spec.createdAt.toISOString() : spec.createdAt;
|
|
25657
|
+
const criteria = spec.acceptance?.criteria ?? [];
|
|
25658
|
+
return [
|
|
25659
|
+
`# ${key} \xB7 ${spec.title}`,
|
|
25660
|
+
"",
|
|
25661
|
+
`\u8BF4\u660E\u7248\u672C v${spec.version}\uFF08\u4E0D\u53EF\u53D8\uFF0C${current ? "\u5F53\u524D\u7248\uFF0C" : ""}\u5730\u5740 ${SPEC_URI(key, spec.version)}\uFF09\xB7 ${at}`,
|
|
25662
|
+
...spec.changeSummary ? [`\u672C\u7248\u53D8\u66F4\uFF1A${spec.changeSummary}`] : [],
|
|
25663
|
+
"",
|
|
25664
|
+
"## \u63CF\u8FF0",
|
|
25665
|
+
"",
|
|
25666
|
+
spec.descriptionMd?.trim() || "\uFF08\u65E0\u63CF\u8FF0\uFF09",
|
|
25667
|
+
"",
|
|
25668
|
+
"## \u9A8C\u6536\u6807\u51C6",
|
|
25669
|
+
"",
|
|
25670
|
+
...criteria.length ? criteria.map((c) => `- [${c.id}] ${c.text}`) : ["\uFF08\u672A\u5B9A\u4E49\u9A8C\u6536\u6807\u51C6\uFF09"]
|
|
25671
|
+
].join("\n");
|
|
25672
|
+
}
|
|
25673
|
+
function createSpecReader(client) {
|
|
25674
|
+
async function resolve(ref) {
|
|
25675
|
+
const [found] = UUID2.test(ref) ? [await client.task.ref.query({ taskId: ref })] : await client.task.list.query({ key: ref, limit: 1 });
|
|
25676
|
+
if (!found) throw new Error(`\u627E\u4E0D\u5230\u4EFB\u52A1 '${ref}'`);
|
|
25677
|
+
return { id: found.id, key: found.key };
|
|
25678
|
+
}
|
|
25679
|
+
return async function readSpec(ref, version2) {
|
|
25680
|
+
if (version2 !== void 0 && !/^\d+$/.test(version2)) {
|
|
25681
|
+
throw new Error(`\u8BF4\u660E\u7248\u672C\u53F7\u5FC5\u987B\u662F\u975E\u8D1F\u6574\u6570\uFF0C\u6536\u5230 '${version2}'`);
|
|
25682
|
+
}
|
|
25683
|
+
try {
|
|
25684
|
+
const task = await resolve(ref);
|
|
25685
|
+
const current = (await client.task.context.query({ taskId: task.id })).specVersion;
|
|
25686
|
+
const wanted = version2 === void 0 ? current : Number(version2);
|
|
25687
|
+
const spec = await client.task.spec.query({ taskId: task.id, version: wanted });
|
|
25688
|
+
return {
|
|
25689
|
+
mimeType: "text/markdown",
|
|
25690
|
+
text: renderSpec(task.key, spec, wanted === current)
|
|
25691
|
+
};
|
|
25692
|
+
} catch (err) {
|
|
25693
|
+
throw new Error(explain(err));
|
|
25694
|
+
}
|
|
25695
|
+
};
|
|
25696
|
+
}
|
|
25697
|
+
|
|
25384
25698
|
// src/server.ts
|
|
25385
25699
|
var SERVER_INFO = {
|
|
25386
25700
|
name: "momentum",
|
|
@@ -25426,6 +25740,29 @@ function createMcpServer(client, profile = "work", options = {}) {
|
|
|
25426
25740
|
(args, extra) => tool.handler(args, extra._meta)
|
|
25427
25741
|
);
|
|
25428
25742
|
}
|
|
25743
|
+
for (const prompt of createPrompts(profile)) {
|
|
25744
|
+
server.registerPrompt(
|
|
25745
|
+
prompt.name,
|
|
25746
|
+
{ title: prompt.title, description: prompt.description, argsSchema: prompt.argsSchema },
|
|
25747
|
+
(args) => ({ description: prompt.description, messages: prompt.render(args) })
|
|
25748
|
+
);
|
|
25749
|
+
}
|
|
25750
|
+
const readSpec = createSpecReader(client);
|
|
25751
|
+
const one = (value) => Array.isArray(value) ? value[0] ?? "" : value ?? "";
|
|
25752
|
+
server.registerResource(
|
|
25753
|
+
"task_spec",
|
|
25754
|
+
new ResourceTemplate("momentum://task/{key}/spec", { list: void 0 }),
|
|
25755
|
+
{ title: "\u4EFB\u52A1\u8BF4\u660E\uFF08\u5F53\u524D\u7248\uFF09", description: "\u4EFB\u52A1\u5F53\u524D\u7248\u672C\u7684\u6807\u9898\u3001\u63CF\u8FF0\u548C\u9A8C\u6536\u6807\u51C6\uFF0C\u6B63\u6587\u91CC\u5199\u660E\u7248\u672C\u53F7\u548C\u90A3\u4E00\u7248\u7684\u4E0D\u53EF\u53D8\u5730\u5740\u3002", mimeType: "text/markdown" },
|
|
25756
|
+
async (uri, vars) => ({ contents: [{ uri: uri.href, ...await readSpec(decodeURIComponent(one(vars.key))) }] })
|
|
25757
|
+
);
|
|
25758
|
+
server.registerResource(
|
|
25759
|
+
"task_spec_version",
|
|
25760
|
+
new ResourceTemplate("momentum://task/{key}/spec/{version}", { list: void 0 }),
|
|
25761
|
+
{ title: "\u4EFB\u52A1\u8BF4\u660E\uFF08\u6307\u5B9A\u7248\u672C\uFF09", description: "\u4EFB\u52A1\u8BF4\u660E\u7684\u67D0\u4E00\u7248\uFF0C\u5185\u5BB9\u4E0D\u53EF\u53D8\u3002\u4EA4\u4ED8\u65F6 based_on_spec_version \u5BF9\u7167\u7684\u5C31\u662F\u5B83\u3002", mimeType: "text/markdown" },
|
|
25762
|
+
async (uri, vars) => ({
|
|
25763
|
+
contents: [{ uri: uri.href, ...await readSpec(decodeURIComponent(one(vars.key)), decodeURIComponent(one(vars.version))) }]
|
|
25764
|
+
})
|
|
25765
|
+
);
|
|
25429
25766
|
return server;
|
|
25430
25767
|
}
|
|
25431
25768
|
|