@ait-co/devtools 0.1.27 → 0.1.28
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 +4 -4
- package/README.md +6 -6
- package/dist/in-app/index.d.ts +37 -28
- package/dist/in-app/index.d.ts.map +1 -1
- package/dist/in-app/index.js +27 -20
- package/dist/in-app/index.js.map +1 -1
- package/dist/mcp/cli.js +2 -2
- package/dist/mcp/server.js +1 -1
- package/dist/panel/index.js +2 -2
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -840,7 +840,7 @@ Both modes expose the same `AIT.*` tool surface — debug mode backed by the Chi
|
|
|
840
840
|
|
|
841
841
|
### Debug mode (CDP via Chii)
|
|
842
842
|
|
|
843
|
-
|
|
843
|
+
Read-only tools only. The phone attach roundtrip is fully wired; all that remains is a single on-device acceptance run. The tool layer is CI-verified via a mockable injectable CDP connection / AIT source.
|
|
844
844
|
|
|
845
845
|
Running `devtools-mcp` as a stdio server starts a local Chii relay on `:9100` and opens a cloudflared quick tunnel, printing a public `wss://*.trycloudflare.com` URL, a QR code, and a secret token in the terminal. When the phone enters the dogfood entry point, the in-app attach UI connects to the relay with that URL and token, and the agent reads console/network/page state via `chrome-devtools-mcp`-compatible tools — diagnosing regressions without anyone watching the phone.
|
|
846
846
|
|
|
@@ -868,11 +868,11 @@ Running `devtools-mcp` as a stdio server starts a local Chii relay on `:9100` an
|
|
|
868
868
|
| `AIT.getMockState` | AIT domain | Mock state snapshot (`window.__ait`) |
|
|
869
869
|
| `AIT.getOperationalEnvironment` | AIT domain | `getOperationalEnvironment()` + SDK version |
|
|
870
870
|
|
|
871
|
-
`AIT.*` covers what raw CDP cannot; the same MCP server forwards it alongside CDP. In debug mode the in-app side answers over the Chii channel
|
|
871
|
+
`AIT.*` covers what raw CDP cannot; the same MCP server forwards it alongside CDP. In debug mode the in-app side answers over the Chii channel.
|
|
872
872
|
|
|
873
873
|
### Dev mode (mock state)
|
|
874
874
|
|
|
875
|
-
`devtools-mcp --mode=dev` reads the mock state from a running browser.
|
|
875
|
+
`devtools-mcp --mode=dev` reads the mock state from a running browser. It shares the same `AIT.*` tool surface as debug mode.
|
|
876
876
|
|
|
877
877
|
#### Architecture
|
|
878
878
|
|
|
@@ -940,7 +940,7 @@ Returns the full current mock state (permissions, location, auth, network, IAP,
|
|
|
940
940
|
| `@ait-co/devtools/unplugin` | Bundler plugin (.vite, .webpack, .rspack, .esbuild, .rollup) |
|
|
941
941
|
| `@ait-co/devtools/mcp/server` | Dev-mode MCP stdio server function (Node.js) |
|
|
942
942
|
| `@ait-co/devtools/mcp/cli` | `devtools-mcp` bin entry point (debug / dev mode, Node.js) |
|
|
943
|
-
| `@ait-co/devtools/in-app` | In-app debug attach —
|
|
943
|
+
| `@ait-co/devtools/in-app` | In-app debug attach — runtime gate (layers B/C) + Chii target.js injection. The consumer wraps the import in `if (__DEBUG_BUILD__)` so it is DCE'd from release builds — dogfood builds only |
|
|
944
944
|
|
|
945
945
|
## Telemetry
|
|
946
946
|
|
package/README.md
CHANGED
|
@@ -843,8 +843,8 @@ tool을 봅니다.
|
|
|
843
843
|
|
|
844
844
|
### Debug 모드 (CDP via Chii)
|
|
845
845
|
|
|
846
|
-
|
|
847
|
-
|
|
846
|
+
read-only tool만 노출합니다. 폰 attach 라운드트립은 fully wired 상태이며 남은 것은 실기기 acceptance
|
|
847
|
+
한 번뿐입니다. tool 계층은 주입 가능한 CDP 연결 / AIT 소스를 mock해 CI에서 검증됩니다.
|
|
848
848
|
|
|
849
849
|
`devtools-mcp`를 stdio로 실행하면 로컬 Chii 릴레이(:9100)를 띄우고 cloudflared quick tunnel로
|
|
850
850
|
공개 `wss://*.trycloudflare.com` URL을 발급한 뒤 QR + secret token을 터미널에 출력합니다.
|
|
@@ -877,12 +877,12 @@ tool을 봅니다.
|
|
|
877
877
|
| `AIT.getOperationalEnvironment` | AIT 도메인 | `getOperationalEnvironment()` + SDK 버전 |
|
|
878
878
|
|
|
879
879
|
`AIT.*`는 raw CDP가 못 잡는 영역으로, 같은 MCP server가 CDP와 함께 forward합니다. debug 모드에서는
|
|
880
|
-
in-app 측이 Chii 채널로
|
|
880
|
+
in-app 측이 Chii 채널로 응답합니다.
|
|
881
881
|
|
|
882
882
|
### Dev 모드 (mock state)
|
|
883
883
|
|
|
884
|
-
`devtools-mcp --mode=dev`는 실행 중인 브라우저의 mock state를 읽습니다.
|
|
885
|
-
|
|
884
|
+
`devtools-mcp --mode=dev`는 실행 중인 브라우저의 mock state를 읽습니다. debug 모드와 같은 `AIT.*`
|
|
885
|
+
tool surface를 공유합니다.
|
|
886
886
|
|
|
887
887
|
#### 구조
|
|
888
888
|
|
|
@@ -950,7 +950,7 @@ export default {
|
|
|
950
950
|
| `@ait-co/devtools/unplugin` | 번들러 플러그인 (.vite, .webpack, .rspack, .esbuild, .rollup) |
|
|
951
951
|
| `@ait-co/devtools/mcp/server` | dev-mode MCP stdio server 함수 (Node.js) |
|
|
952
952
|
| `@ait-co/devtools/mcp/cli` | `devtools-mcp` bin 진입점 (debug / dev 모드, Node.js) |
|
|
953
|
-
| `@ait-co/devtools/in-app` | In-app debug attach —
|
|
953
|
+
| `@ait-co/devtools/in-app` | In-app debug attach — 런타임 gate(layer B·C) + Chii target.js 주입. 소비자가 `if (__DEBUG_BUILD__)`로 import를 감싸 release 빌드에서 DCE — dogfood 빌드 전용 |
|
|
954
954
|
|
|
955
955
|
## 텔레메트리
|
|
956
956
|
|
package/dist/in-app/index.d.ts
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
//#region src/in-app/gate.d.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Runtime activation gate for the in-app debug surface.
|
|
4
4
|
*
|
|
5
5
|
* Spec: docs/superpowers/specs/2026-05-18-in-app-debug-mcp.md
|
|
6
6
|
* "3-layer activation gate". This is the pure gate decision; the Chii client,
|
|
7
7
|
* WebSocket transport, MCP server, and CLI that consume it live in src/mcp/.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* This function evaluates the two RUNTIME layers, B and C. Layer A — the
|
|
10
|
+
* build-time gate — is NOT evaluated here, and deliberately so: it is enforced
|
|
11
|
+
* entirely by the consumer's `if (__DEBUG_BUILD__) { … }` guard around the
|
|
12
|
+
* import site (see sdk-example `src/main.tsx`). `__DEBUG_BUILD__` is a
|
|
13
|
+
* consumer-build-time constant; a release consumer build folds it to `false`
|
|
14
|
+
* and dead-code-eliminates the whole import of `@ait-co/devtools/in-app`, so
|
|
15
|
+
* this code is simply absent from release bundles. A pre-built npm package
|
|
16
|
+
* cannot re-check that flag — it was already baked at devtools' own publish
|
|
17
|
+
* time — so any `isDebugBuild` check inside this function would be permanently
|
|
18
|
+
* `false` and could never pass. Layer A is the consumer guard; B and C are
|
|
19
|
+
* here.
|
|
10
20
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
21
|
+
* Decision matrix (the gate only ever runs in a debug build — Layer A already
|
|
22
|
+
* passed by the time this code is reachable):
|
|
23
|
+
*
|
|
24
|
+
* _deploymentId | debug=1 | result
|
|
25
|
+
* absent | (any) | BLOCKED (Layer B — entry gate)
|
|
26
|
+
* present | absent | BLOCKED (Layer C — opt-in gate)
|
|
27
|
+
* present | present | ATTACH
|
|
16
28
|
*/
|
|
17
29
|
/** Shape returned when the gate allows attachment. */
|
|
18
30
|
interface GateResultAttach {
|
|
@@ -26,30 +38,23 @@ interface GateResultAttach {
|
|
|
26
38
|
interface GateResultBlocked {
|
|
27
39
|
readonly attach: false;
|
|
28
40
|
/**
|
|
29
|
-
* - `'build'` Layer A: `__DEBUG_BUILD__` is false (release build).
|
|
30
41
|
* - `'entry'` Layer B: `_deploymentId` param is absent or empty.
|
|
31
42
|
* - `'opt-in'` Layer C: `debug=1` param is absent.
|
|
32
43
|
* - `'invalid-relay'` Layer C: `relay` param is absent, empty, or not a `wss:` URL.
|
|
44
|
+
*
|
|
45
|
+
* There is no `'build'` reason: Layer A is enforced by the consumer's
|
|
46
|
+
* `if (__DEBUG_BUILD__)` guard, not by this function.
|
|
33
47
|
*/
|
|
34
|
-
readonly reason: '
|
|
48
|
+
readonly reason: 'entry' | 'opt-in' | 'invalid-relay';
|
|
35
49
|
}
|
|
36
50
|
type GateResult = GateResultAttach | GateResultBlocked;
|
|
37
51
|
/**
|
|
38
52
|
* Input for {@link evaluateDebugGate}.
|
|
39
53
|
*
|
|
40
|
-
* Keeping
|
|
54
|
+
* Keeping the field explicit makes the function trivially testable without
|
|
41
55
|
* needing to manipulate `window.location`.
|
|
42
56
|
*/
|
|
43
57
|
interface GateInput {
|
|
44
|
-
/**
|
|
45
|
-
* Whether this is a debug build. Corresponds to the `__DEBUG_BUILD__`
|
|
46
|
-
* compile-time constant injected by tsdown.
|
|
47
|
-
*
|
|
48
|
-
* In source code consumed via `@ait-co/devtools/in-app`, the thin
|
|
49
|
-
* `src/in-app/index.ts` entry reads `__DEBUG_BUILD__` and passes it here.
|
|
50
|
-
* Tests supply it directly.
|
|
51
|
-
*/
|
|
52
|
-
readonly isDebugBuild: boolean;
|
|
53
58
|
/**
|
|
54
59
|
* The URL search params to inspect for gate signals.
|
|
55
60
|
*
|
|
@@ -66,15 +71,18 @@ interface GateInput {
|
|
|
66
71
|
readonly searchParams: URLSearchParams;
|
|
67
72
|
}
|
|
68
73
|
/**
|
|
69
|
-
* Pure function that evaluates the
|
|
74
|
+
* Pure function that evaluates the runtime debug activation layers (B and C).
|
|
70
75
|
*
|
|
71
|
-
* Has no side effects.
|
|
76
|
+
* Has no side effects. The input is explicit. Returns a discriminated union
|
|
72
77
|
* so callers can pattern-match on `result.attach`.
|
|
73
78
|
*
|
|
79
|
+
* Layer A (build-time) is intentionally not evaluated here — see the file-level
|
|
80
|
+
* comment. By the time this function runs, the consumer's `if (__DEBUG_BUILD__)`
|
|
81
|
+
* guard has already passed; this function only decides B and C.
|
|
82
|
+
*
|
|
74
83
|
* @example
|
|
75
84
|
* ```ts
|
|
76
85
|
* const result = evaluateDebugGate({
|
|
77
|
-
* isDebugBuild: __DEBUG_BUILD__,
|
|
78
86
|
* searchParams: new URLSearchParams(window.location.search),
|
|
79
87
|
* });
|
|
80
88
|
* if (result.attach) {
|
|
@@ -114,21 +122,22 @@ declare function deriveTargetScriptUrl(relayUrl: string): string;
|
|
|
114
122
|
* guard — in practice this always runs in a real WebView).
|
|
115
123
|
*
|
|
116
124
|
* @param gateResult - Optional pre-evaluated gate result for testability.
|
|
117
|
-
* Defaults to `checkDebugGate()` which reads the current page URL
|
|
118
|
-
*
|
|
119
|
-
* the need to manipulate `window.location` in tests.
|
|
125
|
+
* Defaults to `checkDebugGate()` which reads the current page URL. Passing a
|
|
126
|
+
* custom value avoids the need to manipulate `window.location` in tests.
|
|
120
127
|
*/
|
|
121
128
|
declare function maybeAttach(gateResult?: GateResult): void;
|
|
122
129
|
//#endregion
|
|
123
130
|
//#region src/in-app/index.d.ts
|
|
124
131
|
/**
|
|
125
|
-
* Evaluates the
|
|
132
|
+
* Evaluates the runtime debug activation layers (B and C) against the current
|
|
133
|
+
* page URL.
|
|
126
134
|
*
|
|
127
135
|
* Returns the gate result. Callers can check `result.attach` to decide whether
|
|
128
136
|
* to proceed with debug surface attachment.
|
|
129
137
|
*
|
|
130
|
-
* This function reads `window.location`
|
|
131
|
-
*
|
|
138
|
+
* This function reads `window.location` only. Layer A (build-time) is enforced
|
|
139
|
+
* by the consumer's `if (__DEBUG_BUILD__)` guard around the import site, not
|
|
140
|
+
* here — see the file-level comment.
|
|
132
141
|
*/
|
|
133
142
|
declare function checkDebugGate(): GateResult;
|
|
134
143
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/in-app/gate.ts","../../src/in-app/attach.ts","../../src/in-app/index.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/in-app/gate.ts","../../src/in-app/attach.ts","../../src/in-app/index.ts"],"mappings":";;AA6BA;;;;;;;;;AASA;;;;;AAaA;;;;;AAQA;;;;;AAqCA;;;UAnEiB,gBAAA;EAAA,SACN,MAAA;EAkEuB;EAAA,SAhEvB,QAAA;EAgEoD;EAAA,SA9DpD,YAAA;AAAA;;UAIM,iBAAA;EAAA,SACN,MAAA;ECV0B;;;;AA4BrC;;;;EA5BqC,SDmB1B,MAAA;AAAA;AAAA,KAGC,UAAA,GAAa,gBAAA,GAAmB,iBAAA;;AEV5C;;;;;UFkBiB,SAAA;;;;;;;;;;;;;;WAcN,YAAA,EAAc,eAAA;AAAA;;;;;;;;;;;;;;;;;;;;;iBAuBT,iBAAA,CAAkB,KAAA,EAAO,SAAA,GAAY,UAAA;;;;;;AA7CrD;;;;;AAQA;;;;;AAqCA;;iBCnEgB,qBAAA,CAAsB,QAAA;;;;;;;;;;AAAtC;;;;;AA4BA;;iBAAgB,WAAA,CAAY,UAAA,GAAY,UAAA;;;;;;;;;;;;;AA5BxC;iBCYgB,cAAA,CAAA,GAAkB,UAAA"}
|
package/dist/in-app/index.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
//#region src/in-app/gate.ts
|
|
2
2
|
/**
|
|
3
|
-
* Pure function that evaluates the
|
|
3
|
+
* Pure function that evaluates the runtime debug activation layers (B and C).
|
|
4
4
|
*
|
|
5
|
-
* Has no side effects.
|
|
5
|
+
* Has no side effects. The input is explicit. Returns a discriminated union
|
|
6
6
|
* so callers can pattern-match on `result.attach`.
|
|
7
7
|
*
|
|
8
|
+
* Layer A (build-time) is intentionally not evaluated here — see the file-level
|
|
9
|
+
* comment. By the time this function runs, the consumer's `if (__DEBUG_BUILD__)`
|
|
10
|
+
* guard has already passed; this function only decides B and C.
|
|
11
|
+
*
|
|
8
12
|
* @example
|
|
9
13
|
* ```ts
|
|
10
14
|
* const result = evaluateDebugGate({
|
|
11
|
-
* isDebugBuild: __DEBUG_BUILD__,
|
|
12
15
|
* searchParams: new URLSearchParams(window.location.search),
|
|
13
16
|
* });
|
|
14
17
|
* if (result.attach) {
|
|
@@ -17,10 +20,6 @@
|
|
|
17
20
|
* ```
|
|
18
21
|
*/
|
|
19
22
|
function evaluateDebugGate(input) {
|
|
20
|
-
if (!input.isDebugBuild) return {
|
|
21
|
-
attach: false,
|
|
22
|
-
reason: "build"
|
|
23
|
-
};
|
|
24
23
|
const deploymentId = input.searchParams.get("_deploymentId") ?? "";
|
|
25
24
|
if (deploymentId === "") return {
|
|
26
25
|
attach: false,
|
|
@@ -105,9 +104,8 @@ let attached = false;
|
|
|
105
104
|
* guard — in practice this always runs in a real WebView).
|
|
106
105
|
*
|
|
107
106
|
* @param gateResult - Optional pre-evaluated gate result for testability.
|
|
108
|
-
* Defaults to `checkDebugGate()` which reads the current page URL
|
|
109
|
-
*
|
|
110
|
-
* the need to manipulate `window.location` in tests.
|
|
107
|
+
* Defaults to `checkDebugGate()` which reads the current page URL. Passing a
|
|
108
|
+
* custom value avoids the need to manipulate `window.location` in tests.
|
|
111
109
|
*/
|
|
112
110
|
function maybeAttach(gateResult = checkDebugGate()) {
|
|
113
111
|
if (!gateResult.attach) {
|
|
@@ -138,24 +136,33 @@ function maybeAttach(gateResult = checkDebugGate()) {
|
|
|
138
136
|
* WebSocket relay, QR/paste UI, and AI-host MCP bin are later phases that
|
|
139
137
|
* require real-device validation and are not included here.
|
|
140
138
|
*
|
|
141
|
-
* This thin entry reads `
|
|
142
|
-
*
|
|
143
|
-
*
|
|
139
|
+
* This thin entry reads `window.location` and calls the pure
|
|
140
|
+
* {@link evaluateDebugGate} function. All testable logic lives in `./gate.ts`
|
|
141
|
+
* and `./attach.ts`, not here.
|
|
142
|
+
*
|
|
143
|
+
* Layer A of the activation gate (build-time) is NOT enforced in this module.
|
|
144
|
+
* It is the consumer's responsibility: the consumer wraps its
|
|
145
|
+
* `import('@ait-co/devtools/in-app')` call site in `if (__DEBUG_BUILD__) { … }`
|
|
146
|
+
* (see sdk-example `src/main.tsx`), where `__DEBUG_BUILD__` is a
|
|
147
|
+
* consumer-build-time constant. A release consumer build folds that constant
|
|
148
|
+
* to `false` and dead-code-eliminates this whole module. This package is
|
|
149
|
+
* pre-built and ships with `__DEBUG_BUILD__` already resolved at devtools'
|
|
150
|
+
* publish time, so it could never re-evaluate the consumer's build channel —
|
|
151
|
+
* which is exactly why Layer A lives at the consumer guard, not here.
|
|
144
152
|
*/
|
|
145
153
|
/**
|
|
146
|
-
* Evaluates the
|
|
154
|
+
* Evaluates the runtime debug activation layers (B and C) against the current
|
|
155
|
+
* page URL.
|
|
147
156
|
*
|
|
148
157
|
* Returns the gate result. Callers can check `result.attach` to decide whether
|
|
149
158
|
* to proceed with debug surface attachment.
|
|
150
159
|
*
|
|
151
|
-
* This function reads `window.location`
|
|
152
|
-
*
|
|
160
|
+
* This function reads `window.location` only. Layer A (build-time) is enforced
|
|
161
|
+
* by the consumer's `if (__DEBUG_BUILD__)` guard around the import site, not
|
|
162
|
+
* here — see the file-level comment.
|
|
153
163
|
*/
|
|
154
164
|
function checkDebugGate() {
|
|
155
|
-
return evaluateDebugGate({
|
|
156
|
-
isDebugBuild: false,
|
|
157
|
-
searchParams: new URLSearchParams(window.location.search)
|
|
158
|
-
});
|
|
165
|
+
return evaluateDebugGate({ searchParams: new URLSearchParams(window.location.search) });
|
|
159
166
|
}
|
|
160
167
|
//#endregion
|
|
161
168
|
export { checkDebugGate, deriveTargetScriptUrl, evaluateDebugGate, maybeAttach };
|
package/dist/in-app/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/in-app/gate.ts","../../src/in-app/attach.ts","../../src/in-app/index.ts"],"sourcesContent":["/**\n * 3-layer activation gate for the in-app debug surface.\n *\n * Spec: docs/superpowers/specs/2026-05-18-in-app-debug-mcp.md\n * \"3-layer activation gate\". This is the pure gate decision; the Chii client,\n * WebSocket transport, MCP server, and CLI that consume it live in src/mcp/.\n *\n * Decision matrix:\n *\n * build channel | _deploymentId | debug=1 | result\n * release | (any) | (any) | BLOCKED (Layer A — code absent via DCE)\n * dogfood | absent | (any) | BLOCKED (Layer B — entry gate)\n * dogfood | present | absent | BLOCKED (Layer C — opt-in gate)\n * dogfood | present | present | ATTACH\n */\n\n/** Shape returned when the gate allows attachment. */\nexport interface GateResultAttach {\n readonly attach: true;\n /** The validated `wss:` relay URL from the `relay` query param. */\n readonly relayUrl: string;\n /** The deployment ID extracted from the `_deploymentId` query param. */\n readonly deploymentId: string;\n}\n\n/** Shape returned when the gate blocks attachment, with a reason code. */\nexport interface GateResultBlocked {\n readonly attach: false;\n /**\n * - `'build'` Layer A: `__DEBUG_BUILD__` is false (release build).\n * - `'entry'` Layer B: `_deploymentId` param is absent or empty.\n * - `'opt-in'` Layer C: `debug=1` param is absent.\n * - `'invalid-relay'` Layer C: `relay` param is absent, empty, or not a `wss:` URL.\n */\n readonly reason: 'build' | 'entry' | 'opt-in' | 'invalid-relay';\n}\n\nexport type GateResult = GateResultAttach | GateResultBlocked;\n\n/**\n * Input for {@link evaluateDebugGate}.\n *\n * Keeping each field explicit makes the function trivially testable without\n * needing to manipulate `window.location`.\n */\nexport interface GateInput {\n /**\n * Whether this is a debug build. Corresponds to the `__DEBUG_BUILD__`\n * compile-time constant injected by tsdown.\n *\n * In source code consumed via `@ait-co/devtools/in-app`, the thin\n * `src/in-app/index.ts` entry reads `__DEBUG_BUILD__` and passes it here.\n * Tests supply it directly.\n */\n readonly isDebugBuild: boolean;\n\n /**\n * The URL search params to inspect for gate signals.\n *\n * Prefer `URLSearchParams` so callers can pass `new URLSearchParams(location.search)`\n * without coupling the pure function to `window`.\n *\n * Layer B open seam (spec open question 2): if the Toss SDK ever exposes\n * `getEntryScheme()` or a similar API that reliably signals a dogfood entry,\n * that signal should be checked before `_deploymentId` here. For now only the\n * `_deploymentId` query param fallback is implemented. Pass a custom\n * `URLSearchParams` to inject the SDK signal at the call site without\n * modifying this function.\n */\n readonly searchParams: URLSearchParams;\n}\n\n/**\n * Pure function that evaluates the 3-layer debug activation gate.\n *\n * Has no side effects. All inputs are explicit. Returns a discriminated union\n * so callers can pattern-match on `result.attach`.\n *\n * @example\n * ```ts\n * const result = evaluateDebugGate({\n * isDebugBuild: __DEBUG_BUILD__,\n * searchParams: new URLSearchParams(window.location.search),\n * });\n * if (result.attach) {\n * // Proceed to load Chii client\n * }\n * ```\n */\nexport function evaluateDebugGate(input: GateInput): GateResult {\n // Layer A — build-time gate.\n // When false, the entire in-app entry + Chii imports are dead-code-eliminated\n // by the bundler (tsdown/Rolldown constant folding). Release builds never\n // contain this branch at all.\n if (!input.isDebugBuild) {\n return { attach: false, reason: 'build' };\n }\n\n // Layer B — runtime entry scheme gate.\n // `_deploymentId` must be present and non-empty. The `intoss-private://`\n // scheme used for dogfood entries includes this param; general user entry\n // paths do not.\n //\n // Open seam (spec open question 2): if the Toss SDK exposes getEntryScheme()\n // or similar, that should be the 1st-priority signal checked here, with\n // `_deploymentId` as fallback. Extend this check at the call site by\n // pre-populating `searchParams` with the SDK signal, or add an optional\n // `entryScheme` field to `GateInput` in a later phase.\n const deploymentId = input.searchParams.get('_deploymentId') ?? '';\n if (deploymentId === '') {\n return { attach: false, reason: 'entry' };\n }\n\n // Layer C — explicit opt-in gate.\n // Require `debug=1` so that an operator who opens a dogfood URL by accident\n // does not inadvertently trigger the debug surface.\n const debugParam = input.searchParams.get('debug');\n if (debugParam !== '1') {\n return { attach: false, reason: 'opt-in' };\n }\n\n // Layer C continued — relay URL validation.\n // `relay=<wss-url>` must be present and must use the `wss:` scheme.\n // Plain `ws:` is rejected (no TLS). `http:`/`https:` are rejected.\n const relayRaw = input.searchParams.get('relay') ?? '';\n if (relayRaw === '') {\n return { attach: false, reason: 'invalid-relay' };\n }\n\n let relayUrl: URL;\n try {\n relayUrl = new URL(relayRaw);\n } catch {\n return { attach: false, reason: 'invalid-relay' };\n }\n\n if (relayUrl.protocol !== 'wss:') {\n return { attach: false, reason: 'invalid-relay' };\n }\n\n return { attach: true, relayUrl: relayUrl.href, deploymentId };\n}\n","/**\n * In-app Chii target injection for the debug attach flow.\n *\n * Spec: docs/superpowers/specs/2026-05-18-in-app-debug-mcp.md\n * \"MCP attach\" topology section — Phase 1 browser-side implementation.\n *\n * This module bridges the 3-layer gate result to a Chii `target.js` script\n * injection. The Chii npm package is the relay SERVER — the in-app side is\n * a plain `<script src=\"…/target.js\">` pointing at the relay host. No chii\n * npm dependency is needed here.\n */\n\nimport { checkDebugGate, type GateResult } from './index.js';\n\n/**\n * Converts a validated `wss:` relay URL into the Chii `target.js` script URL.\n *\n * Scheme is mapped `wss:` → `https:`. Host and port are preserved.\n * Pathname is set to `/target.js` regardless of the relay path.\n * Query params and hash from the relay URL are dropped — the target script\n * URL is a static asset path on the same host.\n *\n * @example\n * deriveTargetScriptUrl('wss://abc.trycloudflare.com/relay')\n * // → 'https://abc.trycloudflare.com/target.js'\n *\n * deriveTargetScriptUrl('wss://h.example.com:9100/')\n * // → 'https://h.example.com:9100/target.js'\n */\nexport function deriveTargetScriptUrl(relayUrl: string): string {\n const u = new URL(relayUrl);\n u.protocol = 'https:';\n u.pathname = '/target.js';\n u.search = '';\n u.hash = '';\n return u.toString();\n}\n\n/** Module-level guard against double-injection within a page lifecycle. */\nlet attached = false;\n\n/**\n * Evaluates the 3-layer debug gate and, if the gate passes, injects the Chii\n * `target.js` script into `document.head`.\n *\n * Idempotent — calling more than once is safe. The second call is a no-op if\n * a script with the same `src` is already present in the document, and the\n * module-level `attached` flag prevents redundant DOM queries after the first\n * successful injection.\n *\n * Safe to call even if `document` is somehow unavailable (defensive boundary\n * guard — in practice this always runs in a real WebView).\n *\n * @param gateResult - Optional pre-evaluated gate result for testability.\n * Defaults to `checkDebugGate()` which reads the current page URL and the\n * `__DEBUG_BUILD__` compile-time constant. Passing a custom value avoids\n * the need to manipulate `window.location` in tests.\n */\nexport function maybeAttach(gateResult: GateResult = checkDebugGate()): void {\n if (!gateResult.attach) {\n console.debug(\n `[@ait-co/devtools] debug attach skipped — gate blocked (reason: ${gateResult.reason})`,\n );\n return;\n }\n\n // Guard against double-injection across repeated calls.\n if (attached) {\n return;\n }\n\n // Defensive: if document is not available (unusual, but possible in some\n // SSR-adjacent edge cases), bail silently rather than throwing.\n if (typeof document === 'undefined') {\n return;\n }\n\n const src = deriveTargetScriptUrl(gateResult.relayUrl);\n\n // Also guard against a script with the same src already in the DOM\n // (e.g. injected by a different code path or a page reload within SPA).\n const existing = document.querySelector<HTMLScriptElement>(`script[src=\"${src}\"]`);\n if (existing !== null) {\n attached = true;\n return;\n }\n\n const script = document.createElement('script');\n script.src = src;\n script.async = true;\n (document.head ?? document.documentElement).appendChild(script);\n\n attached = true;\n}\n","/**\n * @ait-co/devtools/in-app entry point.\n *\n * Spec: docs/superpowers/specs/2026-05-18-in-app-debug-mcp.md\n *\n * Phase 1 — gate + browser-side Chii target injection.\n * WebSocket relay, QR/paste UI, and AI-host MCP bin are later phases that\n * require real-device validation and are not included here.\n *\n * This thin entry reads `__DEBUG_BUILD__` and `window.location`, then calls\n * the pure {@link evaluateDebugGate} function. All testable logic lives in\n * `./gate.ts` and `./attach.ts`, not here.\n */\n\nimport { evaluateDebugGate, type GateResult } from './gate.js';\n\nexport { deriveTargetScriptUrl, maybeAttach } from './attach.js';\nexport type { GateInput, GateResult, GateResultAttach, GateResultBlocked } from './gate.js';\nexport { evaluateDebugGate } from './gate.js';\n\n/**\n * Evaluates the 3-layer debug activation gate against the current page URL.\n *\n * Returns the gate result. Callers can check `result.attach` to decide whether\n * to proceed with debug surface attachment.\n *\n * This function reads `window.location` and the `__DEBUG_BUILD__` compile-time\n * constant. It has no other side effects.\n */\nexport function checkDebugGate(): GateResult {\n return evaluateDebugGate({\n isDebugBuild: __DEBUG_BUILD__,\n searchParams: new URLSearchParams(window.location.search),\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyFA,SAAgB,kBAAkB,OAA8B;AAK9D,KAAI,CAAC,MAAM,aACT,QAAO;EAAE,QAAQ;EAAO,QAAQ;EAAS;CAa3C,MAAM,eAAe,MAAM,aAAa,IAAI,gBAAgB,IAAI;AAChE,KAAI,iBAAiB,GACnB,QAAO;EAAE,QAAQ;EAAO,QAAQ;EAAS;AAO3C,KADmB,MAAM,aAAa,IAAI,QAAQ,KAC/B,IACjB,QAAO;EAAE,QAAQ;EAAO,QAAQ;EAAU;CAM5C,MAAM,WAAW,MAAM,aAAa,IAAI,QAAQ,IAAI;AACpD,KAAI,aAAa,GACf,QAAO;EAAE,QAAQ;EAAO,QAAQ;EAAiB;CAGnD,IAAI;AACJ,KAAI;AACF,aAAW,IAAI,IAAI,SAAS;SACtB;AACN,SAAO;GAAE,QAAQ;GAAO,QAAQ;GAAiB;;AAGnD,KAAI,SAAS,aAAa,OACxB,QAAO;EAAE,QAAQ;EAAO,QAAQ;EAAiB;AAGnD,QAAO;EAAE,QAAQ;EAAM,UAAU,SAAS;EAAM;EAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/GhE,SAAgB,sBAAsB,UAA0B;CAC9D,MAAM,IAAI,IAAI,IAAI,SAAS;AAC3B,GAAE,WAAW;AACb,GAAE,WAAW;AACb,GAAE,SAAS;AACX,GAAE,OAAO;AACT,QAAO,EAAE,UAAU;;;AAIrB,IAAI,WAAW;;;;;;;;;;;;;;;;;;AAmBf,SAAgB,YAAY,aAAyB,gBAAgB,EAAQ;AAC3E,KAAI,CAAC,WAAW,QAAQ;AACtB,UAAQ,MACN,mEAAmE,WAAW,OAAO,GACtF;AACD;;AAIF,KAAI,SACF;AAKF,KAAI,OAAO,aAAa,YACtB;CAGF,MAAM,MAAM,sBAAsB,WAAW,SAAS;AAKtD,KADiB,SAAS,cAAiC,eAAe,IAAI,IAAI,KACjE,MAAM;AACrB,aAAW;AACX;;CAGF,MAAM,SAAS,SAAS,cAAc,SAAS;AAC/C,QAAO,MAAM;AACb,QAAO,QAAQ;AACf,EAAC,SAAS,QAAQ,SAAS,iBAAiB,YAAY,OAAO;AAE/D,YAAW;;;;;;;;;;;;;;;;;;;;;;;;;;AC/Db,SAAgB,iBAA6B;AAC3C,QAAO,kBAAkB;EACvB,cAAA;EACA,cAAc,IAAI,gBAAgB,OAAO,SAAS,OAAO;EAC1D,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/in-app/gate.ts","../../src/in-app/attach.ts","../../src/in-app/index.ts"],"sourcesContent":["/**\n * Runtime activation gate for the in-app debug surface.\n *\n * Spec: docs/superpowers/specs/2026-05-18-in-app-debug-mcp.md\n * \"3-layer activation gate\". This is the pure gate decision; the Chii client,\n * WebSocket transport, MCP server, and CLI that consume it live in src/mcp/.\n *\n * This function evaluates the two RUNTIME layers, B and C. Layer A — the\n * build-time gate — is NOT evaluated here, and deliberately so: it is enforced\n * entirely by the consumer's `if (__DEBUG_BUILD__) { … }` guard around the\n * import site (see sdk-example `src/main.tsx`). `__DEBUG_BUILD__` is a\n * consumer-build-time constant; a release consumer build folds it to `false`\n * and dead-code-eliminates the whole import of `@ait-co/devtools/in-app`, so\n * this code is simply absent from release bundles. A pre-built npm package\n * cannot re-check that flag — it was already baked at devtools' own publish\n * time — so any `isDebugBuild` check inside this function would be permanently\n * `false` and could never pass. Layer A is the consumer guard; B and C are\n * here.\n *\n * Decision matrix (the gate only ever runs in a debug build — Layer A already\n * passed by the time this code is reachable):\n *\n * _deploymentId | debug=1 | result\n * absent | (any) | BLOCKED (Layer B — entry gate)\n * present | absent | BLOCKED (Layer C — opt-in gate)\n * present | present | ATTACH\n */\n\n/** Shape returned when the gate allows attachment. */\nexport interface GateResultAttach {\n readonly attach: true;\n /** The validated `wss:` relay URL from the `relay` query param. */\n readonly relayUrl: string;\n /** The deployment ID extracted from the `_deploymentId` query param. */\n readonly deploymentId: string;\n}\n\n/** Shape returned when the gate blocks attachment, with a reason code. */\nexport interface GateResultBlocked {\n readonly attach: false;\n /**\n * - `'entry'` Layer B: `_deploymentId` param is absent or empty.\n * - `'opt-in'` Layer C: `debug=1` param is absent.\n * - `'invalid-relay'` Layer C: `relay` param is absent, empty, or not a `wss:` URL.\n *\n * There is no `'build'` reason: Layer A is enforced by the consumer's\n * `if (__DEBUG_BUILD__)` guard, not by this function.\n */\n readonly reason: 'entry' | 'opt-in' | 'invalid-relay';\n}\n\nexport type GateResult = GateResultAttach | GateResultBlocked;\n\n/**\n * Input for {@link evaluateDebugGate}.\n *\n * Keeping the field explicit makes the function trivially testable without\n * needing to manipulate `window.location`.\n */\nexport interface GateInput {\n /**\n * The URL search params to inspect for gate signals.\n *\n * Prefer `URLSearchParams` so callers can pass `new URLSearchParams(location.search)`\n * without coupling the pure function to `window`.\n *\n * Layer B open seam (spec open question 2): if the Toss SDK ever exposes\n * `getEntryScheme()` or a similar API that reliably signals a dogfood entry,\n * that signal should be checked before `_deploymentId` here. For now only the\n * `_deploymentId` query param fallback is implemented. Pass a custom\n * `URLSearchParams` to inject the SDK signal at the call site without\n * modifying this function.\n */\n readonly searchParams: URLSearchParams;\n}\n\n/**\n * Pure function that evaluates the runtime debug activation layers (B and C).\n *\n * Has no side effects. The input is explicit. Returns a discriminated union\n * so callers can pattern-match on `result.attach`.\n *\n * Layer A (build-time) is intentionally not evaluated here — see the file-level\n * comment. By the time this function runs, the consumer's `if (__DEBUG_BUILD__)`\n * guard has already passed; this function only decides B and C.\n *\n * @example\n * ```ts\n * const result = evaluateDebugGate({\n * searchParams: new URLSearchParams(window.location.search),\n * });\n * if (result.attach) {\n * // Proceed to load Chii client\n * }\n * ```\n */\nexport function evaluateDebugGate(input: GateInput): GateResult {\n // Layer B — runtime entry scheme gate.\n // `_deploymentId` must be present and non-empty. The `intoss-private://`\n // scheme used for dogfood entries includes this param; general user entry\n // paths do not.\n //\n // Open seam (spec open question 2): if the Toss SDK exposes getEntryScheme()\n // or similar, that should be the 1st-priority signal checked here, with\n // `_deploymentId` as fallback. Extend this check at the call site by\n // pre-populating `searchParams` with the SDK signal, or add an optional\n // `entryScheme` field to `GateInput` in a later phase.\n const deploymentId = input.searchParams.get('_deploymentId') ?? '';\n if (deploymentId === '') {\n return { attach: false, reason: 'entry' };\n }\n\n // Layer C — explicit opt-in gate.\n // Require `debug=1` so that an operator who opens a dogfood URL by accident\n // does not inadvertently trigger the debug surface.\n const debugParam = input.searchParams.get('debug');\n if (debugParam !== '1') {\n return { attach: false, reason: 'opt-in' };\n }\n\n // Layer C continued — relay URL validation.\n // `relay=<wss-url>` must be present and must use the `wss:` scheme.\n // Plain `ws:` is rejected (no TLS). `http:`/`https:` are rejected.\n const relayRaw = input.searchParams.get('relay') ?? '';\n if (relayRaw === '') {\n return { attach: false, reason: 'invalid-relay' };\n }\n\n let relayUrl: URL;\n try {\n relayUrl = new URL(relayRaw);\n } catch {\n return { attach: false, reason: 'invalid-relay' };\n }\n\n if (relayUrl.protocol !== 'wss:') {\n return { attach: false, reason: 'invalid-relay' };\n }\n\n return { attach: true, relayUrl: relayUrl.href, deploymentId };\n}\n","/**\n * In-app Chii target injection for the debug attach flow.\n *\n * Spec: docs/superpowers/specs/2026-05-18-in-app-debug-mcp.md\n * \"MCP attach\" topology section — Phase 1 browser-side implementation.\n *\n * This module bridges the 3-layer gate result to a Chii `target.js` script\n * injection. The Chii npm package is the relay SERVER — the in-app side is\n * a plain `<script src=\"…/target.js\">` pointing at the relay host. No chii\n * npm dependency is needed here.\n */\n\nimport { checkDebugGate, type GateResult } from './index.js';\n\n/**\n * Converts a validated `wss:` relay URL into the Chii `target.js` script URL.\n *\n * Scheme is mapped `wss:` → `https:`. Host and port are preserved.\n * Pathname is set to `/target.js` regardless of the relay path.\n * Query params and hash from the relay URL are dropped — the target script\n * URL is a static asset path on the same host.\n *\n * @example\n * deriveTargetScriptUrl('wss://abc.trycloudflare.com/relay')\n * // → 'https://abc.trycloudflare.com/target.js'\n *\n * deriveTargetScriptUrl('wss://h.example.com:9100/')\n * // → 'https://h.example.com:9100/target.js'\n */\nexport function deriveTargetScriptUrl(relayUrl: string): string {\n const u = new URL(relayUrl);\n u.protocol = 'https:';\n u.pathname = '/target.js';\n u.search = '';\n u.hash = '';\n return u.toString();\n}\n\n/** Module-level guard against double-injection within a page lifecycle. */\nlet attached = false;\n\n/**\n * Evaluates the 3-layer debug gate and, if the gate passes, injects the Chii\n * `target.js` script into `document.head`.\n *\n * Idempotent — calling more than once is safe. The second call is a no-op if\n * a script with the same `src` is already present in the document, and the\n * module-level `attached` flag prevents redundant DOM queries after the first\n * successful injection.\n *\n * Safe to call even if `document` is somehow unavailable (defensive boundary\n * guard — in practice this always runs in a real WebView).\n *\n * @param gateResult - Optional pre-evaluated gate result for testability.\n * Defaults to `checkDebugGate()` which reads the current page URL. Passing a\n * custom value avoids the need to manipulate `window.location` in tests.\n */\nexport function maybeAttach(gateResult: GateResult = checkDebugGate()): void {\n if (!gateResult.attach) {\n console.debug(\n `[@ait-co/devtools] debug attach skipped — gate blocked (reason: ${gateResult.reason})`,\n );\n return;\n }\n\n // Guard against double-injection across repeated calls.\n if (attached) {\n return;\n }\n\n // Defensive: if document is not available (unusual, but possible in some\n // SSR-adjacent edge cases), bail silently rather than throwing.\n if (typeof document === 'undefined') {\n return;\n }\n\n const src = deriveTargetScriptUrl(gateResult.relayUrl);\n\n // Also guard against a script with the same src already in the DOM\n // (e.g. injected by a different code path or a page reload within SPA).\n const existing = document.querySelector<HTMLScriptElement>(`script[src=\"${src}\"]`);\n if (existing !== null) {\n attached = true;\n return;\n }\n\n const script = document.createElement('script');\n script.src = src;\n script.async = true;\n (document.head ?? document.documentElement).appendChild(script);\n\n attached = true;\n}\n","/**\n * @ait-co/devtools/in-app entry point.\n *\n * Spec: docs/superpowers/specs/2026-05-18-in-app-debug-mcp.md\n *\n * Phase 1 — gate + browser-side Chii target injection.\n * WebSocket relay, QR/paste UI, and AI-host MCP bin are later phases that\n * require real-device validation and are not included here.\n *\n * This thin entry reads `window.location` and calls the pure\n * {@link evaluateDebugGate} function. All testable logic lives in `./gate.ts`\n * and `./attach.ts`, not here.\n *\n * Layer A of the activation gate (build-time) is NOT enforced in this module.\n * It is the consumer's responsibility: the consumer wraps its\n * `import('@ait-co/devtools/in-app')` call site in `if (__DEBUG_BUILD__) { … }`\n * (see sdk-example `src/main.tsx`), where `__DEBUG_BUILD__` is a\n * consumer-build-time constant. A release consumer build folds that constant\n * to `false` and dead-code-eliminates this whole module. This package is\n * pre-built and ships with `__DEBUG_BUILD__` already resolved at devtools'\n * publish time, so it could never re-evaluate the consumer's build channel —\n * which is exactly why Layer A lives at the consumer guard, not here.\n */\n\nimport { evaluateDebugGate, type GateResult } from './gate.js';\n\nexport { deriveTargetScriptUrl, maybeAttach } from './attach.js';\nexport type { GateInput, GateResult, GateResultAttach, GateResultBlocked } from './gate.js';\nexport { evaluateDebugGate } from './gate.js';\n\n/**\n * Evaluates the runtime debug activation layers (B and C) against the current\n * page URL.\n *\n * Returns the gate result. Callers can check `result.attach` to decide whether\n * to proceed with debug surface attachment.\n *\n * This function reads `window.location` only. Layer A (build-time) is enforced\n * by the consumer's `if (__DEBUG_BUILD__)` guard around the import site, not\n * here — see the file-level comment.\n */\nexport function checkDebugGate(): GateResult {\n return evaluateDebugGate({\n searchParams: new URLSearchParams(window.location.search),\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAgGA,SAAgB,kBAAkB,OAA8B;CAW9D,MAAM,eAAe,MAAM,aAAa,IAAI,gBAAgB,IAAI;AAChE,KAAI,iBAAiB,GACnB,QAAO;EAAE,QAAQ;EAAO,QAAQ;EAAS;AAO3C,KADmB,MAAM,aAAa,IAAI,QAAQ,KAC/B,IACjB,QAAO;EAAE,QAAQ;EAAO,QAAQ;EAAU;CAM5C,MAAM,WAAW,MAAM,aAAa,IAAI,QAAQ,IAAI;AACpD,KAAI,aAAa,GACf,QAAO;EAAE,QAAQ;EAAO,QAAQ;EAAiB;CAGnD,IAAI;AACJ,KAAI;AACF,aAAW,IAAI,IAAI,SAAS;SACtB;AACN,SAAO;GAAE,QAAQ;GAAO,QAAQ;GAAiB;;AAGnD,KAAI,SAAS,aAAa,OACxB,QAAO;EAAE,QAAQ;EAAO,QAAQ;EAAiB;AAGnD,QAAO;EAAE,QAAQ;EAAM,UAAU,SAAS;EAAM;EAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9GhE,SAAgB,sBAAsB,UAA0B;CAC9D,MAAM,IAAI,IAAI,IAAI,SAAS;AAC3B,GAAE,WAAW;AACb,GAAE,WAAW;AACb,GAAE,SAAS;AACX,GAAE,OAAO;AACT,QAAO,EAAE,UAAU;;;AAIrB,IAAI,WAAW;;;;;;;;;;;;;;;;;AAkBf,SAAgB,YAAY,aAAyB,gBAAgB,EAAQ;AAC3E,KAAI,CAAC,WAAW,QAAQ;AACtB,UAAQ,MACN,mEAAmE,WAAW,OAAO,GACtF;AACD;;AAIF,KAAI,SACF;AAKF,KAAI,OAAO,aAAa,YACtB;CAGF,MAAM,MAAM,sBAAsB,WAAW,SAAS;AAKtD,KADiB,SAAS,cAAiC,eAAe,IAAI,IAAI,KACjE,MAAM;AACrB,aAAW;AACX;;CAGF,MAAM,SAAS,SAAS,cAAc,SAAS;AAC/C,QAAO,MAAM;AACb,QAAO,QAAQ;AACf,EAAC,SAAS,QAAQ,SAAS,iBAAiB,YAAY,OAAO;AAE/D,YAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClDb,SAAgB,iBAA6B;AAC3C,QAAO,kBAAkB,EACvB,cAAc,IAAI,gBAAgB,OAAO,SAAS,OAAO,EAC1D,CAAC"}
|
package/dist/mcp/cli.js
CHANGED
|
@@ -636,7 +636,7 @@ function createDebugServer(deps) {
|
|
|
636
636
|
const { connection, aitSource, getTunnelStatus } = deps;
|
|
637
637
|
const server = new Server({
|
|
638
638
|
name: "ait-debug",
|
|
639
|
-
version: "0.1.
|
|
639
|
+
version: "0.1.28"
|
|
640
640
|
}, { capabilities: { tools: {} } });
|
|
641
641
|
server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: DEBUG_TOOL_DEFINITIONS.map((tool) => ({ ...tool })) }));
|
|
642
642
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
@@ -898,7 +898,7 @@ function createDevServer(deps = {}) {
|
|
|
898
898
|
const aitSource = deps.aitSource ?? new HttpAitSource({ stateEndpoint });
|
|
899
899
|
const server = new Server({
|
|
900
900
|
name: "ait-devtools",
|
|
901
|
-
version: "0.1.
|
|
901
|
+
version: "0.1.28"
|
|
902
902
|
}, { capabilities: { tools: {} } });
|
|
903
903
|
server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: DEV_TOOL_DEFINITIONS.map((tool) => ({ ...tool })) }));
|
|
904
904
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
package/dist/mcp/server.js
CHANGED
|
@@ -234,7 +234,7 @@ function createDevServer(deps = {}) {
|
|
|
234
234
|
const aitSource = deps.aitSource ?? new HttpAitSource({ stateEndpoint });
|
|
235
235
|
const server = new Server({
|
|
236
236
|
name: "ait-devtools",
|
|
237
|
-
version: "0.1.
|
|
237
|
+
version: "0.1.28"
|
|
238
238
|
}, { capabilities: { tools: {} } });
|
|
239
239
|
server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: DEV_TOOL_DEFINITIONS.map((tool) => ({ ...tool })) }));
|
|
240
240
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
package/dist/panel/index.js
CHANGED
|
@@ -1050,7 +1050,7 @@ function readGlobalString(key) {
|
|
|
1050
1050
|
}
|
|
1051
1051
|
const TELEMETRY_ENDPOINT = readGlobalString("__TELEMETRY_ENDPOINT__") ?? "https://t.aitc.dev";
|
|
1052
1052
|
function getVersion() {
|
|
1053
|
-
return "0.1.
|
|
1053
|
+
return "0.1.28";
|
|
1054
1054
|
}
|
|
1055
1055
|
let panelVisibleSince = null;
|
|
1056
1056
|
let accumulatedMs = 0;
|
|
@@ -4182,7 +4182,7 @@ function mount() {
|
|
|
4182
4182
|
mockBadge.textContent = aitState.state.panelEditable ? t("panel.editMode.on") : t("panel.editMode.off");
|
|
4183
4183
|
refreshPanel();
|
|
4184
4184
|
});
|
|
4185
|
-
const headerRight = h("span", { style: "display:flex;align-items:center;gap:6px" }, mockBadge, h("span", { style: "font-size:11px;color:#666;font-weight:400" }, `v0.1.
|
|
4185
|
+
const headerRight = h("span", { style: "display:flex;align-items:center;gap:6px" }, mockBadge, h("span", { style: "font-size:11px;color:#666;font-weight:400" }, `v0.1.28`), closeBtn);
|
|
4186
4186
|
const header = h("div", { className: "ait-panel-header" }, h("span", {}, t("panel.title")), headerRight);
|
|
4187
4187
|
tabsEl = h("div", { className: "ait-panel-tabs" });
|
|
4188
4188
|
for (const tab of getTabs()) {
|
package/package.json
CHANGED