isthmus-cli 0.6.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.
Files changed (99) hide show
  1. package/README.ko.md +135 -31
  2. package/README.md +134 -16
  3. package/Skills/isthmus/SKILL.md +17 -7
  4. package/compatibility.json +10 -0
  5. package/dist/cli/check-command.d.ts +2 -2
  6. package/dist/cli/check-command.js +22 -9
  7. package/dist/cli/check-command.js.map +1 -1
  8. package/dist/cli/command-support.d.ts +19 -1
  9. package/dist/cli/command-support.js +37 -8
  10. package/dist/cli/command-support.js.map +1 -1
  11. package/dist/cli/diff-command.js +4 -3
  12. package/dist/cli/diff-command.js.map +1 -1
  13. package/dist/cli/doctor-command.d.ts +11 -0
  14. package/dist/cli/doctor-command.js +128 -0
  15. package/dist/cli/doctor-command.js.map +1 -0
  16. package/dist/cli/extract-js-command.d.ts +33 -0
  17. package/dist/cli/extract-js-command.js +233 -0
  18. package/dist/cli/extract-js-command.js.map +1 -0
  19. package/dist/cli/graph-command.js +13 -6
  20. package/dist/cli/graph-command.js.map +1 -1
  21. package/dist/cli/init-command.d.ts +11 -0
  22. package/dist/cli/init-command.js +115 -0
  23. package/dist/cli/init-command.js.map +1 -0
  24. package/dist/cli/main.js +52 -1
  25. package/dist/cli/main.js.map +1 -1
  26. package/dist/cli/mcp-server.d.ts +16 -0
  27. package/dist/cli/mcp-server.js +534 -0
  28. package/dist/cli/mcp-server.js.map +1 -0
  29. package/dist/cli/query-command.js +13 -6
  30. package/dist/cli/query-command.js.map +1 -1
  31. package/dist/cli/retentions-command.js +14 -7
  32. package/dist/cli/retentions-command.js.map +1 -1
  33. package/dist/cli/serve-command.d.ts +13 -0
  34. package/dist/cli/serve-command.js +43 -0
  35. package/dist/cli/serve-command.js.map +1 -0
  36. package/dist/exchange/capture-config.d.ts +18 -0
  37. package/dist/exchange/capture-config.js +100 -0
  38. package/dist/exchange/capture-config.js.map +1 -0
  39. package/dist/exchange/messages.d.ts +9 -24
  40. package/dist/exchange/messages.js +25 -55
  41. package/dist/exchange/messages.js.map +1 -1
  42. package/dist/exchange/parse.d.ts +61 -0
  43. package/dist/exchange/parse.js +115 -12
  44. package/dist/exchange/parse.js.map +1 -1
  45. package/dist/extract/js-document.d.ts +22 -0
  46. package/dist/extract/js-document.js +230 -0
  47. package/dist/extract/js-document.js.map +1 -0
  48. package/dist/extract/js-scan.d.ts +93 -0
  49. package/dist/extract/js-scan.js +1205 -0
  50. package/dist/extract/js-scan.js.map +1 -0
  51. package/dist/extract/lexer.d.ts +26 -0
  52. package/dist/extract/lexer.js +316 -0
  53. package/dist/extract/lexer.js.map +1 -0
  54. package/dist/join/join.d.ts +66 -1
  55. package/dist/join/join.js +171 -1
  56. package/dist/join/join.js.map +1 -1
  57. package/dist/join/messages.d.ts +7 -4
  58. package/dist/join/messages.js +15 -8
  59. package/dist/join/messages.js.map +1 -1
  60. package/dist/report/check-report.d.ts +20 -3
  61. package/dist/report/check-report.js +240 -8
  62. package/dist/report/check-report.js.map +1 -1
  63. package/dist/report/codequality.d.ts +45 -0
  64. package/dist/report/codequality.js +74 -0
  65. package/dist/report/codequality.js.map +1 -0
  66. package/dist/report/diff.d.ts +25 -3
  67. package/dist/report/diff.js +91 -11
  68. package/dist/report/diff.js.map +1 -1
  69. package/dist/report/graph.d.ts +10 -4
  70. package/dist/report/graph.js +60 -6
  71. package/dist/report/graph.js.map +1 -1
  72. package/dist/report/preflight-view.js +28 -1
  73. package/dist/report/preflight-view.js.map +1 -1
  74. package/dist/report/preflight.d.ts +4 -4
  75. package/dist/report/preflight.js +81 -46
  76. package/dist/report/preflight.js.map +1 -1
  77. package/dist/report/query.d.ts +11 -4
  78. package/dist/report/query.js +84 -17
  79. package/dist/report/query.js.map +1 -1
  80. package/dist/report/retentions.d.ts +17 -5
  81. package/dist/report/retentions.js +85 -8
  82. package/dist/report/retentions.js.map +1 -1
  83. package/dist/report/rules.d.ts +16 -0
  84. package/dist/report/rules.js +30 -0
  85. package/dist/report/rules.js.map +1 -0
  86. package/dist/report/sarif.d.ts +2 -8
  87. package/dist/report/sarif.js +2 -10
  88. package/dist/report/sarif.js.map +1 -1
  89. package/docs/BRIDGE-EVENTS.md +87 -0
  90. package/docs/BRIDGE-MESSAGES.md +23 -8
  91. package/docs/GRAPH-EXCHANGE.md +141 -14
  92. package/docs/IMPACT.md +1 -1
  93. package/docs/MCP.md +62 -0
  94. package/docs/PREFLIGHT.md +24 -8
  95. package/docs/RUNTIME.md +2 -2
  96. package/docs/TOOLCHAIN.md +5 -5
  97. package/package.json +5 -2
  98. package/scripts/capture-preflight.mjs +32 -44
  99. package/scripts/run-child.mjs +1 -0
