sneakoscope 7.3.0 → 7.6.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 (283) hide show
  1. package/README.md +129 -10
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/dist/cli/codex-app-command.js +1 -1
  5. package/dist/cli/command-manifest-lite.js +4 -1
  6. package/dist/cli/command-registry.js +2 -0
  7. package/dist/cli/install-helpers-codex-lb-chain.js +42 -0
  8. package/dist/cli/install-helpers-codex-lb-config.js +114 -9
  9. package/dist/cli/install-helpers-install-support.js +6 -16
  10. package/dist/cli/install-helpers.js +788 -600
  11. package/dist/cli/router.js +30 -2
  12. package/dist/commands/codex-app.js +37 -1
  13. package/dist/commands/codex-lb.js +491 -300
  14. package/dist/config/skills-manifest.json +57 -71
  15. package/dist/core/align/align-route.js +127 -0
  16. package/dist/core/codex-app/codex-app-fast-ui-repair.js +8 -4
  17. package/dist/core/codex-app/codex-app-restart.js +83 -0
  18. package/dist/core/codex-app/codex-app-ui-state-snapshot.js +8 -4
  19. package/dist/core/codex-app/desktop-routing-snapshot.js +1 -1
  20. package/dist/core/codex-app/menubar/constants.js +5 -0
  21. package/dist/core/codex-app/menubar/generation-transaction-journal.js +1 -3
  22. package/dist/core/codex-app/menubar/installer.js +18 -0
  23. package/dist/core/codex-app/multi-provider-router.js +22 -10
  24. package/dist/core/codex-app/openrouter-activate.js +26 -1
  25. package/dist/core/codex-app.js +118 -26
  26. package/dist/core/codex-control/codex-app-server-runtime-env.js +86 -0
  27. package/dist/core/codex-control/codex-app-server-v2-client.js +78 -8
  28. package/dist/core/codex-control/codex-task-runner.js +2 -2
  29. package/dist/core/codex-lb/capability-runner.js +204 -0
  30. package/dist/core/codex-lb/capability-types.js +1 -0
  31. package/dist/core/codex-lb/codex-lb-env.js +9 -13
  32. package/dist/core/codex-lb/codex-lb-setup.js +45 -8
  33. package/dist/core/codex-lb/codex-lb-tool-catalog.js +52 -74
  34. package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +1 -1
  35. package/dist/core/codex-lb/desktop-auth-invariant.js +185 -0
  36. package/dist/core/codex-lb/desktop-bridge/client.js +34 -0
  37. package/dist/core/codex-lb/desktop-bridge/header-policy.js +106 -0
  38. package/dist/core/codex-lb/desktop-bridge/http-forward.js +101 -0
  39. package/dist/core/codex-lb/desktop-bridge/index.js +10 -0
  40. package/dist/core/codex-lb/desktop-bridge/launchd.js +81 -0
  41. package/dist/core/codex-lb/desktop-bridge/location-rewrite.js +27 -0
  42. package/dist/core/codex-lb/desktop-bridge/security.js +274 -0
  43. package/dist/core/codex-lb/desktop-bridge/server.js +179 -0
  44. package/dist/core/codex-lb/desktop-bridge/state.js +119 -0
  45. package/dist/core/codex-lb/desktop-bridge/types.js +16 -0
  46. package/dist/core/codex-lb/desktop-bridge/websocket-forward.js +151 -0
  47. package/dist/core/codex-lb/desktop-center-credentials.js +189 -0
  48. package/dist/core/codex-lb/desktop-controller.js +1410 -0
  49. package/dist/core/codex-lb/desktop-mode.js +32 -0
  50. package/dist/core/codex-lb/desktop-real-evidence.js +168 -0
  51. package/dist/core/codex-lb/desktop-service.js +613 -0
  52. package/dist/core/codex-lb/legacy-migration.js +575 -0
  53. package/dist/core/codex-lb/migration-receipt.js +246 -0
  54. package/dist/core/codex-lb/probes/auxiliary-surfaces-probe.js +60 -0
  55. package/dist/core/codex-lb/probes/bridge-probe.js +75 -0
  56. package/dist/core/codex-lb/probes/catalog-probe.js +128 -0
  57. package/dist/core/codex-lb/probes/computer-use-probe.js +50 -0
  58. package/dist/core/codex-lb/probes/image-generation-probe.js +47 -0
  59. package/dist/core/codex-lb/probes/probe-evidence.js +39 -0
  60. package/dist/core/codex-lb/probes/voice-realtime-probe.js +44 -0
  61. package/dist/core/codex-lb/trusted-deep-evidence.js +403 -0
  62. package/dist/core/codex-native/core-skill-manifest.js +22 -6
  63. package/dist/core/codex-runtime/codex-desktop-config-policy.js +2 -1
  64. package/dist/core/commands/align-command.js +220 -0
  65. package/dist/core/commands/image-ux-review-command.js +280 -68
  66. package/dist/core/commands/naruto-command.js +257 -8
  67. package/dist/core/commands/ppt-command.js +2 -2
  68. package/dist/core/commands/telegram-command.js +402 -34
  69. package/dist/core/commands/triwiki-command.js +11 -1
  70. package/dist/core/commands/triwiki-graph-command.js +160 -0
  71. package/dist/core/commands/wiki-command.js +100 -20
  72. package/dist/core/doctor/skill-legacy-surface.js +1 -3
  73. package/dist/core/errors/message.js +3 -0
  74. package/dist/core/evidence/evidence-freshness.js +14 -0
  75. package/dist/core/feature-fixtures.js +9 -1
  76. package/dist/core/feature-registry.js +5 -3
  77. package/dist/core/fsx.js +7 -3
  78. package/dist/core/hooks-runtime/codex-commit-hooks-selftest.js +82 -0
  79. package/dist/core/hooks-runtime/context-graph-freshness-preflight.js +113 -0
  80. package/dist/core/hooks-runtime/hook-context.js +15 -2
  81. package/dist/core/hooks-runtime/managed-skill-generation-heal.js +46 -0
  82. package/dist/core/hooks-runtime/naruto-terminal-finalization.js +1 -0
  83. package/dist/core/hooks-runtime/official-subagent-lifecycle.js +1 -1
  84. package/dist/core/hooks-runtime/tool-output-quarantine.js +1 -1
  85. package/dist/core/hooks-runtime.js +33 -89
  86. package/dist/core/image-ux-review/callout-extraction.js +6 -0
  87. package/dist/core/image-ux-review/imagegen-adapter.js +64 -23
  88. package/dist/core/image-ux-review/real-callout-extractor.js +1 -0
  89. package/dist/core/image-ux-review.js +230 -12
  90. package/dist/core/imagegen/codex-lb-imagegen-target.js +21 -7
  91. package/dist/core/imagegen/imagegen-capability.js +10 -4
  92. package/dist/core/imagegen/require-imagegen.js +29 -5
  93. package/dist/core/init/skills.js +25 -13
  94. package/dist/core/init.js +1 -1
  95. package/dist/core/install/installed-package-smoke.js +157 -4
  96. package/dist/core/managed-assets/managed-assets-manifest.js +2 -1
  97. package/dist/core/managed-path-safety.js +8 -10
  98. package/dist/core/mcp-config/backup.js +2 -4
  99. package/dist/core/mcp-config/config-reader.js +2 -4
  100. package/dist/core/mcp-config/scope.js +3 -5
  101. package/dist/core/naruto/context-graph-advisor-scope.js +242 -0
  102. package/dist/core/naruto/context-graph-advisor.js +0 -0
  103. package/dist/core/perf/release-latency-slo.js +12 -6
  104. package/dist/core/pipeline-internals/runtime-core.js +78 -0
  105. package/dist/core/pipeline-internals/runtime-gates.js +5 -2
  106. package/dist/core/policy/latest-version-guidance.js +113 -0
  107. package/dist/core/ppt.js +8 -8
  108. package/dist/core/preflight/parallel-preflight-engine.js +1 -1
  109. package/dist/core/proof/auto-finalize.js +98 -6
  110. package/dist/core/proof/route-proof-gate.js +12 -1
  111. package/dist/core/proof/route-proof-policy.js +8 -8
  112. package/dist/core/release/gate-manifest.js +32 -1
  113. package/dist/core/release/npm-stage-contract.js +21 -0
  114. package/dist/core/release/package-size-budget.js +2 -2
  115. package/dist/core/release/release-gate-contract.js +5 -0
  116. package/dist/core/release/release-proof-io.js +1 -3
  117. package/dist/core/release/release-real-contract.js +5 -4
  118. package/dist/core/release/release-stamp-proof.js +1 -3
  119. package/dist/core/release/stage-publish.js +27 -0
  120. package/dist/core/remote/audit-idempotency.js +50 -18
  121. package/dist/core/remote/codex-public-activity.js +283 -0
  122. package/dist/core/remote/index.js +1 -0
  123. package/dist/core/remote/ssh-worker-client.js +4 -1
  124. package/dist/core/remote/worker.js +206 -27
  125. package/dist/core/research/research-adversarial-review.js +1 -3
  126. package/dist/core/research/research-claim-synthesizer.js +1 -3
  127. package/dist/core/research/research-falsification-runner.js +1 -3
  128. package/dist/core/research/research-source-evidence.js +1 -3
  129. package/dist/core/responses-stream.js +65 -19
  130. package/dist/core/routes/constants.js +1 -1
  131. package/dist/core/routes/design-policy.js +7 -2
  132. package/dist/core/routes/dollar-manifest-lite.js +2 -4
  133. package/dist/core/routes/evidence.js +1 -1
  134. package/dist/core/routes.js +30 -10
  135. package/dist/core/safety/command-contract/contracts.js +2 -0
  136. package/dist/core/safety/command-contract/types.js +1 -1
  137. package/dist/core/search/context-graph-seeds.js +205 -0
  138. package/dist/core/search/context.js +0 -0
  139. package/dist/core/search/provider.js +2 -2
  140. package/dist/core/secret-redaction.js +6 -0
  141. package/dist/core/subagents/naruto-help-contract.js +2 -1
  142. package/dist/core/subagents/naruto-host-credentials.js +161 -0
  143. package/dist/core/subagents/official-subagent-preparation.js +4 -1
  144. package/dist/core/subagents/official-subagent-prompt.js +44 -2
  145. package/dist/core/subagents/official-subagent-runner.js +26 -8
  146. package/dist/core/subagents/triwiki-attention.js +135 -123
  147. package/dist/core/telegram/bot-api.js +85 -10
  148. package/dist/core/telegram/center-snapshot.js +718 -0
  149. package/dist/core/telegram/config.js +158 -31
  150. package/dist/core/telegram/hub.js +288 -33
  151. package/dist/core/telegram/index.js +2 -0
  152. package/dist/core/telegram/ingress-spool.js +419 -0
  153. package/dist/core/telegram/ledgers.js +188 -29
  154. package/dist/core/telegram/messages.js +26 -6
  155. package/dist/core/telegram/owner-lock.js +10 -7
  156. package/dist/core/telegram/runtime-projection.js +38 -3
  157. package/dist/core/telegram/runtime.js +298 -63
  158. package/dist/core/telegram/service.js +137 -8
  159. package/dist/core/telegram/setup.js +291 -73
  160. package/dist/core/text/strings.js +3 -0
  161. package/dist/core/triwiki/code-pack.js +12 -120
  162. package/dist/core/triwiki/context-graph/compiler/cache-key.js +277 -0
  163. package/dist/core/triwiki/context-graph/compiler/extract.js +104 -0
  164. package/dist/core/triwiki/context-graph/compiler/freshness.js +108 -0
  165. package/dist/core/triwiki/context-graph/compiler/index.js +237 -0
  166. package/dist/core/triwiki/context-graph/compiler/merge.js +0 -0
  167. package/dist/core/triwiki/context-graph/compiler/serialize.js +115 -0
  168. package/dist/core/triwiki/context-graph/contracts.js +236 -0
  169. package/dist/core/triwiki/context-graph/extractors/code/builders.js +150 -0
  170. package/dist/core/triwiki/context-graph/extractors/code/declarations.js +161 -0
  171. package/dist/core/triwiki/context-graph/extractors/code/index.js +265 -0
  172. package/dist/core/triwiki/context-graph/extractors/code/inventory.js +237 -0
  173. package/dist/core/triwiki/context-graph/extractors/code/module-graph.js +252 -0
  174. package/dist/core/triwiki/context-graph/extractors/code/modules.js +79 -0
  175. package/dist/core/triwiki/context-graph/extractors/code/references.js +184 -0
  176. package/dist/core/triwiki/context-graph/extractors/code/selection.js +100 -0
  177. package/dist/core/triwiki/context-graph/extractors/code/ts-config.js +161 -0
  178. package/dist/core/triwiki/context-graph/extractors/code/types.js +18 -0
  179. package/dist/core/triwiki/context-graph/extractors/evidence/claims.js +289 -0
  180. package/dist/core/triwiki/context-graph/extractors/evidence/index.js +54 -0
  181. package/dist/core/triwiki/context-graph/extractors/evidence/proof-index.js +213 -0
  182. package/dist/core/triwiki/context-graph/extractors/evidence/proofs.js +266 -0
  183. package/dist/core/triwiki/context-graph/extractors/evidence/redaction.js +177 -0
  184. package/dist/core/triwiki/context-graph/extractors/evidence/shared.js +0 -0
  185. package/dist/core/triwiki/context-graph/extractors/evidence/sources.js +154 -0
  186. package/dist/core/triwiki/context-graph/extractors/index.js +7 -0
  187. package/dist/core/triwiki/context-graph/extractors/topology/commands.js +207 -0
  188. package/dist/core/triwiki/context-graph/extractors/topology/gate-edges.js +201 -0
  189. package/dist/core/triwiki/context-graph/extractors/topology/gates.js +182 -0
  190. package/dist/core/triwiki/context-graph/extractors/topology/globs.js +124 -0
  191. package/dist/core/triwiki/context-graph/extractors/topology/index.js +92 -0
  192. package/dist/core/triwiki/context-graph/extractors/topology/routes.js +135 -0
  193. package/dist/core/triwiki/context-graph/extractors/topology/shared.js +215 -0
  194. package/dist/core/triwiki/context-graph/graph-index.js +143 -0
  195. package/dist/core/triwiki/context-graph/ids.js +0 -0
  196. package/dist/core/triwiki/context-graph/lint/index.js +0 -0
  197. package/dist/core/triwiki/context-graph/lint/rules.js +232 -0
  198. package/dist/core/triwiki/context-graph/lint/warnings.js +93 -0
  199. package/dist/core/triwiki/context-graph/paths.js +116 -0
  200. package/dist/core/triwiki/context-graph/profiles.js +78 -0
  201. package/dist/core/triwiki/context-graph/projections/anchors.js +91 -0
  202. package/dist/core/triwiki/context-graph/projections/attention.js +58 -0
  203. package/dist/core/triwiki/context-graph/projections/code-pack-workspace.js +62 -0
  204. package/dist/core/triwiki/context-graph/projections/code-pack.js +144 -0
  205. package/dist/core/triwiki/context-graph/projections/index.js +7 -0
  206. package/dist/core/triwiki/context-graph/projections/module-view.js +140 -0
  207. package/dist/core/triwiki/context-graph/projections/node-summary.js +118 -0
  208. package/dist/core/triwiki/context-graph/projections/pack-contract.js +6 -0
  209. package/dist/core/triwiki/context-graph/query/explain.js +0 -0
  210. package/dist/core/triwiki/context-graph/query/index.js +178 -0
  211. package/dist/core/triwiki/context-graph/query/load.js +116 -0
  212. package/dist/core/triwiki/context-graph/query/pack.js +117 -0
  213. package/dist/core/triwiki/context-graph/query/rank.js +142 -0
  214. package/dist/core/triwiki/context-graph/query/ranking-config.js +64 -0
  215. package/dist/core/triwiki/context-graph/query/seeds.js +241 -0
  216. package/dist/core/triwiki/context-graph/query/snapshot-cache.js +72 -0
  217. package/dist/core/triwiki/context-graph/query/traverse.js +154 -0
  218. package/dist/core/triwiki/context-graph/query-types.js +29 -0
  219. package/dist/core/triwiki/context-graph/store/compile-lock.js +21 -0
  220. package/dist/core/triwiki/context-graph/store/event-log.js +48 -0
  221. package/dist/core/triwiki/context-graph/store/fragment-cache.js +85 -0
  222. package/dist/core/triwiki/context-graph/store/graph-status.js +85 -0
  223. package/dist/core/triwiki/context-graph/store/snapshot-store.js +155 -0
  224. package/dist/core/triwiki/triwiki-proof-bank-index-repair.js +115 -0
  225. package/dist/core/triwiki/triwiki-proof-bank-index-store.js +290 -0
  226. package/dist/core/triwiki/triwiki-proof-bank-index.js +126 -0
  227. package/dist/core/triwiki/triwiki-proof-bank.js +7 -1
  228. package/dist/core/verification/context-graph-affected.js +271 -0
  229. package/dist/core/version.js +1 -1
  230. package/dist/native/sks-menubar/Sources/AlertFactory.swift +11 -3
  231. package/dist/native/sks-menubar/Sources/AppDelegate.swift +9 -0
  232. package/dist/native/sks-menubar/Sources/ControlCenterWindowController.swift +25 -3
  233. package/dist/native/sks-menubar/Sources/ControlKit.swift +19 -8
  234. package/dist/native/sks-menubar/Sources/DiagnosticsViewController.swift +1 -2
  235. package/dist/native/sks-menubar/Sources/MCPServersViewController.swift +45 -17
  236. package/dist/native/sks-menubar/Sources/OverviewSummary.swift +162 -0
  237. package/dist/native/sks-menubar/Sources/OverviewViewController.swift +136 -190
  238. package/dist/native/sks-menubar/Sources/ProcessClient.swift +107 -11
  239. package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +5 -1
  240. package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +16 -4
  241. package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +4 -1
  242. package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +131 -0
  243. package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +288 -341
  244. package/dist/native/sks-menubar/Sources/RemoteTelegramCenterState.swift +447 -0
  245. package/dist/native/sks-menubar/Sources/RemoteTelegramRendering.swift +484 -0
  246. package/dist/native/sks-menubar/Sources/RemoteTelegramViewController.swift +364 -115
  247. package/dist/native/sks-menubar/Sources/SettingsViewController.swift +73 -12
  248. package/dist/native/sks-menubar/Sources/SidebarItem.swift +3 -3
  249. package/dist/native/sks-menubar/Sources/StatusItemController.swift +13 -13
  250. package/dist/native/sks-menubar/Sources/TelegramHubSupervisor.swift +469 -0
  251. package/dist/native/sks-menubar/Sources/UpdatesViewController.swift +1 -6
  252. package/dist/native/sks-menubar/Tests/AppRuntimeTestSupport.swift +12 -0
  253. package/dist/native/sks-menubar/Tests/NativeTelegramRegressionRunner.swift +55 -0
  254. package/dist/native/sks-menubar/Tests/ProcessClientTests.swift +33 -0
  255. package/dist/native/sks-menubar/Tests/ProvidersViewControllerTests.swift +142 -0
  256. package/dist/native/sks-menubar/Tests/RemoteTelegramCenterStateTests.swift +56 -0
  257. package/dist/native/sks-menubar/Tests/TelegramHubSupervisorTests.swift +55 -0
  258. package/dist/scripts/codex-lb-catalog-passthrough-check.js +120 -0
  259. package/dist/scripts/codex-lb-desktop-auth-invariant-check.js +169 -0
  260. package/dist/scripts/codex-lb-desktop-bridge-check.js +394 -0
  261. package/dist/scripts/codex-lb-desktop-bridge-latency-check.js +196 -0
  262. package/dist/scripts/codex-lb-desktop-capabilities-check.js +287 -0
  263. package/dist/scripts/codex-lb-desktop-real-evidence-check.js +123 -0
  264. package/dist/scripts/codex-lb-fast-mode-truth-check.js +10 -3
  265. package/dist/scripts/codex-lb-fast-ui-preservation-check.js +81 -40
  266. package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +99 -37
  267. package/dist/scripts/context-graph-check.js +191 -0
  268. package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +1 -1
  269. package/dist/scripts/gate-policy-audit-check.js +1 -1
  270. package/dist/scripts/helper-dedup-check.js +0 -2
  271. package/dist/scripts/installed-package-smoke-check.js +4 -1
  272. package/dist/scripts/latest-version-guidance-check.js +74 -0
  273. package/dist/scripts/release-metadata-check.js +21 -4
  274. package/dist/scripts/release-real-check.js +7 -0
  275. package/dist/scripts/ux-review-imagegen-blackbox-check.js +25 -1
  276. package/dist/scripts/ux-review-run-wires-imagegen-check.js +9 -1
  277. package/package.json +8 -3
  278. package/release-gates.v2.json +176 -1
  279. package/runtime-required-scripts.json +30 -0
  280. package/schemas/triwiki/context-graph.schema.json +119 -0
  281. package/dist/cli/install-helpers-codex-lb-selftest-chain.js +0 -112
  282. package/dist/cli/install-helpers-codex-lb-selftest.js +0 -481
  283. package/dist/core/triwiki/code-index-scanner.js +0 -309
