projscan 4.7.0 → 4.8.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 (278) hide show
  1. package/README.md +22 -22
  2. package/dist/cli/commands/start.js +5 -28
  3. package/dist/cli/commands/start.js.map +1 -1
  4. package/dist/cli/commands/startOptionsRegistration.d.ts +2 -0
  5. package/dist/cli/commands/startOptionsRegistration.js +29 -0
  6. package/dist/cli/commands/startOptionsRegistration.js.map +1 -0
  7. package/dist/core/ast.d.ts +2 -17
  8. package/dist/core/ast.js +4 -33
  9. package/dist/core/ast.js.map +1 -1
  10. package/dist/core/astResult.d.ts +20 -0
  11. package/dist/core/astResult.js +39 -0
  12. package/dist/core/astResult.js.map +1 -0
  13. package/dist/core/codeGraph.d.ts +1 -16
  14. package/dist/core/codeGraph.js +4 -89
  15. package/dist/core/codeGraph.js.map +1 -1
  16. package/dist/core/codeGraphAdapterContexts.d.ts +8 -0
  17. package/dist/core/codeGraphAdapterContexts.js +14 -0
  18. package/dist/core/codeGraphAdapterContexts.js.map +1 -0
  19. package/dist/core/codeGraphIncremental.d.ts +17 -0
  20. package/dist/core/codeGraphIncremental.js +64 -0
  21. package/dist/core/codeGraphIncremental.js.map +1 -0
  22. package/dist/core/collisionDetector.d.ts +1 -0
  23. package/dist/core/collisionDetector.js +3 -0
  24. package/dist/core/collisionDetector.js.map +1 -1
  25. package/dist/core/coordination.js +23 -5
  26. package/dist/core/coordination.js.map +1 -1
  27. package/dist/core/coordinationEvidence.d.ts +1 -0
  28. package/dist/core/coordinationEvidence.js.map +1 -1
  29. package/dist/core/frameworkExpressSources.js +6 -31
  30. package/dist/core/frameworkExpressSources.js.map +1 -1
  31. package/dist/core/frameworkFastifySources.js +5 -22
  32. package/dist/core/frameworkFastifySources.js.map +1 -1
  33. package/dist/core/frameworkHonoSources.js +5 -24
  34. package/dist/core/frameworkHonoSources.js.map +1 -1
  35. package/dist/core/frameworkKoaSources.js +5 -24
  36. package/dist/core/frameworkKoaSources.js.map +1 -1
  37. package/dist/core/frameworkSourceContext.d.ts +15 -0
  38. package/dist/core/frameworkSourceContext.js +2 -0
  39. package/dist/core/frameworkSourceContext.js.map +1 -0
  40. package/dist/core/frameworkSourceMatching.d.ts +6 -0
  41. package/dist/core/frameworkSourceMatching.js +29 -0
  42. package/dist/core/frameworkSourceMatching.js.map +1 -0
  43. package/dist/core/frameworkSourceResolvers.d.ts +2 -0
  44. package/dist/core/frameworkSourceResolvers.js +45 -0
  45. package/dist/core/frameworkSourceResolvers.js.map +1 -0
  46. package/dist/core/frameworkSources.d.ts +2 -14
  47. package/dist/core/frameworkSources.js +9 -38
  48. package/dist/core/frameworkSources.js.map +1 -1
  49. package/dist/core/frameworkSvelteKitSources.d.ts +2 -0
  50. package/dist/core/frameworkSvelteKitSources.js +118 -0
  51. package/dist/core/frameworkSvelteKitSources.js.map +1 -0
  52. package/dist/core/intentRouter.d.ts +1 -1
  53. package/dist/core/intentRouter.js +2 -8
  54. package/dist/core/intentRouter.js.map +1 -1
  55. package/dist/core/intentRouterCatalog.js +32 -0
  56. package/dist/core/intentRouterCatalog.js.map +1 -1
  57. package/dist/core/intentRouterKeywordToolGuards.js +5 -0
  58. package/dist/core/intentRouterKeywordToolGuards.js.map +1 -1
  59. package/dist/core/intentRouterKeywordWeights.js +23 -0
  60. package/dist/core/intentRouterKeywordWeights.js.map +1 -1
  61. package/dist/core/intentRouterReleaseSignals.js +3 -18
  62. package/dist/core/intentRouterReleaseSignals.js.map +1 -1
  63. package/dist/core/intentRouterResolution.d.ts +3 -0
  64. package/dist/core/intentRouterResolution.js +11 -0
  65. package/dist/core/intentRouterResolution.js.map +1 -0
  66. package/dist/core/languages/pythonManifests.js +6 -19
  67. package/dist/core/languages/pythonManifests.js.map +1 -1
  68. package/dist/core/languages/pythonPep508.js +1 -1
  69. package/dist/core/languages/pythonPep508.js.map +1 -1
  70. package/dist/core/languages/pythonProjectEvidence.js +4 -4
  71. package/dist/core/languages/pythonProjectEvidence.js.map +1 -1
  72. package/dist/core/languages/pythonPyproject.js +1 -1
  73. package/dist/core/languages/pythonPyproject.js.map +1 -1
  74. package/dist/core/languages/pythonPyprojectEvidence.d.ts +7 -0
  75. package/dist/core/languages/pythonPyprojectEvidence.js +23 -0
  76. package/dist/core/languages/pythonPyprojectEvidence.js.map +1 -0
  77. package/dist/core/languages/pythonRequirements.d.ts +2 -0
  78. package/dist/core/languages/pythonRequirements.js +74 -9
  79. package/dist/core/languages/pythonRequirements.js.map +1 -1
  80. package/dist/core/pluginAnalyzerLoading.d.ts +3 -0
  81. package/dist/core/pluginAnalyzerLoading.js +55 -0
  82. package/dist/core/pluginAnalyzerLoading.js.map +1 -0
  83. package/dist/core/pluginAnalyzerRunning.d.ts +10 -0
  84. package/dist/core/pluginAnalyzerRunning.js +32 -0
  85. package/dist/core/pluginAnalyzerRunning.js.map +1 -0
  86. package/dist/core/pluginIssueValidation.d.ts +2 -0
  87. package/dist/core/pluginIssueValidation.js +22 -0
  88. package/dist/core/pluginIssueValidation.js.map +1 -0
  89. package/dist/core/pluginManifestDiscovery.d.ts +25 -0
  90. package/dist/core/pluginManifestDiscovery.js +80 -0
  91. package/dist/core/pluginManifestDiscovery.js.map +1 -0
  92. package/dist/core/pluginModuleLoading.d.ts +8 -0
  93. package/dist/core/pluginModuleLoading.js +91 -0
  94. package/dist/core/pluginModuleLoading.js.map +1 -0
  95. package/dist/core/pluginReporterLoading.d.ts +41 -0
  96. package/dist/core/pluginReporterLoading.js +105 -0
  97. package/dist/core/pluginReporterLoading.js.map +1 -0
  98. package/dist/core/pluginRuntimeTypes.d.ts +20 -0
  99. package/dist/core/pluginRuntimeTypes.js +2 -0
  100. package/dist/core/pluginRuntimeTypes.js.map +1 -0
  101. package/dist/core/plugins.d.ts +9 -86
  102. package/dist/core/plugins.js +12 -350
  103. package/dist/core/plugins.js.map +1 -1
  104. package/dist/core/preflight.d.ts +1 -2
  105. package/dist/core/preflight.js +4 -91
  106. package/dist/core/preflight.js.map +1 -1
  107. package/dist/core/preflightEvidence.js +11 -0
  108. package/dist/core/preflightEvidence.js.map +1 -1
  109. package/dist/core/preflightInputs.d.ts +1 -0
  110. package/dist/core/preflightInputs.js.map +1 -1
  111. package/dist/core/preflightReasons.d.ts +21 -0
  112. package/dist/core/preflightReasons.js +28 -0
  113. package/dist/core/preflightReasons.js.map +1 -0
  114. package/dist/core/preflightReport.d.ts +9 -0
  115. package/dist/core/preflightReport.js +67 -0
  116. package/dist/core/preflightReport.js.map +1 -0
  117. package/dist/core/review.js +2 -47
  118. package/dist/core/review.js.map +1 -1
  119. package/dist/core/reviewChangedReport.d.ts +13 -0
  120. package/dist/core/reviewChangedReport.js +38 -0
  121. package/dist/core/reviewChangedReport.js.map +1 -0
  122. package/dist/core/reviewComputation.d.ts +9 -0
  123. package/dist/core/reviewComputation.js +14 -0
  124. package/dist/core/reviewComputation.js.map +1 -0
  125. package/dist/core/reviewContractChanges.js +22 -8
  126. package/dist/core/reviewContractChanges.js.map +1 -1
  127. package/dist/core/reviewDataflow.js +18 -0
  128. package/dist/core/reviewDataflow.js.map +1 -1
  129. package/dist/core/roadmapCatalog.js +7 -203
  130. package/dist/core/roadmapCatalog.js.map +1 -1
  131. package/dist/core/roadmapCatalogPost44.d.ts +2 -0
  132. package/dist/core/roadmapCatalogPost44.js +205 -0
  133. package/dist/core/roadmapCatalogPost44.js.map +1 -0
  134. package/dist/core/roadmapCatalogTypes.d.ts +6 -0
  135. package/dist/core/roadmapCatalogTypes.js +2 -0
  136. package/dist/core/roadmapCatalogTypes.js.map +1 -0
  137. package/dist/core/startClaimRouteCriteria.d.ts +7 -0
  138. package/dist/core/startClaimRouteCriteria.js +16 -0
  139. package/dist/core/startClaimRouteCriteria.js.map +1 -0
  140. package/dist/core/startCouplingRouteCriteria.d.ts +2 -0
  141. package/dist/core/startCouplingRouteCriteria.js +13 -0
  142. package/dist/core/startCouplingRouteCriteria.js.map +1 -0
  143. package/dist/core/startDependencyRouteCriteria.d.ts +2 -0
  144. package/dist/core/startDependencyRouteCriteria.js +43 -0
  145. package/dist/core/startDependencyRouteCriteria.js.map +1 -0
  146. package/dist/core/startFileRouteCriteria.d.ts +2 -0
  147. package/dist/core/startFileRouteCriteria.js +56 -0
  148. package/dist/core/startFileRouteCriteria.js.map +1 -0
  149. package/dist/core/startFixedRouteCriteria.d.ts +1 -0
  150. package/dist/core/startFixedRouteCriteria.js +90 -0
  151. package/dist/core/startFixedRouteCriteria.js.map +1 -0
  152. package/dist/core/startImpactRouteCriteria.d.ts +7 -0
  153. package/dist/core/startImpactRouteCriteria.js +14 -0
  154. package/dist/core/startImpactRouteCriteria.js.map +1 -0
  155. package/dist/core/startIntentTargets.d.ts +1 -0
  156. package/dist/core/startIntentTargets.js +28 -0
  157. package/dist/core/startIntentTargets.js.map +1 -1
  158. package/dist/core/startMissionControl.js +8 -2
  159. package/dist/core/startMissionControl.js.map +1 -1
  160. package/dist/core/startMissionPolicy.js +2 -0
  161. package/dist/core/startMissionPolicy.js.map +1 -1
  162. package/dist/core/startMode.d.ts +1 -0
  163. package/dist/core/startMode.js +10 -2
  164. package/dist/core/startMode.js.map +1 -1
  165. package/dist/core/startPreflightRouteCriteria.d.ts +11 -0
  166. package/dist/core/startPreflightRouteCriteria.js +29 -0
  167. package/dist/core/startPreflightRouteCriteria.js.map +1 -0
  168. package/dist/core/startProductPlanningRouteCriteria.d.ts +8 -0
  169. package/dist/core/startProductPlanningRouteCriteria.js +29 -0
  170. package/dist/core/startProductPlanningRouteCriteria.js.map +1 -0
  171. package/dist/core/startRegressionRouteCriteria.d.ts +3 -0
  172. package/dist/core/startRegressionRouteCriteria.js +62 -0
  173. package/dist/core/startRegressionRouteCriteria.js.map +1 -0
  174. package/dist/core/startRouteActions.js +39 -1
  175. package/dist/core/startRouteActions.js.map +1 -1
  176. package/dist/core/startSuccessCriteria.d.ts +2 -3
  177. package/dist/core/startSuccessCriteria.js +15 -419
  178. package/dist/core/startSuccessCriteria.js.map +1 -1
  179. package/dist/core/startUnderstandRouteCriteria.d.ts +3 -0
  180. package/dist/core/startUnderstandRouteCriteria.js +97 -0
  181. package/dist/core/startUnderstandRouteCriteria.js.map +1 -0
  182. package/dist/core/telemetry.d.ts +9 -89
  183. package/dist/core/telemetry.js +33 -391
  184. package/dist/core/telemetry.js.map +1 -1
  185. package/dist/core/telemetryConfig.d.ts +58 -0
  186. package/dist/core/telemetryConfig.js +171 -0
  187. package/dist/core/telemetryConfig.js.map +1 -0
  188. package/dist/core/telemetryEvents.d.ts +57 -0
  189. package/dist/core/telemetryEvents.js +143 -0
  190. package/dist/core/telemetryEvents.js.map +1 -0
  191. package/dist/core/telemetryFlushing.d.ts +10 -0
  192. package/dist/core/telemetryFlushing.js +42 -0
  193. package/dist/core/telemetryFlushing.js.map +1 -0
  194. package/dist/core/telemetryRecording.d.ts +26 -0
  195. package/dist/core/telemetryRecording.js +38 -0
  196. package/dist/core/telemetryRecording.js.map +1 -0
  197. package/dist/core/telemetrySender.d.ts +9 -0
  198. package/dist/core/telemetrySender.js +22 -0
  199. package/dist/core/telemetrySender.js.map +1 -0
  200. package/dist/index.d.ts +4 -60
  201. package/dist/index.js +4 -60
  202. package/dist/index.js.map +1 -1
  203. package/dist/mcp/server.js +2 -13
  204. package/dist/mcp/server.js.map +1 -1
  205. package/dist/mcp/serverMessageHandling.d.ts +3 -0
  206. package/dist/mcp/serverMessageHandling.js +16 -0
  207. package/dist/mcp/serverMessageHandling.js.map +1 -0
  208. package/dist/mcp/toolDefinitions.d.ts +3 -0
  209. package/dist/mcp/toolDefinitions.js +15 -0
  210. package/dist/mcp/toolDefinitions.js.map +1 -0
  211. package/dist/mcp/tools.js +2 -12
  212. package/dist/mcp/tools.js.map +1 -1
  213. package/dist/projscan-sbom.cdx.json +6 -6
  214. package/dist/publicAgent.d.ts +22 -0
  215. package/dist/publicAgent.js +23 -0
  216. package/dist/publicAgent.js.map +1 -0
  217. package/dist/publicCore.d.ts +29 -0
  218. package/dist/publicCore.js +30 -0
  219. package/dist/publicCore.js.map +1 -0
  220. package/dist/publicLanguages.d.ts +1 -0
  221. package/dist/publicLanguages.js +2 -0
  222. package/dist/publicLanguages.js.map +1 -0
  223. package/dist/publicMcp.d.ts +8 -0
  224. package/dist/publicMcp.js +9 -0
  225. package/dist/publicMcp.js.map +1 -0
  226. package/dist/reporters/htmlAnalysisReporter.d.ts +3 -0
  227. package/dist/reporters/htmlAnalysisReporter.js +98 -0
  228. package/dist/reporters/htmlAnalysisReporter.js.map +1 -0
  229. package/dist/reporters/htmlCoverageReporter.d.ts +2 -0
  230. package/dist/reporters/htmlCoverageReporter.js +52 -0
  231. package/dist/reporters/htmlCoverageReporter.js.map +1 -0
  232. package/dist/reporters/htmlImpactReporter.d.ts +2 -0
  233. package/dist/reporters/htmlImpactReporter.js +41 -0
  234. package/dist/reporters/htmlImpactReporter.js.map +1 -0
  235. package/dist/reporters/htmlPrDiffReporter.d.ts +2 -0
  236. package/dist/reporters/htmlPrDiffReporter.js +84 -0
  237. package/dist/reporters/htmlPrDiffReporter.js.map +1 -0
  238. package/dist/reporters/htmlReporter.d.ts +20 -9
  239. package/dist/reporters/htmlReporter.js +7 -365
  240. package/dist/reporters/htmlReporter.js.map +1 -1
  241. package/dist/reporters/htmlReviewReporter.d.ts +2 -0
  242. package/dist/reporters/htmlReviewReporter.js +94 -0
  243. package/dist/reporters/htmlReviewReporter.js.map +1 -0
  244. package/dist/reporters/htmlShared.d.ts +7 -0
  245. package/dist/reporters/htmlShared.js +106 -0
  246. package/dist/reporters/htmlShared.js.map +1 -0
  247. package/dist/tool-manifest.json +2 -2
  248. package/dist/types/preflight.d.ts +19 -0
  249. package/dist/types/start.d.ts +7 -451
  250. package/dist/types/startCommon.d.ts +79 -0
  251. package/dist/types/startCommon.js +2 -0
  252. package/dist/types/startCommon.js.map +1 -0
  253. package/dist/types/startExecution.d.ts +44 -0
  254. package/dist/types/startExecution.js +2 -0
  255. package/dist/types/startExecution.js.map +1 -0
  256. package/dist/types/startMissionControl.d.ts +91 -0
  257. package/dist/types/startMissionControl.js +2 -0
  258. package/dist/types/startMissionControl.js.map +1 -0
  259. package/dist/types/startMissionProof.d.ts +91 -0
  260. package/dist/types/startMissionProof.js +2 -0
  261. package/dist/types/startMissionProof.js.map +1 -0
  262. package/dist/types/startMissionResume.d.ts +100 -0
  263. package/dist/types/startMissionResume.js +2 -0
  264. package/dist/types/startMissionResume.js.map +1 -0
  265. package/dist/types/startMissionReview.d.ts +45 -0
  266. package/dist/types/startMissionReview.js +2 -0
  267. package/dist/types/startMissionReview.js.map +1 -0
  268. package/dist/types/startMissionTooling.d.ts +16 -0
  269. package/dist/types/startMissionTooling.js +2 -0
  270. package/dist/types/startMissionTooling.js.map +1 -0
  271. package/dist/utils/changedFiles.d.ts +1 -0
  272. package/dist/utils/changedFiles.js +7 -4
  273. package/dist/utils/changedFiles.js.map +1 -1
  274. package/docs/GUIDE.md +9 -7
  275. package/docs/ROADMAP.md +2 -2
  276. package/docs/examples/adoption-workflows.md +12 -1
  277. package/docs/examples/swarm-coordination.md +11 -2
  278. package/package.json +1 -1