package/README.ko.md CHANGED
@@ -36,18 +36,47 @@ isthmus는 각 언어 도구가 내보낸 **브리지 사실**(채널 이름 ·
36
36
  검증 앱에서 공개 플러그인 API를 실행했다. 설정과 측정 범위는 [사전 점검](docs/PREFLIGHT.md),
37
37
  [런타임 검증](docs/RUNTIME.md), [고정 소스 구축](docs/TOOLCHAIN.md)을 참조한다.
38
38
 
39
- npm 발행본은 **0.6.0**이며 기능은 호환되는 producer 개발 commit이 필요하다. 발행된
40
- Dart/Swift MethodChannel 절차는 cartograph 0.5.3 이상과 dartograph 0.1.1 이상을 사용하며
41
- 공개 battery 플러그인으로 검증했다. Message channel 지원은 현재 개발 producer가 필요하다.
42
- React Native·EventChannel 추출은 계획이고 보존 근거 내보내기는 현재 cartograph(Swift)를
43
- 대상으로 한다. 전체 적용 범위와 최초 외부 사용자 구축은 아직 검증하지 않았다.
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
+ 런타임 실행·앱 전체 정밀도는 측정하지 않았다.
44
71
 
45
72
  | 문서 | 내용 |
46
73
  |---|---|
47
74
  | [`docs/PRD.md`](docs/PRD.md) | 무엇을 · 누구를 위해 · 어디까지 |
48
75
  | [`docs/PLAN.md`](docs/PLAN.md) | 단계별 계획. **cartograph와 dartograph에 선행 작업이 있다** |
49
76
  | [`docs/GRAPH-EXCHANGE.md`](docs/GRAPH-EXCHANGE.md) | 자매 도구가 내보내는 브리지 사실의 형식. 자매 저장소들이 공유하는 계약 |
77
+ | [`docs/COMPATIBILITY.md`](docs/COMPATIBILITY.md) | 공개 호환 버전, 고정 예제, CI 설정 |
50
78
  | [`docs/RESEARCH.md`](docs/RESEARCH.md) | 확인된 사실 · 확인되지 않은 주장 |
79
+ | [`experiments/real-corpus/`](experiments/real-corpus/) | 고정 공개 플러그인·앱 정밀도 코퍼스(TP/FN/FP 계수) |
51
80
  | [`experiments/phase-0/`](experiments/phase-0/) | Dart·Swift 임시 추출기, 고정 JSON, 손 조인 검증 |
52
81
 
53
82
  ## 의존 관계
@@ -72,20 +101,20 @@ npm install --global isthmus-cli
72
101
  isthmus --help
73
102
  ```
74
103
 
75
- 설치 없이 한 번 실행할 때는 package 이름을 명시한다.
104
+ 설치 없이 한 번 실행할 때는 패키지 이름을 명시한다.
76
105
 
77
106
  ```bash
78
107
  npx isthmus-cli --help
79
108
  ```
80
109
 
81
- `npx isthmus`는 이름이 같은 다른 package를 설치하므로 사용하면 안 된다.
110
+ `npx isthmus`는 이름이 같은 다른 패키지를 설치하므로 사용하면 안 된다.
82
111
 
83
112
  ## 사용
84
113
 
85
114
  `impact --file`·`--symbol`·`--changes` 사전 점검과 정보 손실 없는 `--compact`, 분석
86
115
  공백도 실패시키는 `--strict`를 제공한다. 빌드·계약·현재 브리지 한정 범위는
87
116
  [변경 사전 점검](docs/IMPACT.md)을 참조한다.
88
- Android 개발 지원은 `selection.kotlin`과 Kartograph snapshot을 사용한다. Kotlin Method/Basic
117
+ Android 개발 지원은 `selection.kotlin`과 kartograph snapshot을 사용한다. Kotlin Method/Basic
89
118
  사실을 Dart 소비자에 연결하고 Android 실행은 Kotlin 후보에만 대조한다.
90
119
  [Android 수집 설정](docs/PREFLIGHT.md#android-수집)과 [선택적 Kotlin 도구 구축](docs/TOOLCHAIN.md)을 참조한다.
91
120
  `verify-runtime --expectations`는 revision·시나리오·플랫폼·엔진 인스턴스별
@@ -99,18 +128,24 @@ Android 개발 지원은 `selection.kotlin`과 Kartograph snapshot을 사용한
99
128
  브리지를 연결한다. 별도 수집 workflow는 명시된 입력의 내용 해시로 캐시를 재사용하며,
100
129
  실제 producer를 사용한 합성 소스 검증을 통과했다. 사용법·지원 경계·CI 설정은
101
130
  [언어 간 변경 사전 점검](docs/PREFLIGHT.md)을 참조한다. 실제 앱 전체 검증은 남아 있다.
131
+ `isthmus init [capture.json]`은 그 capture 설정 scaffold를 쓰고(`--toolchain`을 주면
132
+ 구축한 `toolchain.json`의 실제 producer 명령을 채운다), `isthmus doctor <capture.json>`은
133
+ 설정을 검증하고 참조한 실행 파일이 `PATH`나 지정 경로에 있는지 확인만 한다 — 실행하지 않는다.
102
134
  runtime JSON과 `--expectations <checks.json>`를 함께 주면 같은 revision의 실행과
103
- 전이 분석을 대조하고, native 후보·미관찰 경계·시나리오 누락을 기존 정적 공백과 함께 보고한다.
135
+ 전이 분석을 대조하고, 네이티브 후보·미관찰 경계·시나리오 누락을 기존 정적 공백과 함께 보고한다.
104
136
 
105
137
  `preflight <context.json> --summary --strict --compact`로 작은 개요를 읽고,
106
138
  `--explain <exact-producer-symbol-id>`로 한 심볼의 전체 원인 경로를 조회한다.
107
139
  summary는 목록당 기본 20개(`--limit 1..100`)를 표시하며 생략한 항목도 검토 상태에 반영한다.
108
- 선택적 [Basic/Pigeon v2 입력](docs/BRIDGE-MESSAGES.md)은 개발 producer로 literal 주소와
140
+ 선택적 [Basic/Pigeon v2 입력](docs/BRIDGE-MESSAGES.md)은 literal 주소와
109
141
  증명된 prefix 후보를 연결한다. prefix의 suffix·instance 배선 불확실성은 유지한다.
110
- 이 추가 기능에는 개발 producer 필요하다.
111
- 호환 개발 도구를 로컬 Git의 고정 commit에서 새로 구축하는 방법은
112
- [도구 구축 절차](docs/TOOLCHAIN.md)에 있다. Dart AOT 실행 파일, impact Basic을 함께
113
- 제공하는 Cartograph, 격리 설치된 isthmus 패키지를 준비한다.
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 패키지를 준비한다.
114
149
 
115
150
  isthmus CLI는 각 도구가 만든 JSON 파일을 읽는다. 선택적 수집 workflow는 설정에
116
151
  명시한 준비·producer 명령을 실행한다.
@@ -119,7 +154,7 @@ isthmus CLI는 각 도구가 만든 JSON 파일을 읽는다. 선택적 수집 w
119
154
  isthmus check dart-bridges.json swift-bridges.json
120
155
  ```
121
156
 
122
- 전체 명령과 현재 package 버전은 다음과 같이 확인한다.
157
+ 전체 명령과 현재 패키지 버전은 다음과 같이 확인한다.
123
158
 
124
159
  ```bash
125
160
  isthmus --help
@@ -140,6 +175,20 @@ isthmus check dart-bridges.json swift-bridges.json --strict
140
175
  `-h`/`--help`는 어느 위치에 있든 도움말을 내고, `isthmus help <command>`로 명령의
141
176
  사용법을 볼 수 있으며, 모르는 명령은 루트 도움말을 출력한다.
142
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
+
143
192
  ### SARIF 출력
144
193
 
145
194
  check 결과를 GitHub code scanning(또는 그 밖의 SARIF 2.1.0 소비자)에 올리려면
@@ -149,14 +198,32 @@ isthmus-check JSON 대신 SARIF를 요청한다.
149
198
  isthmus check dart-bridges.json swift-bridges.json --format sarif > isthmus.sarif
150
199
  ```
151
200
 
152
- 기본값은 `--format json`으로 버전이 붙은 isthmus-check 문서를 유지한다. SARIF는 같은
201
+ 기본값인 `--format json`은 버전이 붙은 isthmus-check 문서를 유지한다. SARIF는 같은
153
202
  조인 결과의 additive·isthmus 소유 렌더링이다. 모든 이슈는 check 진단 코드를 규칙 id로
154
203
  하는 결과가 되고, 첫 증거 끝점이 주 위치가 되며(프로젝트 상대 경로가 퍼센트 인코딩된
155
204
  저장소 상대 URI가 된다), 나머지 끝점은 관련 위치로 실린다. 베이스라인이 억제한 이슈는
156
205
  `external` suppression을 달고 나온다. 결과마다 논리 이슈 식별자(code·target·channel·
157
206
  method)의 `partialFingerprints` 해시가 있어 소스 줄이 움직여도 중복 판정이 베이스라인
158
- 억제와 같은 기준으로 살아남는다. `--strict`·`--baseline`·`--update-baseline`은 두 형식
159
- 모두와 조합되고 문서화된 종료 코드 동작을 유지한다.
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
+ 코드 동작을 유지한다.
160
227
 
161
228
  ### 베이스라인
162
229
 
@@ -196,11 +263,11 @@ cartograph dead --external-retentions external-retentions.json
196
263
  ```
197
264
 
198
265
  `retentions`는 핸들러의 USR을 우선 사용하고 없으면 `qualifiedName`을 남긴다. 메서드를
199
- 여러 위치에서 호출하면 근거가 전체 호출 위치를 `callers`로 실고(대표 `caller`는 옛
266
+ 여러 위치에서 호출하면 근거가 전체 호출 위치를 `callers`로 싣고(대표 `caller`는 옛
200
267
  소비자를 위해 유지), 근거당 100개 상한을 넘은 호출은 조용히 버리지 않고
201
268
  `callersOmitted`로 계수를 밝힌다. `mixed-targets` 문서는 v1에서 사실별 target을
202
269
  복원할 수 없어 모든 소비 명령이 종료 코드 2로 조인을 보류하며, 이때 몇 개의 문서에서
203
- 관찰한 fact 몇 개가 조인되지 못했는지를 함께 알린다. 먼저 생산 단계에서
270
+ 관찰한 사실 몇 개가 조인되지 못했는지를 함께 알린다. 먼저 생산 단계에서
204
271
  target별 문서로 분리해야 한다.
205
272
 
206
273
  cartograph는 Swift 심볼만 보존하므로 `--for cartograph`는 수신 측 Swift 문서를 최소
@@ -231,7 +298,7 @@ node scripts/verify-public-flutter-plugin.mjs \
231
298
 
232
299
  공개 플러그인 검증은 원본 `addMethodCallDelegate` 구현에서 나온 Swift USR과 원본
233
300
  Dart 호출 위치 세 곳을 확인하고, cartograph `--explain`이 해당 심볼의 대표 근거를
234
- 읽는지 검증한다. 이미 public인 플러그인 handler의 dead 상태 전환을 억지로 만들지는
301
+ 읽는지 검증한다. 이미 public인 플러그인 핸들러의 dead 상태 전환을 억지로 만들지는
235
302
  않는다. 그 전환과 `setMethodCallHandler` 경로는
236
303
  `verify-cartograph-roundtrip.mjs`의 합성 코퍼스가 별도로 검증한다.
237
304
 
@@ -274,7 +341,44 @@ isthmus graph dart-bridges.json swift-bridges.json --format mermaid
274
341
  핸들러를 놓쳤을 수 있다고 스스로 신고해 없는 것인지 못 본 것인지 판정할 수 없음
275
342
  - `unregistered-channel-creation-unverified` (warning): 같은 이유로 등록 여부를 판정할 수 없음
276
343
 
277
- `summary`는 이슈 계수와 함께 관찰량을 싣는다. `observedFacts`는 입력 문서 전체의 fact
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`는 입력 문서 전체의 사실
278
382
  총수이고 `observedLimitations`는 보고된 분석 한계 수다. 이로써 브리지가 없는 프로젝트와
279
383
  아무것도 관찰하지 못한 실행이 같은 보고서를 내지 않는다 — `observedFacts`가 0이면
280
384
  생산자가 서술할 것을 아무것도 보지 못했다는 뜻이다.
@@ -297,15 +401,15 @@ target에 적용한다. 호출 측 한계는 네이티브 코드를 가리지
297
401
  보존된다. 생산자가 tool 이름을 isthmus로 적어도 자체 계수를 신뢰하지 않으며,
298
402
  `unjoined-*`는 소비자가 직접 붙인 `origin: "consumer"`가 있어야 완화 근거가 된다.
299
403
 
300
- 선택적 fact 필드 `sourceLanguage: "objective-c"`는 `.m`/`.mm`의 ObjC 구현을 Swift
404
+ 선택적 사실 필드 `sourceLanguage: "objective-c"`는 `.m`/`.mm`의 ObjC 구현을 Swift
301
405
  그래프와 구분한다. 이 사실에는 symbol을 붙이지 않는다. 매치는 check/query/graph에
302
406
  남고 Swift 보존 목록에서는 제외되며, `omittedObjectiveCHandlers`가 제외 수를 알린다.
303
407
  표식 없는 Swift 핸들러가 호출자가 있는데 symbol 없이 매치되면 여전히 종료 코드 2로
304
408
  실패한다. 이 확장을 지원하는 소비자를 먼저 배포해야 한다. 옛 소비자는 스코프를
305
409
  버리고 넓게 완화하며 ObjC 보존 생성은 실패한다.
306
410
 
307
- 모든 이슈는 관찰된 위치를 `evidence`로 제공한다. 동적 이름, 해석하지 못한 receiver나
308
- handler 본문, USR 누락, 입력 생성 시각 차이, 혼합 target은 `limitations`에 출처와
411
+ 모든 이슈는 관찰된 위치를 `evidence`로 제공한다. 동적 이름, 해석하지 못한 수신자나
412
+ 핸들러 본문, USR 누락, 입력 생성 시각 차이, 혼합 target은 `limitations`에 출처와
309
413
  함께 남긴다. 이 도구는 삭제 가능 여부를 판정하지 않는다.
310
414
 
311
415
  isthmus 출력 문서는 버전 1 안에서 필드 추가나 새 이슈 code를 호환 변경으로 다룬다.
@@ -330,8 +434,8 @@ isthmus 출력 문서는 버전 1 안에서 필드 추가나 새 이슈 code를
330
434
  | `2` | 파일 읽기, JSON, 교환 계약, project 불일치, 플랫폼 구성 누락, 보류된 조인, 크기 상한(입력 텍스트·그래프 간선·베이스라인 항목), 베이스라인 파일 오류·쓰기 실패, 만들 수 없는 보존 근거 등 도구 실패. stderr가 원인을 구분 |
331
435
  | `64` | 잘못된 명령·옵션·입력 개수 또는 `query`의 `notFound`·`ambiguous` |
332
436
 
333
- 저장소 checkout에서 개발할 때는 먼저 `npm ci`를 실행한다. 개발 검증은 타입 체크,
334
- 제품 코드 90% 커버리지, clean build, 실제 CLI·package 계약을 함께 실행한다.
437
+ 저장소 checkout에서 개발할 때는 먼저 `npm ci`를 실행한다. 개발 검증은 타입 체크와 clean build를 실행하고 제품 코드 90% 커버리지를
438
+ 강제하며 실제 CLI·패키지 계약 검증을 함께 수행한다.
335
439
 
336
440
  ```bash
337
441
  npm run verify
@@ -381,16 +485,16 @@ JSON으로 출력한다. 연결에는 호출자와 핸들러 위치가 포함된
381
485
 
382
486
  `--strict`는 새로 관찰된 error가 있을 때만 1이다. 기존 오류·경고·분석 한계만 있으면
383
487
  0이므로 성공 코드가 삭제 안전성이나 완전한 분석을 뜻하지 않는다. `resolvedIssues`도
384
- 이전 불일치가 더 이상 관찰되지 않는다는 뜻이며, 동적 전환·추출기 변경 때문인지 한계를
488
+ 이전 불일치가 더 이상 관찰되지 않는다는 뜻이며, 동적 전환·추출기 변경 때문인지를 한계와
385
489
  함께 확인해야 한다. `--strict`은 인자 위치와 무관하게 인식하며 두 번 이상 줄 수 없다.
386
490
 
387
- 개발 소스의 diff는 Flutter Dart Swift 또는 Kotlin 문서를 받는다. 비교에는 native 언어
388
- 하나만 사용하며 각 시점에 호출/수신 문서가 모두 필요하다.
491
+ `diff`는 호출 문서(Flutter Dart 또는 React Native JS)와 수신 문서(Swift
492
+ 또는 Kotlin)를 받는다. 한 비교에는 네이티브 언어 하나만 사용하며 각 시점에 호출/수신 문서가 모두 필요하다.
389
493
  양 시점의 `project`와 플랫폼·도구별 문서 개수가 같아야 한다. 한 checkout의 같은
390
494
  경로에서 각 revision을 빌드해 JSON을 보관한다. 일부 파일만 추출한 결과와 전체 결과를
391
495
  비교하지 말고 같은 분석 설정을 사용한다. 입력 파일은 합계 256개, 텍스트 길이 제한은
392
496
  기존 CLI와 동일하다. 혼합 target이나 비교 불가능한 입력은 종료 코드 2로 거부한다.
393
- `generatedAt`은 fact 추출 시각이며 revision 순서가 아니다. 비교 방향은 `--before`와
497
+ `generatedAt`은 사실 추출 시각이며 revision 순서가 아니다. 비교 방향은 `--before`와
394
498
  `--after` 인자로 결정되므로 사용자가 올바른 revision의 파일을 지정해야 한다.
395
499
 
396
500
  ## 코딩 에이전트 skill
package/README.md CHANGED
@@ -39,18 +39,55 @@ apps have exercised public plugin APIs. See [preflight](docs/PREFLIGHT.md),
39
39
  [runtime verification](docs/RUNTIME.md), and
40
40
  [building from pinned source commits](docs/TOOLCHAIN.md) for setup and measured limits.
41
41
 
42
- The published npm version is **0.6.0**; these features require compatible producer commits.
43
- The published Dart/Swift MethodChannel workflow uses cartograph 0.5.3+ and dartograph
44
- 0.1.1+; message-channel support currently needs development producers.
45
- React Native and EventChannel extraction remain planned. Retention export currently targets
46
- cartograph (Swift). Full application coverage and first-time external setup remain unverified.
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.
47
82
 
48
83
  | Document | Contents |
49
84
  |---|---|
50
85
  | [`docs/PRD.md`](docs/PRD.md) | What, for whom, how far |
51
86
  | [`docs/PLAN.md`](docs/PLAN.md) | Step-by-step plan. **cartograph and dartograph have prerequisite work** |
52
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 |
53
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) |
54
91
  | [`experiments/phase-0/`](experiments/phase-0/) | Temporary Dart/Swift extractors, pinned JSON, hand-join verification |
55
92
 
56
93
  Internal documents are maintained in Korean, the maintainer's working language.
@@ -92,7 +129,7 @@ Change preflight is available with `impact --file`, `--symbol`, or `--changes`,
92
129
  lossless `--compact` JSON and a gap-aware `--strict` gate. See
93
130
  [change preflight](docs/IMPACT.md) for the build command, contract, and current
94
131
  bridge-only scope.
95
- Android development support uses `selection.kotlin` and a Kartograph snapshot. It connects
132
+ Android development support uses `selection.kotlin` and a kartograph snapshot. It connects
96
133
  Kotlin Method/Basic facts to Dart consumers and matches Android observations only to Kotlin
97
134
  candidates. See [Android capture](docs/PREFLIGHT.md#android-수집) and [toolchain builds](docs/TOOLCHAIN.md).
98
135
  `verify-runtime --expectations` checks recorded calls
@@ -108,6 +145,10 @@ producer impact paths across the bridge. A separate capture workflow caches decl
108
145
  input content and has passed a synthetic source test with real producers. See
109
146
  [cross-language preflight](docs/PREFLIGHT.md) for the contract, CI setup, and remaining
110
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.
111
152
  To combine that context with recorded execution, pass runtime JSON files and
112
153
  `--expectations <checks.json>`. Preflight reports revision alignment, native candidates,
113
154
  and static boundaries missing observations or declared scenarios; existing static gaps remain visible.
@@ -116,11 +157,16 @@ Use `preflight <context.json> --summary --strict --compact` for a bounded overvi
116
157
  `--explain <exact-producer-symbol-id>` for a complete path to one symbol. Summary defaults
117
158
  to 20 items per collection (`--limit 1..100`); omitted items still affect review status.
118
159
  Optional [Basic/Pigeon v2 inputs](docs/BRIDGE-MESSAGES.md) connect literal addresses and
119
- proven prefix candidates with development producers. Prefix matches preserve unresolved
120
- suffix and instance wiring. These additions require development producers.
121
- To build compatible development tools from pinned local Git commits, use the
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
122
168
  [toolchain build workflow (Korean)](docs/TOOLCHAIN.md). It produces a standalone
123
- Dart executable, a Cartograph executable with both impact and message support,
169
+ Dart executable, a cartograph executable with both impact and message support,
124
170
  and an isolated installation of the isthmus package.
125
171
 
126
172
  The isthmus CLI reads JSON produced by the sister tools. The optional capture workflow
@@ -150,6 +196,20 @@ ends option parsing: `isthmus query -- -unusual-name dart-bridges.json swift-bri
150
196
  `-h`/`--help` shows help from any position, `isthmus help <command>` names a command's usage,
151
197
  and an unknown command prints the root help.
152
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
+
153
213
  ### SARIF output
154
214
 
155
215
  To upload check results to GitHub code scanning (or any SARIF 2.1.0 consumer), ask for SARIF
@@ -166,9 +226,27 @@ additive, isthmus-owned rendering of the same join: every issue becomes a result
166
226
  endpoints as related locations, and baseline-suppressed issues carry an `external`
167
227
  suppression. Results include a
168
228
  `partialFingerprints` hash of the logical issue identity (code, target, channel, method), so
169
- deduplication survives source line moves exactly like baseline suppression. `--strict`,
170
- `--baseline`, and `--update-baseline` combine with either format and keep their documented
171
- exit-code behavior.
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.
172
250
 
173
251
  ### Baselines
174
252
 
@@ -272,7 +350,9 @@ When the same method exists on several channels, `query` returns candidates inst
272
350
  one; feed a returned `qualifiedName` back into the same subject position to disambiguate. A
273
351
  `qualifiedName` is `target:` followed by percent-escaped components — `%`, `#`, and `:` are
274
352
  escaped — so splitting on the first `:` and on `#` and decoding the parts always recovers the
275
- channel and method names. A `notFound` or `ambiguous` query exits 64 and prints a one-line
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
276
356
  cause on stderr, so a script can tell a bad invocation from a missing name without parsing
277
357
  stdout.
278
358
  `graph` emits matched edges only and preserves the input `limitations` as a JSON field or as
@@ -295,6 +375,42 @@ The output is `isthmus-check` version 1 JSON, reporting these facts:
295
375
  - `unregistered-channel-creation-unverified` (warning): registration undecidable for the same
296
376
  reason
297
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
+
298
414
  The `summary` carries the issue counts plus observation volume: `observedFacts` is the total
299
415
  number of facts across all input documents and `observedLimitations` counts the reported
300
416
  analysis limitations. This keeps a project with no bridges and a run that observed nothing
@@ -416,9 +532,11 @@ analyzed". `resolvedIssues` likewise means a previous mismatch is no longer obse
416
532
  the limitations to see whether a dynamic transition or an extractor change caused it.
417
533
  `--strict` is recognized at any argument position and cannot be given more than once.
418
534
 
419
- Development `diff` accepts Flutter Dart plus either Swift or Kotlin documents. Keep one native language per comparison.
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.
420
537
  Both sender and receiver documents are required at
421
- each point in time, and the two snapshots must agree on `project` and on the per-platform,
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,
422
540
  per-tool document counts. Build each revision from the same checkout path and keep the JSON.
423
541
  Do not compare a partial extraction against a full one; use the same analysis settings. Input
424
542
  files are capped at 256 total, and the text size limits match the rest of the CLI. Mixed
@@ -3,7 +3,8 @@ name: isthmus
3
3
  description: >-
4
4
  Inspect file or symbol changes across Flutter Dart-to-Swift/Kotlin bridges, trace callers,
5
5
  compare snapshots, or produce cartograph retention evidence. Use before changing
6
- MethodChannel or Pigeon/Basic handlers and their Dart callers; RN extraction is not supported.
6
+ MethodChannel or Pigeon/Basic handlers and their Dart callers. `extract-js` extracts
7
+ React Native caller-side facts from JS/TS sources within its token-scan scope.
7
8
  ---
8
9
 
9
10
  # isthmus
@@ -13,11 +14,21 @@ analysis evidence; it does not authorize source edits, deletion, publishing, or
13
14
 
14
15
  ## Inputs
15
16
 
16
- Use `isthmus-cli` 0.1.4+ (`isthmus` binary), cartograph 0.5.3+ and dartograph 0.1.1+.
17
+ Use `isthmus-cli` 0.1.4+ (`isthmus` binary), cartograph 0.5.3+ and dartograph 0.1.1+
18
+ for the basic check/query/diff/retentions workflow. `impact`, `preflight`,
19
+ `verify-runtime`, and Basic/Pigeon (`--messages`) need isthmus-cli 0.6.0 with the
20
+ compatible producer for each side: cartograph 0.15.1 (Swift), dartograph 0.10.0,
21
+ plus kartograph 0.10.0 when Android/Kotlin inputs are used.
17
22
  Obtain both Dart and Swift bridge-facts JSON with identical project roots and analysis scope.
18
23
  Swift production requires a built compiler index; use `cartograph bridges --target flutter --format json`.
19
- Android preflight requires development Kotlin support: obtain Kotlin facts using
24
+ Android preflight uses public Kotlin support: obtain Kotlin facts using
20
25
  `kartograph bridges --project <root> --target flutter --graph-file <snapshot.json>`.
26
+ For React Native caller-side facts, run `isthmus extract-js <file-or-dir> [more...] [--project <dir>]`
27
+ on the JS/TS sources; it emits a `bridge-facts` document with `platform: "js"`,
28
+ `target: "react-native"` that joins with kartograph/cartograph RN receiver facts.
29
+ Non-literal names stay `dynamic`, and bindings that leave the scanned file set are
30
+ reported only through `limitations` — token-scan output is observation scope, not
31
+ proof of complete app coverage.
21
32
  For Basic/Pigeon add `--messages`. A snapshot must come from the same prepared source/build;
22
33
  source-only names are not compiler symbol identities. Use `selection.kotlin` in the context.
23
34
  The capture workflow accepts `kartograph` and `kartographSnapshot`; Android-only capture does
@@ -31,7 +42,7 @@ If inputs are missing, identify the required files and proceed with independent
31
42
  ## Choose the requested operation
32
43
 
33
44
  - Trace transitive cross-language impact when a current producer context is available
34
- (development source, after 0.5.0):
45
+ (isthmus-cli 0.6.0+):
35
46
  `isthmus preflight <context.json> --summary --strict --compact`.
36
47
  Add `--revision <expected-capture-revision>` when the workflow supplied that revision.
37
48
  Read the whole-report `summary` and `requiresReview`, then bounded collections
@@ -75,8 +86,7 @@ If inputs are missing, identify the required files and proceed with independent
75
86
  `passedChecks` counts expectations, not distinct scenarios. In summary/explanation,
76
87
  `runtime.verification.declaredScenarioPlatforms` counts unique declared scenario/platform
77
88
  pairs; it is not a count of passing scenarios. Multiple checks can share one scenario.
78
- - Preflight a source change: check `isthmus --help` for `impact` (added after the
79
- published 0.5.0; currently requires a build of the development source).
89
+ - Preflight a source change: `impact` is available since isthmus-cli 0.6.0.
80
90
  Run `isthmus impact --file <project-relative-path> <dart.json> <swift.json> --strict --compact`;
81
91
  for a precise producer symbol use `--symbol <qualifiedName-or-usr>` instead.
82
92
  For multiple files, pass `--changes <json>` with
@@ -112,7 +122,7 @@ If inputs are missing, identify the required files and proceed with independent
112
122
  Inspect added/removed logical methods, introduced/resolved issues, both sets of limitations,
113
123
  and producer versions/timestamps. Revisions come from the caller's before/after choice.
114
124
  Same-key endpoint changes and rename inference are outside this comparison.
115
- - Verify recorded runtime calls (development source, after 0.5.0):
125
+ - Verify recorded runtime calls (isthmus-cli 0.6.0+):
116
126
  `isthmus verify-runtime --expectations <checks.json> <runtime.json> [more...] --strict --compact`.
117
127
  Expectations must be specified independently of the observed log. Check `status`,
118
128
  `summary`, unsuccessful `checks`, `failures`, and stale/incomplete `runs`.
@@ -0,0 +1,10 @@
1
+ {
2
+ "format": "isthmus-compatibility",
3
+ "version": 1,
4
+ "isthmus": "0.7.0",
5
+ "producers": {
6
+ "cartograph": "0.18.0",
7
+ "kartograph": "0.10.2",
8
+ "dartograph": "0.14.0"
9
+ }
10
+ }
@@ -1,7 +1,7 @@
1
1
  import { type Clock, type CommandResult, type ReadTextFile, type WriteTextFile } from './command-support.ts';
2
2
  export type { Clock, CommandResult, ReadTextFile, WriteTextFile };
3
- /** check가 내는 보고서 형식이다. SARIF는 isthmus 소유의 additive 출력이다. */
4
- export type CheckOutputFormat = 'json' | 'sarif';
3
+ /** check가 내는 보고서 형식이다. SARIF·Code Quality는 isthmus 소유의 additive 출력이다. */
4
+ export type CheckOutputFormat = 'json' | 'sarif' | 'codequality';
5
5
  /** check 인자를 실행해 프로세스에 독립적인 결과를 반환한다. */
6
6
  export declare function runCheckCommand(arguments_: readonly string[], readTextFile: ReadTextFile, writeTextFile?: WriteTextFile, now?: Clock, producerVersion?: string): Promise<CommandResult>;
7
7
  /** check 명령의 한 줄 사용법이다. */