@jevitate/cli 0.1.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/LICENSE +21 -0
- package/dist/ai-cli.d.ts +31 -0
- package/dist/ai-cli.js +238 -0
- package/dist/ai-cli.js.map +1 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +50663 -0
- package/dist/bin.js.map +1 -0
- package/dist/data-dir.d.ts +9 -0
- package/dist/data-dir.js +13 -0
- package/dist/data-dir.js.map +1 -0
- package/dist/envelope.d.ts +11 -0
- package/dist/envelope.js +7 -0
- package/dist/envelope.js.map +1 -0
- package/dist/explore-api.d.ts +187 -0
- package/dist/explore-api.js +302 -0
- package/dist/explore-api.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/init-keys.d.ts +14 -0
- package/dist/init-keys.js +18 -0
- package/dist/init-keys.js.map +1 -0
- package/dist/init-mcp.d.ts +87 -0
- package/dist/init-mcp.js +198 -0
- package/dist/init-mcp.js.map +1 -0
- package/dist/init-skills.d.ts +80 -0
- package/dist/init-skills.js +256 -0
- package/dist/init-skills.js.map +1 -0
- package/dist/journey-api.d.ts +37 -0
- package/dist/journey-api.js +55 -0
- package/dist/journey-api.js.map +1 -0
- package/dist/load-api.d.ts +48 -0
- package/dist/load-api.js +84 -0
- package/dist/load-api.js.map +1 -0
- package/dist/mcp-api.d.ts +116 -0
- package/dist/mcp-api.js +359 -0
- package/dist/mcp-api.js.map +1 -0
- package/dist/mission-api.d.ts +56 -0
- package/dist/mission-api.js +65 -0
- package/dist/mission-api.js.map +1 -0
- package/dist/program.d.ts +77 -0
- package/dist/program.js +1938 -0
- package/dist/program.js.map +1 -0
- package/dist/record-api.d.ts +74 -0
- package/dist/record-api.js +93 -0
- package/dist/record-api.js.map +1 -0
- package/dist/regression-api.d.ts +17 -0
- package/dist/regression-api.js +16 -0
- package/dist/regression-api.js.map +1 -0
- package/dist/self-heal-adapter.d.ts +31 -0
- package/dist/self-heal-adapter.js +70 -0
- package/dist/self-heal-adapter.js.map +1 -0
- package/dist/source-api.d.ts +147 -0
- package/dist/source-api.js +208 -0
- package/dist/source-api.js.map +1 -0
- package/dist/source-run-api.d.ts +57 -0
- package/dist/source-run-api.js +91 -0
- package/dist/source-run-api.js.map +1 -0
- package/dist/ui-api.d.ts +35 -0
- package/dist/ui-api.js +369 -0
- package/dist/ui-api.js.map +1 -0
- package/dist/ux-api.d.ts +75 -0
- package/dist/ux-api.js +231 -0
- package/dist/ux-api.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +37 -0
- package/dist/version.js.map +1 -0
- package/package.json +85 -0
- package/skills/jevitate-explore/SKILL.md +108 -0
- package/skills/jevitate-load-test/SKILL.md +42 -0
- package/skills/jevitate-mission-scope/SKILL.md +107 -0
- package/skills/jevitate-record/SKILL.md +78 -0
- package/skills/jevitate-run-journey/SKILL.md +72 -0
- package/skills/jevitate-sources/SKILL.md +88 -0
- package/skills/jevitate-ux-review/SKILL.md +68 -0
- package/ui/app.js +538 -0
- package/ui/index.html +546 -0
package/dist/mcp-api.js
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
+
import { ALLOWED_TOOLS, FORBIDDEN_TOOLS, findCapabilities, queueExploration as facadeQueueExploration, aiGenerateText as facadeAiGenerateText, facadeListIncoming, facadeGetCommand, facadeGetThread, facadeQueueAction, facadeQueueRetrieval, facadeApproveAction, facadeCancelCommand, facadeGetSiteHealth, } from "@jevitate/mcp-facade";
|
|
5
|
+
import { FsJourneyStore, JourneyRegistry } from "@jevitate/journey";
|
|
6
|
+
import { FsMissionTargetStore, MissionTargetRegistry, FsMissionQueueStore, } from "@jevitate/missions";
|
|
7
|
+
import { FsInboxStore } from "@jevitate/inbox";
|
|
8
|
+
import { envCredentialStore, } from "@jevitate/ai-core";
|
|
9
|
+
import { safeRunPolicy } from "@jevitate/domain";
|
|
10
|
+
import { runJourneyProgrammatically } from "./journey-api.js";
|
|
11
|
+
const ALLOWED = new Set(ALLOWED_TOOLS);
|
|
12
|
+
const FORBIDDEN = new Set(FORBIDDEN_TOOLS);
|
|
13
|
+
/**
|
|
14
|
+
* Defense-in-depth guard: a tool descriptor may be built ONLY for a name that
|
|
15
|
+
* is in `ALLOWED_TOOLS` and NOT in `FORBIDDEN_TOOLS`. A violation is a build
|
|
16
|
+
* error, never a silently-served or silently-dropped tool.
|
|
17
|
+
*/
|
|
18
|
+
function assertAllowlisted(name) {
|
|
19
|
+
if (FORBIDDEN.has(name)) {
|
|
20
|
+
throw new Error(`refusing to serve forbidden tool '${name}'`);
|
|
21
|
+
}
|
|
22
|
+
if (!ALLOWED.has(name)) {
|
|
23
|
+
throw new Error(`refusing to serve non-allowlisted tool '${name}'`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function jsonResult(value) {
|
|
27
|
+
return { content: [{ type: "text", text: JSON.stringify(value) }] };
|
|
28
|
+
}
|
|
29
|
+
function errorResult(value) {
|
|
30
|
+
return { content: [{ type: "text", text: JSON.stringify(value) }], isError: true };
|
|
31
|
+
}
|
|
32
|
+
/** Strips any known credential VALUE from a diagnostic string so a provider
|
|
33
|
+
* SDK error (which can echo request internals verbatim) never surfaces a key
|
|
34
|
+
* through the MCP result. The message returned to the caller is generic and
|
|
35
|
+
* key-free; this is belt-and-braces on top of the gateway's outbound guard. */
|
|
36
|
+
function redactCredentials(message, store) {
|
|
37
|
+
let out = message;
|
|
38
|
+
for (const key of ["OPENROUTER_API_KEY", "TYPESAFE_API_KEY"]) {
|
|
39
|
+
const value = store.read(key);
|
|
40
|
+
if (value)
|
|
41
|
+
out = out.split(value).join("***REDACTED***");
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Builds the served tool descriptors — EXACTLY one per `ALLOWED_TOOLS` entry.
|
|
47
|
+
* Wired to their real backing services: `find_capabilities` + `run_journey`
|
|
48
|
+
* (journey store), `queue_exploration` (`@jevitate/missions` enqueue over the
|
|
49
|
+
* promoted `MissionTargetRegistry`), and `ai_generate_text` (`@jevitate/ai-core`
|
|
50
|
+
* generation gateway behind a fail-closed credential preflight). The remaining
|
|
51
|
+
* allowlisted tools — the inbox/command-queue surface — are registered (so the
|
|
52
|
+
* served set equals `ALLOWED_TOOLS`) but respond with a typed `not_implemented`
|
|
53
|
+
* error, since no facade-level backing service exists for them in this slice.
|
|
54
|
+
* No handler ever fabricates a success.
|
|
55
|
+
*/
|
|
56
|
+
export function buildMcpTools(deps) {
|
|
57
|
+
const findCaps = deps.findCapabilities ??
|
|
58
|
+
((query) => findCapabilities(new JourneyRegistry(new FsJourneyStore(deps.journeysDir)), query));
|
|
59
|
+
const runJourney = deps.runJourney ??
|
|
60
|
+
((id, params) => runJourneyProgrammatically({ dir: deps.journeysDir, id, params, policy: safeRunPolicy() }));
|
|
61
|
+
// queue_exploration: enqueue over the SAME promoted fs store `jevitate
|
|
62
|
+
// mission target` writes. The store is built lazily inside the closure so
|
|
63
|
+
// constructing the tool set never touches disk; a missing dir is a config
|
|
64
|
+
// error (a refusal), never a silent success.
|
|
65
|
+
const queueExploration = deps.queueExploration ??
|
|
66
|
+
(async (args) => {
|
|
67
|
+
if (!deps.missionTargetsDir || !deps.missionQueueDir) {
|
|
68
|
+
throw new Error("queue_exploration requires missionTargetsDir and missionQueueDir to be configured");
|
|
69
|
+
}
|
|
70
|
+
const targets = new MissionTargetRegistry(new FsMissionTargetStore(deps.missionTargetsDir));
|
|
71
|
+
const queue = new FsMissionQueueStore(deps.missionQueueDir);
|
|
72
|
+
return facadeQueueExploration(targets, queue, args);
|
|
73
|
+
});
|
|
74
|
+
// ai_generate_text: preflight-gated generation. Wired only when a gateway (or
|
|
75
|
+
// an explicit seam) is available — otherwise it stays not_implemented rather
|
|
76
|
+
// than fabricate an answer. The credential store is read ONLY inside the
|
|
77
|
+
// gateway/preflight; never here.
|
|
78
|
+
const credentialStore = deps.credentialStore ?? envCredentialStore();
|
|
79
|
+
const aiGenerateText = deps.aiGenerateText ??
|
|
80
|
+
(deps.generationGateway
|
|
81
|
+
? (args) => facadeAiGenerateText(credentialStore, deps.generationGateway, args)
|
|
82
|
+
: undefined);
|
|
83
|
+
// The 8 inbox tools: the store is built lazily inside this closure (mirrors
|
|
84
|
+
// `queueExploration` above) so constructing the tool set never touches
|
|
85
|
+
// disk. A missing `inboxDir` is a config error (a refusal), never a silent
|
|
86
|
+
// success — `inboxHandler` below catches it (and any store-layer throw,
|
|
87
|
+
// e.g. `getForAgent`/`get`'s fail-closed throw on corrupt/tampered data)
|
|
88
|
+
// and converts it to a typed `internal` error, never lets it fabricate a
|
|
89
|
+
// success or leak an unhandled rejection out of the handler.
|
|
90
|
+
const inboxStore = () => {
|
|
91
|
+
if (!deps.inboxDir) {
|
|
92
|
+
throw new Error("inbox tools require inboxDir to be configured");
|
|
93
|
+
}
|
|
94
|
+
return new FsInboxStore(deps.inboxDir);
|
|
95
|
+
};
|
|
96
|
+
function inboxHandler(fn) {
|
|
97
|
+
return async (args) => {
|
|
98
|
+
try {
|
|
99
|
+
return jsonResult(await fn(inboxStore(), args));
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
return errorResult({ error: "internal", message: err instanceof Error ? err.message : String(err) });
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const idInputSchema = {
|
|
107
|
+
type: "object",
|
|
108
|
+
properties: { id: { type: "string" } },
|
|
109
|
+
required: ["id"],
|
|
110
|
+
};
|
|
111
|
+
const queueCommonProperties = {
|
|
112
|
+
run: { type: "string" },
|
|
113
|
+
journey: { type: "string" },
|
|
114
|
+
step: { type: "string" },
|
|
115
|
+
reason: { type: "string" },
|
|
116
|
+
agent: { type: "string" },
|
|
117
|
+
targetUrl: { type: "string" },
|
|
118
|
+
hasScreenshot: { type: "boolean" },
|
|
119
|
+
findings: {
|
|
120
|
+
type: "array",
|
|
121
|
+
items: {
|
|
122
|
+
type: "object",
|
|
123
|
+
properties: {
|
|
124
|
+
id: { type: "string" },
|
|
125
|
+
title: { type: "string" },
|
|
126
|
+
severity: { type: "string", enum: ["low", "med", "high"] },
|
|
127
|
+
evidence: { type: "string" },
|
|
128
|
+
},
|
|
129
|
+
required: ["id", "title", "severity"],
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
const queueCommonRequired = ["run", "journey", "step", "reason", "agent"];
|
|
134
|
+
const wired = {
|
|
135
|
+
find_capabilities: {
|
|
136
|
+
description: "Find promoted Journeys (capabilities) whose metadata matches a query.",
|
|
137
|
+
inputSchema: { type: "object", properties: { query: { type: "string" } }, required: ["query"] },
|
|
138
|
+
handler: async (args) => jsonResult(await findCaps(typeof args.query === "string" ? args.query : "")),
|
|
139
|
+
},
|
|
140
|
+
run_journey: {
|
|
141
|
+
description: "Run a PUBLISHED Journey by id with string params (fail-closed policy). Never accepts inline steps.",
|
|
142
|
+
inputSchema: {
|
|
143
|
+
type: "object",
|
|
144
|
+
properties: {
|
|
145
|
+
id: { type: "string" },
|
|
146
|
+
params: { type: "object", additionalProperties: { type: "string" } },
|
|
147
|
+
},
|
|
148
|
+
required: ["id"],
|
|
149
|
+
},
|
|
150
|
+
handler: async (args) => {
|
|
151
|
+
if (typeof args.id !== "string" || args.id.length === 0) {
|
|
152
|
+
return errorResult({ error: "invalid_args", message: "run_journey requires a non-empty string 'id'" });
|
|
153
|
+
}
|
|
154
|
+
// Invariant #5: only id + params are threaded through — any inline
|
|
155
|
+
// `steps`/`recording` in the arguments is deliberately ignored.
|
|
156
|
+
const params = args.params && typeof args.params === "object" && !Array.isArray(args.params)
|
|
157
|
+
? args.params
|
|
158
|
+
: {};
|
|
159
|
+
return jsonResult(await runJourney(args.id, params));
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
queue_exploration: {
|
|
163
|
+
description: "Enqueue an exploration mission against a PROMOTED target. Never runs anything — only queues. Refuses unknown/unpromoted targets and over-ceiling budgets.",
|
|
164
|
+
inputSchema: {
|
|
165
|
+
type: "object",
|
|
166
|
+
properties: {
|
|
167
|
+
target: { type: "string" },
|
|
168
|
+
goal: { type: "string" },
|
|
169
|
+
feature: { type: "string" },
|
|
170
|
+
route: { type: "string" },
|
|
171
|
+
successAssertion: { type: "object" },
|
|
172
|
+
strategy: { type: "string" },
|
|
173
|
+
budget: {
|
|
174
|
+
type: "object",
|
|
175
|
+
properties: {
|
|
176
|
+
maxActions: { type: "number" },
|
|
177
|
+
maxDecisions: { type: "number" },
|
|
178
|
+
maxCandidates: { type: "number" },
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
required: ["target"],
|
|
183
|
+
},
|
|
184
|
+
handler: async (args) => {
|
|
185
|
+
try {
|
|
186
|
+
// All shape/budget/promoted-target validation is delegated to
|
|
187
|
+
// `enqueueMission` (fail-closed). A refusal surfaces as a structured
|
|
188
|
+
// error — NEVER a fabricated "queued" success.
|
|
189
|
+
return jsonResult(await queueExploration(args));
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
return errorResult({
|
|
193
|
+
error: "queue_exploration_refused",
|
|
194
|
+
message: err instanceof Error ? err.message : String(err),
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
...(aiGenerateText
|
|
200
|
+
? {
|
|
201
|
+
ai_generate_text: {
|
|
202
|
+
description: "Generate a single text value for a form field via the model gateway. Credential-gated: a missing key returns a typed setup_required result; the key is NEVER sent to the model or returned.",
|
|
203
|
+
inputSchema: {
|
|
204
|
+
type: "object",
|
|
205
|
+
properties: {
|
|
206
|
+
fieldLabel: { type: "string" },
|
|
207
|
+
goal: { type: "string" },
|
|
208
|
+
visibleContext: { type: "string" },
|
|
209
|
+
history: { type: "array", items: { type: "string" } },
|
|
210
|
+
},
|
|
211
|
+
required: ["fieldLabel", "goal", "visibleContext"],
|
|
212
|
+
},
|
|
213
|
+
handler: async (args) => {
|
|
214
|
+
if (typeof args.fieldLabel !== "string" ||
|
|
215
|
+
typeof args.goal !== "string" ||
|
|
216
|
+
typeof args.visibleContext !== "string") {
|
|
217
|
+
return errorResult({
|
|
218
|
+
error: "invalid_args",
|
|
219
|
+
message: "ai_generate_text requires string 'fieldLabel', 'goal' and 'visibleContext'",
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
const history = Array.isArray(args.history) && args.history.every((h) => typeof h === "string")
|
|
223
|
+
? args.history
|
|
224
|
+
: undefined;
|
|
225
|
+
try {
|
|
226
|
+
// The facade applies `withPreflight` — a missing credential
|
|
227
|
+
// returns a typed `setup_required` precondition (the model is
|
|
228
|
+
// never called), which is a legitimate result surface, not an
|
|
229
|
+
// error, so the host can collect the key and retry.
|
|
230
|
+
return jsonResult(await aiGenerateText({
|
|
231
|
+
fieldLabel: args.fieldLabel,
|
|
232
|
+
goal: args.goal,
|
|
233
|
+
visibleContext: args.visibleContext,
|
|
234
|
+
...(history !== undefined ? { history } : {}),
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
// A provider/SDK error can echo request internals verbatim —
|
|
239
|
+
// redact any credential value and return a generic, key-free
|
|
240
|
+
// message. Never surface raw provider error text.
|
|
241
|
+
const raw = err instanceof Error ? err.message : String(err);
|
|
242
|
+
return errorResult({
|
|
243
|
+
error: "ai_generate_failed",
|
|
244
|
+
message: redactCredentials(raw, credentialStore),
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
}
|
|
250
|
+
: {}),
|
|
251
|
+
list_incoming: {
|
|
252
|
+
description: "List pending inbox items (HITL commands awaiting a human) as InboxSummary projections.",
|
|
253
|
+
inputSchema: { type: "object", properties: {} },
|
|
254
|
+
handler: inboxHandler((store) => facadeListIncoming(store)),
|
|
255
|
+
},
|
|
256
|
+
get_command: {
|
|
257
|
+
description: "Agent poll for one inbox item by id (burn-after-read: consumes any human-provided secret input exactly once). Returns not_found for an unknown id.",
|
|
258
|
+
inputSchema: idInputSchema,
|
|
259
|
+
handler: inboxHandler((store, args) => facadeGetCommand(store, args)),
|
|
260
|
+
},
|
|
261
|
+
get_thread: {
|
|
262
|
+
description: "Get the conversation thread (agent/human messages) for one inbox item by id. Never returns secret input.",
|
|
263
|
+
inputSchema: idInputSchema,
|
|
264
|
+
handler: inboxHandler((store, args) => facadeGetThread(store, args)),
|
|
265
|
+
},
|
|
266
|
+
queue_action: {
|
|
267
|
+
description: "Enqueue a HITL inbox item requiring a human decision — kind defaults to 'approval' ('handback'/'review' also accepted). Never resolves anything; only queues.",
|
|
268
|
+
inputSchema: {
|
|
269
|
+
type: "object",
|
|
270
|
+
properties: { ...queueCommonProperties, kind: { type: "string", enum: ["approval", "handback", "review"] } },
|
|
271
|
+
required: queueCommonRequired,
|
|
272
|
+
},
|
|
273
|
+
handler: inboxHandler((store, args) => facadeQueueAction(store, args)),
|
|
274
|
+
},
|
|
275
|
+
queue_retrieval: {
|
|
276
|
+
description: "Enqueue a HITL 'handback' inbox item requesting the human retrieve/provide something back to the agent. Never resolves anything; only queues.",
|
|
277
|
+
inputSchema: { type: "object", properties: queueCommonProperties, required: queueCommonRequired },
|
|
278
|
+
handler: inboxHandler((store, args) => facadeQueueRetrieval(store, args)),
|
|
279
|
+
},
|
|
280
|
+
approve_action: {
|
|
281
|
+
description: "SM1: an agent can NEVER approve an inbox item over MCP — always refuses with human_approval_required. Approval is only permitted from the local jevitate UI.",
|
|
282
|
+
inputSchema: { type: "object", properties: { id: { type: "string" } }, required: ["id"] },
|
|
283
|
+
handler: async () => errorResult(facadeApproveAction()),
|
|
284
|
+
},
|
|
285
|
+
cancel_command: {
|
|
286
|
+
description: "SM1: an agent can NEVER cancel an inbox item over MCP — always refuses with human_approval_required. Cancellation is only permitted from the local jevitate UI.",
|
|
287
|
+
inputSchema: { type: "object", properties: { id: { type: "string" } }, required: ["id"] },
|
|
288
|
+
handler: async () => errorResult(facadeCancelCommand()),
|
|
289
|
+
},
|
|
290
|
+
get_site_health: {
|
|
291
|
+
description: "Report inbox store health: ok, pending count, age of the oldest pending item, and store version.",
|
|
292
|
+
inputSchema: { type: "object", properties: {} },
|
|
293
|
+
handler: inboxHandler((store) => facadeGetSiteHealth(store)),
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
const notImplemented = (name) => async () => errorResult({
|
|
297
|
+
error: "not_implemented",
|
|
298
|
+
tool: name,
|
|
299
|
+
message: `tool '${name}' is allowlisted but not yet wired in this build`,
|
|
300
|
+
});
|
|
301
|
+
return ALLOWED_TOOLS.map((name) => {
|
|
302
|
+
assertAllowlisted(name);
|
|
303
|
+
const w = wired[name];
|
|
304
|
+
if (w)
|
|
305
|
+
return { name, ...w };
|
|
306
|
+
return {
|
|
307
|
+
name,
|
|
308
|
+
description: `Allowlisted Jevitate tool '${name}' (not yet wired).`,
|
|
309
|
+
inputSchema: { type: "object", properties: {} },
|
|
310
|
+
handler: notImplemented(name),
|
|
311
|
+
};
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Constructs the MCP `Server` and registers its `tools/list` and `tools/call`
|
|
316
|
+
* handlers off `buildMcpTools`. Does NOT open a transport — that is
|
|
317
|
+
* `startMcpServer`'s job — so this is safe to construct in a unit test.
|
|
318
|
+
*/
|
|
319
|
+
export function createMcpServer(deps) {
|
|
320
|
+
const tools = buildMcpTools(deps);
|
|
321
|
+
const byName = new Map(tools.map((t) => [t.name, t]));
|
|
322
|
+
const server = new Server({ name: "jevitate", version: "0.0.0" }, { capabilities: { tools: {} } });
|
|
323
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
324
|
+
tools: tools.map((t) => ({ name: t.name, description: t.description, inputSchema: t.inputSchema })),
|
|
325
|
+
}));
|
|
326
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
327
|
+
const { name, arguments: args } = request.params;
|
|
328
|
+
// `McpToolResult` is a strict subset of the SDK's `CallToolResult` (which
|
|
329
|
+
// carries an open index signature); the cast at this boundary keeps the
|
|
330
|
+
// handler-authoring type strict while satisfying the SDK's result shape.
|
|
331
|
+
// Defense in depth: a forbidden or unknown tool is NEVER dispatched.
|
|
332
|
+
if (FORBIDDEN.has(name) || !byName.has(name)) {
|
|
333
|
+
return errorResult({ error: "unknown_tool", tool: name });
|
|
334
|
+
}
|
|
335
|
+
const tool = byName.get(name);
|
|
336
|
+
try {
|
|
337
|
+
return (await tool.handler((args ?? {})));
|
|
338
|
+
}
|
|
339
|
+
catch (err) {
|
|
340
|
+
return errorResult({
|
|
341
|
+
error: "tool_failed",
|
|
342
|
+
tool: name,
|
|
343
|
+
message: err instanceof Error ? err.message : String(err),
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
return server;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Starts the real MCP stdio server. Blocks (the transport owns stdin/stdout)
|
|
351
|
+
* until the client disconnects — callers must NOT write to stdout while it
|
|
352
|
+
* runs, since stdout is the MCP protocol channel.
|
|
353
|
+
*/
|
|
354
|
+
export async function startMcpServer(deps) {
|
|
355
|
+
const server = createMcpServer(deps);
|
|
356
|
+
const transport = new StdioServerTransport();
|
|
357
|
+
await server.connect(transport);
|
|
358
|
+
}
|
|
359
|
+
//# sourceMappingURL=mcp-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-api.js","sourceRoot":"","sources":["../src/mcp-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAuB,MAAM,oCAAoC,CAAC;AACxH,OAAO,EACL,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,gBAAgB,IAAI,sBAAsB,EAC1C,cAAc,IAAI,oBAAoB,EACtC,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GAGpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,kBAAkB,GAInB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAwF9D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,aAAa,CAAC,CAAC;AAC/C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAS,eAAe,CAAC,CAAC;AAEnD;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,IAAY;IACrC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,GAAG,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,2CAA2C,IAAI,GAAG,CAAC,CAAC;IACtE,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;AACtE,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACrF,CAAC;AAED;;;gFAGgF;AAChF,SAAS,iBAAiB,CAAC,OAAe,EAAE,KAAsB;IAChE,IAAI,GAAG,GAAG,OAAO,CAAC;IAClB,KAAK,MAAM,GAAG,IAAI,CAAC,oBAAoB,EAAE,kBAAkB,CAAU,EAAE,CAAC;QACtE,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,KAAK;YAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,IAAgB;IAC5C,MAAM,QAAQ,GACZ,IAAI,CAAC,gBAAgB;QACrB,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,eAAe,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAE1G,MAAM,UAAU,GACd,IAAI,CAAC,UAAU;QACf,CAAC,CAAC,EAAU,EAAE,MAA8B,EAAE,EAAE,CAC9C,0BAA0B,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC;IAEhG,uEAAuE;IACvE,0EAA0E;IAC1E,0EAA0E;IAC1E,6CAA6C;IAC7C,MAAM,gBAAgB,GACpB,IAAI,CAAC,gBAAgB;QACrB,CAAC,KAAK,EAAE,IAAa,EAAE,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrD,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;YACvG,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,qBAAqB,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAC5F,MAAM,KAAK,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC5D,OAAO,sBAAsB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IAEL,8EAA8E;IAC9E,6EAA6E;IAC7E,yEAAyE;IACzE,iCAAiC;IACjC,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,kBAAkB,EAAE,CAAC;IACrE,MAAM,cAAc,GAClB,IAAI,CAAC,cAAc;QACnB,CAAC,IAAI,CAAC,iBAAiB;YACrB,CAAC,CAAC,CAAC,IAAwB,EAAE,EAAE,CAAC,oBAAoB,CAAC,eAAe,EAAE,IAAI,CAAC,iBAAkB,EAAE,IAAI,CAAC;YACpG,CAAC,CAAC,SAAS,CAAC,CAAC;IAEjB,4EAA4E;IAC5E,uEAAuE;IACvE,2EAA2E;IAC3E,wEAAwE;IACxE,yEAAyE;IACzE,yEAAyE;IACzE,6DAA6D;IAC7D,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC,CAAC;IAEF,SAAS,YAAY,CAAC,EAAuG;QAC3H,OAAO,KAAK,EAAE,IAAI,EAAE,EAAE;YACpB,IAAI,CAAC;gBACH,OAAO,UAAU,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;YAClD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,WAAW,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACvG,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG;QACpB,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QACtC,QAAQ,EAAE,CAAC,IAAI,CAAC;KACjB,CAAC;IAEF,MAAM,qBAAqB,GAAG;QAC5B,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACvB,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACxB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC1B,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC7B,aAAa,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QAClC,QAAQ,EAAE;YACR,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACtB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE;oBAC1D,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBAC7B;gBACD,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC;aACtC;SACF;KACF,CAAC;IACF,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE1E,MAAM,KAAK,GAA0C;QACnD,iBAAiB,EAAE;YACjB,WAAW,EAAE,uEAAuE;YACpF,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE;YAC/F,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,QAAQ,CAAC,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SACtG;QACD,WAAW,EAAE;YACX,WAAW,EACT,oGAAoG;YACtG,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACtB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;iBACrE;gBACD,QAAQ,EAAE,CAAC,IAAI,CAAC;aACjB;YACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACtB,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACxD,OAAO,WAAW,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,8CAA8C,EAAE,CAAC,CAAC;gBACzG,CAAC;gBACD,mEAAmE;gBACnE,gEAAgE;gBAChE,MAAM,MAAM,GACV,IAAI,CAAC,MAAM,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;oBAC3E,CAAC,CAAE,IAAI,CAAC,MAAiC;oBACzC,CAAC,CAAC,EAAE,CAAC;gBACT,OAAO,UAAU,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;YACvD,CAAC;SACF;QACD,iBAAiB,EAAE;YACjB,WAAW,EACT,2JAA2J;YAC7J,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAC1B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACxB,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAC3B,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACpC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAC5B,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BAC9B,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BAChC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;yBAClC;qBACF;iBACF;gBACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;aACrB;YACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACtB,IAAI,CAAC;oBACH,8DAA8D;oBAC9D,qEAAqE;oBACrE,+CAA+C;oBAC/C,OAAO,UAAU,CAAC,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;gBAClD,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,WAAW,CAAC;wBACjB,KAAK,EAAE,2BAA2B;wBAClC,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;qBAC1D,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;SACF;QACD,GAAG,CAAC,cAAc;YAChB,CAAC,CAAC;gBACE,gBAAgB,EAAE;oBAChB,WAAW,EACT,6LAA6L;oBAC/L,WAAW,EAAE;wBACX,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BAC9B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BACxB,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BAClC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;yBACtD;wBACD,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,gBAAgB,CAAC;qBACnD;oBACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;wBACtB,IACE,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ;4BACnC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;4BAC7B,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ,EACvC,CAAC;4BACD,OAAO,WAAW,CAAC;gCACjB,KAAK,EAAE,cAAc;gCACrB,OAAO,EAAE,4EAA4E;6BACtF,CAAC,CAAC;wBACL,CAAC;wBACD,MAAM,OAAO,GACX,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;4BAC7E,CAAC,CAAE,IAAI,CAAC,OAAoB;4BAC5B,CAAC,CAAC,SAAS,CAAC;wBAChB,IAAI,CAAC;4BACH,4DAA4D;4BAC5D,8DAA8D;4BAC9D,8DAA8D;4BAC9D,oDAAoD;4BACpD,OAAO,UAAU,CACf,MAAM,cAAc,CAAC;gCACnB,UAAU,EAAE,IAAI,CAAC,UAAU;gCAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;gCACf,cAAc,EAAE,IAAI,CAAC,cAAc;gCACnC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;6BAC9C,CAAC,CACH,CAAC;wBACJ,CAAC;wBAAC,OAAO,GAAG,EAAE,CAAC;4BACb,6DAA6D;4BAC7D,6DAA6D;4BAC7D,kDAAkD;4BAClD,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;4BAC7D,OAAO,WAAW,CAAC;gCACjB,KAAK,EAAE,oBAAoB;gCAC3B,OAAO,EAAE,iBAAiB,CAAC,GAAG,EAAE,eAAe,CAAC;6BACjD,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;iBACF;aACF;YACH,CAAC,CAAC,EAAE,CAAC;QACP,aAAa,EAAE;YACb,WAAW,EAAE,wFAAwF;YACrG,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;YAC/C,OAAO,EAAE,YAAY,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;SAC5D;QACD,WAAW,EAAE;YACX,WAAW,EACT,oJAAoJ;YACtJ,WAAW,EAAE,aAAa;YAC1B,OAAO,EAAE,YAAY,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;SACtE;QACD,UAAU,EAAE;YACV,WAAW,EAAE,0GAA0G;YACvH,WAAW,EAAE,aAAa;YAC1B,OAAO,EAAE,YAAY,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;SACrE;QACD,YAAY,EAAE;YACZ,WAAW,EACT,+JAA+J;YACjK,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE,GAAG,qBAAqB,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE;gBAC5G,QAAQ,EAAE,mBAAmB;aAC9B;YACD,OAAO,EAAE,YAAY,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;SACvE;QACD,eAAe,EAAE;YACf,WAAW,EACT,+IAA+I;YACjJ,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,qBAAqB,EAAE,QAAQ,EAAE,mBAAmB,EAAE;YACjG,OAAO,EAAE,YAAY,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;SAC1E;QACD,cAAc,EAAE;YACd,WAAW,EACT,8JAA8J;YAChK,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE;YACzF,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,mBAAmB,EAAE,CAAC;SACxD;QACD,cAAc,EAAE;YACd,WAAW,EACT,iKAAiK;YACnK,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE;YACzF,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,mBAAmB,EAAE,CAAC;SACxD;QACD,eAAe,EAAE;YACf,WAAW,EAAE,kGAAkG;YAC/G,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;YAC/C,OAAO,EAAE,YAAY,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;SAC7D;KACF,CAAC;IAEF,MAAM,cAAc,GAClB,CAAC,IAAY,EAAsB,EAAE,CACrC,KAAK,IAAI,EAAE,CACT,WAAW,CAAC;QACV,KAAK,EAAE,iBAAiB;QACxB,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,SAAS,IAAI,kDAAkD;KACzE,CAAC,CAAC;IAEP,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAChC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACxB,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO;YACL,IAAI;YACJ,WAAW,EAAE,8BAA8B,IAAI,oBAAoB;YACnE,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;YAC/C,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC;SAC9B,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAgB;IAC9C,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EACtC,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAChC,CAAC;IAEF,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;KACpG,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAA2B,EAAE;QACzF,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACjD,0EAA0E;QAC1E,wEAAwE;QACxE,yEAAyE;QACzE,qEAAqE;QACrE,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,OAAO,WAAW,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,CAAmB,CAAC;QAC9E,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;QAC/B,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC,CAAmB,CAAC;QACzF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC;gBACjB,KAAK,EAAE,aAAa;gBACpB,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aAC1D,CAAmB,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAgB;IACnD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { MissionTargetRegistry, type MissionTarget, type MissionTargetStore } from "@jevitate/missions";
|
|
2
|
+
/**
|
|
3
|
+
* Distinct from `@jevitate/missions`' generic promote error so the CLI can map
|
|
4
|
+
* "no such target to promote" to its own error code (E_UNKNOWN_MISSION_TARGET)
|
|
5
|
+
* without string-matching an error message — mirrors `journey-api.ts`'s
|
|
6
|
+
* `UnknownJourneyError`.
|
|
7
|
+
*/
|
|
8
|
+
export declare class UnknownMissionTargetError extends Error {
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The store + registry pair the CLI operates on. Bundling them makes the
|
|
12
|
+
* unit-testable seam a single injectable value: production wires the real
|
|
13
|
+
* fs-backed pair via `missionTargetContext(dir)`, while tests can inject an
|
|
14
|
+
* in-memory `MissionTargetStore`.
|
|
15
|
+
*/
|
|
16
|
+
export interface MissionTargetContext {
|
|
17
|
+
store: MissionTargetStore;
|
|
18
|
+
registry: MissionTargetRegistry;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Builds the real fs-backed store + registry for a targets directory. This is
|
|
22
|
+
* the ONE place the CLI locates the same on-disk store that `queue_exploration`
|
|
23
|
+
* resolves against (via `MissionTargetRegistry.resolve`), so a target
|
|
24
|
+
* registered/promoted here is exactly the one the MCP tool can resolve.
|
|
25
|
+
*/
|
|
26
|
+
export declare function missionTargetContext(dir: string): MissionTargetContext;
|
|
27
|
+
export interface AddMissionTargetInput {
|
|
28
|
+
id: string;
|
|
29
|
+
name: string;
|
|
30
|
+
authorizedOrigin: string;
|
|
31
|
+
baseUrl: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Registers a mission target. SECURITY: registering is NOT the same as
|
|
36
|
+
* promoting — a freshly-added target is `promoted: false`, so
|
|
37
|
+
* `queue_exploration` (`MissionTargetRegistry.resolve`) refuses it until a
|
|
38
|
+
* separate `promote` flips the gate. `registry.put` re-validates against
|
|
39
|
+
* `MissionTargetSchema` BEFORE any disk write (fail-closed: an invalid target
|
|
40
|
+
* — e.g. a path-unsafe id — is never persisted).
|
|
41
|
+
*/
|
|
42
|
+
export declare function addMissionTarget(ctx: MissionTargetContext, input: AddMissionTargetInput, nowIso?: () => string): Promise<MissionTarget>;
|
|
43
|
+
/**
|
|
44
|
+
* Lists ALL mission targets (promoted and unpromoted) straight from the store
|
|
45
|
+
* — a local/dev-facing listing of everything on disk. This mirrors
|
|
46
|
+
* `journey list` (store-direct, all) vs `journey find` (registry, promoted-
|
|
47
|
+
* only): the promoted-only projection is what `queue_exploration` sees, not
|
|
48
|
+
* this listing.
|
|
49
|
+
*/
|
|
50
|
+
export declare function listMissionTargets(ctx: MissionTargetContext): Promise<MissionTarget[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Promotes a registered target so `queue_exploration` can resolve it. An
|
|
53
|
+
* unknown id is refused with `UnknownMissionTargetError` (never silently
|
|
54
|
+
* created). Returns the persisted, now-promoted target.
|
|
55
|
+
*/
|
|
56
|
+
export declare function promoteMissionTarget(ctx: MissionTargetContext, id: string): Promise<MissionTarget>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { FsMissionTargetStore, MissionTargetRegistry, } from "@jevitate/missions";
|
|
2
|
+
/**
|
|
3
|
+
* Distinct from `@jevitate/missions`' generic promote error so the CLI can map
|
|
4
|
+
* "no such target to promote" to its own error code (E_UNKNOWN_MISSION_TARGET)
|
|
5
|
+
* without string-matching an error message — mirrors `journey-api.ts`'s
|
|
6
|
+
* `UnknownJourneyError`.
|
|
7
|
+
*/
|
|
8
|
+
export class UnknownMissionTargetError extends Error {
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Builds the real fs-backed store + registry for a targets directory. This is
|
|
12
|
+
* the ONE place the CLI locates the same on-disk store that `queue_exploration`
|
|
13
|
+
* resolves against (via `MissionTargetRegistry.resolve`), so a target
|
|
14
|
+
* registered/promoted here is exactly the one the MCP tool can resolve.
|
|
15
|
+
*/
|
|
16
|
+
export function missionTargetContext(dir) {
|
|
17
|
+
const store = new FsMissionTargetStore(dir);
|
|
18
|
+
return { store, registry: new MissionTargetRegistry(store) };
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Registers a mission target. SECURITY: registering is NOT the same as
|
|
22
|
+
* promoting — a freshly-added target is `promoted: false`, so
|
|
23
|
+
* `queue_exploration` (`MissionTargetRegistry.resolve`) refuses it until a
|
|
24
|
+
* separate `promote` flips the gate. `registry.put` re-validates against
|
|
25
|
+
* `MissionTargetSchema` BEFORE any disk write (fail-closed: an invalid target
|
|
26
|
+
* — e.g. a path-unsafe id — is never persisted).
|
|
27
|
+
*/
|
|
28
|
+
export async function addMissionTarget(ctx, input, nowIso = () => new Date().toISOString()) {
|
|
29
|
+
const target = {
|
|
30
|
+
id: input.id,
|
|
31
|
+
name: input.name,
|
|
32
|
+
authorizedOrigin: input.authorizedOrigin,
|
|
33
|
+
baseUrl: input.baseUrl,
|
|
34
|
+
...(input.description !== undefined ? { description: input.description } : {}),
|
|
35
|
+
promoted: false,
|
|
36
|
+
createdAtIso: nowIso(),
|
|
37
|
+
};
|
|
38
|
+
await ctx.registry.put(target);
|
|
39
|
+
return target;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Lists ALL mission targets (promoted and unpromoted) straight from the store
|
|
43
|
+
* — a local/dev-facing listing of everything on disk. This mirrors
|
|
44
|
+
* `journey list` (store-direct, all) vs `journey find` (registry, promoted-
|
|
45
|
+
* only): the promoted-only projection is what `queue_exploration` sees, not
|
|
46
|
+
* this listing.
|
|
47
|
+
*/
|
|
48
|
+
export function listMissionTargets(ctx) {
|
|
49
|
+
return ctx.store.list();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Promotes a registered target so `queue_exploration` can resolve it. An
|
|
53
|
+
* unknown id is refused with `UnknownMissionTargetError` (never silently
|
|
54
|
+
* created). Returns the persisted, now-promoted target.
|
|
55
|
+
*/
|
|
56
|
+
export async function promoteMissionTarget(ctx, id) {
|
|
57
|
+
const existing = await ctx.store.get(id);
|
|
58
|
+
if (!existing) {
|
|
59
|
+
throw new UnknownMissionTargetError(`unknown mission target '${id}'`);
|
|
60
|
+
}
|
|
61
|
+
await ctx.registry.promote(id);
|
|
62
|
+
const promoted = await ctx.store.get(id);
|
|
63
|
+
return promoted ?? { ...existing, promoted: true };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=mission-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mission-api.js","sourceRoot":"","sources":["../src/mission-api.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GAGtB,MAAM,oBAAoB,CAAC;AAE5B;;;;;GAKG;AACH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;CAAG;AAavD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,MAAM,KAAK,GAAG,IAAI,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC5C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;AAC/D,CAAC;AAUD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAyB,EACzB,KAA4B,EAC5B,SAAuB,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;IAErD,MAAM,MAAM,GAAkB;QAC5B,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,QAAQ,EAAE,KAAK;QACf,YAAY,EAAE,MAAM,EAAE;KACvB,CAAC;IACF,MAAM,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAyB;IAC1D,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,GAAyB,EACzB,EAAU;IAEV,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,yBAAyB,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzC,OAAO,QAAQ,IAAI,EAAE,GAAG,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import type { ProfileManager } from "@jevitate/daemon";
|
|
3
|
+
import { type StartUiServerDeps, type UiServerHandle } from "./ui-api.js";
|
|
4
|
+
import { type AiCliDeps } from "./ai-cli.js";
|
|
5
|
+
import { type DetectionDeps } from "./init-skills.js";
|
|
6
|
+
import { type ExploreCliDeps } from "./explore-api.js";
|
|
7
|
+
import { type RecorderLike } from "./record-api.js";
|
|
8
|
+
import { type RunResolvedJourney } from "./source-run-api.js";
|
|
9
|
+
import { type GitExec, type GhPort } from "@jevitate/sources";
|
|
10
|
+
import type { BrowserPort, BrowserSession } from "@jevitate/playwright";
|
|
11
|
+
/** Injectable wiring for the `record` command (all optional; real defaults). */
|
|
12
|
+
export interface RecordCliDeps {
|
|
13
|
+
/** Testing seam — defaults to a real `PlaywrightBrowserPort`. */
|
|
14
|
+
browserPortFactory?: () => BrowserPort;
|
|
15
|
+
/** Testing seam — defaults to a real `@jevitate/recorder` `Recorder`. */
|
|
16
|
+
recorderFactory?: (session: BrowserSession, site: string) => RecorderLike;
|
|
17
|
+
/** Testing seam — the "user signalled done" wait. Defaults to Enter on stdin. */
|
|
18
|
+
waitForStop?: () => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export interface CliDeps {
|
|
21
|
+
profiles: ProfileManager;
|
|
22
|
+
dbPath?: string;
|
|
23
|
+
journeysDir?: string;
|
|
24
|
+
/** Optional, additive: overrides the mission-targets store directory
|
|
25
|
+
* (default: ~/.jevitate/missions/targets). Same dir `queue_exploration`
|
|
26
|
+
* resolves promoted targets from. */
|
|
27
|
+
missionTargetsDir?: string;
|
|
28
|
+
/** Optional, additive: overrides the inbox store directory (default:
|
|
29
|
+
* ~/.jevitate/inbox). Same dir BOTH `jevitate mcp`'s inbox tools AND
|
|
30
|
+
* `jevitate ui` resolve against by default — Task 8 threads one resolved
|
|
31
|
+
* dir into both so they serve/consume the same store. */
|
|
32
|
+
inboxDir?: string;
|
|
33
|
+
/** Optional, additive: `jevitate ui` wiring (see ui-api.ts). Omitted in
|
|
34
|
+
* production means the real `startUiServer`, which binds a real loopback
|
|
35
|
+
* HTTP port — tests inject a fake so no port is ever bound. */
|
|
36
|
+
ui?: {
|
|
37
|
+
startUiServer?: (deps: StartUiServerDeps) => Promise<UiServerHandle>;
|
|
38
|
+
};
|
|
39
|
+
/** Optional, additive: `@jevitate/ai-core` wiring (see ai-cli.ts). Omitted in
|
|
40
|
+
* production means real env + the deterministic fake generation gateway. */
|
|
41
|
+
ai?: AiCliDeps;
|
|
42
|
+
/** Optional, additive: `@jevitate/explore` wiring (see explore-api.ts). */
|
|
43
|
+
explore?: ExploreCliDeps;
|
|
44
|
+
/** Optional, additive: `jevitate record` wiring (see record-api.ts). */
|
|
45
|
+
record?: RecordCliDeps;
|
|
46
|
+
/** Optional, additive: `jevitate init` wiring (see init-skills.ts). Omitted
|
|
47
|
+
* in production means the real `existsSync`/`homedir`/`cwd` and the real
|
|
48
|
+
* `~/.jevitate/skills-install-state.json` state path. */
|
|
49
|
+
init?: {
|
|
50
|
+
detection?: DetectionDeps;
|
|
51
|
+
statePath?: string;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Optional, additive: distributed-Journey-sources wiring (see source-api.ts).
|
|
55
|
+
* Every field is injectable so tests never touch the network, the real home
|
|
56
|
+
* dir, or the real `git`/`gh` binaries. Omitted in production means the real
|
|
57
|
+
* `~/.jevitate/sources` clone dir, `<cwd>/jevitate.lock`, `~/.jevitate/trust`
|
|
58
|
+
* stores, and the real `git`/`gh` ports.
|
|
59
|
+
*/
|
|
60
|
+
sources?: {
|
|
61
|
+
sourcesDir?: string;
|
|
62
|
+
lockPath?: string;
|
|
63
|
+
trustDir?: string;
|
|
64
|
+
ackDir?: string;
|
|
65
|
+
git?: GitExec;
|
|
66
|
+
gh?: GhPort;
|
|
67
|
+
now?: () => string;
|
|
68
|
+
/** Identity recorded in a `TrustRecord`/`TouAck`; defaults to the OS user. */
|
|
69
|
+
approvedBy?: string;
|
|
70
|
+
/** Optional, additive: `jevitate source run` runner seam (see
|
|
71
|
+
* source-run-api.ts). Omitted in production means the real
|
|
72
|
+
* Playwright-backed `realResolvedJourneyRunner`; tests inject a fake so no
|
|
73
|
+
* browser launches. */
|
|
74
|
+
runJourney?: RunResolvedJourney;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export declare function buildProgram(deps: CliDeps): Command;
|