@ait-co/devtools 0.1.41 → 0.1.44
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.en.md +85 -0
- package/README.md +85 -0
- package/dist/mcp/cli.js +1355 -207
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +94 -53
- package/dist/mcp/server.js.map +1 -1
- package/dist/mock/index.d.ts +0 -4
- package/dist/mock/index.d.ts.map +1 -1
- package/dist/mock/index.js +0 -1
- package/dist/mock/index.js.map +1 -1
- package/dist/panel/index.js +40 -52
- package/dist/panel/index.js.map +1 -1
- package/package.json +1 -1
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","names":[],"sources":["../../src/mcp/ait-source.ts","../../src/mcp/server.ts"],"mappings":";;;;;;;AAsBA;;;;;AAGA;;;;;;;;;;;;;KAHY,kBAAA;AAqBZ;AAAA,UAlBiB,UAAA;;EAEf,MAAA;EAiBiB;EAfjB,IAAA;EAwBsB;EAtBtB,SAAA;EAsByB;EApBzB,MAAA;EAuBe;EArBf,MAAA;;EAEA,KAAA;EAuBU;EArBV,QAAA,EAAU,kBAAA;AAAA;;UAIK,iBAAA;EACf,KAAA,EAAO,UAAA;AAAA;;;;;;;KASG,YAAA,GAAe,MAAA;;UAGV,yBAAA;EAW2C;EAT1D,WAAA;EAYuB;EAVvB,UAAA;AAAA;;UAIe,YAAA;EACf,uBAAA,EAAyB,iBAAA;EACzB,kBAAA,EAAoB,YAAA;EACpB,+BAAA,EAAiC,yBAAA;AAAA;AAAA,KAGvB,aAAA,SAAsB,YAAA;;;;;UAMjB,SAAA;EACf,GAAA,WAAc,aAAA,EAAe,MAAA,EAAQ,CAAA,GAAI,OAAA,CAAQ,YAAA,CAAa,CAAA;AAAA;;;
|
|
1
|
+
{"version":3,"file":"server.d.ts","names":[],"sources":["../../src/mcp/ait-source.ts","../../src/mcp/server.ts"],"mappings":";;;;;;;AAsBA;;;;;AAGA;;;;;;;;;;;;;KAHY,kBAAA;AAqBZ;AAAA,UAlBiB,UAAA;;EAEf,MAAA;EAiBiB;EAfjB,IAAA;EAwBsB;EAtBtB,SAAA;EAsByB;EApBzB,MAAA;EAuBe;EArBf,MAAA;;EAEA,KAAA;EAuBU;EArBV,QAAA,EAAU,kBAAA;AAAA;;UAIK,iBAAA;EACf,KAAA,EAAO,UAAA;AAAA;;;;;;;KASG,YAAA,GAAe,MAAA;;UAGV,yBAAA;EAW2C;EAT1D,WAAA;EAYuB;EAVvB,UAAA;AAAA;;UAIe,YAAA;EACf,uBAAA,EAAyB,iBAAA;EACzB,kBAAA,EAAoB,YAAA;EACpB,+BAAA,EAAiC,yBAAA;AAAA;AAAA,KAGvB,aAAA,SAAsB,YAAA;;;;;UAMjB,SAAA;EACf,GAAA,WAAc,aAAA,EAAe,MAAA,EAAQ,CAAA,GAAI,OAAA,CAAQ,YAAA,CAAa,CAAA;AAAA;;;UCmB/C,mBAAA;EDhCY;ECkC3B,SAAA,GAAY,SAAA;AAAA;;iBAIE,eAAA,CAAgB,IAAA,GAAM,mBAAA,GAA2B,MAAA;;iBAsD3C,YAAA,CAAA,GAAgB,OAAA"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -38,6 +38,22 @@ var HttpAitSource = class {
|
|
|
38
38
|
}
|
|
39
39
|
};
|
|
40
40
|
//#endregion
|
|
41
|
+
//#region src/mcp/errors.ts
|
|
42
|
+
/**
|
|
43
|
+
* 한국어 한 줄 "원인 + 다음 행동" 포맷으로 에러 결과를 빌드한다.
|
|
44
|
+
*
|
|
45
|
+
* @param message - 사용자에게 보여줄 에러 본문 (원인 + 다음 행동 포함).
|
|
46
|
+
*/
|
|
47
|
+
function mcpError(message) {
|
|
48
|
+
return {
|
|
49
|
+
content: [{
|
|
50
|
+
type: "text",
|
|
51
|
+
text: message
|
|
52
|
+
}],
|
|
53
|
+
isError: true
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
41
57
|
//#region src/mcp/sdk-signatures.ts
|
|
42
58
|
function isObject(v) {
|
|
43
59
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
@@ -183,7 +199,8 @@ new Set([
|
|
|
183
199
|
type: "object",
|
|
184
200
|
properties: {},
|
|
185
201
|
required: []
|
|
186
|
-
}
|
|
202
|
+
},
|
|
203
|
+
availableIn: "both"
|
|
187
204
|
},
|
|
188
205
|
{
|
|
189
206
|
name: "list_network_requests",
|
|
@@ -192,16 +209,18 @@ new Set([
|
|
|
192
209
|
type: "object",
|
|
193
210
|
properties: {},
|
|
194
211
|
required: []
|
|
195
|
-
}
|
|
212
|
+
},
|
|
213
|
+
availableIn: "both"
|
|
196
214
|
},
|
|
197
215
|
{
|
|
198
216
|
name: "list_pages",
|
|
199
|
-
description: "Returns the single active page (at most one) the relay sees attached. When a second page attaches, the previous one is evicted (last-attach wins — single-attach model). The result includes `singleAttachModel: true` so the agent knows the array is always 0 or 1 entries. Also returns whether the cloudflared tunnel is up and the public wss relay URL. Each page entry includes a `lastSeenAt` ISO timestamp (last inbound CDP message from that target — useful to detect stale entries when the phone app backgrounded). The result also includes `crashDetectedAt` (ISO timestamp or null): when non-null, a page crash was detected via Inspector.targetCrashed / Target.targetDestroyed since the last attach, the pages list will be empty, and `crashWarning` shows a Korean hint to re-attach. Call this first to confirm a page is attached before reading console/network.",
|
|
217
|
+
description: "Returns the single active page (at most one) the relay sees attached. When a second page attaches, the previous one is evicted (last-attach wins — single-attach model). The result includes `singleAttachModel: true` so the agent knows the array is always 0 or 1 entries. Also returns whether the cloudflared tunnel is up and the public wss relay URL. The `tunnel` field includes `droppedAt` (ISO timestamp or null/undefined): when non-null the tunnel has permanently dropped after 3 failed reissue attempts — restart the debug server with `npx @ait-co/devtools devtools-mcp`. Each page entry includes a `lastSeenAt` ISO timestamp (last inbound CDP message from that target — useful to detect stale entries when the phone app backgrounded). The result also includes `crashDetectedAt` (ISO timestamp or null): when non-null, a page crash was detected via Inspector.targetCrashed / Target.targetDestroyed since the last attach, the pages list will be empty, and `crashWarning` shows a Korean hint to re-attach. Call this first to confirm a page is attached before reading console/network.",
|
|
200
218
|
inputSchema: {
|
|
201
219
|
type: "object",
|
|
202
220
|
properties: {},
|
|
203
221
|
required: []
|
|
204
|
-
}
|
|
222
|
+
},
|
|
223
|
+
availableIn: "both"
|
|
205
224
|
},
|
|
206
225
|
{
|
|
207
226
|
name: "build_attach_url",
|
|
@@ -223,7 +242,8 @@ new Set([
|
|
|
223
242
|
}
|
|
224
243
|
},
|
|
225
244
|
required: ["scheme_url"]
|
|
226
|
-
}
|
|
245
|
+
},
|
|
246
|
+
availableIn: "relay"
|
|
227
247
|
},
|
|
228
248
|
{
|
|
229
249
|
name: "get_dom_document",
|
|
@@ -232,7 +252,8 @@ new Set([
|
|
|
232
252
|
type: "object",
|
|
233
253
|
properties: {},
|
|
234
254
|
required: []
|
|
235
|
-
}
|
|
255
|
+
},
|
|
256
|
+
availableIn: "both"
|
|
236
257
|
},
|
|
237
258
|
{
|
|
238
259
|
name: "take_snapshot",
|
|
@@ -241,7 +262,8 @@ new Set([
|
|
|
241
262
|
type: "object",
|
|
242
263
|
properties: {},
|
|
243
264
|
required: []
|
|
244
|
-
}
|
|
265
|
+
},
|
|
266
|
+
availableIn: "both"
|
|
245
267
|
},
|
|
246
268
|
{
|
|
247
269
|
name: "take_screenshot",
|
|
@@ -250,16 +272,18 @@ new Set([
|
|
|
250
272
|
type: "object",
|
|
251
273
|
properties: {},
|
|
252
274
|
required: []
|
|
253
|
-
}
|
|
275
|
+
},
|
|
276
|
+
availableIn: "both"
|
|
254
277
|
},
|
|
255
278
|
{
|
|
256
279
|
name: "measure_safe_area",
|
|
257
|
-
description: "Runs a safe-area probe on the attached mini-app page via Runtime.evaluate and returns normalized safe-area insets, viewport geometry, device pixel ratio, and User-Agent. Read-only — does not modify page state. Use in a relay session (phone attached) to get ground-truth values for upgrading a viewport preset from extrapolated/placeholder to measured. Requires
|
|
280
|
+
description: "Runs a safe-area probe on the attached mini-app page via Runtime.evaluate and returns normalized safe-area insets, viewport geometry, device pixel ratio, and User-Agent. Read-only — does not modify page state. Tier C per RFC #277: the same Runtime.evaluate probe runs in both `mock` (devtools panel page with window.__ait state) and `relay` (real-device WebView with window.__sdk). The result includes a `source: \"mock\" | \"relay\"` field so consumers can identify provenance without inspecting payload values. Use in a relay session (phone attached) to get ground-truth values for upgrading a viewport preset from extrapolated/placeholder to measured. Requires a page to be attached — call list_pages first.",
|
|
258
281
|
inputSchema: {
|
|
259
282
|
type: "object",
|
|
260
283
|
properties: {},
|
|
261
284
|
required: []
|
|
262
|
-
}
|
|
285
|
+
},
|
|
286
|
+
availableIn: "both"
|
|
263
287
|
},
|
|
264
288
|
{
|
|
265
289
|
name: "evaluate",
|
|
@@ -271,7 +295,8 @@ new Set([
|
|
|
271
295
|
description: "JavaScript expression to evaluate in the page context."
|
|
272
296
|
} },
|
|
273
297
|
required: ["expression"]
|
|
274
|
-
}
|
|
298
|
+
},
|
|
299
|
+
availableIn: "both"
|
|
275
300
|
},
|
|
276
301
|
{
|
|
277
302
|
name: "list_exceptions",
|
|
@@ -283,7 +308,8 @@ new Set([
|
|
|
283
308
|
description: "Maximum number of exceptions to return (default 50, max 50)."
|
|
284
309
|
} },
|
|
285
310
|
required: []
|
|
286
|
-
}
|
|
311
|
+
},
|
|
312
|
+
availableIn: "both"
|
|
287
313
|
},
|
|
288
314
|
{
|
|
289
315
|
name: "call_sdk",
|
|
@@ -302,7 +328,8 @@ new Set([
|
|
|
302
328
|
}
|
|
303
329
|
},
|
|
304
330
|
required: ["name"]
|
|
305
|
-
}
|
|
331
|
+
},
|
|
332
|
+
availableIn: "both"
|
|
306
333
|
},
|
|
307
334
|
{
|
|
308
335
|
name: "AIT.getSdkCallHistory",
|
|
@@ -311,7 +338,8 @@ new Set([
|
|
|
311
338
|
type: "object",
|
|
312
339
|
properties: {},
|
|
313
340
|
required: []
|
|
314
|
-
}
|
|
341
|
+
},
|
|
342
|
+
availableIn: "both"
|
|
315
343
|
},
|
|
316
344
|
{
|
|
317
345
|
name: "AIT.getMockState",
|
|
@@ -320,7 +348,8 @@ new Set([
|
|
|
320
348
|
type: "object",
|
|
321
349
|
properties: {},
|
|
322
350
|
required: []
|
|
323
|
-
}
|
|
351
|
+
},
|
|
352
|
+
availableIn: "both"
|
|
324
353
|
},
|
|
325
354
|
{
|
|
326
355
|
name: "AIT.getOperationalEnvironment",
|
|
@@ -329,7 +358,21 @@ new Set([
|
|
|
329
358
|
type: "object",
|
|
330
359
|
properties: {},
|
|
331
360
|
required: []
|
|
332
|
-
}
|
|
361
|
+
},
|
|
362
|
+
availableIn: "both"
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
name: "get_diagnostics",
|
|
366
|
+
description: "Returns a single-call server status snapshot so the agent can diagnose \"why is this not working?\" without calling multiple tools. Fields: mcpVersion (MCP SDK version), devtoolsVersion (@ait-co/devtools package version), tunnel (up/wssUrl/pid/startedAt), pages (list_pages result + lastSeenAt stats), lastAttachAt, lastDetachAt, recentErrors (last N server-side errors, PII/secret redacted), environment (getEnvironment() result + reason), serverLockHolder (pid + startedAt from the lock file, or null). All fields are nullable — missing data is null, not an error. Tier C (both mock and relay). Call this first when debugging session state.",
|
|
367
|
+
inputSchema: {
|
|
368
|
+
type: "object",
|
|
369
|
+
properties: { recent_errors_limit: {
|
|
370
|
+
type: "number",
|
|
371
|
+
description: "Maximum number of recent server-side errors to include (default 10, max 50)."
|
|
372
|
+
} },
|
|
373
|
+
required: []
|
|
374
|
+
},
|
|
375
|
+
availableIn: "both"
|
|
333
376
|
}
|
|
334
377
|
].map((t) => t.name));
|
|
335
378
|
`
|
|
@@ -350,17 +393,28 @@ new Set([
|
|
|
350
393
|
};
|
|
351
394
|
document.documentElement.removeChild(el);
|
|
352
395
|
var sdkInsets = null;
|
|
396
|
+
var sdkInsetsSource = null;
|
|
353
397
|
var sdkInsetsError = undefined;
|
|
354
398
|
try {
|
|
355
399
|
var sdk = window.__sdk;
|
|
400
|
+
var ait = window.__ait;
|
|
356
401
|
if (sdk && sdk.SafeAreaInsets && typeof sdk.SafeAreaInsets.get === 'function') {
|
|
357
402
|
sdkInsets = sdk.SafeAreaInsets.get();
|
|
403
|
+
sdkInsetsSource = 'window.__sdk';
|
|
358
404
|
} else if (sdk && typeof sdk.getSafeAreaInsets === 'function') {
|
|
359
405
|
sdkInsets = sdk.getSafeAreaInsets();
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
406
|
+
sdkInsetsSource = 'window.__sdk';
|
|
407
|
+
} else if (ait && ait.state && ait.state.safeAreaInsets &&
|
|
408
|
+
typeof ait.state.safeAreaInsets.top === 'number') {
|
|
409
|
+
var s = ait.state.safeAreaInsets;
|
|
410
|
+
sdkInsets = { top: s.top, bottom: s.bottom, left: s.left, right: s.right };
|
|
411
|
+
sdkInsetsSource = 'window.__ait';
|
|
412
|
+
} else if (!sdk && !ait) {
|
|
413
|
+
sdkInsetsError = 'neither window.__sdk (relay) nor window.__ait (mock) available';
|
|
414
|
+
} else if (sdk) {
|
|
363
415
|
sdkInsetsError = 'neither SafeAreaInsets.get nor getSafeAreaInsets found on window.__sdk';
|
|
416
|
+
} else {
|
|
417
|
+
sdkInsetsError = 'window.__ait.state.safeAreaInsets is missing or malformed';
|
|
364
418
|
}
|
|
365
419
|
} catch(e) {
|
|
366
420
|
sdkInsetsError = String(e && e.message || e);
|
|
@@ -377,6 +431,7 @@ new Set([
|
|
|
377
431
|
var result = {
|
|
378
432
|
cssEnv: cssEnv,
|
|
379
433
|
sdkInsets: sdkInsets,
|
|
434
|
+
sdkInsetsSource: sdkInsetsSource,
|
|
380
435
|
navBarHeight: navBarHeight,
|
|
381
436
|
navBarHeightSource: navBarHeightSource,
|
|
382
437
|
innerWidth: window.innerWidth,
|
|
@@ -447,7 +502,13 @@ function getOperationalEnvironment(source) {
|
|
|
447
502
|
* }
|
|
448
503
|
* }
|
|
449
504
|
*/
|
|
450
|
-
/**
|
|
505
|
+
/**
|
|
506
|
+
* Tool descriptors served by the dev-mode server.
|
|
507
|
+
*
|
|
508
|
+
* All dev-mode tools are Tier C (both envs) per RFC #277 — the dev-mode server
|
|
509
|
+
* itself is the mock-side embodiment of those Tier C tools. `availableIn` is
|
|
510
|
+
* declared so the surface stays consistent with the debug-mode registry.
|
|
511
|
+
*/
|
|
451
512
|
const DEV_TOOL_DEFINITIONS = [
|
|
452
513
|
{
|
|
453
514
|
name: "AIT.getMockState",
|
|
@@ -456,7 +517,8 @@ const DEV_TOOL_DEFINITIONS = [
|
|
|
456
517
|
type: "object",
|
|
457
518
|
properties: {},
|
|
458
519
|
required: []
|
|
459
|
-
}
|
|
520
|
+
},
|
|
521
|
+
availableIn: "both"
|
|
460
522
|
},
|
|
461
523
|
{
|
|
462
524
|
name: "AIT.getOperationalEnvironment",
|
|
@@ -465,7 +527,8 @@ const DEV_TOOL_DEFINITIONS = [
|
|
|
465
527
|
type: "object",
|
|
466
528
|
properties: {},
|
|
467
529
|
required: []
|
|
468
|
-
}
|
|
530
|
+
},
|
|
531
|
+
availableIn: "both"
|
|
469
532
|
},
|
|
470
533
|
{
|
|
471
534
|
name: "AIT.getSdkCallHistory",
|
|
@@ -474,7 +537,8 @@ const DEV_TOOL_DEFINITIONS = [
|
|
|
474
537
|
type: "object",
|
|
475
538
|
properties: {},
|
|
476
539
|
required: []
|
|
477
|
-
}
|
|
540
|
+
},
|
|
541
|
+
availableIn: "both"
|
|
478
542
|
},
|
|
479
543
|
{
|
|
480
544
|
name: "devtools_get_mock_state",
|
|
@@ -483,7 +547,8 @@ const DEV_TOOL_DEFINITIONS = [
|
|
|
483
547
|
type: "object",
|
|
484
548
|
properties: {},
|
|
485
549
|
required: []
|
|
486
|
-
}
|
|
550
|
+
},
|
|
551
|
+
availableIn: "both"
|
|
487
552
|
}
|
|
488
553
|
];
|
|
489
554
|
const DEV_TOOL_NAMES = new Set(DEV_TOOL_DEFINITIONS.map((t) => t.name));
|
|
@@ -493,47 +558,23 @@ function createDevServer(deps = {}) {
|
|
|
493
558
|
const aitSource = deps.aitSource ?? new HttpAitSource({ stateEndpoint });
|
|
494
559
|
const server = new Server({
|
|
495
560
|
name: "ait-devtools",
|
|
496
|
-
version: "0.1.
|
|
561
|
+
version: "0.1.44"
|
|
497
562
|
}, { capabilities: { tools: {} } });
|
|
498
563
|
server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: DEV_TOOL_DEFINITIONS.map((tool) => ({ ...tool })) }));
|
|
499
564
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
500
565
|
const name = request.params.name;
|
|
501
|
-
if (!DEV_TOOL_NAMES.has(name)) return {
|
|
502
|
-
content: [{
|
|
503
|
-
type: "text",
|
|
504
|
-
text: `Unknown tool: ${name}`
|
|
505
|
-
}],
|
|
506
|
-
isError: true
|
|
507
|
-
};
|
|
566
|
+
if (!DEV_TOOL_NAMES.has(name)) return mcpError(`알 수 없는 tool: ${name}`);
|
|
508
567
|
try {
|
|
509
568
|
const effective = name === "devtools_get_mock_state" ? "AIT.getMockState" : name;
|
|
510
|
-
if (!isAitToolName(effective)) return {
|
|
511
|
-
content: [{
|
|
512
|
-
type: "text",
|
|
513
|
-
text: `Unknown tool: ${name}`
|
|
514
|
-
}],
|
|
515
|
-
isError: true
|
|
516
|
-
};
|
|
569
|
+
if (!isAitToolName(effective)) return mcpError(`알 수 없는 tool: ${name}`);
|
|
517
570
|
switch (effective) {
|
|
518
571
|
case "AIT.getMockState": return jsonResult(await getMockState(aitSource));
|
|
519
572
|
case "AIT.getOperationalEnvironment": return jsonResult(await getOperationalEnvironment(aitSource));
|
|
520
573
|
case "AIT.getSdkCallHistory": return jsonResult(await getSdkCallHistory(aitSource));
|
|
521
|
-
default: return {
|
|
522
|
-
content: [{
|
|
523
|
-
type: "text",
|
|
524
|
-
text: `Unknown tool: ${name}`
|
|
525
|
-
}],
|
|
526
|
-
isError: true
|
|
527
|
-
};
|
|
574
|
+
default: return mcpError(`알 수 없는 tool: ${name}`);
|
|
528
575
|
}
|
|
529
576
|
} catch (err) {
|
|
530
|
-
return {
|
|
531
|
-
content: [{
|
|
532
|
-
type: "text",
|
|
533
|
-
text: `${err instanceof Error ? err.message : String(err)}\nIs the Vite dev server running with the @ait-co/devtools unplugin option \`mcp: true\`? Is AIT_DEVTOOLS_URL set correctly?`
|
|
534
|
-
}],
|
|
535
|
-
isError: true
|
|
536
|
-
};
|
|
577
|
+
return mcpError(`${name} 실패: ${err instanceof Error ? err.message : String(err)}\nVite dev 서버가 @ait-co/devtools unplugin \`mcp: true\` 옵션으로 실행 중인지 확인하세요. AIT_DEVTOOLS_URL 환경변수가 올바르게 설정됐는지도 확인하세요.`);
|
|
537
578
|
}
|
|
538
579
|
});
|
|
539
580
|
return server;
|