@moltzap/client 2026.803.0 → 2026.805.0
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/channel-base/index.d.ts +0 -2
- package/dist/channel-base/index.d.ts.map +1 -1
- package/dist/channel-base/index.js +0 -2
- package/dist/channel-base/index.js.map +1 -1
- package/dist/channel-core.d.ts +45 -19
- package/dist/channel-core.d.ts.map +1 -1
- package/dist/channel-core.js +45 -18
- package/dist/channel-core.js.map +1 -1
- package/dist/harness/client-runtime.d.ts +24 -0
- package/dist/harness/client-runtime.d.ts.map +1 -0
- package/dist/harness/client-runtime.js +107 -0
- package/dist/harness/client-runtime.js.map +1 -0
- package/dist/harness/index.d.ts +5 -0
- package/dist/harness/index.d.ts.map +1 -0
- package/dist/harness/index.js +5 -0
- package/dist/harness/index.js.map +1 -0
- package/dist/harness/runtime.d.ts +149 -0
- package/dist/harness/runtime.d.ts.map +1 -0
- package/dist/harness/runtime.js +68 -0
- package/dist/harness/runtime.js.map +1 -0
- package/dist/harness-client.d.ts +43 -0
- package/dist/harness-client.d.ts.map +1 -0
- package/dist/harness-client.js +21 -0
- package/dist/harness-client.js.map +1 -0
- package/dist/harness-mcp-server.d.ts.map +1 -1
- package/dist/harness-mcp-server.js +107 -17
- package/dist/harness-mcp-server.js.map +1 -1
- package/dist/harness-mcp-subscription.d.ts +21 -0
- package/dist/harness-mcp-subscription.d.ts.map +1 -0
- package/dist/harness-mcp-subscription.js +324 -0
- package/dist/harness-mcp-subscription.js.map +1 -0
- package/dist/harness-mcp-wire.d.ts +9 -2
- package/dist/harness-mcp-wire.d.ts.map +1 -1
- package/dist/harness-mcp-wire.js +41 -10
- package/dist/harness-mcp-wire.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/moltzapd.d.ts +2 -1
- package/dist/moltzapd.d.ts.map +1 -1
- package/dist/moltzapd.js +19 -5
- package/dist/moltzapd.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -4
- package/dist/channel-base/reply-guard.d.ts +0 -52
- package/dist/channel-base/reply-guard.d.ts.map +0 -1
- package/dist/channel-base/reply-guard.js +0 -78
- package/dist/channel-base/reply-guard.js.map +0 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { JSONSchema, Schema } from "effect";
|
|
2
|
+
import { type ConversationId } from "@moltzap/protocol/conversation";
|
|
3
|
+
/** Harness MCP extension carrying the runtime event contract. */
|
|
4
|
+
export declare const HARNESS_EVENTS_EXTENSION = "xyz.moltzap/events-v1";
|
|
5
|
+
/** Subscription filter requesting reply-capable harness turns. */
|
|
6
|
+
export declare const HARNESS_TURN_READY_FILTER = "xyz.moltzap/turnReady";
|
|
7
|
+
/** Notification method carrying one coalesced inbound turn. */
|
|
8
|
+
export declare const HARNESS_TURN_READY_NOTIFICATION = "notifications/xyz.moltzap/turn_ready";
|
|
9
|
+
/** Tool used for model output in the current conversation. */
|
|
10
|
+
export declare const HARNESS_REPLY_TOOL = "reply";
|
|
11
|
+
/** One nonempty batch of protocol messages delivered as a model turn. */
|
|
12
|
+
declare const harnessTurnEventSchema: Schema.filter<Schema.Struct<{
|
|
13
|
+
messages: Schema.NonEmptyArray<Schema.Struct<{
|
|
14
|
+
id: Schema.Schema<import("@moltzap/protocol/conversation").MessageId, string, never>;
|
|
15
|
+
conversationId: Schema.Schema<import("@moltzap/protocol/conversation").ConversationId, string, never>;
|
|
16
|
+
senderId: Schema.Schema<import("@moltzap/protocol/identity").AgentId, string, never>;
|
|
17
|
+
parts: Schema.filter<Schema.NonEmptyArray<Schema.Union<[Schema.Struct<{
|
|
18
|
+
type: Schema.Literal<["text"]>;
|
|
19
|
+
text: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
20
|
+
}>, Schema.Struct<{
|
|
21
|
+
type: Schema.Literal<["image"]>;
|
|
22
|
+
url: Schema.filter<Schema.Schema<string, string, never>>;
|
|
23
|
+
altText: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
24
|
+
}>, Schema.Struct<{
|
|
25
|
+
type: Schema.Literal<["file"]>;
|
|
26
|
+
url: Schema.filter<Schema.Schema<string, string, never>>;
|
|
27
|
+
name: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
28
|
+
mimeType: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
29
|
+
size: Schema.optional<Schema.filter<Schema.filter<typeof Schema.Number>>>;
|
|
30
|
+
}>]>>>;
|
|
31
|
+
createdAt: Schema.Schema<string, string, never>;
|
|
32
|
+
}>>;
|
|
33
|
+
}>>;
|
|
34
|
+
/** Advertised reply arguments. Routing authority remains outside tool input. */
|
|
35
|
+
declare const harnessReplyInputSchema: Schema.Struct<{
|
|
36
|
+
payload: typeof Schema.String;
|
|
37
|
+
}>;
|
|
38
|
+
/** The reply operation has no additional result data. */
|
|
39
|
+
declare const harnessReplyResultSchema: Schema.Struct<{}>;
|
|
40
|
+
/** Private route nested under the harness extension key in MCP request metadata. */
|
|
41
|
+
declare const harnessReplyRouteSchema: Schema.Struct<{
|
|
42
|
+
conversationId: Schema.Schema<ConversationId, string, never>;
|
|
43
|
+
}>;
|
|
44
|
+
/** Decoded harness turn event. */
|
|
45
|
+
export type HarnessTurnEvent = Schema.Schema.Type<typeof harnessTurnEventSchema>;
|
|
46
|
+
/** Decoded reply input. */
|
|
47
|
+
export type HarnessReplyInput = Schema.Schema.Type<typeof harnessReplyInputSchema>;
|
|
48
|
+
/** Decoded reply result. */
|
|
49
|
+
export type HarnessReplyResult = Schema.Schema.Type<typeof harnessReplyResultSchema>;
|
|
50
|
+
/** Decoded private reply route. */
|
|
51
|
+
export type HarnessReplyRoute = Schema.Schema.Type<typeof harnessReplyRouteSchema>;
|
|
52
|
+
/** JSON Schema advertised for the payload-only reply tool arguments. */
|
|
53
|
+
export declare const harnessReplyInputJsonSchema: JSONSchema.JsonSchema7Root;
|
|
54
|
+
/** JSON Schema advertised for the empty reply result. */
|
|
55
|
+
export declare const harnessReplyResultJsonSchema: JSONSchema.JsonSchema7Root;
|
|
56
|
+
/**
|
|
57
|
+
* Strictly decode a turn event received from the MCP boundary.
|
|
58
|
+
* @param value Untrusted notification parameters.
|
|
59
|
+
* @returns The decoded nonempty protocol-message batch.
|
|
60
|
+
*/
|
|
61
|
+
export declare const decodeHarnessTurnEvent: (value: unknown) => import("effect/Effect").Effect<{
|
|
62
|
+
readonly messages: readonly [{
|
|
63
|
+
readonly id: import("@moltzap/protocol/conversation").MessageId;
|
|
64
|
+
readonly conversationId: ConversationId;
|
|
65
|
+
readonly senderId: import("@moltzap/protocol/identity").AgentId;
|
|
66
|
+
readonly parts: readonly [{
|
|
67
|
+
readonly type: "text";
|
|
68
|
+
readonly text: string;
|
|
69
|
+
} | {
|
|
70
|
+
readonly type: "image";
|
|
71
|
+
readonly url: string;
|
|
72
|
+
readonly altText?: string | undefined;
|
|
73
|
+
} | {
|
|
74
|
+
readonly type: "file";
|
|
75
|
+
readonly url: string;
|
|
76
|
+
readonly name: string;
|
|
77
|
+
readonly mimeType?: string | undefined;
|
|
78
|
+
readonly size?: number | undefined;
|
|
79
|
+
}, ...({
|
|
80
|
+
readonly type: "text";
|
|
81
|
+
readonly text: string;
|
|
82
|
+
} | {
|
|
83
|
+
readonly type: "image";
|
|
84
|
+
readonly url: string;
|
|
85
|
+
readonly altText?: string | undefined;
|
|
86
|
+
} | {
|
|
87
|
+
readonly type: "file";
|
|
88
|
+
readonly url: string;
|
|
89
|
+
readonly name: string;
|
|
90
|
+
readonly mimeType?: string | undefined;
|
|
91
|
+
readonly size?: number | undefined;
|
|
92
|
+
})[]];
|
|
93
|
+
readonly createdAt: string;
|
|
94
|
+
}, ...{
|
|
95
|
+
readonly id: import("@moltzap/protocol/conversation").MessageId;
|
|
96
|
+
readonly conversationId: ConversationId;
|
|
97
|
+
readonly senderId: import("@moltzap/protocol/identity").AgentId;
|
|
98
|
+
readonly parts: readonly [{
|
|
99
|
+
readonly type: "text";
|
|
100
|
+
readonly text: string;
|
|
101
|
+
} | {
|
|
102
|
+
readonly type: "image";
|
|
103
|
+
readonly url: string;
|
|
104
|
+
readonly altText?: string | undefined;
|
|
105
|
+
} | {
|
|
106
|
+
readonly type: "file";
|
|
107
|
+
readonly url: string;
|
|
108
|
+
readonly name: string;
|
|
109
|
+
readonly mimeType?: string | undefined;
|
|
110
|
+
readonly size?: number | undefined;
|
|
111
|
+
}, ...({
|
|
112
|
+
readonly type: "text";
|
|
113
|
+
readonly text: string;
|
|
114
|
+
} | {
|
|
115
|
+
readonly type: "image";
|
|
116
|
+
readonly url: string;
|
|
117
|
+
readonly altText?: string | undefined;
|
|
118
|
+
} | {
|
|
119
|
+
readonly type: "file";
|
|
120
|
+
readonly url: string;
|
|
121
|
+
readonly name: string;
|
|
122
|
+
readonly mimeType?: string | undefined;
|
|
123
|
+
readonly size?: number | undefined;
|
|
124
|
+
})[]];
|
|
125
|
+
readonly createdAt: string;
|
|
126
|
+
}[]];
|
|
127
|
+
}, import("effect/ParseResult").ParseError, never>;
|
|
128
|
+
/**
|
|
129
|
+
* Build the private request metadata consumed by the production harness client.
|
|
130
|
+
* @param originatingConversationId Conversation associated with the live turn.
|
|
131
|
+
* @returns Namespaced MCP request metadata containing the private route.
|
|
132
|
+
*/
|
|
133
|
+
export declare const harnessReplyRequestMeta: (originatingConversationId: ConversationId) => Readonly<Record<string, unknown>>;
|
|
134
|
+
/**
|
|
135
|
+
* Decode the private reply route while allowing unrelated MCP metadata keys.
|
|
136
|
+
* @param requestMeta Untrusted MCP request metadata.
|
|
137
|
+
* @returns The decoded conversation route.
|
|
138
|
+
*/
|
|
139
|
+
export declare const decodeHarnessReplyRoute: (requestMeta: unknown) => import("effect/Effect").Effect<{
|
|
140
|
+
readonly conversationId: ConversationId;
|
|
141
|
+
}, import("effect/ParseResult").ParseError, never>;
|
|
142
|
+
/**
|
|
143
|
+
* Return the conversation carried by the first message in a nonempty turn.
|
|
144
|
+
* @param turn Decoded nonempty message batch.
|
|
145
|
+
* @returns Conversation carried by the first protocol message.
|
|
146
|
+
*/
|
|
147
|
+
export declare const harnessTurnConversationId: (turn: HarnessTurnEvent) => ConversationId;
|
|
148
|
+
export {};
|
|
149
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/harness/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,gCAAgC,CAAC;AAGxC,iEAAiE;AACjE,eAAO,MAAM,wBAAwB,0BAA0B,CAAC;AAEhE,kEAAkE;AAClE,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAEjE,+DAA+D;AAC/D,eAAO,MAAM,+BAA+B,yCACJ,CAAC;AAEzC,8DAA8D;AAC9D,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAK1C,yEAAyE;AACzE,QAAA,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;GAS3B,CAAC;AAEF,gFAAgF;AAChF,QAAA,MAAM,uBAAuB;;EAE3B,CAAC;AAEH,yDAAyD;AACzD,QAAA,MAAM,wBAAwB,mBAAoB,CAAC;AAEnD,oFAAoF;AACpF,QAAA,MAAM,uBAAuB;;EAE3B,CAAC;AAEH,kCAAkC;AAClC,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAC/C,OAAO,sBAAsB,CAC9B,CAAC;AAEF,2BAA2B;AAC3B,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAChD,OAAO,uBAAuB,CAC/B,CAAC;AAEF,4BAA4B;AAC5B,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CACjD,OAAO,wBAAwB,CAChC,CAAC;AAEF,mCAAmC;AACnC,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAChD,OAAO,uBAAuB,CAC/B,CAAC;AAOF,wEAAwE;AACxE,eAAO,MAAM,2BAA2B,4BAGvC,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,4BAA4B,4BAGxC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,UAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDACR,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,8BACP,cAAc,KACxC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAIjC,CAAC;AAOH;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,gBAAiB,OAAO;;kDAK3D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,SAC9B,gBAAgB,KACrB,cAAiD,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { JSONSchema, Schema } from "effect";
|
|
2
|
+
import { conversationId, } from "@moltzap/protocol/conversation";
|
|
3
|
+
import { messageReceivedNotificationDefinition } from "@moltzap/protocol/message";
|
|
4
|
+
/** Harness MCP extension carrying the runtime event contract. */
|
|
5
|
+
export const HARNESS_EVENTS_EXTENSION = "xyz.moltzap/events-v1";
|
|
6
|
+
/** Subscription filter requesting reply-capable harness turns. */
|
|
7
|
+
export const HARNESS_TURN_READY_FILTER = "xyz.moltzap/turnReady";
|
|
8
|
+
/** Notification method carrying one coalesced inbound turn. */
|
|
9
|
+
export const HARNESS_TURN_READY_NOTIFICATION = "notifications/xyz.moltzap/turn_ready";
|
|
10
|
+
/** Tool used for model output in the current conversation. */
|
|
11
|
+
export const HARNESS_REPLY_TOOL = "reply";
|
|
12
|
+
const messageSchema = messageReceivedNotificationDefinition.paramsSchema.fields.message;
|
|
13
|
+
/** One nonempty batch of protocol messages delivered as a model turn. */
|
|
14
|
+
const harnessTurnEventSchema = Schema.Struct({
|
|
15
|
+
messages: Schema.NonEmptyArray(messageSchema),
|
|
16
|
+
}).pipe(Schema.filter((turn) => turn.messages.every((message) => message.conversationId === turn.messages[0].conversationId) || "every turn message must belong to the same conversation"));
|
|
17
|
+
/** Advertised reply arguments. Routing authority remains outside tool input. */
|
|
18
|
+
const harnessReplyInputSchema = Schema.Struct({
|
|
19
|
+
payload: Schema.String,
|
|
20
|
+
});
|
|
21
|
+
/** The reply operation has no additional result data. */
|
|
22
|
+
const harnessReplyResultSchema = Schema.Struct({});
|
|
23
|
+
/** Private route nested under the harness extension key in MCP request metadata. */
|
|
24
|
+
const harnessReplyRouteSchema = Schema.Struct({
|
|
25
|
+
conversationId,
|
|
26
|
+
});
|
|
27
|
+
const decodeTurnEvent = Schema.decodeUnknown(harnessTurnEventSchema);
|
|
28
|
+
const decodeReplyRoute = Schema.decodeUnknown(harnessReplyRouteSchema);
|
|
29
|
+
const strictDecodeOptions = { onExcessProperty: "error" };
|
|
30
|
+
/** JSON Schema advertised for the payload-only reply tool arguments. */
|
|
31
|
+
export const harnessReplyInputJsonSchema = JSONSchema.make(harnessReplyInputSchema, { target: "jsonSchema2020-12" });
|
|
32
|
+
/** JSON Schema advertised for the empty reply result. */
|
|
33
|
+
export const harnessReplyResultJsonSchema = JSONSchema.make(harnessReplyResultSchema, { target: "jsonSchema2020-12" });
|
|
34
|
+
/**
|
|
35
|
+
* Strictly decode a turn event received from the MCP boundary.
|
|
36
|
+
* @param value Untrusted notification parameters.
|
|
37
|
+
* @returns The decoded nonempty protocol-message batch.
|
|
38
|
+
*/
|
|
39
|
+
export const decodeHarnessTurnEvent = (value) => decodeTurnEvent(value, strictDecodeOptions);
|
|
40
|
+
/**
|
|
41
|
+
* Build the private request metadata consumed by the production harness client.
|
|
42
|
+
* @param originatingConversationId Conversation associated with the live turn.
|
|
43
|
+
* @returns Namespaced MCP request metadata containing the private route.
|
|
44
|
+
*/
|
|
45
|
+
export const harnessReplyRequestMeta = (originatingConversationId) => ({
|
|
46
|
+
[HARNESS_EVENTS_EXTENSION]: {
|
|
47
|
+
conversationId: originatingConversationId,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
const isUnknownRecord = (value) => typeof value === "object" && value !== null;
|
|
51
|
+
/**
|
|
52
|
+
* Decode the private reply route while allowing unrelated MCP metadata keys.
|
|
53
|
+
* @param requestMeta Untrusted MCP request metadata.
|
|
54
|
+
* @returns The decoded conversation route.
|
|
55
|
+
*/
|
|
56
|
+
export const decodeHarnessReplyRoute = (requestMeta) => {
|
|
57
|
+
const extensionValue = isUnknownRecord(requestMeta)
|
|
58
|
+
? requestMeta[HARNESS_EVENTS_EXTENSION]
|
|
59
|
+
: undefined;
|
|
60
|
+
return decodeReplyRoute(extensionValue, strictDecodeOptions);
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Return the conversation carried by the first message in a nonempty turn.
|
|
64
|
+
* @param turn Decoded nonempty message batch.
|
|
65
|
+
* @returns Conversation carried by the first protocol message.
|
|
66
|
+
*/
|
|
67
|
+
export const harnessTurnConversationId = (turn) => turn.messages[0].conversationId;
|
|
68
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/harness/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Context, Layer, type Effect, type Scope, type Stream } from "effect";
|
|
2
|
+
import type { ConversationId } from "@moltzap/protocol/conversation";
|
|
3
|
+
import type { Message } from "@moltzap/protocol/message";
|
|
4
|
+
/** One reply-capable batch emitted by the local harness daemon. */
|
|
5
|
+
export interface HarnessTurn {
|
|
6
|
+
/** Existing conversation associated with every message in this turn. */
|
|
7
|
+
readonly conversationId: ConversationId;
|
|
8
|
+
/** Existing protocol messages in their daemon-provided order. */
|
|
9
|
+
readonly messages: readonly [Message, ...Message[]];
|
|
10
|
+
/** Sends model output through the MCP reply route captured by this turn. */
|
|
11
|
+
readonly reply: (payload: string) => Effect.Effect<void, Error>;
|
|
12
|
+
}
|
|
13
|
+
/** Adapter-facing capability backed only by the daemon's loopback MCP surface. */
|
|
14
|
+
export interface HarnessClientService {
|
|
15
|
+
/** The sole receive stream owned by this scoped client. */
|
|
16
|
+
readonly turns: Stream.Stream<HarnessTurn, Error>;
|
|
17
|
+
}
|
|
18
|
+
declare const HarnessClient_base: Context.TagClass<HarnessClient, "@moltzap/client/HarnessClient", HarnessClientService>;
|
|
19
|
+
/** Effect service tag consumed by runtime adapters. */
|
|
20
|
+
export declare class HarnessClient extends HarnessClient_base {
|
|
21
|
+
}
|
|
22
|
+
/** Inputs needed to connect one scoped harness client. */
|
|
23
|
+
export interface HarnessClientOptions {
|
|
24
|
+
/** Loopback `POST /mcp` endpoint owned by one running `moltzapd`. */
|
|
25
|
+
readonly url: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Acquires one turn-ready harness connection and receive stream for the
|
|
29
|
+
* lifetime of the enclosing scope. The private adapter owns MCP translation.
|
|
30
|
+
*
|
|
31
|
+
* @param options Fixed loopback MCP endpoint.
|
|
32
|
+
* @returns The scoped adapter-facing service value.
|
|
33
|
+
*/
|
|
34
|
+
export declare const acquireHarnessClient: (options: HarnessClientOptions) => Effect.Effect<HarnessClientService, Error, Scope.Scope>;
|
|
35
|
+
/**
|
|
36
|
+
* Builds the scoped runtime-adapter layer for one daemon endpoint.
|
|
37
|
+
*
|
|
38
|
+
* @param options Fixed loopback MCP endpoint.
|
|
39
|
+
* @returns A Layer providing the scoped HarnessClient capability.
|
|
40
|
+
*/
|
|
41
|
+
export declare const makeHarnessClientLayer: (options: HarnessClientOptions) => Layer.Layer<HarnessClient, Error>;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=harness-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-client.d.ts","sourceRoot":"","sources":["../src/harness-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,MAAM,EAAE,KAAK,KAAK,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAGzD,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACpD,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;CACjE;AAED,kFAAkF;AAClF,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;CACnD;;AAED,uDAAuD;AACvD,qBAAa,aAAc,SAAQ,kBAGhC;CAAG;AAEN,0DAA0D;AAC1D,MAAM,WAAW,oBAAoB;IACnC,qEAAqE;IACrE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,YACtB,oBAAoB,KAC5B,MAAM,CAAC,MAAM,CAAC,oBAAoB,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAClB,CAAC;AAExC;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,YACxB,oBAAoB,KAC5B,KAAK,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CACyB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Context, Layer } from "effect";
|
|
2
|
+
import { acquireHarnessClientInternal } from "./harness/index.js";
|
|
3
|
+
/** Effect service tag consumed by runtime adapters. */
|
|
4
|
+
export class HarnessClient extends Context.Tag("@moltzap/client/HarnessClient")() {
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Acquires one turn-ready harness connection and receive stream for the
|
|
8
|
+
* lifetime of the enclosing scope. The private adapter owns MCP translation.
|
|
9
|
+
*
|
|
10
|
+
* @param options Fixed loopback MCP endpoint.
|
|
11
|
+
* @returns The scoped adapter-facing service value.
|
|
12
|
+
*/
|
|
13
|
+
export const acquireHarnessClient = (options) => acquireHarnessClientInternal(options);
|
|
14
|
+
/**
|
|
15
|
+
* Builds the scoped runtime-adapter layer for one daemon endpoint.
|
|
16
|
+
*
|
|
17
|
+
* @param options Fixed loopback MCP endpoint.
|
|
18
|
+
* @returns A Layer providing the scoped HarnessClient capability.
|
|
19
|
+
*/
|
|
20
|
+
export const makeHarnessClientLayer = (options) => Layer.scoped(HarnessClient, acquireHarnessClient(options));
|
|
21
|
+
//# sourceMappingURL=harness-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-client.js","sourceRoot":"","sources":["../src/harness-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAwC,MAAM,QAAQ,CAAC;AAG9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAkBlE,uDAAuD;AACvD,MAAM,OAAO,aAAc,SAAQ,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,EAG5E;CAAG;AAQN;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,OAA6B,EAC4B,EAAE,CAC3D,4BAA4B,CAAC,OAAO,CAAC,CAAC;AAExC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,OAA6B,EACM,EAAE,CACrC,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-mcp-server.d.ts","sourceRoot":"","sources":["../src/harness-mcp-server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,EAGL,KAAK,MAAM,IAAI,cAAc,EAC9B,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"harness-mcp-server.d.ts","sourceRoot":"","sources":["../src/harness-mcp-server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,EAGL,KAAK,MAAM,IAAI,cAAc,EAC9B,MAAM,WAAW,CAAC;AAEnB,OAAO,EAGL,MAAM,EAIN,KAAK,KAAK,EACX,MAAM,QAAQ,CAAC;AAUhB,UAAU,2BAA2B;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,mBAAmB,EAAE,cAAc,CAAC;IAC7C,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;CACzC;AAmRD;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,YAC7B,2BAA2B,KACnC,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CASF,CAAC"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { localhostHostValidation, localhostOriginValidation, toNodeHandler, } from "@modelcontextprotocol/node";
|
|
2
2
|
// eslint-disable-next-line agent-code-guard/prefer-effect-platform -- The official MCP Node adapter supplies a Node RequestListener, so this package-private process boundary must host that exact interface.
|
|
3
3
|
import { createServer, } from "node:http";
|
|
4
|
-
import { Effect, Exit } from "effect";
|
|
4
|
+
import { Deferred, Duration, Effect, Exit, Fiber, Option, } from "effect";
|
|
5
5
|
const REGISTER_MCP_PATH = "/register/mcp";
|
|
6
6
|
const HARNESS_MCP_PATH = "/mcp";
|
|
7
7
|
const POST_METHOD = "POST";
|
|
8
8
|
const LOOPBACK_HOST = "127.0.0.1";
|
|
9
|
+
// Loopback readers normally drain immediately; one second tolerates scheduler
|
|
10
|
+
// delay without allowing a stopped reader to retain the daemon lifetime.
|
|
11
|
+
const RESPONSE_DRAIN_GRACE_PERIOD = Duration.seconds(1);
|
|
9
12
|
const respond = (status, body, response, headers = {}) => {
|
|
10
13
|
response.writeHead(status, {
|
|
11
14
|
"content-type": "text/plain; charset=utf-8",
|
|
@@ -13,6 +16,45 @@ const respond = (status, body, response, headers = {}) => {
|
|
|
13
16
|
});
|
|
14
17
|
response.end(body);
|
|
15
18
|
};
|
|
19
|
+
const makeResponseTracker = () => {
|
|
20
|
+
const inFlight = new Set();
|
|
21
|
+
const responseWaiters = new Set();
|
|
22
|
+
const finish = (response) => {
|
|
23
|
+
inFlight.delete(response);
|
|
24
|
+
if (inFlight.size === 0) {
|
|
25
|
+
for (const resume of responseWaiters) {
|
|
26
|
+
resume();
|
|
27
|
+
}
|
|
28
|
+
responseWaiters.clear();
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
track: (response, nodeResponse) => {
|
|
33
|
+
inFlight.add(response);
|
|
34
|
+
Effect.runFork(Effect.tryPromise({
|
|
35
|
+
try: () => response,
|
|
36
|
+
catch: (error) => error,
|
|
37
|
+
}).pipe(Effect.catchAll((error) => Effect.sync(() => {
|
|
38
|
+
nodeResponse.destroy(error instanceof Error ? error : undefined);
|
|
39
|
+
})), Effect.ensuring(Effect.sync(() => {
|
|
40
|
+
finish(response);
|
|
41
|
+
}))));
|
|
42
|
+
},
|
|
43
|
+
waitForResponses: Effect.async((resume) => {
|
|
44
|
+
if (inFlight.size === 0) {
|
|
45
|
+
resume(Effect.succeed(undefined));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const done = () => {
|
|
49
|
+
resume(Effect.succeed(undefined));
|
|
50
|
+
};
|
|
51
|
+
responseWaiters.add(done);
|
|
52
|
+
return Effect.sync(() => {
|
|
53
|
+
responseWaiters.delete(done);
|
|
54
|
+
});
|
|
55
|
+
}),
|
|
56
|
+
};
|
|
57
|
+
};
|
|
16
58
|
/**
|
|
17
59
|
* Routes the daemon's two loopback MCP surfaces through one Node listener.
|
|
18
60
|
*
|
|
@@ -25,11 +67,12 @@ const makeHarnessMcpRequestListener = (registrationHandler, harnessHandler) => {
|
|
|
25
67
|
const validateOrigin = localhostOriginValidation();
|
|
26
68
|
const registrationNodeHandler = toNodeHandler(registrationHandler);
|
|
27
69
|
const harnessNodeHandler = toNodeHandler(harnessHandler);
|
|
70
|
+
const responses = makeResponseTracker();
|
|
28
71
|
const handlers = new Map([
|
|
29
72
|
[REGISTER_MCP_PATH, registrationNodeHandler],
|
|
30
73
|
[HARNESS_MCP_PATH, harnessNodeHandler],
|
|
31
74
|
]);
|
|
32
|
-
|
|
75
|
+
const listener = (request, response) => {
|
|
33
76
|
if (!validateHost(request, response) ||
|
|
34
77
|
!validateOrigin(request, response)) {
|
|
35
78
|
return;
|
|
@@ -44,20 +87,43 @@ const makeHarnessMcpRequestListener = (registrationHandler, harnessHandler) => {
|
|
|
44
87
|
respond(405, "Method not allowed.", response, { allow: POST_METHOD });
|
|
45
88
|
return;
|
|
46
89
|
}
|
|
47
|
-
handler(request, response)
|
|
48
|
-
|
|
90
|
+
responses.track(handler(request, response), response);
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
listener,
|
|
94
|
+
waitForResponses: responses.waitForResponses,
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
const trackConnections = (server) => {
|
|
98
|
+
const sockets = new Set();
|
|
99
|
+
server.on("connection", (socket) => {
|
|
100
|
+
sockets.add(socket);
|
|
101
|
+
socket.once("close", () => {
|
|
102
|
+
sockets.delete(socket);
|
|
49
103
|
});
|
|
104
|
+
});
|
|
105
|
+
return () => {
|
|
106
|
+
for (const socket of sockets) {
|
|
107
|
+
socket.destroy();
|
|
108
|
+
}
|
|
109
|
+
server.closeAllConnections();
|
|
50
110
|
};
|
|
51
111
|
};
|
|
52
112
|
const listen = (options) => Effect.async((resume) => {
|
|
53
|
-
const
|
|
113
|
+
const requests = makeHarnessMcpRequestListener(options.registrationHandler, options.harnessHandler);
|
|
114
|
+
const server = createServer(requests.listener);
|
|
115
|
+
const destroyConnections = trackConnections(server);
|
|
54
116
|
const onError = (error) => {
|
|
55
117
|
resume(Effect.fail(error));
|
|
56
118
|
};
|
|
57
119
|
server.once("error", onError);
|
|
58
120
|
server.listen(options.port, LOOPBACK_HOST, () => {
|
|
59
121
|
server.off("error", onError);
|
|
60
|
-
resume(Effect.succeed(
|
|
122
|
+
resume(Effect.succeed({
|
|
123
|
+
destroyConnections,
|
|
124
|
+
server,
|
|
125
|
+
waitForResponses: requests.waitForResponses,
|
|
126
|
+
}));
|
|
61
127
|
});
|
|
62
128
|
return Effect.async((cancelResume) => {
|
|
63
129
|
server.off("error", onError);
|
|
@@ -74,23 +140,47 @@ const listen = (options) => Effect.async((resume) => {
|
|
|
74
140
|
}
|
|
75
141
|
});
|
|
76
142
|
});
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
resume(error === undefined
|
|
84
|
-
? Effect.succeed(undefined)
|
|
85
|
-
: Effect.logWarning("Harness MCP HTTP server close failed", error).pipe(Effect.as(undefined)));
|
|
143
|
+
const beginClose = (server) => Effect.gen(function* () {
|
|
144
|
+
const completion = yield* Deferred.make();
|
|
145
|
+
yield* Effect.sync(() => {
|
|
146
|
+
server.close((error) => {
|
|
147
|
+
Effect.runSync(Deferred.succeed(completion, error));
|
|
148
|
+
});
|
|
86
149
|
});
|
|
150
|
+
return Deferred.await(completion).pipe(Effect.flatMap((error) => error === undefined
|
|
151
|
+
? Effect.succeed(undefined)
|
|
152
|
+
: Effect.logWarning("Harness MCP HTTP server close failed", error).pipe(Effect.as(undefined))));
|
|
87
153
|
});
|
|
88
154
|
const closeHandler = (handler) => Effect.tryPromise({
|
|
89
155
|
try: () => handler.close(),
|
|
90
156
|
catch: (error) => error,
|
|
91
157
|
}).pipe(Effect.catchAll((error) => Effect.logWarning("Harness MCP handler close failed").pipe(Effect.annotateLogs({ error: String(error) }))), Effect.asVoid);
|
|
92
158
|
const closeHandlers = (options) => Effect.forEach(new Set([options.registrationHandler, options.harnessHandler]), closeHandler, { concurrency: 2, discard: true });
|
|
93
|
-
const release = (
|
|
159
|
+
const release = (running, options) => Effect.gen(function* () {
|
|
160
|
+
const closeCompletion = yield* beginClose(running.server);
|
|
161
|
+
// Handler closure finishes the Web stream before the Node adapter drains
|
|
162
|
+
// it. A local client that stops reading must not retain the daemon scope,
|
|
163
|
+
// so graceful draining is bounded before active connections are closed.
|
|
164
|
+
const gracefulClose = yield* Effect.fork(Effect.all([closeHandlers(options), running.waitForResponses], {
|
|
165
|
+
concurrency: 2,
|
|
166
|
+
discard: true,
|
|
167
|
+
}));
|
|
168
|
+
// acquireRelease finalizers are uninterruptible. Only this observation is
|
|
169
|
+
// interruptible so the grace timer can win; the close fiber remains owned
|
|
170
|
+
// here and is joined after any forced connection shutdown.
|
|
171
|
+
const drained = yield* Fiber.join(gracefulClose).pipe(Effect.timeoutOption(RESPONSE_DRAIN_GRACE_PERIOD), Effect.interruptible);
|
|
172
|
+
if (Option.isNone(drained)) {
|
|
173
|
+
yield* Effect.logWarning("Harness MCP response drain timed out; closing active connections");
|
|
174
|
+
yield* Effect.sync(running.destroyConnections);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
running.server.closeAllConnections();
|
|
178
|
+
}
|
|
179
|
+
if (Option.isNone(drained)) {
|
|
180
|
+
yield* Fiber.join(gracefulClose);
|
|
181
|
+
}
|
|
182
|
+
yield* closeCompletion;
|
|
183
|
+
});
|
|
94
184
|
/**
|
|
95
185
|
* Acquires the guarded loopback HTTP server for one explicitly supplied port.
|
|
96
186
|
* The caller owns port selection and keeps the returned server alive by
|
|
@@ -101,5 +191,5 @@ const release = (server, options) => closeHandlers(options).pipe(Effect.zipRight
|
|
|
101
191
|
*/
|
|
102
192
|
export const acquireHarnessMcpHttpServer = (options) =>
|
|
103
193
|
// eslint-disable-next-line agent-code-guard/acquire-release-requires-scope -- this package-private helper returns the scoped acquisition to its process owner
|
|
104
|
-
Effect.acquireRelease(listen(options).pipe(Effect.onExit((exit) => Exit.isSuccess(exit) ? Effect.void : closeHandlers(options))), (
|
|
194
|
+
Effect.acquireRelease(listen(options).pipe(Effect.onExit((exit) => Exit.isSuccess(exit) ? Effect.void : closeHandlers(options))), (running) => release(running, options)).pipe(Effect.map((running) => running.server));
|
|
105
195
|
//# sourceMappingURL=harness-mcp-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-mcp-server.js","sourceRoot":"","sources":["../src/harness-mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,uBAAuB,EACvB,yBAAyB,EACzB,aAAa,GACd,MAAM,4BAA4B,CAAC;AAEpC,8MAA8M;AAC9M,OAAO,EACL,YAAY,GAGb,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"harness-mcp-server.js","sourceRoot":"","sources":["../src/harness-mcp-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Implementation, type McpHttpHandler } from "@modelcontextprotocol/server";
|
|
2
|
+
interface HarnessMcpSubscriptionOptions {
|
|
3
|
+
readonly delegate: McpHttpHandler;
|
|
4
|
+
readonly implementation: Implementation;
|
|
5
|
+
readonly onerror?: (error: Error) => void;
|
|
6
|
+
}
|
|
7
|
+
/** An official MCP handler augmented with one caller-typed event publisher. */
|
|
8
|
+
export interface HarnessMcpSubscriptionHandler<Payload extends object> extends McpHttpHandler {
|
|
9
|
+
/** Publishes one complete custom notification to the retained POST response. */
|
|
10
|
+
readonly publish: (payload: Payload) => boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Adds the MoltZap turn-ready subscription extension to an official MCP HTTP
|
|
14
|
+
* handler. Every non-extension request remains owned by the SDK delegate.
|
|
15
|
+
*
|
|
16
|
+
* @param options Official handler, server identity, and optional error sink.
|
|
17
|
+
* @returns The official handler surface plus a typed custom publisher.
|
|
18
|
+
*/
|
|
19
|
+
export declare const makeHarnessMcpSubscriptionHandler: <Payload extends object>(options: HarnessMcpSubscriptionOptions) => HarnessMcpSubscriptionHandler<Payload>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=harness-mcp-subscription.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-mcp-subscription.d.ts","sourceRoot":"","sources":["../src/harness-mcp-subscription.ts"],"names":[],"mappings":"AACA,OAAO,EAOL,KAAK,cAAc,EAEnB,KAAK,cAAc,EAEpB,MAAM,8BAA8B,CAAC;AAyBtC,UAAU,6BAA6B;IACrC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3C;AAED,+EAA+E;AAC/E,MAAM,WAAW,6BAA6B,CAAC,OAAO,SAAS,MAAM,CACnE,SAAQ,cAAc;IACtB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;CACjD;AA4XD;;;;;;GAMG;AACH,eAAO,MAAM,iCAAiC,GAAI,OAAO,SAAS,MAAM,WAC7D,6BAA6B,KACrC,6BAA6B,CAAC,OAAO,CACuB,CAAC"}
|