@yugabytedb/meko-mcp 2.2.0 → 2.5.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/README.md +168 -61
- package/assets/hooks-handlers/lib/capture-cleanup-cli.js +2134 -0
- package/assets/hooks-handlers/lib/capture-notices.js +224 -14
- package/assets/hooks-handlers/lib/capture-state.js +206 -1
- package/assets/hooks-handlers/lib/capture-status-cli.js +6 -2
- package/assets/hooks-handlers/lib/capture.js +1364 -139
- package/assets/hooks-handlers/lib/checkpoint-timer.js +445 -18
- package/assets/hooks-handlers/lib/journal-bridge.js +218 -0
- package/assets/hooks-handlers/lib/kiro-handler.js +26 -4
- package/assets/hooks-handlers/lib/opencode-handler.js +643 -0
- package/assets/hooks-handlers/lib/opencode-normalizer.js +145 -0
- package/assets/hooks-handlers/lib/terminal-handoff.js +10 -1
- package/assets/opencode-plugin/meko.js +213 -0
- package/assets/scripts/meko-statusline.sh +102 -19
- package/assets/skills/meko-mcp-tools/SKILL.md +59 -16
- package/assets/skills/meko-mcp-tools/references/_sections.md +2 -2
- package/assets/skills/meko-mcp-tools/references/tools-agent-id-conventions.md +15 -7
- package/assets/skills/meko-mcp-tools/references/tools-cookbook.md +275 -19
- package/assets/skills/meko-mcp-tools/references/tools-datapack-workflow.md +7 -4
- package/assets/skills/meko-mcp-tools/references/tools-known-limitations.md +39 -11
- package/assets/skills/meko-mcp-tools/references/tools-memory-vs-conversation.md +10 -6
- package/assets/skills/meko-mcp-tools/references/tools-overview.md +44 -29
- package/assets/skills/meko-mcp-tools/references/tools-rag-workflow.md +79 -14
- package/assets/skills/meko-mcp-tools/references/tools-troubleshooting.md +47 -1
- package/assets/skills/meko-mcp-tools/references/tools-user-id-conventions.md +6 -39
- package/assets/skills/meko-mcp-tools-desktop/SKILL.md +57 -21
- package/assets/skills/meko-mcp-tools-desktop/desktop/README.md +4 -4
- package/assets/skills/meko-mcp-tools-desktop/references/_sections.md +1 -1
- package/assets/skills/meko-mcp-tools-desktop/references/tools-agent-id-conventions.md +8 -6
- package/assets/skills/meko-mcp-tools-desktop/references/tools-cookbook.md +284 -38
- package/assets/skills/meko-mcp-tools-desktop/references/tools-known-limitations.md +32 -10
- package/assets/skills/meko-mcp-tools-desktop/references/tools-memory-vs-conversation.md +16 -12
- package/assets/skills/meko-mcp-tools-desktop/references/tools-overview.md +46 -31
- package/assets/skills/meko-mcp-tools-desktop/references/tools-rag-workflow.md +79 -14
- package/assets/skills/meko-mcp-tools-desktop/references/tools-troubleshooting.md +69 -1
- package/assets/skills/meko-select-datapack-desktop/SKILL.md +93 -14
- package/assets/skills/meko-select-datapack-desktop/references/cookbook.md +44 -12
- package/assets/skills/meko-select-datapack-desktop/references/role-display-future.md +14 -10
- package/assets/skills/meko-select-datapack-desktop/references/troubleshooting.md +17 -5
- package/bin/create-meko-setup.mjs +186 -30
- package/lib/autofix.mjs +100 -0
- package/lib/browser-login.mjs +495 -0
- package/lib/capture-cleanup.mjs +63 -0
- package/lib/clients/claude-code.mjs +1 -0
- package/lib/clients/codex.mjs +80 -35
- package/lib/clients/common.mjs +7 -0
- package/lib/clients/index.mjs +2 -0
- package/lib/clients/kiro.mjs +5 -5
- package/lib/clients/opencode.mjs +537 -0
- package/lib/config.mjs +68 -1
- package/lib/installer.mjs +18 -2
- package/lib/migrate/adapters/claude-code.mjs +11 -2
- package/lib/migrate/adapters/codex.mjs +9 -2
- package/lib/migrate/adapters/memory-md.mjs +27 -8
- package/lib/migrate/adapters/opencode.mjs +148 -0
- package/lib/migrate/claude-parser.mjs +153 -9
- package/lib/migrate/datapack.mjs +254 -16
- package/lib/migrate/id.mjs +195 -13
- package/lib/migrate/mcp-client.mjs +59 -1
- package/lib/migrate/opencode-normalizer.mjs +132 -0
- package/lib/migrate/orchestrator.mjs +294 -78
- package/lib/migrate/progress.mjs +239 -5
- package/lib/migrate/registry.mjs +72 -0
- package/lib/migrate.mjs +97 -9
- package/lib/validate.mjs +111 -22
- package/package.json +5 -5
- package/scripts/bundle-assets.mjs +4 -0
package/lib/validate.mjs
CHANGED
|
@@ -38,8 +38,13 @@ const CORE_TOOLS = [
|
|
|
38
38
|
/** Nil UUID used as the conversation_id placeholder for the canary call. */
|
|
39
39
|
const NIL_UUID = "00000000-0000-0000-0000-000000000000";
|
|
40
40
|
|
|
41
|
-
/**
|
|
42
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Tool the canary invokes. `datapack_search(limit=1)` reads one page whatever
|
|
43
|
+
* the account size; a server that predates it gets `datapack_list`, which
|
|
44
|
+
* reads the whole account.
|
|
45
|
+
*/
|
|
46
|
+
const CANARY_TOOL = "datapack_search";
|
|
47
|
+
const LEGACY_CANARY_TOOL = "datapack_list";
|
|
43
48
|
|
|
44
49
|
// ---------------------------------------------------------------------------
|
|
45
50
|
// 1. Config validation
|
|
@@ -139,9 +144,10 @@ export async function validateTools(url, apiKey) {
|
|
|
139
144
|
* The canary's job is to prove the part of the stack that connectivity +
|
|
140
145
|
* tools/list don't cover: auth was accepted as a real Meko identity, the
|
|
141
146
|
* tenant resolver mapped it to an account, and the datapack routing wired
|
|
142
|
-
* up the user's actual workspace. We invoke `
|
|
143
|
-
*
|
|
144
|
-
*
|
|
147
|
+
* up the user's actual workspace. We invoke `datapack_search(limit=1)` for
|
|
148
|
+
* this, or `datapack_list` on a server whose tools/list has no
|
|
149
|
+
* `datapack_search`. Either is a single read-only call against the system
|
|
150
|
+
* schema and returns deterministically (every authenticated user has at
|
|
145
151
|
* least one datapack: their default).
|
|
146
152
|
*
|
|
147
153
|
* Why not memory_add? The previous canary did a write/read/delete round-trip
|
|
@@ -166,11 +172,13 @@ export async function validateTools(url, apiKey) {
|
|
|
166
172
|
* initialize handshake is performed.
|
|
167
173
|
* @param {number} [options.timeoutMs] - Override the canary call's transport timeout.
|
|
168
174
|
* Defaults to DEFAULT_REQUEST_TIMEOUT_MS.
|
|
175
|
+
* @param {string[]} [options.toolNames] - Tool names from an earlier tools/list.
|
|
176
|
+
* If omitted, the canary lists tools itself.
|
|
169
177
|
* @returns {Promise<{
|
|
170
178
|
* ok: boolean,
|
|
171
179
|
* message: string,
|
|
172
180
|
* datapack_count: number|null,
|
|
173
|
-
* step?: "initialize"|"datapack_list",
|
|
181
|
+
* step?: "initialize"|"datapack_search"|"datapack_list",
|
|
174
182
|
* }>}
|
|
175
183
|
*/
|
|
176
184
|
export async function validateCanary(url, apiKey, options = {}) {
|
|
@@ -190,11 +198,77 @@ export async function validateCanary(url, apiKey, options = {}) {
|
|
|
190
198
|
sessionId = init.sessionId;
|
|
191
199
|
}
|
|
192
200
|
|
|
201
|
+
let toolNames = options.toolNames;
|
|
202
|
+
if (!Array.isArray(toolNames)) {
|
|
203
|
+
// A failed listing just means we cannot tell; datapack_list works on
|
|
204
|
+
// every server.
|
|
205
|
+
const listed = await sendToolsList(url, apiKey, sessionId);
|
|
206
|
+
toolNames = listed.tools;
|
|
207
|
+
}
|
|
208
|
+
if (toolNames.includes(CANARY_TOOL)) {
|
|
209
|
+
return searchCanary(url, apiKey, sessionId, timeoutMs);
|
|
210
|
+
}
|
|
211
|
+
return listCanary(url, apiKey, sessionId, timeoutMs);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async function searchCanary(url, apiKey, sessionId, timeoutMs) {
|
|
193
215
|
const callRes = await mcpCallTool(
|
|
194
216
|
url,
|
|
195
217
|
apiKey,
|
|
196
218
|
sessionId,
|
|
197
219
|
CANARY_TOOL,
|
|
220
|
+
{ conversation_id: NIL_UUID, limit: 1 },
|
|
221
|
+
{ timeoutMs },
|
|
222
|
+
);
|
|
223
|
+
if (!callRes.ok) {
|
|
224
|
+
return {
|
|
225
|
+
ok: false,
|
|
226
|
+
datapack_count: null,
|
|
227
|
+
step: CANARY_TOOL,
|
|
228
|
+
message: `Canary: ${callRes.message}`,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const datapacks = parseDatapackSearchPage(callRes.text);
|
|
233
|
+
if (!datapacks) {
|
|
234
|
+
return {
|
|
235
|
+
ok: false,
|
|
236
|
+
datapack_count: null,
|
|
237
|
+
step: CANARY_TOOL,
|
|
238
|
+
message:
|
|
239
|
+
`Canary: ${CANARY_TOOL} returned an unexpected response shape ` +
|
|
240
|
+
`(expected an object with a datapacks array). Check the server logs.`,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
if (datapacks.length === 0) {
|
|
244
|
+
return zeroDatapacks(CANARY_TOOL);
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
ok: true,
|
|
248
|
+
datapack_count: datapacks.length,
|
|
249
|
+
message: `Canary OK — ${CANARY_TOOL} found a datapack.`,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function zeroDatapacks(tool) {
|
|
254
|
+
return {
|
|
255
|
+
ok: false,
|
|
256
|
+
datapack_count: 0,
|
|
257
|
+
step: tool,
|
|
258
|
+
message:
|
|
259
|
+
`Canary: ${tool} returned zero datapacks. Every authenticated ` +
|
|
260
|
+
`Meko user should have at least their default datapack — this likely ` +
|
|
261
|
+
`means the API token authenticated but resolved to the wrong tenant. ` +
|
|
262
|
+
`Verify the API key matches the tenant the URL points at.`,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async function listCanary(url, apiKey, sessionId, timeoutMs) {
|
|
267
|
+
const callRes = await mcpCallTool(
|
|
268
|
+
url,
|
|
269
|
+
apiKey,
|
|
270
|
+
sessionId,
|
|
271
|
+
LEGACY_CANARY_TOOL,
|
|
198
272
|
{
|
|
199
273
|
scope: "read",
|
|
200
274
|
conversation_id: NIL_UUID,
|
|
@@ -210,7 +284,7 @@ export async function validateCanary(url, apiKey, options = {}) {
|
|
|
210
284
|
return {
|
|
211
285
|
ok: false,
|
|
212
286
|
datapack_count: null,
|
|
213
|
-
step:
|
|
287
|
+
step: LEGACY_CANARY_TOOL,
|
|
214
288
|
message: `Canary: ${callRes.message}`,
|
|
215
289
|
};
|
|
216
290
|
}
|
|
@@ -224,30 +298,21 @@ export async function validateCanary(url, apiKey, options = {}) {
|
|
|
224
298
|
return {
|
|
225
299
|
ok: false,
|
|
226
300
|
datapack_count: null,
|
|
227
|
-
step:
|
|
301
|
+
step: LEGACY_CANARY_TOOL,
|
|
228
302
|
message:
|
|
229
|
-
`Canary: ${
|
|
303
|
+
`Canary: ${LEGACY_CANARY_TOOL} returned an unexpected response shape ` +
|
|
230
304
|
`(expected a JSON array of datapack objects). Check the server logs.`,
|
|
231
305
|
};
|
|
232
306
|
}
|
|
233
307
|
|
|
234
308
|
if (datapacks.length === 0) {
|
|
235
|
-
return
|
|
236
|
-
ok: false,
|
|
237
|
-
datapack_count: 0,
|
|
238
|
-
step: CANARY_TOOL,
|
|
239
|
-
message:
|
|
240
|
-
`Canary: ${CANARY_TOOL} returned zero datapacks. Every authenticated ` +
|
|
241
|
-
`Meko user should have at least their default datapack — this likely ` +
|
|
242
|
-
`means the API token authenticated but resolved to the wrong tenant. ` +
|
|
243
|
-
`Verify the API key matches the tenant the URL points at.`,
|
|
244
|
-
};
|
|
309
|
+
return zeroDatapacks(LEGACY_CANARY_TOOL);
|
|
245
310
|
}
|
|
246
311
|
|
|
247
312
|
return {
|
|
248
313
|
ok: true,
|
|
249
314
|
datapack_count: datapacks.length,
|
|
250
|
-
message: `Canary OK — ${
|
|
315
|
+
message: `Canary OK — ${LEGACY_CANARY_TOOL} returned ${datapacks.length} datapack(s).`,
|
|
251
316
|
};
|
|
252
317
|
}
|
|
253
318
|
|
|
@@ -263,8 +328,8 @@ export async function validateCanary(url, apiKey, options = {}) {
|
|
|
263
328
|
* canary reuses that same session too.
|
|
264
329
|
*
|
|
265
330
|
* The canary is skipped (not failed) when tools/list didn't pass — the
|
|
266
|
-
* canary depends on `datapack_list`
|
|
267
|
-
* already surfaces that.
|
|
331
|
+
* canary depends on `datapack_list` (a core tool) or `datapack_search`
|
|
332
|
+
* being present, and a tools failure already surfaces that.
|
|
268
333
|
*
|
|
269
334
|
* @param {string} url - Full MCP endpoint URL.
|
|
270
335
|
* @param {string|null} apiKey - Optional API key.
|
|
@@ -292,6 +357,7 @@ export async function runValidation(url, apiKey, serverName = "meko", options =
|
|
|
292
357
|
if (tools.ok && connectivity.ok) {
|
|
293
358
|
canary = await validateCanary(url, apiKey, {
|
|
294
359
|
sessionId: connectivity.sessionId,
|
|
360
|
+
toolNames: tools.tools,
|
|
295
361
|
});
|
|
296
362
|
} else {
|
|
297
363
|
canary = {
|
|
@@ -508,6 +574,29 @@ function extractFirstText(result) {
|
|
|
508
574
|
return null;
|
|
509
575
|
}
|
|
510
576
|
|
|
577
|
+
/**
|
|
578
|
+
* Parse a `datapack_search` response body and return its `datapacks` rows,
|
|
579
|
+
* or `null` if the body is not a recognizable page.
|
|
580
|
+
*
|
|
581
|
+
* @param {string|null} text
|
|
582
|
+
* @returns {Array|null}
|
|
583
|
+
*/
|
|
584
|
+
function parseDatapackSearchPage(text) {
|
|
585
|
+
if (!text) return null;
|
|
586
|
+
let body;
|
|
587
|
+
try {
|
|
588
|
+
body = JSON.parse(text);
|
|
589
|
+
} catch {
|
|
590
|
+
return null;
|
|
591
|
+
}
|
|
592
|
+
if (!body || typeof body !== "object" || !Array.isArray(body.datapacks)) return null;
|
|
593
|
+
const rows = body.datapacks;
|
|
594
|
+
const allLookLikeDatapacks = rows.every(
|
|
595
|
+
(entry) => entry && typeof entry === "object" && typeof entry.datapack_id === "string",
|
|
596
|
+
);
|
|
597
|
+
return allLookLikeDatapacks ? rows : null;
|
|
598
|
+
}
|
|
599
|
+
|
|
511
600
|
/**
|
|
512
601
|
* Parse a `datapack_list` response body and return the array of datapacks,
|
|
513
602
|
* or `null` if the body is not a recognizable datapack list.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yugabytedb/meko-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Installer for Meko across Claude, Cursor, Codex, and Kiro clients",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
"prepack": "node scripts/bundle-assets.mjs",
|
|
19
19
|
"postpack": "node scripts/bundle-assets.mjs --clean",
|
|
20
20
|
"bundle-assets": "node scripts/bundle-assets.mjs",
|
|
21
|
-
"test": "node --test \"test/*.mjs\" && node --test \"test/serial/*.mjs\"",
|
|
21
|
+
"test": "node --import ./test/helpers/hermetic-env.mjs --test \"test/*.mjs\" && node --import ./test/helpers/hermetic-env.mjs --test \"test/serial/*.mjs\"",
|
|
22
22
|
"smoke": "./scripts/prepublish-smoke.sh",
|
|
23
|
-
"test:unit": "node --test test/config.test.mjs test/validate.test.mjs test/clients.test.mjs",
|
|
24
|
-
"test:integration": "RUN_INSTALLER_INTEGRATION=1 node --test test/installer.test.mjs",
|
|
25
|
-
"test:integration:cloud": "RUN_INSTALLER_INTEGRATION=1 node --test test/installer.test.mjs"
|
|
23
|
+
"test:unit": "node --import ./test/helpers/hermetic-env.mjs --test test/config.test.mjs test/validate.test.mjs test/clients.test.mjs",
|
|
24
|
+
"test:integration": "RUN_INSTALLER_INTEGRATION=1 node --import ./test/helpers/hermetic-env.mjs --test test/installer.test.mjs",
|
|
25
|
+
"test:integration:cloud": "RUN_INSTALLER_INTEGRATION=1 node --import ./test/helpers/hermetic-env.mjs --test test/installer.test.mjs"
|
|
26
26
|
},
|
|
27
27
|
"engines": {
|
|
28
28
|
"node": ">=20.18.1"
|
|
@@ -30,6 +30,10 @@ const PAYLOAD = [
|
|
|
30
30
|
from: join(repoRoot, "skills", "hooks-handlers"),
|
|
31
31
|
to: join(assetsDir, "hooks-handlers"),
|
|
32
32
|
},
|
|
33
|
+
{
|
|
34
|
+
from: join(repoRoot, "skills", "opencode-plugin"),
|
|
35
|
+
to: join(assetsDir, "opencode-plugin"),
|
|
36
|
+
},
|
|
33
37
|
{
|
|
34
38
|
from: join(repoRoot, "skills", "scripts", "package-desktop-skill.sh"),
|
|
35
39
|
to: join(assetsDir, "scripts", "package-desktop-skill.sh"),
|