@@ -1,309 +0,0 @@
1
- import { spawnSync } from 'node:child_process';
2
- import fs from 'node:fs';
3
- import path from 'node:path';
4
- import { collectInputFiles } from './triwiki-cache-key.js';
5
- export const CODE_INDEX_SCHEMA = 'sks.code-index.v1';
6
- const DEFAULT_MAX_LINES_PER_FILE = 120;
7
- const DEFAULT_MAX_FILES = 4000;
8
- const CODE_EXT_RE = /\.(js|ts|tsx|jsx|cjs|mjs)$/;
9
- const ENTRY_FILE_RE = /^(index|mod)\.(ts|tsx|js|jsx|mjs|cjs)$/;
10
- const EXPORT_LINE_RE = /^\s*export\s+(?:default\s+)?(?:const|let|var|function|class|interface|type|enum|abstract\s+class|async\s+function)\s+[A-Za-z0-9_$]+/;
11
- const EXPORT_BRACE_RE = /^\s*export\s*\{/;
12
- const EXPORT_STAR_RE = /^\s*export\s*\*/;
13
- const IMPORT_SPEC_RE = /(?:from\s+|require\()\s*['"](\.\.?\/[^'"]+)['"]/g;
14
- const RISK_HIGH_FAN_IN = 5;
15
- const RISK_HIGH_FILE_COUNT = 40;
16
- const RISK_MEDIUM_FAN_IN = 2;
17
- const RISK_MEDIUM_FILE_COUNT = 15;
18
- export async function scanCodebaseIndex(root, opts = {}) {
19
- const resolvedRoot = path.resolve(root);
20
- const maxLinesPerFile = opts.maxLinesPerFile ?? DEFAULT_MAX_LINES_PER_FILE;
21
- const maxFiles = opts.maxFiles ?? DEFAULT_MAX_FILES;
22
- const inventory = listSourceFiles(resolvedRoot);
23
- const truncatedByCap = inventory.length > maxFiles;
24
- const scannedFiles = truncatedByCap ? inventory.slice(0, maxFiles) : inventory;
25
- const boundaries = inferModuleBoundaries(resolvedRoot);
26
- const fileRecords = readFileRecords(resolvedRoot, scannedFiles, maxLinesPerFile);
27
- const modulesByPath = assignFilesToModules(boundaries, fileRecords);
28
- const moduleIdForFile = buildFileToModuleIdIndex(modulesByPath);
29
- const cards = buildModuleCards(resolvedRoot, modulesByPath, moduleIdForFile);
30
- return {
31
- schema: CODE_INDEX_SCHEMA,
32
- generated_at: new Date().toISOString(),
33
- root: resolvedRoot,
34
- modules: cards,
35
- truncated: truncatedByCap,
36
- scanned_file_count: scannedFiles.length,
37
- scanned_files_cap: maxFiles
38
- };
39
- }
40
- function listSourceFiles(root) {
41
- const gitFiles = tryGitLsFiles(root);
42
- const all = gitFiles !== null ? gitFiles : walkFallback(root);
43
- return all.filter((rel) => CODE_EXT_RE.test(rel)).sort();
44
- }
45
- function tryGitLsFiles(root) {
46
- try {
47
- const result = spawnSync('git', ['ls-files'], { cwd: root, encoding: 'utf8' });
48
- if (result.status !== 0 || result.error)
49
- return null;
50
- return String(result.stdout || '').split('\n').map((line) => line.trim()).filter(Boolean);
51
- }
52
- catch {
53
- return null;
54
- }
55
- }
56
- function walkFallback(root) {
57
- const collected = collectInputFiles(root, ['.']);
58
- return collected.records.map((record) => record.path);
59
- }
60
- function inferModuleBoundaries(root) {
61
- const boundaries = [];
62
- const seen = new Set();
63
- const addBoundary = (dir) => {
64
- const normalized = dir.replace(/\\/g, '/').replace(/\/+$/, '');
65
- if (!normalized || seen.has(normalized))
66
- return;
67
- seen.add(normalized);
68
- boundaries.push({ module_id: moduleIdFromDir(normalized), dir: normalized });
69
- };
70
- for (const sourceRoot of listDirs(root, '.').filter((name) => name === 'src' || name === 'source' || name === 'lib')) {
71
- for (const topLevel of listDirs(root, sourceRoot)) {
72
- addBoundary(topLevel);
73
- for (const nested of listDirs(root, topLevel))
74
- addBoundary(nested);
75
- }
76
- }
77
- const workspaces = readWorkspaceGlobs(root);
78
- for (const glob of workspaces) {
79
- for (const dir of resolveWorkspaceGlob(root, glob))
80
- addBoundary(dir);
81
- }
82
- return boundaries.sort((a, b) => a.dir.localeCompare(b.dir));
83
- }
84
- function listDirs(root, rel) {
85
- const absolute = rel === '.' ? root : path.join(root, rel);
86
- let entries;
87
- try {
88
- entries = fs.readdirSync(absolute, { withFileTypes: true });
89
- }
90
- catch (error) {
91
- if (isMissingOrInaccessible(error))
92
- return [];
93
- throw error;
94
- }
95
- return entries
96
- .filter((entry) => entry.isDirectory() && !isExcludedDirName(entry.name))
97
- .map((entry) => (rel === '.' ? entry.name : `${rel}/${entry.name}`))
98
- .sort();
99
- }
100
- function isExcludedDirName(name) {
101
- return name === '.git' || name === 'node_modules' || name === 'dist' || name === 'build' || name === 'coverage' || name === '__tests__' || name.startsWith('.');
102
- }
103
- function isMissingOrInaccessible(error) {
104
- const code = error?.code;
105
- return code === 'ENOENT' || code === 'EACCES' || code === 'ENOTDIR' || code === 'EPERM' || code === 'EISDIR';
106
- }
107
- function readWorkspaceGlobs(root) {
108
- try {
109
- const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
110
- if (!pkg.workspaces)
111
- return [];
112
- if (Array.isArray(pkg.workspaces))
113
- return pkg.workspaces;
114
- return pkg.workspaces.packages || [];
115
- }
116
- catch {
117
- return [];
118
- }
119
- }
120
- function resolveWorkspaceGlob(root, glob) {
121
- const normalized = glob.replace(/\\/g, '/');
122
- if (!normalized.includes('*')) {
123
- return fs.existsSync(path.join(root, normalized)) ? [normalized.replace(/\/+$/, '')] : [];
124
- }
125
- const starIndex = normalized.indexOf('*');
126
- const prefix = normalized.slice(0, starIndex).replace(/\/+$/, '');
127
- return listDirs(root, prefix || '.');
128
- }
129
- function moduleIdFromDir(dir) {
130
- return dir.replace(/^src\//, '').replace(/\//g, '-') || 'root';
131
- }
132
- function readFileRecords(root, files, maxLinesPerFile) {
133
- const out = [];
134
- for (const rel of files) {
135
- const absolute = path.join(root, rel);
136
- let text = '';
137
- try {
138
- text = fs.readFileSync(absolute, 'utf8');
139
- }
140
- catch (error) {
141
- if (isMissingOrInaccessible(error))
142
- continue;
143
- throw error;
144
- }
145
- const lines = text.split(/\r?\n/);
146
- const loc = lines.length && lines[lines.length - 1] === '' ? lines.length - 1 : lines.length;
147
- const scanLines = lines.slice(0, maxLinesPerFile);
148
- const exportLines = [];
149
- for (const line of scanLines) {
150
- if (EXPORT_LINE_RE.test(line) || EXPORT_BRACE_RE.test(line) || EXPORT_STAR_RE.test(line)) {
151
- exportLines.push(line.trim());
152
- }
153
- }
154
- const importSpecifiers = [];
155
- for (const line of scanLines) {
156
- IMPORT_SPEC_RE.lastIndex = 0;
157
- let match;
158
- while ((match = IMPORT_SPEC_RE.exec(line))) {
159
- if (match[1])
160
- importSpecifiers.push(match[1]);
161
- }
162
- }
163
- out.push({ rel, loc, exportLines, importSpecifiers });
164
- }
165
- return out;
166
- }
167
- function assignFilesToModules(boundaries, files) {
168
- const sortedBoundaries = [...boundaries].sort((a, b) => b.dir.length - a.dir.length);
169
- const map = new Map();
170
- for (const boundary of boundaries)
171
- map.set(boundary.module_id, { boundary, files: [] });
172
- for (const file of files) {
173
- const owner = sortedBoundaries.find((boundary) => file.rel === boundary.dir || file.rel.startsWith(`${boundary.dir}/`));
174
- if (!owner)
175
- continue;
176
- map.get(owner.module_id).files.push(file);
177
- }
178
- for (const [moduleId, entry] of map) {
179
- if (!entry.files.length)
180
- map.delete(moduleId);
181
- }
182
- return map;
183
- }
184
- function buildFileToModuleIdIndex(modulesByPath) {
185
- const index = new Map();
186
- for (const [moduleId, entry] of modulesByPath) {
187
- for (const file of entry.files)
188
- index.set(file.rel, moduleId);
189
- }
190
- return index;
191
- }
192
- function buildModuleCards(root, modulesByPath, moduleIdForFile) {
193
- const fanIn = new Map();
194
- const dependencyEdgesByModule = new Map();
195
- for (const [moduleId, entry] of modulesByPath) {
196
- const edges = new Set();
197
- for (const file of entry.files) {
198
- for (const specifier of file.importSpecifiers) {
199
- const resolvedRel = resolveRelativeImport(root, file.rel, specifier);
200
- if (!resolvedRel)
201
- continue;
202
- const targetModuleId = moduleIdForFile.get(resolvedRel);
203
- if (!targetModuleId || targetModuleId === moduleId)
204
- continue;
205
- edges.add(targetModuleId);
206
- }
207
- }
208
- dependencyEdgesByModule.set(moduleId, edges);
209
- for (const target of edges)
210
- fanIn.set(target, (fanIn.get(target) || 0) + 1);
211
- }
212
- const cards = [];
213
- for (const [moduleId, entry] of modulesByPath) {
214
- const files = entry.files;
215
- const loc = files.reduce((sum, file) => sum + file.loc, 0);
216
- const exportsSummary = files.flatMap((file) => file.exportLines);
217
- const dependencyEdges = [...(dependencyEdgesByModule.get(moduleId) || [])].sort();
218
- const entryPoints = collectEntryPoints(root, entry.boundary.dir, files);
219
- const fanInCount = fanIn.get(moduleId) || 0;
220
- const risk = computeRisk(fanInCount, files.length);
221
- cards.push({
222
- module_id: moduleId,
223
- paths: [entry.boundary.dir],
224
- entry_points: entryPoints,
225
- exports_summary: exportsSummary,
226
- dependency_edges: dependencyEdges,
227
- file_count: files.length,
228
- loc,
229
- risk
230
- });
231
- }
232
- return cards.sort((a, b) => a.module_id.localeCompare(b.module_id));
233
- }
234
- function computeRisk(fanIn, fileCount) {
235
- if (fanIn >= RISK_HIGH_FAN_IN || fileCount >= RISK_HIGH_FILE_COUNT)
236
- return 'high';
237
- if (fanIn >= RISK_MEDIUM_FAN_IN || fileCount >= RISK_MEDIUM_FILE_COUNT)
238
- return 'medium';
239
- return 'low';
240
- }
241
- function collectEntryPoints(root, dir, files) {
242
- const entryPoints = new Set();
243
- const pkgPath = path.join(root, dir, 'package.json');
244
- if (fs.existsSync(pkgPath)) {
245
- try {
246
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
247
- if (typeof pkg.main === 'string')
248
- entryPoints.add(normalizeEntryPath(dir, pkg.main));
249
- if (typeof pkg.bin === 'string')
250
- entryPoints.add(normalizeEntryPath(dir, pkg.bin));
251
- else if (pkg.bin && typeof pkg.bin === 'object') {
252
- for (const value of Object.values(pkg.bin))
253
- if (typeof value === 'string')
254
- entryPoints.add(normalizeEntryPath(dir, value));
255
- }
256
- for (const value of collectExportsPaths(pkg.exports))
257
- entryPoints.add(normalizeEntryPath(dir, value));
258
- }
259
- catch {
260
- }
261
- }
262
- for (const file of files) {
263
- const base = path.basename(file.rel);
264
- if (ENTRY_FILE_RE.test(base))
265
- entryPoints.add(file.rel);
266
- }
267
- return [...entryPoints].sort();
268
- }
269
- function collectExportsPaths(exportsField) {
270
- if (typeof exportsField === 'string')
271
- return [exportsField];
272
- if (!exportsField || typeof exportsField !== 'object')
273
- return [];
274
- const out = [];
275
- for (const value of Object.values(exportsField)) {
276
- if (typeof value === 'string')
277
- out.push(value);
278
- else
279
- out.push(...collectExportsPaths(value));
280
- }
281
- return out;
282
- }
283
- function normalizeEntryPath(dir, entry) {
284
- const cleaned = entry.replace(/^\.\//, '');
285
- return `${dir}/${cleaned}`.replace(/\\/g, '/');
286
- }
287
- function resolveRelativeImport(root, fromRel, specifier) {
288
- const fromDir = path.posix.dirname(fromRel);
289
- const joined = path.posix.normalize(path.posix.join(fromDir, specifier));
290
- const candidates = [
291
- `${joined}.ts`,
292
- `${joined}.tsx`,
293
- `${joined}.js`,
294
- `${joined}.jsx`,
295
- `${joined}/index.ts`,
296
- `${joined}/index.tsx`,
297
- `${joined}/index.js`,
298
- `${joined}/index.jsx`,
299
- joined
300
- ];
301
- for (const candidate of candidates) {
302
- const absolute = path.join(root, candidate);
303
- if (!fs.existsSync(absolute))
304
- continue;
305
- if (fs.statSync(absolute).isFile())
306
- return candidate;
307
- }
308
- return null;
309
- }