@@ -0,0 +1,80 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { validateManifest } from './pluginManifestValidation.js';
4
+ export const PLUGIN_DIR = '.projscan-plugins';
5
+ export const PLUGIN_MANIFEST_EXT = '.projscan-plugin.json';
6
+ export async function readPluginManifestFile(manifestPath) {
7
+ let raw;
8
+ try {
9
+ raw = await fs.readFile(manifestPath, 'utf-8');
10
+ }
11
+ catch (err) {
12
+ const message = `unable to read manifest: ${formatError(err)}`;
13
+ return {
14
+ ok: false,
15
+ reason: message,
16
+ diagnostic: {
17
+ code: 'read-error',
18
+ message,
19
+ hint: 'Check file permissions and try again.',
20
+ },
21
+ };
22
+ }
23
+ let parsed;
24
+ try {
25
+ parsed = JSON.parse(raw);
26
+ }
27
+ catch (err) {
28
+ const message = `invalid JSON: ${formatError(err)}`;
29
+ return {
30
+ ok: false,
31
+ reason: message,
32
+ diagnostic: {
33
+ code: 'invalid-json',
34
+ message,
35
+ hint: 'Fix the manifest so it is valid JSON.',
36
+ },
37
+ };
38
+ }
39
+ const validation = validateManifest(parsed);
40
+ return validation.ok
41
+ ? { ok: true, manifest: validation.manifest }
42
+ : { ok: false, reason: validation.reason, diagnostic: validation.diagnostic };
43
+ }
44
+ /**
45
+ * Discover every plugin manifest under `<root>/.projscan-plugins/`. Manifests
46
+ * that fail to parse or validate are returned with `manifest: null` and an
47
+ * `error` so the CLI / MCP tool can surface them without throwing.
48
+ */
49
+ export async function discoverPluginManifests(rootPath) {
50
+ const dir = path.join(rootPath, PLUGIN_DIR);
51
+ let entries;
52
+ try {
53
+ entries = await fs.readdir(dir);
54
+ }
55
+ catch {
56
+ return [];
57
+ }
58
+ const out = [];
59
+ for (const name of entries.sort()) {
60
+ if (!name.endsWith(PLUGIN_MANIFEST_EXT))
61
+ continue;
62
+ const manifestPath = path.join(dir, name);
63
+ const result = await readPluginManifestFile(manifestPath);
64
+ if (!result.ok) {
65
+ out.push({
66
+ manifestPath,
67
+ manifest: null,
68
+ error: result.reason,
69
+ diagnostic: result.diagnostic,
70
+ });
71
+ continue;
72
+ }
73
+ out.push({ manifestPath, manifest: result.manifest });
74
+ }
75
+ return out;
76
+ }
77
+ function formatError(err) {
78
+ return err instanceof Error ? err.message : String(err);
79
+ }
80
+ //# sourceMappingURL=pluginManifestDiscovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginManifestDiscovery.js","sourceRoot":"","sources":["../../src/core/pluginManifestDiscovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ type PluginManifestLabel = 'manifest' | 'reporter manifest';
2
+ export declare function assertPluginModuleReadable(manifestModule: string, modulePath: string): Promise<void>;
3
+ export declare function describePluginModuleLoadError(err: unknown, manifestModule: string, modulePath: string, manifestLabel: PluginManifestLabel): {
4
+ message: string;
5
+ hint?: string;
6
+ };
7
+ export declare function importPluginModule(modulePath: string): Promise<Record<string, unknown>>;
8
+ export {};
@@ -0,0 +1,91 @@
1
+ import fs from 'node:fs/promises';
2
+ import { pathToFileURL } from 'node:url';
3
+ // Keep arbitrary plugin file URLs out of Vite/Vitest's static import transform.
4
+ const dynamicImport = new Function('specifier', 'return import(specifier)');
5
+ class PluginModuleMissingError extends Error {
6
+ manifestModule;
7
+ modulePath;
8
+ constructor(manifestModule, modulePath) {
9
+ super(`module "${manifestModule}" was not found at ${modulePath}`);
10
+ this.manifestModule = manifestModule;
11
+ this.modulePath = modulePath;
12
+ }
13
+ }
14
+ class PluginModuleReadError extends Error {
15
+ manifestModule;
16
+ modulePath;
17
+ constructor(manifestModule, modulePath, err) {
18
+ super(`module "${manifestModule}" could not be read at ${modulePath}: ${formatError(err)}`);
19
+ this.manifestModule = manifestModule;
20
+ this.modulePath = modulePath;
21
+ }
22
+ }
23
+ export async function assertPluginModuleReadable(manifestModule, modulePath) {
24
+ try {
25
+ await fs.access(modulePath);
26
+ }
27
+ catch (err) {
28
+ const code = typeof err === 'object' && err !== null && 'code' in err
29
+ ? String(err.code)
30
+ : '';
31
+ if (code === 'ENOENT')
32
+ throw new PluginModuleMissingError(manifestModule, modulePath);
33
+ throw new PluginModuleReadError(manifestModule, modulePath, err);
34
+ }
35
+ }
36
+ export function describePluginModuleLoadError(err, manifestModule, modulePath, manifestLabel) {
37
+ if (err instanceof PluginModuleMissingError) {
38
+ return {
39
+ message: err.message,
40
+ hint: `Check the ${manifestLabel} "module" path.`,
41
+ };
42
+ }
43
+ if (err instanceof PluginModuleReadError) {
44
+ return {
45
+ message: err.message,
46
+ hint: `Check file permissions for the ${manifestLabel} "module" path.`,
47
+ };
48
+ }
49
+ if (err instanceof SyntaxError) {
50
+ return {
51
+ message: `syntax error in module "${manifestModule}": ${formatError(err)}`,
52
+ hint: `Run node "${modulePath}" to reproduce the syntax error.`,
53
+ };
54
+ }
55
+ return { message: formatError(err) };
56
+ }
57
+ export function importPluginModule(modulePath) {
58
+ return dynamicImport(pathToFileURL(modulePath).href).catch(async (err) => {
59
+ if (!isMissingDynamicImportCallback(err))
60
+ throw err;
61
+ return importPluginModuleFromSource(modulePath);
62
+ });
63
+ }
64
+ function isMissingDynamicImportCallback(err) {
65
+ return err instanceof TypeError && err.message.includes('dynamic import callback was not specified');
66
+ }
67
+ async function importPluginModuleFromSource(modulePath) {
68
+ const source = await fs.readFile(modulePath, 'utf-8');
69
+ const defaultMatch = source.match(/^\s*export\s+default\s+([\s\S]*?)\s*;?\s*$/);
70
+ if (defaultMatch) {
71
+ const expression = defaultMatch[1].trim().replace(/;$/, '');
72
+ return { default: new Function(`return (${expression});`)() };
73
+ }
74
+ const names = [];
75
+ let transformed = source.replace(/\bexport\s+(async\s+function|function)\s+([A-Za-z_$][\w$]*)/g, (_m, kind, name) => {
76
+ names.push(String(name));
77
+ return `${kind} ${name}`;
78
+ });
79
+ transformed = transformed.replace(/\bexport\s+const\s+([A-Za-z_$][\w$]*)\s*=/g, (_m, name) => {
80
+ names.push(String(name));
81
+ return `const ${name} =`;
82
+ });
83
+ if (names.length === 0) {
84
+ throw new Error('unsupported module syntax in Vitest VM fallback');
85
+ }
86
+ return new Function(`${transformed}\nreturn { ${names.join(', ')} };`)();
87
+ }
88
+ function formatError(err) {
89
+ return err instanceof Error ? err.message : String(err);
90
+ }
91
+ //# sourceMappingURL=pluginModuleLoading.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginModuleLoading.js","sourceRoot":"","sources":["../../src/core/pluginModuleLoading.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { PluginDiagnostic, PluginReporterCommand, PluginReporterManifest } from './pluginManifestValidation.js';
2
+ export interface PluginReporterContext<TPayload = unknown> {
3
+ command: PluginReporterCommand;
4
+ rootPath: string;
5
+ manifest: PluginReporterManifest;
6
+ payload: TPayload;
7
+ }
8
+ export interface PluginReporterExports {
9
+ render: (context: PluginReporterContext) => Promise<string> | string;
10
+ }
11
+ export interface LoadedReporterPlugin {
12
+ manifest: PluginReporterManifest;
13
+ /** Absolute path to the manifest file on disk. */
14
+ manifestPath: string;
15
+ /** Absolute path to the resolved module entry point. */
16
+ modulePath: string;
17
+ exports: PluginReporterExports;
18
+ }
19
+ export type PluginReporterResolveResult = {
20
+ ok: true;
21
+ plugin: LoadedReporterPlugin;
22
+ } | {
23
+ ok: false;
24
+ reason: string;
25
+ diagnostic: PluginDiagnostic;
26
+ };
27
+ export type PluginReporterRenderResult = {
28
+ ok: true;
29
+ output: string;
30
+ } | {
31
+ ok: false;
32
+ reason: string;
33
+ diagnostic: PluginDiagnostic;
34
+ };
35
+ export interface PluginReporterResolveOptions {
36
+ pluginsEnabled: boolean;
37
+ previewFlag: string;
38
+ }
39
+ export declare function resolveReporterPlugin(rootPath: string, reporterName: string, command: PluginReporterCommand, options: PluginReporterResolveOptions): Promise<PluginReporterResolveResult>;
40
+ export declare function renderReporterPlugin(plugin: LoadedReporterPlugin, context: PluginReporterContext): Promise<PluginReporterRenderResult>;
41
+ export declare function loadReporterPlugin(manifest: PluginReporterManifest, manifestPath: string): Promise<PluginReporterResolveResult>;
@@ -0,0 +1,105 @@
1
+ import path from 'node:path';
2
+ import { discoverPluginManifests } from './pluginManifestDiscovery.js';
3
+ import { assertPluginModuleReadable, describePluginModuleLoadError, importPluginModule, } from './pluginModuleLoading.js';
4
+ import { getPluginTrustStatus } from './pluginTrust.js';
5
+ export async function resolveReporterPlugin(rootPath, reporterName, command, options) {
6
+ if (!options.pluginsEnabled) {
7
+ return pluginRuntimeFail({
8
+ code: 'plugins-disabled',
9
+ message: `reporter plugins require ${options.previewFlag}=1`,
10
+ hint: `Set ${options.previewFlag}=1 in the environment to enable plugin reporters.`,
11
+ });
12
+ }
13
+ const entries = await discoverPluginManifests(rootPath);
14
+ const reporters = entries.filter((entry) => entry.manifest?.kind === 'reporter');
15
+ const entry = reporters.find((candidate) => candidate.manifest.name === reporterName);
16
+ if (!entry) {
17
+ return pluginRuntimeFail({
18
+ code: 'reporter-not-found',
19
+ message: `reporter plugin "${reporterName}" was not found`,
20
+ hint: 'Run `projscan plugin list` to see discovered reporter plugins.',
21
+ });
22
+ }
23
+ if (!entry.manifest.commands.includes(command)) {
24
+ return pluginRuntimeFail({
25
+ code: 'reporter-unsupported-command',
26
+ message: `reporter plugin "${reporterName}" does not support command "${command}"`,
27
+ hint: `Add "${command}" to the reporter manifest's commands array or choose a different reporter.`,
28
+ });
29
+ }
30
+ return loadReporterPlugin(entry.manifest, entry.manifestPath);
31
+ }
32
+ export async function renderReporterPlugin(plugin, context) {
33
+ try {
34
+ const output = await plugin.exports.render(context);
35
+ if (typeof output !== 'string') {
36
+ return pluginRuntimeFail({
37
+ code: 'reporter-render-error',
38
+ message: `reporter plugin "${plugin.manifest.name}" returned ${typeof output}; expected string`,
39
+ hint: 'Reporter render(context) must return text for stdout.',
40
+ });
41
+ }
42
+ return { ok: true, output };
43
+ }
44
+ catch (err) {
45
+ return pluginRuntimeFail({
46
+ code: 'reporter-render-error',
47
+ message: `reporter plugin "${plugin.manifest.name}" failed during render: ${formatError(err)}`,
48
+ hint: 'Fix the reporter render(context) implementation and try again.',
49
+ });
50
+ }
51
+ }
52
+ export async function loadReporterPlugin(manifest, manifestPath) {
53
+ const modulePath = path.resolve(path.dirname(manifestPath), manifest.module);
54
+ try {
55
+ await assertPluginModuleReadable(manifest.module, modulePath);
56
+ // Importing a reporter executes local code, so trust must be checked first.
57
+ const trust = await getPluginTrustStatus(modulePath);
58
+ if (trust.status !== 'trusted') {
59
+ return pluginRuntimeFail(untrustedReporterDiagnostic(manifest.name, trust.status));
60
+ }
61
+ const mod = await importPluginModule(modulePath);
62
+ const exportsObj = (mod.default ?? mod);
63
+ if (typeof exportsObj.render !== 'function') {
64
+ return pluginRuntimeFail({
65
+ code: 'invalid-reporter-export',
66
+ message: `reporter plugin "${manifest.name}" missing required export "render"`,
67
+ hint: 'Use export default { render(context) { ... } } or export a named render function.',
68
+ });
69
+ }
70
+ return {
71
+ ok: true,
72
+ plugin: {
73
+ manifest,
74
+ manifestPath,
75
+ modulePath,
76
+ exports: { render: exportsObj.render },
77
+ },
78
+ };
79
+ }
80
+ catch (err) {
81
+ const detail = describePluginModuleLoadError(err, manifest.module, modulePath, 'reporter manifest');
82
+ return pluginRuntimeFail({
83
+ code: 'reporter-load-error',
84
+ message: `reporter plugin "${manifest.name}" failed to load: ${detail.message}`,
85
+ hint: detail.hint ?? 'Check the reporter module path and module syntax.',
86
+ });
87
+ }
88
+ }
89
+ function untrustedReporterDiagnostic(name, status) {
90
+ const changed = status === 'changed';
91
+ return {
92
+ code: 'plugin-untrusted',
93
+ message: changed
94
+ ? `reporter plugin "${name}" changed since it was trusted; not executed`
95
+ : `reporter plugin "${name}" is not trusted; not executed`,
96
+ hint: `${changed ? 'Re-run' : 'Run'} \`projscan plugin trust ${name}\` to approve this reporter.`,
97
+ };
98
+ }
99
+ function pluginRuntimeFail(diagnostic) {
100
+ return { ok: false, reason: diagnostic.message, diagnostic };
101
+ }
102
+ function formatError(err) {
103
+ return err instanceof Error ? err.message : String(err);
104
+ }
105
+ //# sourceMappingURL=pluginReporterLoading.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginReporterLoading.js","sourceRoot":"","sources":["../../src/core/pluginReporterLoading.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { CodeGraph } from './codeGraph.js';
2
+ import type { DataflowReport, FileEntry, Issue, SemanticGraphReport } from '../types.js';
3
+ import type { PluginAnalyzerManifest } from './pluginManifestValidation.js';
4
+ export interface PluginAnalyzerContext {
5
+ schemaVersion: 1;
6
+ getCodeGraph: () => Promise<CodeGraph>;
7
+ getSemanticGraph: () => Promise<SemanticGraphReport>;
8
+ getDataflow: () => Promise<DataflowReport>;
9
+ }
10
+ export interface PluginAnalyzerExports {
11
+ check: (rootPath: string, files: FileEntry[], context?: PluginAnalyzerContext) => Promise<Issue[]> | Issue[];
12
+ }
13
+ export interface LoadedPlugin {
14
+ manifest: PluginAnalyzerManifest;
15
+ /** Absolute path to the manifest file on disk. */
16
+ manifestPath: string;
17
+ /** Absolute path to the resolved module entry point. */
18
+ modulePath: string;
19
+ exports: PluginAnalyzerExports;
20
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pluginRuntimeTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginRuntimeTypes.js","sourceRoot":"","sources":["../../src/core/pluginRuntimeTypes.ts"],"names":[],"mappings":""}
@@ -1,6 +1,6 @@
1
- import type { CodeGraph } from './codeGraph.js';
2
- import type { FileEntry, Issue, DataflowReport, SemanticGraphReport } from '../types.js';
3
- import type { PluginAnalyzerManifest, PluginDiagnostic, PluginManifest, PluginReporterCommand, PluginReporterManifest } from './pluginManifestValidation.js';
1
+ import type { PluginReporterResolveResult } from './pluginReporterLoading.js';
2
+ import type { LoadedPlugin } from './pluginRuntimeTypes.js';
3
+ import type { PluginReporterCommand } from './pluginManifestValidation.js';
4
4
  /**
5
5
  * Stable local plugin API (2.0+).
6
6
  *
@@ -16,83 +16,15 @@ import type { PluginAnalyzerManifest, PluginDiagnostic, PluginManifest, PluginRe
16
16
  * discipline as the rest of projscan.
17
17
  */
18
18
  export declare const PLUGIN_PREVIEW_FLAG = "PROJSCAN_PLUGINS_PREVIEW";
19
- export declare const PLUGIN_DIR = ".projscan-plugins";
20
- export declare const PLUGIN_MANIFEST_EXT = ".projscan-plugin.json";
19
+ export { PLUGIN_DIR, PLUGIN_MANIFEST_EXT, discoverPluginManifests, readPluginManifestFile, } from './pluginManifestDiscovery.js';
20
+ export type { PluginDiscoveryEntry, PluginManifestFileResult } from './pluginManifestDiscovery.js';
21
+ export type { LoadedPlugin, PluginAnalyzerContext, PluginAnalyzerExports, } from './pluginRuntimeTypes.js';
22
+ export { runAnalyzerPlugins } from './pluginAnalyzerRunning.js';
21
23
  export { PLUGIN_REPORTER_COMMANDS, PLUGIN_SCHEMA_VERSION, validateManifest, } from './pluginManifestValidation.js';
22
24
  export type { PluginAnalyzerManifest, PluginDiagnostic, PluginKind, PluginManifest, PluginReporterCommand, PluginReporterManifest, } from './pluginManifestValidation.js';
23
- export interface PluginAnalyzerContext {
24
- schemaVersion: 1;
25
- getCodeGraph: () => Promise<CodeGraph>;
26
- getSemanticGraph: () => Promise<SemanticGraphReport>;
27
- getDataflow: () => Promise<DataflowReport>;
28
- }
29
- export interface PluginAnalyzerExports {
30
- check: (rootPath: string, files: FileEntry[], context?: PluginAnalyzerContext) => Promise<Issue[]> | Issue[];
31
- }
32
- export interface PluginReporterContext<TPayload = unknown> {
33
- command: PluginReporterCommand;
34
- rootPath: string;
35
- manifest: PluginReporterManifest;
36
- payload: TPayload;
37
- }
38
- export interface PluginReporterExports {
39
- render: (context: PluginReporterContext) => Promise<string> | string;
40
- }
41
- export interface LoadedPlugin {
42
- manifest: PluginAnalyzerManifest;
43
- /** Absolute path to the manifest file on disk. */
44
- manifestPath: string;
45
- /** Absolute path to the resolved module entry point. */
46
- modulePath: string;
47
- exports: PluginAnalyzerExports;
48
- }
49
- export interface LoadedReporterPlugin {
50
- manifest: PluginReporterManifest;
51
- /** Absolute path to the manifest file on disk. */
52
- manifestPath: string;
53
- /** Absolute path to the resolved module entry point. */
54
- modulePath: string;
55
- exports: PluginReporterExports;
56
- }
57
- export interface PluginDiscoveryEntry {
58
- manifestPath: string;
59
- manifest: PluginManifest | null;
60
- /** Set when the manifest failed to parse or validate. */
61
- error?: string;
62
- diagnostic?: PluginDiagnostic;
63
- }
64
- export type PluginManifestFileResult = {
65
- ok: true;
66
- manifest: PluginManifest;
67
- } | {
68
- ok: false;
69
- reason: string;
70
- diagnostic: PluginDiagnostic;
71
- };
72
- export type PluginReporterResolveResult = {
73
- ok: true;
74
- plugin: LoadedReporterPlugin;
75
- } | {
76
- ok: false;
77
- reason: string;
78
- diagnostic: PluginDiagnostic;
79
- };
80
- export type PluginReporterRenderResult = {
81
- ok: true;
82
- output: string;
83
- } | {
84
- ok: false;
85
- reason: string;
86
- diagnostic: PluginDiagnostic;
87
- };
25
+ export { renderReporterPlugin } from './pluginReporterLoading.js';
26
+ export type { LoadedReporterPlugin, PluginReporterContext, PluginReporterExports, PluginReporterRenderResult, PluginReporterResolveResult, } from './pluginReporterLoading.js';
88
27
  export declare function pluginsEnabled(): boolean;
89
- export declare function readPluginManifestFile(manifestPath: string): Promise<PluginManifestFileResult>;
90
- /**
91
- * Discover every plugin manifest under `<root>/.projscan-plugins/`. Manifests
92
- * that fail to parse or validate are returned with `manifest: null` and an
93
- * `error` so the CLI / MCP tool can surface them without throwing.
94
- */
95
- export declare function discoverPluginManifests(rootPath: string): Promise<PluginDiscoveryEntry[]>;
96
28
  /**
97
29
  * Discover, validate, and dynamically import every plugin under the
98
30
  * project. Returns [] when the preview flag is off.
@@ -103,12 +35,3 @@ export declare function discoverPluginManifests(rootPath: string): Promise<Plugi
103
35
  */
104
36
  export declare function loadPlugins(rootPath: string): Promise<LoadedPlugin[]>;
105
37
  export declare function resolveReporterPlugin(rootPath: string, reporterName: string, command: PluginReporterCommand): Promise<PluginReporterResolveResult>;
106
- export declare function renderReporterPlugin(plugin: LoadedReporterPlugin, context: PluginReporterContext): Promise<PluginReporterRenderResult>;
107
- /**
108
- * Run every loaded analyzer plugin against `files`. Issues that don't pass
109
- * a tight shape check are dropped so a malformed plugin can't poison the
110
- * issue stream. Each plugin's output is also re-stamped with `id` prefixed
111
- * by the plugin name (so two plugins emitting the same local rule id can't
112
- * collide).
113
- */
114
- export declare function runAnalyzerPlugins(plugins: LoadedPlugin[], rootPath: string, files: FileEntry[], context?: PluginAnalyzerContext): Promise<Issue[]>;