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.
Files changed (146) hide show
  1. package/README.ko.md +170 -45
  2. package/README.md +178 -36
  3. package/Skills/isthmus/SKILL.md +104 -5
  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 +20 -2
  9. package/dist/cli/command-support.js +38 -9
  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/impact-command.d.ts +5 -0
  22. package/dist/cli/impact-command.js +111 -0
  23. package/dist/cli/impact-command.js.map +1 -0
  24. package/dist/cli/init-command.d.ts +11 -0
  25. package/dist/cli/init-command.js +115 -0
  26. package/dist/cli/init-command.js.map +1 -0
  27. package/dist/cli/main.js +67 -1
  28. package/dist/cli/main.js.map +1 -1
  29. package/dist/cli/mcp-server.d.ts +16 -0
  30. package/dist/cli/mcp-server.js +534 -0
  31. package/dist/cli/mcp-server.js.map +1 -0
  32. package/dist/cli/preflight-command.d.ts +5 -0
  33. package/dist/cli/preflight-command.js +83 -0
  34. package/dist/cli/preflight-command.js.map +1 -0
  35. package/dist/cli/query-command.js +13 -6
  36. package/dist/cli/query-command.js.map +1 -1
  37. package/dist/cli/retentions-command.js +14 -7
  38. package/dist/cli/retentions-command.js.map +1 -1
  39. package/dist/cli/runtime-command.d.ts +5 -0
  40. package/dist/cli/runtime-command.js +42 -0
  41. package/dist/cli/runtime-command.js.map +1 -0
  42. package/dist/cli/runtime-json-reader.d.ts +12 -0
  43. package/dist/cli/runtime-json-reader.js +37 -0
  44. package/dist/cli/runtime-json-reader.js.map +1 -0
  45. package/dist/cli/serve-command.d.ts +13 -0
  46. package/dist/cli/serve-command.js +43 -0
  47. package/dist/cli/serve-command.js.map +1 -0
  48. package/dist/exchange/capture-config.d.ts +18 -0
  49. package/dist/exchange/capture-config.js +100 -0
  50. package/dist/exchange/capture-config.js.map +1 -0
  51. package/dist/exchange/impact-selection.d.ts +13 -0
  52. package/dist/exchange/impact-selection.js +35 -0
  53. package/dist/exchange/impact-selection.js.map +1 -0
  54. package/dist/exchange/kartograph-impact.d.ts +4 -0
  55. package/dist/exchange/kartograph-impact.js +169 -0
  56. package/dist/exchange/kartograph-impact.js.map +1 -0
  57. package/dist/exchange/messages.d.ts +36 -0
  58. package/dist/exchange/messages.js +96 -0
  59. package/dist/exchange/messages.js.map +1 -0
  60. package/dist/exchange/parse.d.ts +69 -0
  61. package/dist/exchange/parse.js +127 -20
  62. package/dist/exchange/parse.js.map +1 -1
  63. package/dist/exchange/preflight-context.d.ts +71 -0
  64. package/dist/exchange/preflight-context.js +317 -0
  65. package/dist/exchange/preflight-context.js.map +1 -0
  66. package/dist/exchange/producer-impact.d.ts +17 -0
  67. package/dist/exchange/producer-impact.js +226 -0
  68. package/dist/exchange/producer-impact.js.map +1 -0
  69. package/dist/exchange/runtime.d.ts +69 -0
  70. package/dist/exchange/runtime.js +160 -0
  71. package/dist/exchange/runtime.js.map +1 -0
  72. package/dist/extract/js-document.d.ts +22 -0
  73. package/dist/extract/js-document.js +230 -0
  74. package/dist/extract/js-document.js.map +1 -0
  75. package/dist/extract/js-scan.d.ts +93 -0
  76. package/dist/extract/js-scan.js +1205 -0
  77. package/dist/extract/js-scan.js.map +1 -0
  78. package/dist/extract/lexer.d.ts +26 -0
  79. package/dist/extract/lexer.js +316 -0
  80. package/dist/extract/lexer.js.map +1 -0
  81. package/dist/join/join.d.ts +66 -1
  82. package/dist/join/join.js +171 -1
  83. package/dist/join/join.js.map +1 -1
  84. package/dist/join/message-address.d.ts +7 -0
  85. package/dist/join/message-address.js +37 -0
  86. package/dist/join/message-address.js.map +1 -0
  87. package/dist/join/messages.d.ts +26 -0
  88. package/dist/join/messages.js +87 -0
  89. package/dist/join/messages.js.map +1 -0
  90. package/dist/report/check-report.d.ts +20 -3
  91. package/dist/report/check-report.js +240 -8
  92. package/dist/report/check-report.js.map +1 -1
  93. package/dist/report/codequality.d.ts +45 -0
  94. package/dist/report/codequality.js +74 -0
  95. package/dist/report/codequality.js.map +1 -0
  96. package/dist/report/diff.d.ts +25 -3
  97. package/dist/report/diff.js +91 -10
  98. package/dist/report/diff.js.map +1 -1
  99. package/dist/report/graph.d.ts +10 -4
  100. package/dist/report/graph.js +60 -6
  101. package/dist/report/graph.js.map +1 -1
  102. package/dist/report/impact.d.ts +62 -0
  103. package/dist/report/impact.js +168 -0
  104. package/dist/report/impact.js.map +1 -0
  105. package/dist/report/preflight-runtime.d.ts +42 -0
  106. package/dist/report/preflight-runtime.js +193 -0
  107. package/dist/report/preflight-runtime.js.map +1 -0
  108. package/dist/report/preflight-view.d.ts +146 -0
  109. package/dist/report/preflight-view.js +216 -0
  110. package/dist/report/preflight-view.js.map +1 -0
  111. package/dist/report/preflight.d.ts +104 -0
  112. package/dist/report/preflight.js +331 -0
  113. package/dist/report/preflight.js.map +1 -0
  114. package/dist/report/query.d.ts +11 -4
  115. package/dist/report/query.js +84 -17
  116. package/dist/report/query.js.map +1 -1
  117. package/dist/report/retentions.d.ts +17 -5
  118. package/dist/report/retentions.js +85 -8
  119. package/dist/report/retentions.js.map +1 -1
  120. package/dist/report/rules.d.ts +16 -0
  121. package/dist/report/rules.js +30 -0
  122. package/dist/report/rules.js.map +1 -0
  123. package/dist/report/runtime-impact.d.ts +38 -0
  124. package/dist/report/runtime-impact.js +94 -0
  125. package/dist/report/runtime-impact.js.map +1 -0
  126. package/dist/report/runtime.d.ts +54 -0
  127. package/dist/report/runtime.js +137 -0
  128. package/dist/report/runtime.js.map +1 -0
  129. package/dist/report/sarif.d.ts +2 -8
  130. package/dist/report/sarif.js +2 -10
  131. package/dist/report/sarif.js.map +1 -1
  132. package/dist/report/sorted-json.d.ts +1 -1
  133. package/dist/report/sorted-json.js +2 -2
  134. package/dist/report/sorted-json.js.map +1 -1
  135. package/docs/BRIDGE-EVENTS.md +87 -0
  136. package/docs/BRIDGE-MESSAGES.md +117 -0
  137. package/docs/GRAPH-EXCHANGE.md +382 -0
  138. package/docs/IMPACT.md +96 -0
  139. package/docs/MCP.md +62 -0
  140. package/docs/PREFLIGHT.md +311 -0
  141. package/docs/RUNTIME.md +172 -0
  142. package/docs/TOOLCHAIN.md +101 -0
  143. package/package.json +14 -2
  144. package/scripts/build-preflight-toolchain.mjs +186 -0
  145. package/scripts/capture-preflight.mjs +380 -0
  146. package/scripts/run-child.mjs +17 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight-runtime.js","sourceRoot":"","sources":["../../src/report/preflight-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { compareStrings } from '../compare.ts';\nimport type { BridgeLocation } from '../exchange/parse.ts';\nimport type { PreflightContext } from '../exchange/preflight-context.ts';\nimport type { BridgeRuntimeDocument, RuntimeExpectations, RuntimeOutcome, RuntimePlatform, RuntimeRoute } from '../exchange/runtime.ts';\nimport { RuntimeValidationError } from '../exchange/runtime.ts';\nimport type { BridgeEndpoint } from '../join/join.ts';\nimport { MessageAddressIndex } from '../join/message-address.ts';\nimport type { PreflightLimitation, PreflightReport } from './preflight.ts';\nimport { verifyRuntimeEvidence } from './runtime.ts';\nimport type { RuntimeVerificationReport } from './runtime.ts';\n\ntype NativeLanguage = 'swift' | 'kotlin';\n\n/** 실제 주소 관찰과 정적 후보를 구분하며 기록의 run·instance를 보존한다. */\nexport interface PreflightRuntimeRoute extends RuntimeRoute {\n readonly runId: string;\n readonly scenario: string;\n readonly platform: RuntimePlatform;\n readonly instance: string;\n readonly observedCalls: number;\n readonly outcomes: Readonly<Record<RuntimeOutcome, number>>;\n readonly callers: readonly BridgeLocation[];\n readonly callersOmitted: number;\n readonly selectionReasons: readonly ('route' | 'caller-file')[];\n readonly staticStatus: 'candidates' | 'unobserved' | 'unsupported';\n readonly boundaryKeys: readonly string[];\n readonly candidateKey?: string;\n}\n\n/** 같은 주소의 후보는 runtime 인스턴스 수와 무관하게 한 번만 싣는다. */\nexport interface PreflightRuntimeCandidates {\n readonly key: string;\n readonly channel: string;\n readonly method?: string;\n readonly transport?: 'basic-message-channel';\n readonly matching?: 'literal' | 'prefix';\n readonly handlers: readonly BridgeEndpoint[];\n readonly handlersOmitted: number;\n}\n\n/** 선언된 시나리오의 검증과 선택한 정적 경계의 실행 공백을 별도로 제공한다. */\nexport interface PreflightRuntimeReport {\n readonly aligned: boolean;\n readonly verification: RuntimeVerificationReport;\n readonly routes: readonly PreflightRuntimeRoute[];\n readonly candidates: readonly PreflightRuntimeCandidates[];\n readonly unobservedBoundaries: readonly string[];\n readonly uncoveredBoundaries: readonly string[];\n}\n\n/** runtime은 원래 정적 간선을 바꾸지 않고 독립 검증과 후보 근거만 추가한다. */\nexport function attachPreflightRuntime(\n context: PreflightContext, report: PreflightReport,\n expectations: RuntimeExpectations, documents: readonly BridgeRuntimeDocument[],\n): PreflightReport {\n if (expectations.project !== context.project || report.project !== context.project || report.revision !== context.revision) {\n throw new RuntimeValidationError('Preflight and runtime expectations must describe the same project and capture.');\n }\n const verification = verifyRuntimeEvidence(expectations, documents);\n const aligned = expectations.revision === context.revision;\n const files = new Set(report.reviewFiles);\n const addedFiles = new Set<string>();\n const byRoute = new Map<string, string[]>();\n const nativePlatforms = new Set([...context.bridges, ...(context.messages ?? [])]\n .flatMap(({ platform }) => platform === 'swift' || platform === 'kotlin' ? [platform] : []));\n const messagePlatforms = new Set((context.messages ?? []).map(({ platform }) => platform));\n const boundaryPlatforms = new Map(report.boundaries.map(({ subject, receivers }) => {\n const platforms = new Set(receivers.flatMap(({ platform }) => platform === 'swift' || platform === 'kotlin' ? [platform] : []));\n return [subject.key, platforms.size > 0 ? platforms : nativePlatforms];\n }));\n const messageBoundaries = new MessageAddressIndex<string>();\n const methodChannels = new Set<string>();\n for (const { subject } of report.boundaries) {\n if (subject.target !== 'flutter') continue;\n if (subject.transport === 'basic-message-channel') {\n messageBoundaries.add(subject.channel, subject.matching ?? 'literal', subject.key);\n continue;\n }\n const key = routeKey(subject.channel, subject.method);\n const keys = byRoute.get(key) ?? [];\n keys.push(subject.key);\n byRoute.set(key, keys);\n if (subject.method !== undefined) methodChannels.add(subject.channel);\n }\n const required = report.boundaries.filter(({ subject }) => subject.target === 'flutter' &&\n (subject.transport === 'basic-message-channel' || subject.method !== undefined || !methodChannels.has(subject.channel)));\n const boundaryKeys = (channel: string, method: string | undefined, transport: string, platform: NativeLanguage | undefined) => (transport === 'basic-message-channel'\n ? messageBoundaries.matching(channel)\n : [...(byRoute.get(routeKey(channel, method)) ?? []), ...(byRoute.get(routeKey(channel, undefined)) ?? [])])\n .filter((key) => platform !== undefined && boundaryPlatforms.get(key)?.has(platform));\n const pair = (key: string, platform: string): string => JSON.stringify([key, platform]);\n const declared = new Set(expectations.checks.flatMap((check) => {\n const platform = nativeLanguage(check.platform);\n return boundaryKeys(check.channel, check.method, check.transport, platform).map((key) => pair(key, platform!));\n }));\n const observed = new Set<string>();\n const handlers = new Map<string, { channel: string; method: string; endpoints: Map<string, BridgeEndpoint> }>();\n for (const document of context.bridges) {\n if ((document.platform !== 'swift' && document.platform !== 'kotlin') || document.target !== 'flutter') continue;\n for (const fact of document.facts) {\n if (fact.kind !== 'method-handle' || fact.dynamic || fact.channel === null || fact.method === undefined) continue;\n const key = candidateKey(document.platform, fact.channel, fact.method);\n let group = handlers.get(key);\n if (group === undefined) {\n group = { channel: fact.channel, method: fact.method, endpoints: new Map() };\n handlers.set(key, group);\n }\n group.endpoints.set(JSON.stringify([fact.location.path, fact.location.line, fact.location.column,\n fact.symbol?.usr ?? null, fact.symbol?.qualifiedName ?? null, fact.sourceLanguage ?? null]), {\n platform: document.platform, location: fact.location,\n ...(fact.symbol === undefined ? {} : { symbol: fact.symbol }),\n ...(fact.sourceLanguage === undefined ? {} : { sourceLanguage: fact.sourceLanguage }),\n });\n }\n }\n const candidateGroups = new Map<string, PreflightRuntimeCandidates>();\n const nativeMessages = new MessageAddressIndex<{ endpoint: BridgeEndpoint; matching: 'literal' | 'prefix' }>();\n for (const document of context.messages ?? []) {\n if (document.platform !== 'swift' && document.platform !== 'kotlin') continue;\n for (const fact of document.facts) {\n const address = fact.dynamic ? fact.channelPrefix : fact.channel;\n if (!address) continue;\n nativeMessages.add(address, fact.dynamic ? 'prefix' : 'literal', { matching: fact.dynamic ? 'prefix' : 'literal',\n endpoint: { platform: document.platform, location: fact.location, ...(fact.symbol === undefined ? {} : { symbol: fact.symbol }),\n ...(fact.sourceLanguage === undefined ? {} : { sourceLanguage: fact.sourceLanguage }),\n ...(fact.dynamic ? { channelExpression: fact.channel, channelPrefix: fact.channelPrefix } : {}) } });\n }\n }\n let messageCandidateWork = 0;\n const groups = new Map<string, {\n route: Omit<PreflightRuntimeRoute, 'callers' | 'callersOmitted' | 'selectionReasons' | 'observedCalls' | 'outcomes'>;\n count: number; outcomes: Record<RuntimeOutcome, number>;\n callers: Map<string, BridgeLocation>; reasons: Set<'route' | 'caller-file'>;\n }>();\n for (const document of [...documents].sort((a, b) => compareStrings(a.run.id, b.run.id))) {\n // 기대 문서가 이전 revision이어도 현재 정적 분석과 같은 실행만 경계 근거에 연결한다.\n if (document.revision !== context.revision) continue;\n for (const event of document.events) {\n const platform = nativeLanguage(document.run.platform);\n const supported = platform !== undefined && nativePlatforms.has(platform)\n && (event.transport === 'method-channel' || messagePlatforms.has(platform));\n const route = candidateKey(platform, event.channel, event.method, event.transport);\n const keys = supported ? boundaryKeys(event.channel, event.method, event.transport, platform) : [];\n const fromFile = event.caller !== undefined && files.has(event.caller.path);\n if (keys.length === 0 && !fromFile) continue;\n for (const key of keys) observed.add(pair(key, platform!));\n const candidates = supported && event.transport === 'method-channel' ? handlers.get(route) : undefined;\n if (candidates !== undefined && !candidateGroups.has(route)) {\n const endpoints = [...candidates.endpoints.entries()].sort(([a], [b]) => compareStrings(a, b)).map(([, value]) => value);\n for (const endpoint of endpoints) addedFiles.add(endpoint.location.path);\n candidateGroups.set(route, { key: route, channel: candidates.channel, method: candidates.method,\n handlers: endpoints.slice(0, 20), handlersOmitted: Math.max(0, endpoints.length - 20) });\n }\n if (supported && event.transport === 'basic-message-channel' && !candidateGroups.has(route)) {\n const addressMatches = nativeMessages.matching(event.channel);\n messageCandidateWork += addressMatches.length;\n if (messageCandidateWork > 1_000_000) throw new RuntimeValidationError('Message runtime candidate budget exceeded.');\n const matches = addressMatches.filter(({ endpoint }) => endpoint.platform === platform);\n if (matches.length > 0) {\n const unique = [...new Map(matches.map(({ endpoint }) => [JSON.stringify(endpoint), endpoint])).entries()]\n .sort(([a], [b]) => compareStrings(a, b)).map(([, endpoint]) => endpoint);\n for (const endpoint of unique) addedFiles.add(endpoint.location.path);\n candidateGroups.set(route, { key: route, channel: event.channel, transport: 'basic-message-channel',\n matching: matches.some(({ matching }) => matching === 'prefix') ? 'prefix' : 'literal',\n handlers: unique.slice(0, 20), handlersOmitted: Math.max(0, unique.length - 20) });\n }\n }\n const hasCandidates = supported && candidateGroups.has(route);\n const key = JSON.stringify([document.run.id, event.transport, event.channel, event.method ?? null, event.instance]);\n let group = groups.get(key);\n if (group === undefined) {\n group = { route: {\n runId: document.run.id, scenario: document.run.scenario, platform: document.run.platform,\n transport: event.transport, channel: event.channel, ...(event.method === undefined ? {} : { method: event.method }),\n instance: event.instance, staticStatus: !supported ? 'unsupported' : hasCandidates ? 'candidates' : 'unobserved',\n boundaryKeys: [...new Set(keys)].sort(compareStrings),\n ...(!hasCandidates ? {} : { candidateKey: route }),\n }, count: 0, outcomes: { success: 0, error: 0, timeout: 0, pending: 0, 'missing-handler': 0 },\n callers: new Map(), reasons: new Set() };\n groups.set(key, group);\n }\n group.count++;\n group.outcomes[event.outcome]++;\n if (keys.length > 0) group.reasons.add('route');\n if (fromFile) group.reasons.add('caller-file');\n if (event.caller !== undefined) {\n group.callers.set(JSON.stringify([event.caller.path, event.caller.line, event.caller.column]), event.caller);\n addedFiles.add(event.caller.path);\n }\n }\n }\n const routes = [...groups.entries()].sort(([a], [b]) => compareStrings(a, b)).map(([, group]): PreflightRuntimeRoute => ({\n ...group.route, observedCalls: group.count, outcomes: group.outcomes,\n callers: [...group.callers.entries()].sort(([a], [b]) => compareStrings(a, b)).slice(0, 20).map(([, caller]) => caller),\n callersOmitted: Math.max(0, group.callers.size - 20), selectionReasons: [...group.reasons].sort(compareStrings),\n }));\n const missingPlatform = (set: Set<string>, key: string): boolean =>\n [...(boundaryPlatforms.get(key) ?? [])].some((platform) => !set.has(pair(key, platform)));\n const unobservedBoundaries = required.filter(({ subject }) => missingPlatform(observed, subject.key))\n .map(({ subject }) => subject.key).sort(compareStrings);\n const uncoveredBoundaries = required.filter(({ subject }) => !aligned || missingPlatform(declared, subject.key))\n .map(({ subject }) => subject.key).sort(compareStrings);\n const gaps: PreflightLimitation[] = [];\n if (!aligned) gaps.push({ code: 'stale-runtime-expectations', message: 'Runtime expectations target a different capture revision.' });\n if (verification.status !== 'passed') gaps.push({ code: 'runtime-verification-gap',\n message: 'Declared runtime scenarios contain failures, missing observations, stale runs, or incomplete evidence.' });\n if (unobservedBoundaries.length > 0) gaps.push({ code: 'unobserved-runtime-boundaries',\n message: `${unobservedBoundaries.length} related static boundary(s) have no current runtime observations.` });\n if (uncoveredBoundaries.length > 0) gaps.push({ code: 'uncovered-runtime-boundaries',\n message: `${uncoveredBoundaries.length} related static boundary(s) have no current scenario expectation.` });\n if (routes.some(({ staticStatus }) => staticStatus !== 'candidates')) gaps.push({ code: 'runtime-static-binding-gap',\n message: 'Some related runtime routes have no supported static handler candidate; observations do not identify native symbols.' });\n const reviewFiles = [...new Set([...report.reviewFiles, ...addedFiles])].sort(compareStrings);\n const candidates = [...candidateGroups.entries()].sort(([a], [b]) => compareStrings(a, b)).map(([, value]) => value);\n return { ...report, runtime: { aligned, verification, routes, candidates, unobservedBoundaries, uncoveredBoundaries },\n reviewFiles, limitations: [...report.limitations, ...gaps],\n summary: { ...report.summary, reviewFiles: reviewFiles.length, evidenceGaps: report.summary.evidenceGaps + gaps.length } };\n}\n\nfunction routeKey(channel: string, method: string | undefined, transport = 'method-channel'): string {\n return JSON.stringify(transport === 'basic-message-channel' ? [transport, channel, null] : [channel, method ?? null]);\n}\nfunction nativeLanguage(platform: RuntimePlatform): NativeLanguage | undefined {\n return platform === 'android' ? 'kotlin' : platform === 'ios' || platform === 'macos' ? 'swift' : undefined;\n}\nfunction candidateKey(platform: NativeLanguage | undefined, channel: string, method: string | undefined,\n transport = 'method-channel'): string {\n return platform === 'kotlin' ? JSON.stringify(['kotlin', transport, channel, method ?? null]) : routeKey(channel, method, transport);\n}\n"]}
@@ -0,0 +1,146 @@
1
+ import type { BridgeEndpoint, JoinLimitation } from '../join/join.ts';
2
+ import { type PreflightRelation, type PreflightReport, type PreflightSubject } from './preflight.ts';
3
+ import type { RuntimeVerificationReport } from './runtime.ts';
4
+ /** 모든 항목 수를 보존하면서 표시 항목만 제한하는 컬렉션이다. */
5
+ export interface PreflightBounded<T> {
6
+ readonly total: number;
7
+ readonly items: readonly T[];
8
+ readonly omitted: number;
9
+ }
10
+ /** 목록 소비자가 사용할 수 있는 작은 심볼 투영이다. */
11
+ export type PreflightSubjectPreview = PreflightSubject;
12
+ export interface PreflightIssuePreview {
13
+ readonly code: string;
14
+ readonly severity: 'error' | 'warning';
15
+ readonly channel: string;
16
+ readonly method?: string;
17
+ readonly message: string;
18
+ }
19
+ export interface PreflightLimitationPreview {
20
+ readonly code: string;
21
+ readonly message: string;
22
+ readonly analysis?: string;
23
+ }
24
+ export interface PreflightBridgeLimitationPreview {
25
+ readonly platform: JoinLimitation['platform'];
26
+ readonly target: JoinLimitation['target'];
27
+ readonly tool: string;
28
+ readonly message: string;
29
+ readonly channels?: PreflightBounded<string>;
30
+ }
31
+ export interface PreflightRuntimeRoutePreview {
32
+ readonly runId: string;
33
+ readonly scenario: string;
34
+ readonly platform: string;
35
+ readonly transport: string;
36
+ readonly channel: string;
37
+ readonly method?: string;
38
+ readonly instance?: string;
39
+ readonly observedCalls: number;
40
+ readonly staticStatus: string;
41
+ readonly candidateKey?: string;
42
+ }
43
+ export interface PreflightRuntimeCandidatePreview {
44
+ readonly key: string;
45
+ readonly channel: string;
46
+ readonly method?: string;
47
+ readonly transport?: 'basic-message-channel';
48
+ readonly matching?: 'literal' | 'prefix';
49
+ readonly handlerCount: number;
50
+ readonly handlersOmitted: number;
51
+ readonly handlers: PreflightBounded<BridgeEndpoint>;
52
+ }
53
+ export interface PreflightRuntimeView {
54
+ readonly aligned: boolean;
55
+ readonly verification: {
56
+ readonly status: string;
57
+ readonly scope: string;
58
+ readonly summary: RuntimeVerificationReport['summary'];
59
+ readonly declaredScenarioPlatforms: number;
60
+ readonly nonpassedChecks: PreflightBounded<PreflightRuntimeCheckPreview>;
61
+ };
62
+ readonly unobservedBoundaries: PreflightBounded<string>;
63
+ readonly uncoveredBoundaries: PreflightBounded<string>;
64
+ readonly routes: PreflightBounded<PreflightRuntimeRoutePreview>;
65
+ readonly candidates: PreflightBounded<PreflightRuntimeCandidatePreview>;
66
+ }
67
+ export interface PreflightRuntimeCheckPreview {
68
+ readonly id: string;
69
+ readonly scenario: string;
70
+ readonly platform: string;
71
+ readonly transport: string;
72
+ readonly channel: string;
73
+ readonly method?: string;
74
+ readonly instance?: string;
75
+ readonly status: string;
76
+ readonly observedCalls: number;
77
+ }
78
+ /** 원본 보고서를 변경하지 않고 정적·runtime 정보를 압축한 뷰다. */
79
+ export interface PreflightSummaryView {
80
+ readonly format: 'isthmus-preflight-summary';
81
+ readonly version: 1;
82
+ readonly project: string;
83
+ readonly revision: string;
84
+ readonly scope: PreflightReport['scope'];
85
+ readonly complete: false;
86
+ readonly status: PreflightReport['status'];
87
+ readonly summary: PreflightReport['summary'];
88
+ readonly requiresReview: boolean;
89
+ readonly roots: PreflightBounded<{
90
+ readonly subject: PreflightSubjectPreview;
91
+ readonly depth: 0;
92
+ }>;
93
+ readonly affected: PreflightBounded<{
94
+ readonly subject: PreflightSubjectPreview;
95
+ readonly depth: number;
96
+ }>;
97
+ readonly reviewFiles: PreflightBounded<string>;
98
+ readonly issues: PreflightBounded<PreflightIssuePreview>;
99
+ readonly limitations: PreflightBounded<PreflightLimitationPreview>;
100
+ readonly bridgeLimitations: PreflightBounded<PreflightBridgeLimitationPreview>;
101
+ readonly messageLimitations?: PreflightBounded<PreflightBridgeLimitationPreview>;
102
+ readonly producers: PreflightBounded<PreflightReport['producers'][number]>;
103
+ readonly runtime?: PreflightRuntimeView;
104
+ }
105
+ interface PreflightPathStep {
106
+ readonly subject: PreflightSubjectPreview;
107
+ readonly depth: number;
108
+ readonly relations: PreflightBounded<PreflightRelationPreview>;
109
+ }
110
+ type PreflightRelationPreview = {
111
+ readonly kind: 'language';
112
+ readonly analysis: string;
113
+ readonly relationships: PreflightBounded<string>;
114
+ } | Exclude<PreflightRelation, {
115
+ readonly kind: 'language';
116
+ }>;
117
+ export interface PreflightExplanationView {
118
+ readonly format: 'isthmus-preflight-explanation';
119
+ readonly version: 1;
120
+ readonly project: string;
121
+ readonly revision: string;
122
+ readonly scope: PreflightReport['scope'];
123
+ readonly complete: false;
124
+ readonly status: 'found' | 'notFound' | 'ambiguous';
125
+ readonly selector: string;
126
+ readonly summary: PreflightReport['summary'];
127
+ readonly requiresReview: boolean;
128
+ readonly issues: PreflightBounded<PreflightIssuePreview>;
129
+ readonly limitations: PreflightBounded<PreflightLimitationPreview>;
130
+ readonly bridgeLimitations: PreflightBounded<PreflightBridgeLimitationPreview>;
131
+ readonly messageLimitations?: PreflightBounded<PreflightBridgeLimitationPreview>;
132
+ readonly runtime?: PreflightRuntimeView;
133
+ readonly result?: {
134
+ readonly subject: PreflightSubjectPreview;
135
+ readonly path: readonly PreflightPathStep[];
136
+ };
137
+ readonly candidates?: PreflightBounded<{
138
+ readonly key: string;
139
+ readonly subject: PreflightSubjectPreview;
140
+ }>;
141
+ }
142
+ /** 전체 보고서에서 상태와 개수를 계산한 뒤 목록 항목만 제한한 preflight 뷰를 만든다. */
143
+ export declare function createPreflightSummary(report: PreflightReport, limit?: number): PreflightSummaryView;
144
+ /** 정확히 일치하는 심볼을 설명하고, 찾으면 root부터의 전체 경로를 제공한다. */
145
+ export declare function createPreflightExplanation(report: PreflightReport, selector: string): PreflightExplanationView;
146
+ export {};
@@ -0,0 +1,216 @@
1
+ import { compareStrings } from "../compare.js";
2
+ import { isReceiverPlatform } from "../exchange/parse.js";
3
+ import { hasPreflightBlockers, PreflightGraphError } from "./preflight.js";
4
+ const VIEW_LIMIT = 20;
5
+ /** 전체 보고서에서 상태와 개수를 계산한 뒤 목록 항목만 제한한 preflight 뷰를 만든다. */
6
+ export function createPreflightSummary(report, limit = VIEW_LIMIT) {
7
+ assertLimit(limit);
8
+ const view = commonView(report, limit);
9
+ return {
10
+ format: 'isthmus-preflight-summary', version: 1,
11
+ project: report.project, revision: report.revision, scope: report.scope,
12
+ complete: false, status: report.status, summary: report.summary,
13
+ requiresReview: requiresReview(report),
14
+ roots: bounded(sortedRoots(report.roots).map((subject) => ({ subject, depth: 0 })), limit),
15
+ affected: bounded(sortedAffected(report.affected).map(({ subject, depth }) => ({ subject, depth })), limit),
16
+ ...view,
17
+ };
18
+ }
19
+ /** 정확히 일치하는 심볼을 설명하고, 찾으면 root부터의 전체 경로를 제공한다. */
20
+ export function createPreflightExplanation(report, selector) {
21
+ const limit = VIEW_LIMIT;
22
+ const view = commonView(report, limit);
23
+ const subjects = allSubjects(report);
24
+ const matches = matchingSubjects(subjects, selector);
25
+ const base = {
26
+ format: 'isthmus-preflight-explanation', version: 1,
27
+ project: report.project, revision: report.revision, scope: report.scope,
28
+ complete: false, selector, summary: report.summary,
29
+ requiresReview: requiresReview(report), ...view,
30
+ };
31
+ if (matches.length === 0)
32
+ return { ...base, status: 'notFound' };
33
+ const candidates = bounded(matches.map(({ subject }) => ({ key: subject.key, subject })), limit);
34
+ if (matches.length !== 1)
35
+ return { ...base, status: 'ambiguous', candidates };
36
+ const target = matches[0].subject;
37
+ return { ...base, status: 'found', result: { subject: target, path: pathFor(report, target.key) } };
38
+ }
39
+ function commonView(report, limit) {
40
+ return {
41
+ reviewFiles: bounded([...report.reviewFiles].sort(compareStrings), limit),
42
+ issues: bounded([...report.issues].sort(compareIssues).map(issuePreview), limit),
43
+ limitations: bounded([...report.limitations].sort(compareLimitations).map(({ code, message, analysis }) => ({
44
+ code, message, ...(analysis === undefined ? {} : { analysis }),
45
+ })), limit),
46
+ bridgeLimitations: bounded([...report.bridgeLimitations].sort(compareBridgeLimitations).map((limitation) => ({
47
+ platform: limitation.platform, target: limitation.target, tool: limitation.tool, message: limitation.message,
48
+ ...(limitation.channels === undefined ? {} : { channels: bounded([...limitation.channels].sort(compareStrings), limit) }),
49
+ })), limit),
50
+ ...(report.messageLimitations === undefined ? {} : { messageLimitations: bounded([...report.messageLimitations]
51
+ .sort(compareBridgeLimitations).map(({ platform, target, tool, message }) => ({ platform, target, tool, message })), limit) }),
52
+ producers: bounded([...report.producers].sort((a, b) => compareStrings(a.analysis, b.analysis) || compareStrings(a.platform, b.platform)), limit),
53
+ ...(report.runtime === undefined ? {} : { runtime: runtimeView(report, limit) }),
54
+ };
55
+ }
56
+ function runtimeView(report, limit) {
57
+ const runtime = report.runtime;
58
+ const checks = runtime.verification.checks.filter(({ status }) => status !== 'passed');
59
+ const pairs = new Set(runtime.verification.checks.map(({ expected }) => JSON.stringify([expected.scenario, expected.platform])));
60
+ return {
61
+ aligned: runtime.aligned,
62
+ verification: {
63
+ status: runtime.verification.status, scope: runtime.verification.scope,
64
+ summary: runtime.verification.summary,
65
+ declaredScenarioPlatforms: pairs.size,
66
+ nonpassedChecks: bounded(checks.map(runtimeCheckPreview).sort(compareRuntimeChecks), limit),
67
+ },
68
+ unobservedBoundaries: bounded([...runtime.unobservedBoundaries].sort(compareStrings), limit),
69
+ uncoveredBoundaries: bounded([...runtime.uncoveredBoundaries].sort(compareStrings), limit),
70
+ routes: bounded(runtime.routes.map(runtimeRoutePreview).sort(compareRuntimeRoutes), limit),
71
+ candidates: bounded(runtime.candidates.map((candidate) => ({
72
+ key: candidate.key, channel: candidate.channel, ...(candidate.method === undefined ? {} : { method: candidate.method }),
73
+ ...(candidate.transport === undefined ? {} : { transport: candidate.transport, matching: candidate.matching }),
74
+ handlerCount: candidate.handlers.length + candidate.handlersOmitted, handlersOmitted: candidate.handlersOmitted,
75
+ handlers: { total: candidate.handlers.length + candidate.handlersOmitted,
76
+ items: candidate.handlers.slice(0, limit),
77
+ omitted: candidate.handlers.length + candidate.handlersOmitted - Math.min(candidate.handlers.length, limit) },
78
+ })).sort((a, b) => compareStrings(a.key, b.key)), limit),
79
+ };
80
+ }
81
+ function runtimeCheckPreview(check) {
82
+ const expected = check.expected;
83
+ return {
84
+ id: expected.id, scenario: expected.scenario, platform: expected.platform,
85
+ transport: expected.transport, channel: expected.channel,
86
+ ...(expected.method === undefined ? {} : { method: expected.method }),
87
+ ...(expected.instance === undefined ? {} : { instance: expected.instance }),
88
+ status: check.status, observedCalls: check.observedCalls,
89
+ };
90
+ }
91
+ function runtimeRoutePreview(route) {
92
+ return {
93
+ runId: route.runId, scenario: route.scenario, platform: route.platform, transport: route.transport,
94
+ channel: route.channel, ...(route.method === undefined ? {} : { method: route.method }),
95
+ ...(route.instance === undefined ? {} : { instance: route.instance }),
96
+ observedCalls: route.observedCalls, staticStatus: route.staticStatus,
97
+ ...(route.candidateKey === undefined ? {} : { candidateKey: route.candidateKey }),
98
+ };
99
+ }
100
+ /** 증거 위치가 수신 측(네이티브) 플랫폼에서 온 것인지 구분한다. */
101
+ function isReceiverEndpoint(endpoint) {
102
+ return isReceiverPlatform(endpoint.platform);
103
+ }
104
+ function issuePreview(issue) {
105
+ const route = issue.method === undefined ? issue.channel : `${issue.channel}.${issue.method}`;
106
+ const message = issue.code === 'unhandled-invocation' || issue.code === 'unhandled-invocation-unverified'
107
+ ? `No native handler was verified for ${route}.`
108
+ : issue.code === 'unregistered-channel-creation' || issue.code === 'unregistered-channel-creation-unverified'
109
+ ? `No native registration was verified for ${route}.`
110
+ : issue.code === 'registration-without-creation'
111
+ ? `Native registration has no verified channel creation for ${route}.`
112
+ : issue.code === 'module-import-without-export' || issue.code === 'module-import-without-export-unverified'
113
+ ? `No native module export was verified for ${route}.`
114
+ : issue.code === 'module-import-without-export-optional'
115
+ ? `No native module export was verified for ${route}, but every caller tolerates absence.`
116
+ : issue.code === 'module-import-mechanism-mismatch'
117
+ ? `Observed module exports for ${route} resolve through a different bridge mechanism.`
118
+ : issue.code === 'component-require-without-export' || issue.code === 'component-require-without-export-unverified'
119
+ // Expo require가 코어 export만 관찰된 경우 error 코드지만
120
+ // 원인은 mechanism 불일치다 — 없다는 문구는 틀리다.
121
+ ? issue.evidence.some(isReceiverEndpoint)
122
+ ? `Observed component exports for ${route} resolve through a different bridge mechanism.`
123
+ : `No native component export was verified for ${route}.`
124
+ : issue.code === 'component-require-mechanism-mismatch'
125
+ ? `Observed component exports for ${route} resolve through a different bridge mechanism.`
126
+ : issue.code === 'module-export-without-import'
127
+ ? `Native module export has no verified import for ${route}.`
128
+ : issue.code === 'module-export-mechanism-mismatch'
129
+ ? `Observed module imports for ${route} resolve through a different bridge mechanism.`
130
+ : issue.code === 'component-export-without-require'
131
+ ? `Native component export has no verified require for ${route}.`
132
+ : issue.code === 'component-export-mechanism-mismatch'
133
+ ? `Observed component requires for ${route} resolve through a different bridge mechanism.`
134
+ : `Native handler has no verified invocation for ${route}.`;
135
+ return {
136
+ code: issue.code, severity: issue.severity, channel: issue.channel,
137
+ ...(issue.method === undefined ? {} : { method: issue.method }), message,
138
+ };
139
+ }
140
+ function pathFor(report, targetKey) {
141
+ const roots = new Map(report.roots.map((subject) => [subject.key, subject]));
142
+ const affected = new Map(report.affected.map((item) => [item.subject.key, item]));
143
+ const steps = [];
144
+ const seen = new Set();
145
+ let reachedRoot = false;
146
+ let key = targetKey;
147
+ while (key !== undefined) {
148
+ if (seen.has(key))
149
+ throw new PreflightGraphError('Preflight explanation encountered a cyclic path.');
150
+ seen.add(key);
151
+ const root = roots.get(key);
152
+ if (root !== undefined) {
153
+ steps.push({ subject: root, depth: 0, relations: bounded([], VIEW_LIMIT) });
154
+ reachedRoot = true;
155
+ break;
156
+ }
157
+ const item = affected.get(key);
158
+ if (item === undefined)
159
+ throw new PreflightGraphError('Preflight explanation refers to an unknown path node.');
160
+ steps.push({ subject: item.subject, depth: item.depth, relations: relationPreview(item.relations, VIEW_LIMIT) });
161
+ key = item.via;
162
+ }
163
+ if (!reachedRoot) {
164
+ throw new PreflightGraphError('Preflight explanation could not find a root path.');
165
+ }
166
+ return steps.reverse();
167
+ }
168
+ function relationPreview(relations, limit) {
169
+ return bounded(relations.map((relation) => relation.kind === 'language'
170
+ ? { kind: 'language', analysis: relation.analysis, relationships: bounded([...relation.relationships].sort(compareStrings), limit) }
171
+ : relation), limit);
172
+ }
173
+ function allSubjects(report) {
174
+ const values = [...report.roots, ...report.affected.map(({ subject }) => subject)];
175
+ const unique = new Map();
176
+ values.forEach((subject, index) => { if (!unique.has(subject.key))
177
+ unique.set(subject.key, { subject, index }); });
178
+ return [...unique.values()].sort((a, b) => compareStrings(a.subject.key, b.subject.key) || a.index - b.index);
179
+ }
180
+ function matchingSubjects(subjects, selector) {
181
+ const keys = subjects.filter(({ subject }) => subject.key === selector);
182
+ if (keys.length > 0)
183
+ return keys;
184
+ const ids = subjects.filter(({ subject }) => subject.kind === 'symbol' && subject.symbol.id === selector);
185
+ if (ids.length > 0)
186
+ return ids;
187
+ return subjects.filter(({ subject }) => subject.kind === 'symbol' && subject.symbol.qualifiedName === selector);
188
+ }
189
+ function sortedRoots(subjects) { return [...subjects].sort((a, b) => compareStrings(a.key, b.key)); }
190
+ function sortedAffected(affected) {
191
+ return [...affected].sort((a, b) => a.depth - b.depth || compareStrings(a.subject.key, b.subject.key));
192
+ }
193
+ function bounded(items, limit) {
194
+ return { total: items.length, items: items.slice(0, limit), omitted: Math.max(0, items.length - limit) };
195
+ }
196
+ function assertLimit(limit) {
197
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100)
198
+ throw new RangeError('Preflight view limit must be an integer from 1 to 100.');
199
+ }
200
+ function requiresReview(report) {
201
+ return hasPreflightBlockers(report);
202
+ }
203
+ function compareIssues(a, b) {
204
+ return compareStrings(a.code, b.code) || compareStrings(a.channel, b.channel) || compareStrings(a.method ?? '', b.method ?? '') || compareStrings(a.severity, b.severity);
205
+ }
206
+ function compareLimitations(a, b) {
207
+ return compareStrings(a.code, b.code) || compareStrings(a.analysis ?? '', b.analysis ?? '') || compareStrings(a.message, b.message);
208
+ }
209
+ function compareBridgeLimitations(a, b) {
210
+ return compareStrings(a.platform, b.platform) || compareStrings(a.target ?? '', b.target ?? '') || compareStrings(a.tool, b.tool) || compareStrings(a.message, b.message);
211
+ }
212
+ function compareRuntimeChecks(a, b) { return compareStrings(a.id, b.id); }
213
+ function compareRuntimeRoutes(a, b) {
214
+ return compareStrings(a.runId, b.runId) || compareStrings(a.channel, b.channel) || compareStrings(a.method ?? '', b.method ?? '') || compareStrings(a.instance ?? '', b.instance ?? '');
215
+ }
216
+ //# sourceMappingURL=preflight-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight-view.js","sourceRoot":"","sources":["../../src/report/preflight-view.ts"],"names":[],"mappings":"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","sourcesContent":["import { compareStrings } from '../compare.ts';\nimport { isReceiverPlatform } from '../exchange/parse.ts';\nimport type { BridgeEndpoint, JoinLimitation } from '../join/join.ts';\nimport { hasPreflightBlockers, PreflightGraphError, type PreflightAffected, type PreflightRelation, type PreflightReport, type PreflightSubject } from './preflight.ts';\nimport type { RuntimeCheckResult } from './runtime.ts';\nimport type { RuntimeVerificationReport } from './runtime.ts';\n\n/** 모든 항목 수를 보존하면서 표시 항목만 제한하는 컬렉션이다. */\nexport interface PreflightBounded<T> {\n readonly total: number;\n readonly items: readonly T[];\n readonly omitted: number;\n}\n\n/** 목록 소비자가 사용할 수 있는 작은 심볼 투영이다. */\nexport type PreflightSubjectPreview = PreflightSubject;\n\nexport interface PreflightIssuePreview {\n readonly code: string;\n readonly severity: 'error' | 'warning';\n readonly channel: string;\n readonly method?: string;\n readonly message: string;\n}\n\nexport interface PreflightLimitationPreview {\n readonly code: string;\n readonly message: string;\n readonly analysis?: string;\n}\n\nexport interface PreflightBridgeLimitationPreview {\n readonly platform: JoinLimitation['platform'];\n readonly target: JoinLimitation['target'];\n readonly tool: string;\n readonly message: string;\n readonly channels?: PreflightBounded<string>;\n}\n\nexport interface PreflightRuntimeRoutePreview {\n readonly runId: string;\n readonly scenario: string;\n readonly platform: string;\n readonly transport: string;\n readonly channel: string;\n readonly method?: string;\n readonly instance?: string;\n readonly observedCalls: number;\n readonly staticStatus: string;\n readonly candidateKey?: string;\n}\n\nexport interface PreflightRuntimeCandidatePreview {\n readonly key: string;\n readonly channel: string;\n readonly method?: string;\n readonly transport?: 'basic-message-channel';\n readonly matching?: 'literal' | 'prefix';\n readonly handlerCount: number;\n readonly handlersOmitted: number;\n readonly handlers: PreflightBounded<BridgeEndpoint>;\n}\n\nexport interface PreflightRuntimeView {\n readonly aligned: boolean;\n readonly verification: {\n readonly status: string;\n readonly scope: string;\n readonly summary: RuntimeVerificationReport['summary'];\n readonly declaredScenarioPlatforms: number;\n readonly nonpassedChecks: PreflightBounded<PreflightRuntimeCheckPreview>;\n };\n readonly unobservedBoundaries: PreflightBounded<string>;\n readonly uncoveredBoundaries: PreflightBounded<string>;\n readonly routes: PreflightBounded<PreflightRuntimeRoutePreview>;\n readonly candidates: PreflightBounded<PreflightRuntimeCandidatePreview>;\n}\n\nexport interface PreflightRuntimeCheckPreview {\n readonly id: string;\n readonly scenario: string;\n readonly platform: string;\n readonly transport: string;\n readonly channel: string;\n readonly method?: string;\n readonly instance?: string;\n readonly status: string;\n readonly observedCalls: number;\n}\n\n/** 원본 보고서를 변경하지 않고 정적·runtime 정보를 압축한 뷰다. */\nexport interface PreflightSummaryView {\n readonly format: 'isthmus-preflight-summary';\n readonly version: 1;\n readonly project: string;\n readonly revision: string;\n readonly scope: PreflightReport['scope'];\n readonly complete: false;\n readonly status: PreflightReport['status'];\n readonly summary: PreflightReport['summary'];\n readonly requiresReview: boolean;\n readonly roots: PreflightBounded<{ readonly subject: PreflightSubjectPreview; readonly depth: 0 }>;\n readonly affected: PreflightBounded<{ readonly subject: PreflightSubjectPreview; readonly depth: number }>;\n readonly reviewFiles: PreflightBounded<string>;\n readonly issues: PreflightBounded<PreflightIssuePreview>;\n readonly limitations: PreflightBounded<PreflightLimitationPreview>;\n readonly bridgeLimitations: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly messageLimitations?: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly producers: PreflightBounded<PreflightReport['producers'][number]>;\n readonly runtime?: PreflightRuntimeView;\n}\n\ninterface PreflightPathStep {\n readonly subject: PreflightSubjectPreview;\n readonly depth: number;\n readonly relations: PreflightBounded<PreflightRelationPreview>;\n}\n\ntype PreflightRelationPreview =\n | { readonly kind: 'language'; readonly analysis: string; readonly relationships: PreflightBounded<string> }\n | Exclude<PreflightRelation, { readonly kind: 'language' }>;\n\nexport interface PreflightExplanationView {\n readonly format: 'isthmus-preflight-explanation';\n readonly version: 1;\n readonly project: string;\n readonly revision: string;\n readonly scope: PreflightReport['scope'];\n readonly complete: false;\n readonly status: 'found' | 'notFound' | 'ambiguous';\n readonly selector: string;\n readonly summary: PreflightReport['summary'];\n readonly requiresReview: boolean;\n readonly issues: PreflightBounded<PreflightIssuePreview>;\n readonly limitations: PreflightBounded<PreflightLimitationPreview>;\n readonly bridgeLimitations: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly messageLimitations?: PreflightBounded<PreflightBridgeLimitationPreview>;\n readonly runtime?: PreflightRuntimeView;\n readonly result?: { readonly subject: PreflightSubjectPreview; readonly path: readonly PreflightPathStep[] };\n readonly candidates?: PreflightBounded<{ readonly key: string; readonly subject: PreflightSubjectPreview }>;\n}\n\nconst VIEW_LIMIT = 20;\n\n/** 전체 보고서에서 상태와 개수를 계산한 뒤 목록 항목만 제한한 preflight 뷰를 만든다. */\nexport function createPreflightSummary(report: PreflightReport, limit = VIEW_LIMIT): PreflightSummaryView {\n assertLimit(limit);\n const view = commonView(report, limit);\n return {\n format: 'isthmus-preflight-summary', version: 1,\n project: report.project, revision: report.revision, scope: report.scope,\n complete: false, status: report.status, summary: report.summary,\n requiresReview: requiresReview(report),\n roots: bounded(sortedRoots(report.roots).map((subject) => ({ subject, depth: 0 as const })), limit),\n affected: bounded(sortedAffected(report.affected).map(({ subject, depth }) => ({ subject, depth })), limit),\n ...view,\n };\n}\n\n/** 정확히 일치하는 심볼을 설명하고, 찾으면 root부터의 전체 경로를 제공한다. */\nexport function createPreflightExplanation(report: PreflightReport, selector: string): PreflightExplanationView {\n const limit = VIEW_LIMIT;\n const view = commonView(report, limit);\n const subjects = allSubjects(report);\n const matches = matchingSubjects(subjects, selector);\n const base = {\n format: 'isthmus-preflight-explanation' as const, version: 1 as const,\n project: report.project, revision: report.revision, scope: report.scope,\n complete: false as const, selector, summary: report.summary,\n requiresReview: requiresReview(report), ...view,\n };\n if (matches.length === 0) return { ...base, status: 'notFound' };\n const candidates = bounded(matches.map(({ subject }) => ({ key: subject.key, subject })), limit);\n if (matches.length !== 1) return { ...base, status: 'ambiguous', candidates };\n const target = matches[0]!.subject;\n return { ...base, status: 'found', result: { subject: target, path: pathFor(report, target.key) } };\n}\n\nfunction commonView(report: PreflightReport, limit: number): Pick<PreflightSummaryView, 'reviewFiles' | 'issues' | 'limitations' | 'bridgeLimitations' | 'messageLimitations' | 'producers' | 'runtime'> {\n return {\n reviewFiles: bounded([...report.reviewFiles].sort(compareStrings), limit),\n issues: bounded([...report.issues].sort(compareIssues).map(issuePreview), limit),\n limitations: bounded([...report.limitations].sort(compareLimitations).map(({ code, message, analysis }) => ({\n code, message, ...(analysis === undefined ? {} : { analysis }),\n })), limit),\n bridgeLimitations: bounded([...report.bridgeLimitations].sort(compareBridgeLimitations).map((limitation) => ({\n platform: limitation.platform, target: limitation.target, tool: limitation.tool, message: limitation.message,\n ...(limitation.channels === undefined ? {} : { channels: bounded([...limitation.channels].sort(compareStrings), limit) }),\n })), limit),\n ...(report.messageLimitations === undefined ? {} : { messageLimitations: bounded([...report.messageLimitations]\n .sort(compareBridgeLimitations).map(({ platform, target, tool, message }) => ({ platform, target, tool, message })), limit) }),\n producers: bounded([...report.producers].sort((a, b) => compareStrings(a.analysis, b.analysis) || compareStrings(a.platform, b.platform)), limit),\n ...(report.runtime === undefined ? {} : { runtime: runtimeView(report, limit) }),\n };\n}\n\nfunction runtimeView(report: PreflightReport, limit: number): PreflightRuntimeView {\n const runtime = report.runtime!;\n const checks = runtime.verification.checks.filter(({ status }) => status !== 'passed');\n const pairs = new Set(runtime.verification.checks.map(({ expected }) => JSON.stringify([expected.scenario, expected.platform])));\n return {\n aligned: runtime.aligned,\n verification: {\n status: runtime.verification.status, scope: runtime.verification.scope,\n summary: runtime.verification.summary,\n declaredScenarioPlatforms: pairs.size,\n nonpassedChecks: bounded(checks.map(runtimeCheckPreview).sort(compareRuntimeChecks), limit),\n },\n unobservedBoundaries: bounded([...runtime.unobservedBoundaries].sort(compareStrings), limit),\n uncoveredBoundaries: bounded([...runtime.uncoveredBoundaries].sort(compareStrings), limit),\n routes: bounded(runtime.routes.map(runtimeRoutePreview).sort(compareRuntimeRoutes), limit),\n candidates: bounded(runtime.candidates.map((candidate) => ({\n key: candidate.key, channel: candidate.channel, ...(candidate.method === undefined ? {} : { method: candidate.method }),\n ...(candidate.transport === undefined ? {} : { transport: candidate.transport, matching: candidate.matching! }),\n handlerCount: candidate.handlers.length + candidate.handlersOmitted, handlersOmitted: candidate.handlersOmitted,\n handlers: { total: candidate.handlers.length + candidate.handlersOmitted,\n items: candidate.handlers.slice(0, limit),\n omitted: candidate.handlers.length + candidate.handlersOmitted - Math.min(candidate.handlers.length, limit) },\n })).sort((a, b) => compareStrings(a.key, b.key)), limit),\n };\n}\n\nfunction runtimeCheckPreview(check: RuntimeCheckResult): PreflightRuntimeCheckPreview {\n const expected = check.expected;\n return {\n id: expected.id, scenario: expected.scenario, platform: expected.platform,\n transport: expected.transport, channel: expected.channel,\n ...(expected.method === undefined ? {} : { method: expected.method }),\n ...(expected.instance === undefined ? {} : { instance: expected.instance }),\n status: check.status, observedCalls: check.observedCalls,\n };\n}\n\nfunction runtimeRoutePreview(route: NonNullable<PreflightReport['runtime']>['routes'][number]): PreflightRuntimeRoutePreview {\n return {\n runId: route.runId, scenario: route.scenario, platform: route.platform, transport: route.transport,\n channel: route.channel, ...(route.method === undefined ? {} : { method: route.method }),\n ...(route.instance === undefined ? {} : { instance: route.instance }),\n observedCalls: route.observedCalls, staticStatus: route.staticStatus,\n ...(route.candidateKey === undefined ? {} : { candidateKey: route.candidateKey }),\n };\n}\n\n/** 증거 위치가 수신 측(네이티브) 플랫폼에서 온 것인지 구분한다. */\nfunction isReceiverEndpoint(endpoint: BridgeEndpoint): boolean {\n return isReceiverPlatform(endpoint.platform);\n}\n\nfunction issuePreview(issue: PreflightReport['issues'][number]): PreflightIssuePreview {\n const route = issue.method === undefined ? issue.channel : `${issue.channel}.${issue.method}`;\n const message = issue.code === 'unhandled-invocation' || issue.code === 'unhandled-invocation-unverified'\n ? `No native handler was verified for ${route}.`\n : issue.code === 'unregistered-channel-creation' || issue.code === 'unregistered-channel-creation-unverified'\n ? `No native registration was verified for ${route}.`\n : issue.code === 'registration-without-creation'\n ? `Native registration has no verified channel creation for ${route}.`\n : issue.code === 'module-import-without-export' || issue.code === 'module-import-without-export-unverified'\n ? `No native module export was verified for ${route}.`\n : issue.code === 'module-import-without-export-optional'\n ? `No native module export was verified for ${route}, but every caller tolerates absence.`\n : issue.code === 'module-import-mechanism-mismatch'\n ? `Observed module exports for ${route} resolve through a different bridge mechanism.`\n : issue.code === 'component-require-without-export' || issue.code === 'component-require-without-export-unverified'\n // Expo require가 코어 export만 관찰된 경우 error 코드지만\n // 원인은 mechanism 불일치다 — 없다는 문구는 틀리다.\n ? issue.evidence.some(isReceiverEndpoint)\n ? `Observed component exports for ${route} resolve through a different bridge mechanism.`\n : `No native component export was verified for ${route}.`\n : issue.code === 'component-require-mechanism-mismatch'\n ? `Observed component exports for ${route} resolve through a different bridge mechanism.`\n : issue.code === 'module-export-without-import'\n ? `Native module export has no verified import for ${route}.`\n : issue.code === 'module-export-mechanism-mismatch'\n ? `Observed module imports for ${route} resolve through a different bridge mechanism.`\n : issue.code === 'component-export-without-require'\n ? `Native component export has no verified require for ${route}.`\n : issue.code === 'component-export-mechanism-mismatch'\n ? `Observed component requires for ${route} resolve through a different bridge mechanism.`\n : `Native handler has no verified invocation for ${route}.`;\n return {\n code: issue.code, severity: issue.severity, channel: issue.channel,\n ...(issue.method === undefined ? {} : { method: issue.method }), message,\n };\n}\n\nfunction pathFor(report: PreflightReport, targetKey: string): PreflightPathStep[] {\n const roots = new Map(report.roots.map((subject) => [subject.key, subject]));\n const affected = new Map(report.affected.map((item) => [item.subject.key, item]));\n const steps: PreflightPathStep[] = [];\n const seen = new Set<string>();\n let reachedRoot = false;\n let key: string | undefined = targetKey;\n while (key !== undefined) {\n if (seen.has(key)) throw new PreflightGraphError('Preflight explanation encountered a cyclic path.');\n seen.add(key);\n const root = roots.get(key);\n if (root !== undefined) {\n steps.push({ subject: root, depth: 0, relations: bounded([], VIEW_LIMIT) });\n reachedRoot = true;\n break;\n }\n const item = affected.get(key);\n if (item === undefined) throw new PreflightGraphError('Preflight explanation refers to an unknown path node.');\n steps.push({ subject: item.subject, depth: item.depth, relations: relationPreview(item.relations, VIEW_LIMIT) });\n key = item.via;\n }\n if (!reachedRoot) {\n throw new PreflightGraphError('Preflight explanation could not find a root path.');\n }\n return steps.reverse();\n}\n\nfunction relationPreview(relations: readonly PreflightRelation[], limit: number): PreflightBounded<PreflightRelationPreview> {\n return bounded(relations.map((relation) => relation.kind === 'language'\n ? { kind: 'language' as const, analysis: relation.analysis, relationships: bounded([...relation.relationships].sort(compareStrings), limit) }\n : relation), limit);\n}\n\nfunction allSubjects(report: PreflightReport): Array<{ subject: PreflightSubject; index: number }> {\n const values = [...report.roots, ...report.affected.map(({ subject }) => subject)];\n const unique = new Map<string, { subject: PreflightSubject; index: number }>();\n values.forEach((subject, index) => { if (!unique.has(subject.key)) unique.set(subject.key, { subject, index }); });\n return [...unique.values()].sort((a, b) => compareStrings(a.subject.key, b.subject.key) || a.index - b.index);\n}\n\nfunction matchingSubjects(subjects: readonly { subject: PreflightSubject; index: number }[], selector: string): Array<{ subject: PreflightSubject; index: number }> {\n const keys = subjects.filter(({ subject }) => subject.key === selector);\n if (keys.length > 0) return keys;\n const ids = subjects.filter(({ subject }) => subject.kind === 'symbol' && subject.symbol.id === selector);\n if (ids.length > 0) return ids;\n return subjects.filter(({ subject }) => subject.kind === 'symbol' && subject.symbol.qualifiedName === selector);\n}\n\nfunction sortedRoots(subjects: readonly PreflightSubject[]): PreflightSubject[] { return [...subjects].sort((a, b) => compareStrings(a.key, b.key)); }\nfunction sortedAffected(affected: readonly PreflightAffected[]): PreflightAffected[] {\n return [...affected].sort((a, b) => a.depth - b.depth || compareStrings(a.subject.key, b.subject.key));\n}\n\nfunction bounded<T>(items: readonly T[], limit: number): PreflightBounded<T> {\n return { total: items.length, items: items.slice(0, limit), omitted: Math.max(0, items.length - limit) };\n}\n\nfunction assertLimit(limit: number): asserts limit is number {\n if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100) throw new RangeError('Preflight view limit must be an integer from 1 to 100.');\n}\n\nfunction requiresReview(report: PreflightReport): boolean {\n return hasPreflightBlockers(report);\n}\n\nfunction compareIssues(a: PreflightReport['issues'][number], b: PreflightReport['issues'][number]): number {\n return compareStrings(a.code, b.code) || compareStrings(a.channel, b.channel) || compareStrings(a.method ?? '', b.method ?? '') || compareStrings(a.severity, b.severity);\n}\nfunction compareLimitations(a: PreflightReport['limitations'][number], b: PreflightReport['limitations'][number]): number {\n return compareStrings(a.code, b.code) || compareStrings(a.analysis ?? '', b.analysis ?? '') || compareStrings(a.message, b.message);\n}\nfunction compareBridgeLimitations(a: JoinLimitation, b: JoinLimitation): number {\n return compareStrings(a.platform, b.platform) || compareStrings(a.target ?? '', b.target ?? '') || compareStrings(a.tool, b.tool) || compareStrings(a.message, b.message);\n}\nfunction compareRuntimeChecks(a: PreflightRuntimeCheckPreview, b: PreflightRuntimeCheckPreview): number { return compareStrings(a.id, b.id); }\nfunction compareRuntimeRoutes(a: PreflightRuntimeRoutePreview, b: PreflightRuntimeRoutePreview): number {\n return compareStrings(a.runId, b.runId) || compareStrings(a.channel, b.channel) || compareStrings(a.method ?? '', b.method ?? '') || compareStrings(a.instance ?? '', b.instance ?? '');\n}\n"]}
@@ -0,0 +1,104 @@
1
+ import type { ImpactSymbol, PreflightContext } from '../exchange/preflight-context.ts';
2
+ import type { BridgeEndpoint, JoinLimitation } from '../join/join.ts';
3
+ import type { BridgeTarget } from '../exchange/parse.ts';
4
+ import type { CheckIssue } from './check-report.ts';
5
+ import type { PreflightRuntimeReport } from './preflight-runtime.ts';
6
+ import type { BridgeHandlerDependency, BridgeMessageTransport } from '../exchange/messages.ts';
7
+ import type { BridgeSymbol } from '../exchange/parse.ts';
8
+ type Language = 'dart' | 'swift' | 'kotlin';
9
+ /** 언어 심볼과 경계의 키 공간을 분리한다. 원래 producer ID는 symbol.id에 보존한다. */
10
+ export type PreflightSubject = {
11
+ readonly key: string;
12
+ readonly kind: 'symbol';
13
+ readonly platform: Language;
14
+ readonly symbol: ImpactSymbol;
15
+ } | {
16
+ readonly key: string;
17
+ readonly kind: 'bridge';
18
+ readonly target: BridgeTarget;
19
+ readonly channel: string;
20
+ readonly method?: string;
21
+ readonly transport?: BridgeMessageTransport;
22
+ readonly matching?: 'literal' | 'prefix';
23
+ };
24
+ /** 실제 producer 사용 관계와 문자열 브리지 관계를 서로 다른 근거로 표시한다. */
25
+ export type PreflightRelation = {
26
+ readonly kind: 'language';
27
+ readonly analysis: string;
28
+ readonly relationships: readonly string[];
29
+ } | {
30
+ readonly kind: 'bridge-message-dependency' | 'bridge-stream-dependency' | 'bridge-method-dependency';
31
+ readonly evidence: BridgeEndpoint;
32
+ readonly dependency: Omit<BridgeHandlerDependency, 'dispatchTargets'>;
33
+ readonly dispatchTarget?: BridgeSymbol;
34
+ } | {
35
+ readonly kind: 'bridge-handler' | 'bridge-registration' | 'bridge-invocation' | 'bridge-creation' | 'bridge-message-send' | 'bridge-message-handler' | 'bridge-stream-listen' | 'bridge-stream-handler';
36
+ readonly evidence: BridgeEndpoint;
37
+ };
38
+ /** 가장 가까운 변경 씨앗까지의 선행 정점을 공유해 긴 경로 복사를 피한다. */
39
+ export interface PreflightAffected {
40
+ readonly subject: PreflightSubject;
41
+ readonly depth: number;
42
+ readonly via: string;
43
+ readonly relations: readonly PreflightRelation[];
44
+ }
45
+ /** 근거를 연결할 수 없는 부분과 발생 위치다. */
46
+ export interface PreflightLimitation {
47
+ readonly code: string;
48
+ readonly message: string;
49
+ readonly analysis?: string;
50
+ readonly evidence?: BridgeEndpoint;
51
+ }
52
+ /** 언어별 영향 투영과 브리지 관계를 연결한 사전 검토 문서다. */
53
+ export interface PreflightReport {
54
+ readonly format: 'isthmus-preflight';
55
+ readonly version: 1;
56
+ readonly project: string;
57
+ readonly revision: string;
58
+ readonly scope: 'cross-language-impact';
59
+ readonly complete: false;
60
+ readonly status: 'observed' | 'unobserved' | 'noChanges';
61
+ readonly selection: PreflightContext['selection'];
62
+ readonly roots: readonly PreflightSubject[];
63
+ readonly affected: readonly PreflightAffected[];
64
+ readonly boundaries: readonly {
65
+ subject: Extract<PreflightSubject, {
66
+ kind: 'bridge';
67
+ }>;
68
+ relationship: 'consumer' | 'dependency';
69
+ callers: readonly BridgeEndpoint[];
70
+ receivers: readonly BridgeEndpoint[];
71
+ }[];
72
+ readonly reviewFiles: readonly string[];
73
+ readonly issues: readonly CheckIssue[];
74
+ readonly limitations: readonly PreflightLimitation[];
75
+ readonly bridgeLimitations: readonly JoinLimitation[];
76
+ readonly messageLimitations?: readonly JoinLimitation[];
77
+ readonly runtime?: PreflightRuntimeReport;
78
+ readonly producers: ReadonlyArray<{
79
+ analysis: string;
80
+ platform: Language;
81
+ tool: {
82
+ name: string;
83
+ version: string;
84
+ };
85
+ truncated: boolean;
86
+ }>;
87
+ readonly summary: {
88
+ selectedSymbols: number;
89
+ affectedSymbols: number;
90
+ bridgeBoundaries: number;
91
+ reviewFiles: number;
92
+ errors: number;
93
+ warnings: number;
94
+ evidenceGaps: number;
95
+ };
96
+ }
97
+ /** 잘못된 그래프 투영과 자원 상한 초과를 입력 값 없이 구분한다. */
98
+ export declare class PreflightGraphError extends Error {
99
+ }
100
+ /** 전체 언어 그래프가 아닌 producer의 영향 숲을 경계에서 연결한다. */
101
+ export declare function createPreflightReport(context: PreflightContext): PreflightReport;
102
+ /** 관찰된 영향과 "영향 없음"의 보증을 구분하며 관련 공백은 CI 검토를 요구한다. */
103
+ export declare function hasPreflightBlockers(report: PreflightReport): boolean;
104
+ export {};