isthmus-cli 0.5.0 → 0.7.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.ko.md +170 -45
- package/README.md +178 -36
- package/Skills/isthmus/SKILL.md +104 -5
- package/compatibility.json +10 -0
- package/dist/cli/check-command.d.ts +2 -2
- package/dist/cli/check-command.js +22 -9
- package/dist/cli/check-command.js.map +1 -1
- package/dist/cli/command-support.d.ts +20 -2
- package/dist/cli/command-support.js +38 -9
- package/dist/cli/command-support.js.map +1 -1
- package/dist/cli/diff-command.js +4 -3
- package/dist/cli/diff-command.js.map +1 -1
- package/dist/cli/doctor-command.d.ts +11 -0
- package/dist/cli/doctor-command.js +128 -0
- package/dist/cli/doctor-command.js.map +1 -0
- package/dist/cli/extract-js-command.d.ts +33 -0
- package/dist/cli/extract-js-command.js +233 -0
- package/dist/cli/extract-js-command.js.map +1 -0
- package/dist/cli/graph-command.js +13 -6
- package/dist/cli/graph-command.js.map +1 -1
- package/dist/cli/impact-command.d.ts +5 -0
- package/dist/cli/impact-command.js +111 -0
- package/dist/cli/impact-command.js.map +1 -0
- package/dist/cli/init-command.d.ts +11 -0
- package/dist/cli/init-command.js +115 -0
- package/dist/cli/init-command.js.map +1 -0
- package/dist/cli/main.js +67 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/mcp-server.d.ts +16 -0
- package/dist/cli/mcp-server.js +534 -0
- package/dist/cli/mcp-server.js.map +1 -0
- package/dist/cli/preflight-command.d.ts +5 -0
- package/dist/cli/preflight-command.js +83 -0
- package/dist/cli/preflight-command.js.map +1 -0
- package/dist/cli/query-command.js +13 -6
- package/dist/cli/query-command.js.map +1 -1
- package/dist/cli/retentions-command.js +14 -7
- package/dist/cli/retentions-command.js.map +1 -1
- package/dist/cli/runtime-command.d.ts +5 -0
- package/dist/cli/runtime-command.js +42 -0
- package/dist/cli/runtime-command.js.map +1 -0
- package/dist/cli/runtime-json-reader.d.ts +12 -0
- package/dist/cli/runtime-json-reader.js +37 -0
- package/dist/cli/runtime-json-reader.js.map +1 -0
- package/dist/cli/serve-command.d.ts +13 -0
- package/dist/cli/serve-command.js +43 -0
- package/dist/cli/serve-command.js.map +1 -0
- package/dist/exchange/capture-config.d.ts +18 -0
- package/dist/exchange/capture-config.js +100 -0
- package/dist/exchange/capture-config.js.map +1 -0
- package/dist/exchange/impact-selection.d.ts +13 -0
- package/dist/exchange/impact-selection.js +35 -0
- package/dist/exchange/impact-selection.js.map +1 -0
- package/dist/exchange/kartograph-impact.d.ts +4 -0
- package/dist/exchange/kartograph-impact.js +169 -0
- package/dist/exchange/kartograph-impact.js.map +1 -0
- package/dist/exchange/messages.d.ts +36 -0
- package/dist/exchange/messages.js +96 -0
- package/dist/exchange/messages.js.map +1 -0
- package/dist/exchange/parse.d.ts +69 -0
- package/dist/exchange/parse.js +127 -20
- package/dist/exchange/parse.js.map +1 -1
- package/dist/exchange/preflight-context.d.ts +71 -0
- package/dist/exchange/preflight-context.js +317 -0
- package/dist/exchange/preflight-context.js.map +1 -0
- package/dist/exchange/producer-impact.d.ts +17 -0
- package/dist/exchange/producer-impact.js +226 -0
- package/dist/exchange/producer-impact.js.map +1 -0
- package/dist/exchange/runtime.d.ts +69 -0
- package/dist/exchange/runtime.js +160 -0
- package/dist/exchange/runtime.js.map +1 -0
- package/dist/extract/js-document.d.ts +22 -0
- package/dist/extract/js-document.js +230 -0
- package/dist/extract/js-document.js.map +1 -0
- package/dist/extract/js-scan.d.ts +93 -0
- package/dist/extract/js-scan.js +1205 -0
- package/dist/extract/js-scan.js.map +1 -0
- package/dist/extract/lexer.d.ts +26 -0
- package/dist/extract/lexer.js +316 -0
- package/dist/extract/lexer.js.map +1 -0
- package/dist/join/join.d.ts +66 -1
- package/dist/join/join.js +171 -1
- package/dist/join/join.js.map +1 -1
- package/dist/join/message-address.d.ts +7 -0
- package/dist/join/message-address.js +37 -0
- package/dist/join/message-address.js.map +1 -0
- package/dist/join/messages.d.ts +26 -0
- package/dist/join/messages.js +87 -0
- package/dist/join/messages.js.map +1 -0
- package/dist/report/check-report.d.ts +20 -3
- package/dist/report/check-report.js +240 -8
- package/dist/report/check-report.js.map +1 -1
- package/dist/report/codequality.d.ts +45 -0
- package/dist/report/codequality.js +74 -0
- package/dist/report/codequality.js.map +1 -0
- package/dist/report/diff.d.ts +25 -3
- package/dist/report/diff.js +91 -10
- package/dist/report/diff.js.map +1 -1
- package/dist/report/graph.d.ts +10 -4
- package/dist/report/graph.js +60 -6
- package/dist/report/graph.js.map +1 -1
- package/dist/report/impact.d.ts +62 -0
- package/dist/report/impact.js +168 -0
- package/dist/report/impact.js.map +1 -0
- package/dist/report/preflight-runtime.d.ts +42 -0
- package/dist/report/preflight-runtime.js +193 -0
- package/dist/report/preflight-runtime.js.map +1 -0
- package/dist/report/preflight-view.d.ts +146 -0
- package/dist/report/preflight-view.js +216 -0
- package/dist/report/preflight-view.js.map +1 -0
- package/dist/report/preflight.d.ts +104 -0
- package/dist/report/preflight.js +331 -0
- package/dist/report/preflight.js.map +1 -0
- package/dist/report/query.d.ts +11 -4
- package/dist/report/query.js +84 -17
- package/dist/report/query.js.map +1 -1
- package/dist/report/retentions.d.ts +17 -5
- package/dist/report/retentions.js +85 -8
- package/dist/report/retentions.js.map +1 -1
- package/dist/report/rules.d.ts +16 -0
- package/dist/report/rules.js +30 -0
- package/dist/report/rules.js.map +1 -0
- package/dist/report/runtime-impact.d.ts +38 -0
- package/dist/report/runtime-impact.js +94 -0
- package/dist/report/runtime-impact.js.map +1 -0
- package/dist/report/runtime.d.ts +54 -0
- package/dist/report/runtime.js +137 -0
- package/dist/report/runtime.js.map +1 -0
- package/dist/report/sarif.d.ts +2 -8
- package/dist/report/sarif.js +2 -10
- package/dist/report/sarif.js.map +1 -1
- package/dist/report/sorted-json.d.ts +1 -1
- package/dist/report/sorted-json.js +2 -2
- package/dist/report/sorted-json.js.map +1 -1
- package/docs/BRIDGE-EVENTS.md +87 -0
- package/docs/BRIDGE-MESSAGES.md +117 -0
- package/docs/GRAPH-EXCHANGE.md +382 -0
- package/docs/IMPACT.md +96 -0
- package/docs/MCP.md +62 -0
- package/docs/PREFLIGHT.md +311 -0
- package/docs/RUNTIME.md +172 -0
- package/docs/TOOLCHAIN.md +101 -0
- package/package.json +14 -2
- package/scripts/build-preflight-toolchain.mjs +186 -0
- package/scripts/capture-preflight.mjs +380 -0
- package/scripts/run-child.mjs +17 -0
package/README.ko.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# isthmus
|
|
2
2
|
|
|
3
3
|
크로스플랫폼 앱에서 **언어 경계를 넘는 호출**을 그래프로 잇는 도구.
|
|
4
|
-
[cartograph](https://github.com/ictechgy/cartograph)(Swift) · kartograph(Kotlin
|
|
4
|
+
[cartograph](https://github.com/ictechgy/cartograph)(Swift) · [kartograph](https://github.com/ictechgy/kartograph)(Kotlin) ·
|
|
5
5
|
[dartograph](https://github.com/ictechgy/dartograph)(Dart)가 각자 그린 지도를 하나로 붙인다.
|
|
6
6
|
|
|
7
7
|
[English](README.md)
|
|
@@ -22,43 +22,61 @@ React Native나 Flutter 앱의 네이티브 코드는 JS/Dart가 **문자열 이
|
|
|
22
22
|
|
|
23
23
|
isthmus는 각 언어 도구가 내보낸 **브리지 사실**(채널 이름 · 메서드 이름 · 등록 지점 ·
|
|
24
24
|
호출 지점)을 문자열 키로 조인해서, 경계를 넘는 간선을 만들고 위 세 가지를 답한다.
|
|
25
|
-
그리고 그 결과를 cartograph
|
|
25
|
+
그리고 그 결과를 cartograph에 **보존 근거로 돌려준다** — "Swift
|
|
26
26
|
`CameraHandler.takePhoto`는 `lib/camera.dart:42`가 채널 `com.example/camera`로 부르므로
|
|
27
27
|
보존".
|
|
28
28
|
|
|
29
29
|
## 상태
|
|
30
30
|
|
|
31
|
-
**0.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
`
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
31
|
+
**0.6.0**은 Flutter Dart ↔ Swift/Kotlin 변경 사전 점검, MethodChannel·Pigeon/BasicMessageChannel
|
|
32
|
+
사실, 명시한 런타임 시나리오 대조와 내용 기반 수집 캐시를 지원한다. `impact
|
|
33
|
+
--file`/`--symbol`/`--changes`(정보 손실 없는 `--compact` JSON과 분석 공백도 실패시키는
|
|
34
|
+
`--strict` 포함), producer 전이 영향 경로를 다루는 `preflight <context.json>`의
|
|
35
|
+
`--summary`/`--explain`, `verify-runtime --expectations`가 추가됐다. 실제 macOS·Android
|
|
36
|
+
검증 앱에서 공개 플러그인 API를 실행했다. 설정과 측정 범위는 [사전 점검](docs/PREFLIGHT.md),
|
|
37
|
+
[런타임 검증](docs/RUNTIME.md), [고정 소스 구축](docs/TOOLCHAIN.md)을 참조한다.
|
|
38
|
+
|
|
39
|
+
npm 발행본은 **0.7.0**이다. 공개 호환 producer 세트는 cartograph **0.18.0**,
|
|
40
|
+
kartograph **0.10.2**, dartograph **0.14.0**이다 — 설치 명령·고정 예제·CI 예시는
|
|
41
|
+
[호환 버전](docs/COMPATIBILITY.md)을 참조한다. MethodChannel 조인과 보존 근거 왕복은
|
|
42
|
+
cartograph 0.5.3 이상·dartograph 0.1.1 이상부터 지원하며, 이전 공개 세트
|
|
43
|
+
(cartograph 0.15.1·dartograph 0.10.0·isthmus 0.6.0)로 왕복을 다시 확인했다.
|
|
44
|
+
React Native 모듈·컴포넌트 사실(`module-import`↔`module-export`,
|
|
45
|
+
`component-require`↔`component-export`)은 `react-native` target 안에서 이름으로
|
|
46
|
+
조인된다. 선택적 `mechanism` 필드가 core와 Expo 해석 경로를 구분한다. Expo의
|
|
47
|
+
`requireNativeModule` 계열 수입은 TurboModuleRegistry 폴백으로 core·Expo 양쪽
|
|
48
|
+
수출에 닿지만, `requireNativeViewManager`는 mechanism이 일치해야 한다. 같은 이름이
|
|
49
|
+
다른 mechanism으로만 관찰되면 상대편 부재 대신 `*-mechanism-mismatch` 경고로 보고된다.
|
|
50
|
+
부재를 허용하는 조회(`requireOptionalNativeModule`,
|
|
51
|
+
`TurboModuleRegistry.get`/`getNullable`)로 부른 수입은 `optional: true`를 싣고,
|
|
52
|
+
부재 모듈의 호출자가 전부 부재를 허용하면 error 대신
|
|
53
|
+
`module-import-without-export-optional` 경고가 나온다.
|
|
54
|
+
`isthmus extract-js`가 JS/TS 소스에서 호출 측 사실을 추출하고(`NativeModules.*`,
|
|
55
|
+
`TurboModuleRegistry.get*`, `requireNativeComponent`/`codegenNativeComponent`,
|
|
56
|
+
`requireNativeModule` 계열 호출, 해석된 멤버 호출), cartograph와 kartograph는
|
|
57
|
+
Expo Modules DSL(`Module`/`definition()`, `Name`, `Function`, `View`,
|
|
58
|
+
`@ExpoModule`/`@JS`)을 스캔해 그 수출에 `mechanism: "expo"`를 표시한다 —
|
|
59
|
+
`GRAPH-EXCHANGE.md`에 적힌 토큰 스캔 관찰 범위 안에서 end-to-end RN 조인이
|
|
60
|
+
재현된다. EventChannel v2 전송은 자매 저장소 전반에 구현됐고, `check`가 v2
|
|
61
|
+
Bridge·Event 문서를 직접 소비해 transport별 진단을 낸다.
|
|
62
|
+
보존 근거보내기는 현재 cartograph(Swift)를 대상으로 한다.
|
|
63
|
+
앱 전체 적용 범위와 최초 외부 사용자 구축은 아직 검증하지 않았다.
|
|
64
|
+
|
|
65
|
+
변경 예측은 고정된 공개 정밀도 코퍼스 — `battery_plus`·`shared_preferences_foundation`·
|
|
66
|
+
`url_launcher_macos`와 **LocalSend** 앱, 파일/심볼/버전 diff 15케이스 — 로 측정한다.
|
|
67
|
+
최근 실행은 **TP 83 / FN 0 / FP 0**을 기록했고, 최초의 앱 수준 Dart↔Swift↔Kotlin
|
|
68
|
+
3방향 조인을 포함한다([`experiments/real-corpus/`](experiments/real-corpus/)).
|
|
69
|
+
이 수치는 스텁 컴파일 Swift와 소스 스캔 Kotlin 위의 정적 브리지 경계이며,
|
|
70
|
+
런타임 실행·앱 전체 정밀도는 측정하지 않았다.
|
|
55
71
|
|
|
56
72
|
| 문서 | 내용 |
|
|
57
73
|
|---|---|
|
|
58
74
|
| [`docs/PRD.md`](docs/PRD.md) | 무엇을 · 누구를 위해 · 어디까지 |
|
|
59
75
|
| [`docs/PLAN.md`](docs/PLAN.md) | 단계별 계획. **cartograph와 dartograph에 선행 작업이 있다** |
|
|
60
76
|
| [`docs/GRAPH-EXCHANGE.md`](docs/GRAPH-EXCHANGE.md) | 자매 도구가 내보내는 브리지 사실의 형식. 자매 저장소들이 공유하는 계약 |
|
|
77
|
+
| [`docs/COMPATIBILITY.md`](docs/COMPATIBILITY.md) | 공개 호환 버전, 고정 예제, CI 설정 |
|
|
61
78
|
| [`docs/RESEARCH.md`](docs/RESEARCH.md) | 확인된 사실 · 확인되지 않은 주장 |
|
|
79
|
+
| [`experiments/real-corpus/`](experiments/real-corpus/) | 고정 공개 플러그인·앱 정밀도 코퍼스(TP/FN/FP 계수) |
|
|
62
80
|
| [`experiments/phase-0/`](experiments/phase-0/) | Dart·Swift 임시 추출기, 고정 JSON, 손 조인 검증 |
|
|
63
81
|
|
|
64
82
|
## 의존 관계
|
|
@@ -83,23 +101,60 @@ npm install --global isthmus-cli
|
|
|
83
101
|
isthmus --help
|
|
84
102
|
```
|
|
85
103
|
|
|
86
|
-
설치 없이 한 번 실행할 때는
|
|
104
|
+
설치 없이 한 번 실행할 때는 패키지 이름을 명시한다.
|
|
87
105
|
|
|
88
106
|
```bash
|
|
89
107
|
npx isthmus-cli --help
|
|
90
108
|
```
|
|
91
109
|
|
|
92
|
-
`npx isthmus`는 이름이 같은 다른
|
|
110
|
+
`npx isthmus`는 이름이 같은 다른 패키지를 설치하므로 사용하면 안 된다.
|
|
93
111
|
|
|
94
112
|
## 사용
|
|
95
113
|
|
|
96
|
-
|
|
114
|
+
`impact --file`·`--symbol`·`--changes` 사전 점검과 정보 손실 없는 `--compact`, 분석
|
|
115
|
+
공백도 실패시키는 `--strict`를 제공한다. 빌드·계약·현재 브리지 한정 범위는
|
|
116
|
+
[변경 사전 점검](docs/IMPACT.md)을 참조한다.
|
|
117
|
+
Android 개발 지원은 `selection.kotlin`과 kartograph snapshot을 사용한다. Kotlin Method/Basic
|
|
118
|
+
사실을 Dart 소비자에 연결하고 Android 실행은 Kotlin 후보에만 대조한다.
|
|
119
|
+
[Android 수집 설정](docs/PREFLIGHT.md#android-수집)과 [선택적 Kotlin 도구 구축](docs/TOOLCHAIN.md)을 참조한다.
|
|
120
|
+
`verify-runtime --expectations`는 revision·시나리오·플랫폼·엔진 인스턴스별
|
|
121
|
+
통신 기록을 대조한다([계약](docs/RUNTIME.md)). 선택적 [Flutter 수집기](packages/isthmus_runtime/README.md)는
|
|
122
|
+
실제 macOS·Android 앱에서 핸들러와 `url_launcher_macos 3.2.2`·
|
|
123
|
+
`shared_preferences_android 2.4.1`의 Pigeon 생성 API로 검증했다.
|
|
124
|
+
언어 내부 전이 영향 연결과 스냅샷 수집은 구현됐으며, 더 넓은 앱 적용 범위와
|
|
125
|
+
처음 설치하는 사용자의 재현 절차는 검증 중이다.
|
|
126
|
+
|
|
127
|
+
0.6.0의 `preflight <context.json> --strict --compact`는 producer의 전이 영향과
|
|
128
|
+
브리지를 연결한다. 별도 수집 workflow는 명시된 입력의 내용 해시로 캐시를 재사용하며,
|
|
129
|
+
실제 producer를 사용한 합성 소스 검증을 통과했다. 사용법·지원 경계·CI 설정은
|
|
130
|
+
[언어 간 변경 사전 점검](docs/PREFLIGHT.md)을 참조한다. 실제 앱 전체 검증은 남아 있다.
|
|
131
|
+
`isthmus init [capture.json]`은 그 capture 설정 scaffold를 쓰고(`--toolchain`을 주면
|
|
132
|
+
구축한 `toolchain.json`의 실제 producer 명령을 채운다), `isthmus doctor <capture.json>`은
|
|
133
|
+
설정을 검증하고 참조한 실행 파일이 `PATH`나 지정 경로에 있는지 확인만 한다 — 실행하지 않는다.
|
|
134
|
+
runtime JSON과 `--expectations <checks.json>`를 함께 주면 같은 revision의 실행과
|
|
135
|
+
전이 분석을 대조하고, 네이티브 후보·미관찰 경계·시나리오 누락을 기존 정적 공백과 함께 보고한다.
|
|
136
|
+
|
|
137
|
+
`preflight <context.json> --summary --strict --compact`로 작은 개요를 읽고,
|
|
138
|
+
`--explain <exact-producer-symbol-id>`로 한 심볼의 전체 원인 경로를 조회한다.
|
|
139
|
+
summary는 목록당 기본 20개(`--limit 1..100`)를 표시하며 생략한 항목도 검토 상태에 반영한다.
|
|
140
|
+
선택적 [Basic/Pigeon v2 입력](docs/BRIDGE-MESSAGES.md)은 literal 주소와
|
|
141
|
+
증명된 prefix 후보를 연결한다. prefix의 suffix·instance 배선 불확실성은 유지한다.
|
|
142
|
+
이 추가 기능은 위에 나열한 공개 producer 버전의 `bridges --messages`로 사용할 수 있다.
|
|
143
|
+
에이전트 클라이언트는 `isthmus serve`(MCP stdio 서버)로 같은 명령을 도구로 호출할 수 있다 —
|
|
144
|
+
check·query·graph·diff·impact·preflight·retentions를 노출한다.
|
|
145
|
+
[MCP 서버 계약](docs/MCP.md)을 본다.
|
|
146
|
+
검증된 개발 조합을 재현하거나 도구를 직접 감사하려면 로컬 Git의 고정 commit에서
|
|
147
|
+
구축하는 [도구 구축 절차](docs/TOOLCHAIN.md)를 쓴다. Dart AOT 실행 파일, impact와
|
|
148
|
+
Basic을 함께 제공하는 cartograph, 격리 설치된 isthmus 패키지를 준비한다.
|
|
149
|
+
|
|
150
|
+
isthmus CLI는 각 도구가 만든 JSON 파일을 읽는다. 선택적 수집 workflow는 설정에
|
|
151
|
+
명시한 준비·producer 명령을 실행한다.
|
|
97
152
|
|
|
98
153
|
```bash
|
|
99
154
|
isthmus check dart-bridges.json swift-bridges.json
|
|
100
155
|
```
|
|
101
156
|
|
|
102
|
-
전체 명령과 현재
|
|
157
|
+
전체 명령과 현재 패키지 버전은 다음과 같이 확인한다.
|
|
103
158
|
|
|
104
159
|
```bash
|
|
105
160
|
isthmus --help
|
|
@@ -120,6 +175,20 @@ isthmus check dart-bridges.json swift-bridges.json --strict
|
|
|
120
175
|
`-h`/`--help`는 어느 위치에 있든 도움말을 내고, `isthmus help <command>`로 명령의
|
|
121
176
|
사용법을 볼 수 있으며, 모르는 명령은 루트 도움말을 출력한다.
|
|
122
177
|
|
|
178
|
+
### React Native 호출 측 사실
|
|
179
|
+
|
|
180
|
+
React Native 앱에서는 `isthmus extract-js`가 호출 측 문서를 직접 만든다 — JS/TS
|
|
181
|
+
파일이나 디렉터리를 넘기고, 결과를 자매 도구가 낸 Swift·Kotlin 문서와 함께
|
|
182
|
+
`check`에 넣는다:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
isthmus extract-js src/ --project . > js-bridges.json
|
|
186
|
+
isthmus check js-bridges.json ios-bridges.json android-bridges.json
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
출력은 자매 도구가 만드는 것과 같은 `bridge-facts` 버전 1 문서라 모든 소비
|
|
190
|
+
명령이 그대로 받는다.
|
|
191
|
+
|
|
123
192
|
### SARIF 출력
|
|
124
193
|
|
|
125
194
|
check 결과를 GitHub code scanning(또는 그 밖의 SARIF 2.1.0 소비자)에 올리려면
|
|
@@ -129,14 +198,32 @@ isthmus-check JSON 대신 SARIF를 요청한다.
|
|
|
129
198
|
isthmus check dart-bridges.json swift-bridges.json --format sarif > isthmus.sarif
|
|
130
199
|
```
|
|
131
200
|
|
|
132
|
-
|
|
201
|
+
기본값인 `--format json`은 버전이 붙은 isthmus-check 문서를 유지한다. SARIF는 같은
|
|
133
202
|
조인 결과의 additive·isthmus 소유 렌더링이다. 모든 이슈는 check 진단 코드를 규칙 id로
|
|
134
203
|
하는 결과가 되고, 첫 증거 끝점이 주 위치가 되며(프로젝트 상대 경로가 퍼센트 인코딩된
|
|
135
204
|
저장소 상대 URI가 된다), 나머지 끝점은 관련 위치로 실린다. 베이스라인이 억제한 이슈는
|
|
136
205
|
`external` suppression을 달고 나온다. 결과마다 논리 이슈 식별자(code·target·channel·
|
|
137
206
|
method)의 `partialFingerprints` 해시가 있어 소스 줄이 움직여도 중복 판정이 베이스라인
|
|
138
|
-
억제와 같은 기준으로 살아남는다.
|
|
139
|
-
|
|
207
|
+
억제와 같은 기준으로 살아남는다.
|
|
208
|
+
|
|
209
|
+
### GitLab Code Quality 출력
|
|
210
|
+
|
|
211
|
+
check 결과를 GitLab 머지 요청 위젯에 표시하려면 Code Quality 아티팩트를 대신 낸다.
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
isthmus check dart-bridges.json swift-bridges.json --format codequality > gl-code-quality-report.json
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
억제되지 않은 모든 이슈가 첫 증거 끝점의 발견 하나가 된다. `check_name`은 `isthmus:`에
|
|
218
|
+
진단 코드를 붙인 값이고, `severity`는 error를 `major`로·warning을 `minor`로 내리며,
|
|
219
|
+
`fingerprint`는 SARIF와 같은 논리 이슈 해시를 재사용해 실행 사이의 병합 판정이 유지된다.
|
|
220
|
+
이 형식에는 억제 개념이 없으므로 베이스라인이 받아들인 이슈는 새 발견으로 다시 뜨지
|
|
221
|
+
않도록 목록에서 제외한다 — 베이스라인을 머지 요청 파이프라인에만 적용하고 기본
|
|
222
|
+
브랜치에는 적용하지 않으면, GitLab 비교가 받아들인 이슈를 해당 머지 요청이 "고친"
|
|
223
|
+
것으로 표시할 수 있다는 점에 유의한다.
|
|
224
|
+
|
|
225
|
+
`--strict`·`--baseline`·`--update-baseline`은 모든 형식과 조합되고 문서화된 종료
|
|
226
|
+
코드 동작을 유지한다.
|
|
140
227
|
|
|
141
228
|
### 베이스라인
|
|
142
229
|
|
|
@@ -176,11 +263,11 @@ cartograph dead --external-retentions external-retentions.json
|
|
|
176
263
|
```
|
|
177
264
|
|
|
178
265
|
`retentions`는 핸들러의 USR을 우선 사용하고 없으면 `qualifiedName`을 남긴다. 메서드를
|
|
179
|
-
여러 위치에서 호출하면 근거가 전체 호출 위치를 `callers`로
|
|
266
|
+
여러 위치에서 호출하면 근거가 전체 호출 위치를 `callers`로 싣고(대표 `caller`는 옛
|
|
180
267
|
소비자를 위해 유지), 근거당 100개 상한을 넘은 호출은 조용히 버리지 않고
|
|
181
268
|
`callersOmitted`로 계수를 밝힌다. `mixed-targets` 문서는 v1에서 사실별 target을
|
|
182
269
|
복원할 수 없어 모든 소비 명령이 종료 코드 2로 조인을 보류하며, 이때 몇 개의 문서에서
|
|
183
|
-
관찰한
|
|
270
|
+
관찰한 사실 몇 개가 조인되지 못했는지를 함께 알린다. 먼저 생산 단계에서
|
|
184
271
|
target별 문서로 분리해야 한다.
|
|
185
272
|
|
|
186
273
|
cartograph는 Swift 심볼만 보존하므로 `--for cartograph`는 수신 측 Swift 문서를 최소
|
|
@@ -211,7 +298,7 @@ node scripts/verify-public-flutter-plugin.mjs \
|
|
|
211
298
|
|
|
212
299
|
공개 플러그인 검증은 원본 `addMethodCallDelegate` 구현에서 나온 Swift USR과 원본
|
|
213
300
|
Dart 호출 위치 세 곳을 확인하고, cartograph `--explain`이 해당 심볼의 대표 근거를
|
|
214
|
-
읽는지 검증한다. 이미 public인 플러그인
|
|
301
|
+
읽는지 검증한다. 이미 public인 플러그인 핸들러의 dead 상태 전환을 억지로 만들지는
|
|
215
302
|
않는다. 그 전환과 `setMethodCallHandler` 경로는
|
|
216
303
|
`verify-cartograph-roundtrip.mjs`의 합성 코퍼스가 별도로 검증한다.
|
|
217
304
|
|
|
@@ -254,7 +341,44 @@ isthmus graph dart-bridges.json swift-bridges.json --format mermaid
|
|
|
254
341
|
핸들러를 놓쳤을 수 있다고 스스로 신고해 없는 것인지 못 본 것인지 판정할 수 없음
|
|
255
342
|
- `unregistered-channel-creation-unverified` (warning): 같은 이유로 등록 여부를 판정할 수 없음
|
|
256
343
|
|
|
257
|
-
|
|
344
|
+
React Native 이름 경계도 같은 방향으로 보고한다 — `require`/`import`에 맞는
|
|
345
|
+
`export`가 없으면 error, `export`에 호출자가 없으면 warning이다.
|
|
346
|
+
|
|
347
|
+
- `module-import-without-export` (error) / `-unverified` (warning)
|
|
348
|
+
- `module-import-without-export-optional` (warning): 호출자가 전부 부재 허용
|
|
349
|
+
API를 썼으므로 수출 부재가 크래시가 아니라 기능 저하임
|
|
350
|
+
- `module-export-without-import` (warning)
|
|
351
|
+
- `component-require-without-export` (error) / `-unverified` (warning)
|
|
352
|
+
- `component-export-without-require` (warning)
|
|
353
|
+
- `module-import-mechanism-mismatch`, `module-export-mechanism-mismatch`,
|
|
354
|
+
`component-require-mechanism-mismatch`, `component-export-mechanism-mismatch`
|
|
355
|
+
(warning): 이름이 상대편에 있지만 호환되지 않는 core/Expo 해석 경로로만
|
|
356
|
+
관찰됨
|
|
357
|
+
|
|
358
|
+
`check`는 BasicMessageChannel·EventChannel bridge-facts v2 문서도 직접 소비해
|
|
359
|
+
같은 짝 규칙으로 transport별 진단을 보고한다.
|
|
360
|
+
|
|
361
|
+
- `unhandled-message-send` (error) / `-unverified` (warning): Dart Basic send에
|
|
362
|
+
대응 네이티브 메시지 핸들러가 없음
|
|
363
|
+
- `message-handler-without-send` (warning): 네이티브 Basic 핸들러에 대응 Dart
|
|
364
|
+
send가 없음
|
|
365
|
+
- `unhandled-stream-listen` (error) / `-unverified` (warning): Dart Event 스트림
|
|
366
|
+
listener에 대응 네이티브 스트림 핸들러가 없음
|
|
367
|
+
- `stream-handler-without-listen` (warning): 네이티브 Event 핸들러에 대응 Dart
|
|
368
|
+
listener가 없음
|
|
369
|
+
|
|
370
|
+
dynamic `channelPrefix` 경로는 판정이 아니라 후보다 — 항상
|
|
371
|
+
`dynamic-message-address`·`dynamic-stream-address` 소비자 한계로 실리고, 관찰된
|
|
372
|
+
상대가 없으면 `unmatched-message-boundary`·`unmatched-stream-boundary`가 더해지며,
|
|
373
|
+
증명된 prefix가 없는 동적 주소는 `unresolved-message-addresses` 한계에 포함된다.
|
|
374
|
+
빠진 쪽을 prefix 후보가 덮는 literal 경계도 error 대신 같은 후보 한계로 내린다.
|
|
375
|
+
`summary`는 v2 입력이 있을 때만 `matchedMessages`·`matchedStreams`(literal 매치만)를
|
|
376
|
+
더한다. `query`는 v2 경계를 `message`·`stream` kind 주체로, `graph`는 literal v2 경계를
|
|
377
|
+
`message`·`stream` 간선으로, `diff`는 literal v2 경계의 추가·삭제와 v2 진단을 생산한다.
|
|
378
|
+
`retentions --for cartograph`는 literal v2 Swift 핸들러를 method 없는 근거로 보존하고,
|
|
379
|
+
`impact`는 여전히 v1 입력만 받고 version 2를 거부한다.
|
|
380
|
+
|
|
381
|
+
`summary`는 이슈 계수와 함께 관찰량을 싣는다. `observedFacts`는 입력 문서 전체의 사실
|
|
258
382
|
총수이고 `observedLimitations`는 보고된 분석 한계 수다. 이로써 브리지가 없는 프로젝트와
|
|
259
383
|
아무것도 관찰하지 못한 실행이 같은 보고서를 내지 않는다 — `observedFacts`가 0이면
|
|
260
384
|
생산자가 서술할 것을 아무것도 보지 못했다는 뜻이다.
|
|
@@ -277,15 +401,15 @@ target에 적용한다. 호출 측 한계는 네이티브 코드를 가리지
|
|
|
277
401
|
보존된다. 생산자가 tool 이름을 isthmus로 적어도 자체 계수를 신뢰하지 않으며,
|
|
278
402
|
`unjoined-*`는 소비자가 직접 붙인 `origin: "consumer"`가 있어야 완화 근거가 된다.
|
|
279
403
|
|
|
280
|
-
선택적
|
|
404
|
+
선택적 사실 필드 `sourceLanguage: "objective-c"`는 `.m`/`.mm`의 ObjC 구현을 Swift
|
|
281
405
|
그래프와 구분한다. 이 사실에는 symbol을 붙이지 않는다. 매치는 check/query/graph에
|
|
282
406
|
남고 Swift 보존 목록에서는 제외되며, `omittedObjectiveCHandlers`가 제외 수를 알린다.
|
|
283
407
|
표식 없는 Swift 핸들러가 호출자가 있는데 symbol 없이 매치되면 여전히 종료 코드 2로
|
|
284
408
|
실패한다. 이 확장을 지원하는 소비자를 먼저 배포해야 한다. 옛 소비자는 스코프를
|
|
285
409
|
버리고 넓게 완화하며 ObjC 보존 생성은 실패한다.
|
|
286
410
|
|
|
287
|
-
모든 이슈는 관찰된 위치를 `evidence`로 제공한다. 동적 이름, 해석하지 못한
|
|
288
|
-
|
|
411
|
+
모든 이슈는 관찰된 위치를 `evidence`로 제공한다. 동적 이름, 해석하지 못한 수신자나
|
|
412
|
+
핸들러 본문, USR 누락, 입력 생성 시각 차이, 혼합 target은 `limitations`에 출처와
|
|
289
413
|
함께 남긴다. 이 도구는 삭제 가능 여부를 판정하지 않는다.
|
|
290
414
|
|
|
291
415
|
isthmus 출력 문서는 버전 1 안에서 필드 추가나 새 이슈 code를 호환 변경으로 다룬다.
|
|
@@ -310,8 +434,8 @@ isthmus 출력 문서는 버전 1 안에서 필드 추가나 새 이슈 code를
|
|
|
310
434
|
| `2` | 파일 읽기, JSON, 교환 계약, project 불일치, 플랫폼 구성 누락, 보류된 조인, 크기 상한(입력 텍스트·그래프 간선·베이스라인 항목), 베이스라인 파일 오류·쓰기 실패, 만들 수 없는 보존 근거 등 도구 실패. stderr가 원인을 구분 |
|
|
311
435
|
| `64` | 잘못된 명령·옵션·입력 개수 또는 `query`의 `notFound`·`ambiguous` |
|
|
312
436
|
|
|
313
|
-
저장소 checkout에서 개발할 때는 먼저 `npm ci`를 실행한다. 개발 검증은 타입
|
|
314
|
-
|
|
437
|
+
저장소 checkout에서 개발할 때는 먼저 `npm ci`를 실행한다. 개발 검증은 타입 체크와 clean build를 실행하고 제품 코드 90% 커버리지를
|
|
438
|
+
강제하며 실제 CLI·패키지 계약 검증을 함께 수행한다.
|
|
315
439
|
|
|
316
440
|
```bash
|
|
317
441
|
npm run verify
|
|
@@ -361,15 +485,16 @@ JSON으로 출력한다. 연결에는 호출자와 핸들러 위치가 포함된
|
|
|
361
485
|
|
|
362
486
|
`--strict`는 새로 관찰된 error가 있을 때만 1이다. 기존 오류·경고·분석 한계만 있으면
|
|
363
487
|
0이므로 성공 코드가 삭제 안전성이나 완전한 분석을 뜻하지 않는다. `resolvedIssues`도
|
|
364
|
-
이전 불일치가 더 이상 관찰되지 않는다는 뜻이며, 동적 전환·추출기 변경
|
|
488
|
+
이전 불일치가 더 이상 관찰되지 않는다는 뜻이며, 동적 전환·추출기 변경 때문인지를 한계와
|
|
365
489
|
함께 확인해야 한다. `--strict`은 인자 위치와 무관하게 인식하며 두 번 이상 줄 수 없다.
|
|
366
490
|
|
|
367
|
-
|
|
491
|
+
`diff`는 호출 문서(Flutter Dart 또는 React Native JS)와 수신 문서(Swift
|
|
492
|
+
또는 Kotlin)를 받는다. 한 비교에는 네이티브 언어 하나만 사용하며 각 시점에 호출/수신 문서가 모두 필요하다.
|
|
368
493
|
양 시점의 `project`와 플랫폼·도구별 문서 개수가 같아야 한다. 한 checkout의 같은
|
|
369
494
|
경로에서 각 revision을 빌드해 JSON을 보관한다. 일부 파일만 추출한 결과와 전체 결과를
|
|
370
495
|
비교하지 말고 같은 분석 설정을 사용한다. 입력 파일은 합계 256개, 텍스트 길이 제한은
|
|
371
496
|
기존 CLI와 동일하다. 혼합 target이나 비교 불가능한 입력은 종료 코드 2로 거부한다.
|
|
372
|
-
`generatedAt`은
|
|
497
|
+
`generatedAt`은 사실 추출 시각이며 revision 순서가 아니다. 비교 방향은 `--before`와
|
|
373
498
|
`--after` 인자로 결정되므로 사용자가 올바른 revision의 파일을 지정해야 한다.
|
|
374
499
|
|
|
375
500
|
## 코딩 에이전트 skill
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# isthmus
|
|
2
2
|
|
|
3
3
|
**Cross-language bridge calls in cross-platform apps, joined into one graph.**
|
|
4
|
-
[cartograph](https://github.com/ictechgy/cartograph) (Swift) · kartograph (Kotlin
|
|
4
|
+
[cartograph](https://github.com/ictechgy/cartograph) (Swift) · [kartograph](https://github.com/ictechgy/kartograph) (Kotlin) ·
|
|
5
5
|
[dartograph](https://github.com/ictechgy/dartograph) (Dart) each draw their own map; isthmus
|
|
6
6
|
joins them into one.
|
|
7
7
|
|
|
@@ -24,46 +24,70 @@ see these strings. As a result:
|
|
|
24
24
|
|
|
25
25
|
isthmus joins the **bridge facts** each language tool exports (channel names, method names,
|
|
26
26
|
registration sites, invocation sites) by string key, builds the edges that cross the boundary,
|
|
27
|
-
and answers those three questions. It then hands the result **back to cartograph
|
|
27
|
+
and answers those three questions. It then hands the result **back to cartograph as
|
|
28
28
|
retention evidence** — "keep Swift `CameraHandler.takePhoto`, because `lib/camera.dart:42`
|
|
29
29
|
calls it over channel `com.example/camera`".
|
|
30
30
|
|
|
31
31
|
## Status
|
|
32
32
|
|
|
33
|
-
**0.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
33
|
+
**0.6.0** supports Flutter Dart ↔ Swift/Kotlin change preflight, MethodChannel and
|
|
34
|
+
Pigeon/BasicMessageChannel facts, declared runtime scenarios, and content-based capture reuse.
|
|
35
|
+
It adds `impact --file`/`--symbol`/`--changes` (with lossless `--compact` JSON and a
|
|
36
|
+
gap-aware `--strict` gate), `preflight <context.json>` with `--summary`/`--explain` over
|
|
37
|
+
producer impact paths, and `verify-runtime --expectations`. Actual macOS and Android fixture
|
|
38
|
+
apps have exercised public plugin APIs. See [preflight](docs/PREFLIGHT.md),
|
|
39
|
+
[runtime verification](docs/RUNTIME.md), and
|
|
40
|
+
[building from pinned source commits](docs/TOOLCHAIN.md) for setup and measured limits.
|
|
41
|
+
|
|
42
|
+
The published npm version is **0.7.0**. The compatible public producer set is
|
|
43
|
+
cartograph **0.18.0**, kartograph **0.10.2**, and dartograph **0.14.0** — see
|
|
44
|
+
[compatible versions (Korean)](docs/COMPATIBILITY.md) for install commands, a
|
|
45
|
+
fixed end-to-end example, and a CI sketch. MethodChannel joins and the retention
|
|
46
|
+
round trip are supported from cartograph 0.5.3+ and dartograph 0.1.1+ — exercised on a
|
|
47
|
+
public battery plugin — and the round trip was re-verified on the previous public
|
|
48
|
+
set (cartograph 0.15.1, dartograph 0.10.0, isthmus 0.6.0).
|
|
49
|
+
React Native module/component facts (`module-import`↔`module-export`,
|
|
50
|
+
`component-require`↔`component-export`) join by name inside the `react-native`
|
|
51
|
+
target. An optional `mechanism` field keeps the core and Expo resolution paths
|
|
52
|
+
apart: Expo `requireNativeModule`-family imports reach core and Expo exports
|
|
53
|
+
through the TurboModuleRegistry fallback, while `requireNativeViewManager`
|
|
54
|
+
requires a mechanism match, and a name observed only through a different
|
|
55
|
+
mechanism is reported as a `*-mechanism-mismatch` warning instead of a missing
|
|
56
|
+
counterpart. Imports made through absence-tolerant lookups
|
|
57
|
+
(`requireOptionalNativeModule`, `TurboModuleRegistry.get`/`getNullable`) carry
|
|
58
|
+
`optional: true`; when every caller of a missing module tolerates absence, the
|
|
59
|
+
finding is the `module-import-without-export-optional` warning rather than an
|
|
60
|
+
error. `isthmus extract-js` extracts caller-side facts from JS/TS sources
|
|
61
|
+
(`NativeModules.*`, `TurboModuleRegistry.get*`,
|
|
62
|
+
`requireNativeComponent`/`codegenNativeComponent`,
|
|
63
|
+
`requireNativeModule`-family calls, and resolved member calls), and cartograph
|
|
64
|
+
and kartograph scan the Expo Modules DSL (`Module`/`definition()`, `Name`,
|
|
65
|
+
`Function`, `View`, `@ExpoModule`/`@JS`) and mark those exports
|
|
66
|
+
`mechanism: "expo"` — end-to-end RN joins are reproducible within the
|
|
67
|
+
token-scan observation scope documented in `GRAPH-EXCHANGE.md`.
|
|
68
|
+
EventChannel v2 transport is implemented across the sister repositories, and
|
|
69
|
+
`check` now consumes the v2 Bridge/Event documents directly with
|
|
70
|
+
transport-specific diagnostics. Retention export currently targets cartograph
|
|
71
|
+
(Swift). Full application coverage and first-time external setup remain
|
|
72
|
+
unverified.
|
|
73
|
+
|
|
74
|
+
Change predictions are measured against a pinned public precision corpus —
|
|
75
|
+
`battery_plus`, `shared_preferences_foundation`, `url_launcher_macos`, and the
|
|
76
|
+
**LocalSend** app — over 15 file/symbol/version-diff cases. The latest run
|
|
77
|
+
recorded **TP 83 / FN 0 / FP 0**, including the first app-level
|
|
78
|
+
Dart↔Swift↔Kotlin join ([`experiments/real-corpus/`](experiments/real-corpus/)).
|
|
79
|
+
These are static bridge-boundary numbers over stub-compiled Swift and
|
|
80
|
+
source-scanned Kotlin; runtime execution and full-app precision are not
|
|
81
|
+
measured.
|
|
60
82
|
|
|
61
83
|
| Document | Contents |
|
|
62
84
|
|---|---|
|
|
63
85
|
| [`docs/PRD.md`](docs/PRD.md) | What, for whom, how far |
|
|
64
86
|
| [`docs/PLAN.md`](docs/PLAN.md) | Step-by-step plan. **cartograph and dartograph have prerequisite work** |
|
|
65
87
|
| [`docs/GRAPH-EXCHANGE.md`](docs/GRAPH-EXCHANGE.md) | The bridge-facts format the sister tools export — the contract shared across the sister repositories |
|
|
88
|
+
| [`docs/COMPATIBILITY.md`](docs/COMPATIBILITY.md) | Compatible public versions, fixed example, and CI setup |
|
|
66
89
|
| [`docs/RESEARCH.md`](docs/RESEARCH.md) | Confirmed facts vs. unconfirmed claims |
|
|
90
|
+
| [`experiments/real-corpus/`](experiments/real-corpus/) | Pinned public-plugin/app precision corpus (TP/FN/FP counts) |
|
|
67
91
|
| [`experiments/phase-0/`](experiments/phase-0/) | Temporary Dart/Swift extractors, pinned JSON, hand-join verification |
|
|
68
92
|
|
|
69
93
|
Internal documents are maintained in Korean, the maintainer's working language.
|
|
@@ -101,7 +125,52 @@ Do not use `npx isthmus` — that installs a different package with the same nam
|
|
|
101
125
|
|
|
102
126
|
## Usage
|
|
103
127
|
|
|
104
|
-
|
|
128
|
+
Change preflight is available with `impact --file`, `--symbol`, or `--changes`, plus
|
|
129
|
+
lossless `--compact` JSON and a gap-aware `--strict` gate. See
|
|
130
|
+
[change preflight](docs/IMPACT.md) for the build command, contract, and current
|
|
131
|
+
bridge-only scope.
|
|
132
|
+
Android development support uses `selection.kotlin` and a kartograph snapshot. It connects
|
|
133
|
+
Kotlin Method/Basic facts to Dart consumers and matches Android observations only to Kotlin
|
|
134
|
+
candidates. See [Android capture](docs/PREFLIGHT.md#android-수집) and [toolchain builds](docs/TOOLCHAIN.md).
|
|
135
|
+
`verify-runtime --expectations` checks recorded calls
|
|
136
|
+
by revision, scenario, platform, and engine instance. See the [runtime contract](docs/RUNTIME.md).
|
|
137
|
+
The optional [Flutter recorder](packages/isthmus_runtime/README.md) has been exercised
|
|
138
|
+
in real macOS and Android apps, including the Pigeon-generated APIs of
|
|
139
|
+
`url_launcher_macos 3.2.2` and `shared_preferences_android 2.4.1`. Transitive producer impact
|
|
140
|
+
and snapshot capture are implemented; broader application coverage and first-time setup remain
|
|
141
|
+
under validation.
|
|
142
|
+
|
|
143
|
+
0.6.0 exposes `preflight <context.json> --strict --compact` to compose
|
|
144
|
+
producer impact paths across the bridge. A separate capture workflow caches declared
|
|
145
|
+
input content and has passed a synthetic source test with real producers. See
|
|
146
|
+
[cross-language preflight](docs/PREFLIGHT.md) for the contract, CI setup, and remaining
|
|
147
|
+
real-application validation.
|
|
148
|
+
`isthmus init [capture.json]` scaffolds that capture config — `--toolchain` fills real
|
|
149
|
+
producer commands from a built `toolchain.json` — and `isthmus doctor <capture.json>`
|
|
150
|
+
validates the config and checks that the referenced executables resolve on `PATH` or at
|
|
151
|
+
the given path, without running them.
|
|
152
|
+
To combine that context with recorded execution, pass runtime JSON files and
|
|
153
|
+
`--expectations <checks.json>`. Preflight reports revision alignment, native candidates,
|
|
154
|
+
and static boundaries missing observations or declared scenarios; existing static gaps remain visible.
|
|
155
|
+
|
|
156
|
+
Use `preflight <context.json> --summary --strict --compact` for a bounded overview, then
|
|
157
|
+
`--explain <exact-producer-symbol-id>` for a complete path to one symbol. Summary defaults
|
|
158
|
+
to 20 items per collection (`--limit 1..100`); omitted items still affect review status.
|
|
159
|
+
Optional [Basic/Pigeon v2 inputs](docs/BRIDGE-MESSAGES.md) connect literal addresses and
|
|
160
|
+
proven prefix candidates. Prefix matches preserve unresolved
|
|
161
|
+
suffix and instance wiring. These additions are available in the public producer
|
|
162
|
+
versions listed above (`bridges --messages`).
|
|
163
|
+
Agent clients can call the same commands over `isthmus serve`, an MCP stdio server
|
|
164
|
+
that exposes check, query, graph, diff, impact, preflight, and retentions as tools.
|
|
165
|
+
See the [MCP server contract](docs/MCP.md).
|
|
166
|
+
To reproduce a verified development combination or audit the toolchain, build the tools
|
|
167
|
+
from pinned local Git commits with the
|
|
168
|
+
[toolchain build workflow (Korean)](docs/TOOLCHAIN.md). It produces a standalone
|
|
169
|
+
Dart executable, a cartograph executable with both impact and message support,
|
|
170
|
+
and an isolated installation of the isthmus package.
|
|
171
|
+
|
|
172
|
+
The isthmus CLI reads JSON produced by the sister tools. The optional capture workflow
|
|
173
|
+
runs the preparation and producer commands declared in its configuration:
|
|
105
174
|
|
|
106
175
|
```bash
|
|
107
176
|
isthmus check dart-bridges.json swift-bridges.json
|
|
@@ -127,6 +196,20 @@ ends option parsing: `isthmus query -- -unusual-name dart-bridges.json swift-bri
|
|
|
127
196
|
`-h`/`--help` shows help from any position, `isthmus help <command>` names a command's usage,
|
|
128
197
|
and an unknown command prints the root help.
|
|
129
198
|
|
|
199
|
+
### React Native caller facts
|
|
200
|
+
|
|
201
|
+
For a React Native app, `isthmus extract-js` produces the caller-side document
|
|
202
|
+
itself — pass JS/TS files or directories, and feed the result to `check`
|
|
203
|
+
alongside the Swift and Kotlin documents the sister tools emit:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
isthmus extract-js src/ --project . > js-bridges.json
|
|
207
|
+
isthmus check js-bridges.json ios-bridges.json android-bridges.json
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
The output is the same `bridge-facts` version 1 document the sister tools
|
|
211
|
+
produce, so every consuming command accepts it unchanged.
|
|
212
|
+
|
|
130
213
|
### SARIF output
|
|
131
214
|
|
|
132
215
|
To upload check results to GitHub code scanning (or any SARIF 2.1.0 consumer), ask for SARIF
|
|
@@ -143,9 +226,27 @@ additive, isthmus-owned rendering of the same join: every issue becomes a result
|
|
|
143
226
|
endpoints as related locations, and baseline-suppressed issues carry an `external`
|
|
144
227
|
suppression. Results include a
|
|
145
228
|
`partialFingerprints` hash of the logical issue identity (code, target, channel, method), so
|
|
146
|
-
deduplication survives source line moves exactly like baseline suppression.
|
|
147
|
-
|
|
148
|
-
|
|
229
|
+
deduplication survives source line moves exactly like baseline suppression.
|
|
230
|
+
|
|
231
|
+
### GitLab Code Quality output
|
|
232
|
+
|
|
233
|
+
To surface check results in GitLab merge request widgets, emit a Code Quality
|
|
234
|
+
artifact instead:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
isthmus check dart-bridges.json swift-bridges.json --format codequality > gl-code-quality-report.json
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Every unsuppressed issue becomes one finding at its first evidence endpoint: `check_name`
|
|
241
|
+
is `isthmus:` plus the issue code, `severity` maps errors to `major` and warnings to
|
|
242
|
+
`minor`, and `fingerprint` reuses the same logical-issue hash as SARIF, so GitLab merges
|
|
243
|
+
findings across runs. The format has no suppression concept, so baseline-accepted issues
|
|
244
|
+
are left out rather than resurfaced as new findings — note that when the baseline is
|
|
245
|
+
applied on merge request pipelines but not on the default branch, GitLab's comparison
|
|
246
|
+
can present those accepted issues as "fixed" by the merge request.
|
|
247
|
+
|
|
248
|
+
`--strict`, `--baseline`, and `--update-baseline` combine with any format and keep their
|
|
249
|
+
documented exit-code behavior.
|
|
149
250
|
|
|
150
251
|
### Baselines
|
|
151
252
|
|
|
@@ -249,7 +350,9 @@ When the same method exists on several channels, `query` returns candidates inst
|
|
|
249
350
|
one; feed a returned `qualifiedName` back into the same subject position to disambiguate. A
|
|
250
351
|
`qualifiedName` is `target:` followed by percent-escaped components — `%`, `#`, and `:` are
|
|
251
352
|
escaped — so splitting on the first `:` and on `#` and decoding the parts always recovers the
|
|
252
|
-
channel and method names.
|
|
353
|
+
channel and method names. Module and component subjects carry a `module:`/`component:` kind
|
|
354
|
+
segment before the name so a channel, a module, and a component that share a name stay
|
|
355
|
+
resolvable. A `notFound` or `ambiguous` query exits 64 and prints a one-line
|
|
253
356
|
cause on stderr, so a script can tell a bad invocation from a missing name without parsing
|
|
254
357
|
stdout.
|
|
255
358
|
`graph` emits matched edges only and preserves the input `limitations` as a JSON field or as
|
|
@@ -272,6 +375,42 @@ The output is `isthmus-check` version 1 JSON, reporting these facts:
|
|
|
272
375
|
- `unregistered-channel-creation-unverified` (warning): registration undecidable for the same
|
|
273
376
|
reason
|
|
274
377
|
|
|
378
|
+
React Native name boundaries follow the same pairing — a `require`/`import` with no
|
|
379
|
+
matching `export` is an error, an `export` with no caller is a warning:
|
|
380
|
+
|
|
381
|
+
- `module-import-without-export` (error) / `-unverified` (warning)
|
|
382
|
+
- `module-import-without-export-optional` (warning): every caller used an absence-tolerant
|
|
383
|
+
API, so the app degrades rather than crashes when the export is missing
|
|
384
|
+
- `module-export-without-import` (warning)
|
|
385
|
+
- `component-require-without-export` (error) / `-unverified` (warning)
|
|
386
|
+
- `component-export-without-require` (warning)
|
|
387
|
+
- `module-import-mechanism-mismatch`, `module-export-mechanism-mismatch`,
|
|
388
|
+
`component-require-mechanism-mismatch`, `component-export-mechanism-mismatch` (warnings):
|
|
389
|
+
the name exists on the other side but only through an incompatible core/Expo
|
|
390
|
+
resolution path
|
|
391
|
+
|
|
392
|
+
`check` also consumes BasicMessageChannel and EventChannel bridge-facts v2 documents and
|
|
393
|
+
reports transport-specific diagnostics with the same pairing:
|
|
394
|
+
|
|
395
|
+
- `unhandled-message-send` (error) / `-unverified` (warning): a Dart Basic send has no
|
|
396
|
+
native message handler
|
|
397
|
+
- `message-handler-without-send` (warning): a native Basic handler has no Dart send
|
|
398
|
+
- `unhandled-stream-listen` (error) / `-unverified` (warning): a Dart Event stream listener
|
|
399
|
+
has no native stream handler
|
|
400
|
+
- `stream-handler-without-listen` (warning): a native Event handler has no Dart listener
|
|
401
|
+
|
|
402
|
+
A dynamic `channelPrefix` route is a candidate, not a verdict — it is carried as the
|
|
403
|
+
`dynamic-message-address`/`dynamic-stream-address` consumer limitation and, with no observed
|
|
404
|
+
counterpart, additionally as `unmatched-message-boundary`/`unmatched-stream-boundary`; a
|
|
405
|
+
dynamic address with no proven prefix is counted as `unresolved-message-addresses`. A literal
|
|
406
|
+
boundary whose missing side is covered by a prefix candidate is downgraded the same way
|
|
407
|
+
rather than reported as an error. The summary adds `matchedMessages`/`matchedStreams` (literal
|
|
408
|
+
matches only) when v2 inputs are present. `query` resolves v2 boundaries as `message`/`stream`
|
|
409
|
+
kind subjects, `graph` emits `message`/`stream` edges for literal matches, and `diff` reports
|
|
410
|
+
added/removed literal v2 boundaries plus v2 diagnostics. `retentions --for cartograph` keeps
|
|
411
|
+
literal v2 Swift handlers with method-less evidence; `impact` still requires v1 inputs and
|
|
412
|
+
rejects version 2.
|
|
413
|
+
|
|
275
414
|
The `summary` carries the issue counts plus observation volume: `observedFacts` is the total
|
|
276
415
|
number of facts across all input documents and `observedLimitations` counts the reported
|
|
277
416
|
analysis limitations. This keeps a project with no bridges and a run that observed nothing
|
|
@@ -393,8 +532,11 @@ analyzed". `resolvedIssues` likewise means a previous mismatch is no longer obse
|
|
|
393
532
|
the limitations to see whether a dynamic transition or an extractor change caused it.
|
|
394
533
|
`--strict` is recognized at any argument position and cannot be given more than once.
|
|
395
534
|
|
|
396
|
-
`diff`
|
|
397
|
-
|
|
535
|
+
`diff` accepts caller documents (Flutter Dart or React Native JS) plus either Swift or Kotlin
|
|
536
|
+
receiver documents. Keep one native language per comparison.
|
|
537
|
+
Both sender and receiver documents are required at
|
|
538
|
+
each point in time, and the two snapshots must agree on `project`, on the observed set of
|
|
539
|
+
bridge targets, and on the per-platform,
|
|
398
540
|
per-tool document counts. Build each revision from the same checkout path and keep the JSON.
|
|
399
541
|
Do not compare a partial extraction against a full one; use the same analysis settings. Input
|
|
400
542
|
files are capped at 256 total, and the text size limits match the rest of the CLI. Mixed
|