progmune-runtime 2.1.6 → 3.2.1

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 (356) hide show
  1. package/README.md +119 -461
  2. package/dist/ablation-study.js +144 -0
  3. package/dist/ablation-study.test.js +18 -0
  4. package/dist/action-runtime.js +3 -1
  5. package/dist/active-learning.js +211 -0
  6. package/dist/analytics.js +139 -0
  7. package/dist/asset-factory.js +309 -0
  8. package/dist/asset-growth.js +244 -0
  9. package/dist/asset-promotion.js +382 -0
  10. package/dist/asset-quality.js +550 -0
  11. package/dist/audit/business-translator.js +285 -0
  12. package/dist/audit/cli.js +66 -0
  13. package/dist/audit/formatters/html.js +379 -0
  14. package/dist/audit/formatters/json.js +11 -0
  15. package/dist/audit/formatters/markdown.js +192 -0
  16. package/dist/audit/formatters/terminal.js +189 -0
  17. package/dist/audit/index.js +25 -0
  18. package/dist/audit/report-builder.js +318 -0
  19. package/dist/audit/types.js +8 -0
  20. package/dist/audit.js +3 -3
  21. package/dist/auto-benchmark-generator.js +137 -0
  22. package/dist/auto-benchmark-generator.test.js +45 -0
  23. package/dist/auto-protocol-synthesizer.js +362 -0
  24. package/dist/auto-protocol-synthesizer.test.js +82 -0
  25. package/dist/autonomous-patch.js +175 -0
  26. package/dist/autonomous-patch.test.js +128 -0
  27. package/dist/badge/badge-server.js +98 -0
  28. package/dist/behavior-miner.js +442 -0
  29. package/dist/belief-layer.js +475 -0
  30. package/dist/benchmark-count.js +5 -0
  31. package/dist/benchmark-generator.js +211 -0
  32. package/dist/benchmark-harness.js +201 -0
  33. package/dist/benchmark-pass-rate.js +7 -0
  34. package/dist/benchmark-report.js +8 -3
  35. package/dist/benchmark-save.js +14 -1
  36. package/dist/bootstrap-validation.js +197 -0
  37. package/dist/bootstrap-validation.test.js +51 -0
  38. package/dist/branch-ledger.js +1 -1
  39. package/dist/capability-gap.js +130 -0
  40. package/dist/certify-html.js +351 -0
  41. package/dist/certify.js +326 -0
  42. package/dist/check.js +4 -4
  43. package/dist/compliance-miner.js +447 -0
  44. package/dist/continuous-benchmark.js +194 -0
  45. package/dist/continuous-benchmark.test.js +116 -0
  46. package/dist/corpus-stats.js +173 -0
  47. package/dist/counterfactual-engine.js +288 -0
  48. package/dist/coverage-dashboard.js +109 -0
  49. package/dist/coverage-system.test.js +205 -0
  50. package/dist/cross-repo-precision.js +352 -0
  51. package/dist/cve-benchmark.js +180 -0
  52. package/dist/cve-benchmark.test.js +28 -0
  53. package/dist/cve-collector.js +73 -0
  54. package/dist/data-quality.js +141 -0
  55. package/dist/decision-engine.js +388 -0
  56. package/dist/derive-metadata.js +250 -0
  57. package/dist/difficulty-active.test.js +198 -0
  58. package/dist/difficulty-map.js +244 -0
  59. package/dist/discovery-analytics.js +125 -0
  60. package/dist/discovery-model.js +149 -0
  61. package/dist/discovery-optimize.test.js +199 -0
  62. package/dist/discovery-trace.js +276 -0
  63. package/dist/discovery-trace.test.js +97 -0
  64. package/dist/emitter.js +83 -1
  65. package/dist/enterprise-dashboard.js +405 -0
  66. package/dist/eval-hardening.js +297 -0
  67. package/dist/eval-hardening.test.js +85 -0
  68. package/dist/evaluation-campaign.js +359 -0
  69. package/dist/evaluation-campaign.test.js +181 -0
  70. package/dist/evidence-growth.js +143 -0
  71. package/dist/evidence-repository.js +209 -0
  72. package/dist/evidence-system.js +441 -0
  73. package/dist/execute.js +15 -7
  74. package/dist/experimental/software-physics.js +291 -0
  75. package/dist/experimental/state-inference.js +516 -0
  76. package/dist/experimental/unsupervised-physics.js +230 -0
  77. package/dist/extract-ir-python.js +54 -7
  78. package/dist/extract-ir.js +376 -12
  79. package/dist/failure-collector.js +2 -2
  80. package/dist/failure-corpus.js +322 -9
  81. package/dist/feedback.js +16 -5
  82. package/dist/feedback.test.js +49 -0
  83. package/dist/file-lock.js +1 -1
  84. package/dist/flywheel-batch.js +292 -0
  85. package/dist/frameworks/express-cli.js +237 -0
  86. package/dist/frameworks/express-detector.js +445 -0
  87. package/dist/frameworks/express-detector.test.js +206 -0
  88. package/dist/frameworks/index.js +30 -0
  89. package/dist/frameworks/nestjs-detector.js +302 -0
  90. package/dist/frameworks/trpc-detector.js +161 -0
  91. package/dist/frameworks/version-awareness.js +179 -0
  92. package/dist/function-synonyms.js +164 -0
  93. package/dist/function-synonyms.test.js +68 -0
  94. package/dist/generalization.test.js +352 -0
  95. package/dist/goal-annotator.js +113 -0
  96. package/dist/goal-planner.js +563 -0
  97. package/dist/gold-cve.js +164 -0
  98. package/dist/gold-cve.test.js +104 -0
  99. package/dist/gold-quality.js +206 -0
  100. package/dist/gold-tiers.js +241 -0
  101. package/dist/governance-dashboard.js +327 -0
  102. package/dist/graph-viz.js +240 -0
  103. package/dist/guided-frontier.js +195 -0
  104. package/dist/hierarchical-planner.js +148 -0
  105. package/dist/identifier-parser.js +260 -0
  106. package/dist/immune-metrics.js +93 -0
  107. package/dist/immune-receiver.js +158 -0
  108. package/dist/immune-reporter.js +1 -1
  109. package/dist/improvement-orchestrator.js +206 -0
  110. package/dist/inject-p0-vocabulary.js +300 -0
  111. package/dist/intent-parser.js +218 -0
  112. package/dist/invariant-algebra.js +476 -0
  113. package/dist/invariant-calculus.js +533 -0
  114. package/dist/ir-utils.js +70 -0
  115. package/dist/ir-utils.test.js +50 -0
  116. package/dist/knowledge-api.js +312 -0
  117. package/dist/knowledge-evolution.js +452 -0
  118. package/dist/knowledge-explorer.js +506 -0
  119. package/dist/knowledge-flywheel.js +274 -0
  120. package/dist/knowledge-governance.js +338 -0
  121. package/dist/knowledge-governance.test.js +150 -0
  122. package/dist/knowledge-graph.js +181 -0
  123. package/dist/knowledge-guided-synth.js +246 -0
  124. package/dist/knowledge-loop.test.js +77 -0
  125. package/dist/knowledge-object.js +316 -0
  126. package/dist/knowledge-package.js +98 -0
  127. package/dist/kpi-dashboard.js +561 -0
  128. package/dist/l3-cross-function.js +280 -0
  129. package/dist/learning-ranker.js +148 -0
  130. package/dist/learning-ranker.test.js +291 -0
  131. package/dist/ledger/accountability.js +322 -0
  132. package/dist/ledger/chain-builder.js +185 -0
  133. package/dist/ledger/cli.js +222 -0
  134. package/dist/ledger/index.js +13 -0
  135. package/dist/ledger/signatures.js +193 -0
  136. package/dist/ledger/types.js +9 -0
  137. package/dist/llm.js +74 -3
  138. package/dist/load-benchmarks.js +8 -3
  139. package/dist/logger.js +66 -0
  140. package/dist/logger.test.js +37 -0
  141. package/dist/logistic-reward.js +339 -0
  142. package/dist/logistic-reward.test.js +180 -0
  143. package/dist/macro-graph.js +193 -0
  144. package/dist/macro-repair.js +183 -0
  145. package/dist/mcp-server.mjs +1202 -483
  146. package/dist/memory-layer.js +42 -5
  147. package/dist/multi-repo-precision.js +422 -0
  148. package/dist/name-free-protocol.js +425 -0
  149. package/dist/name-free-protocol.test.js +170 -0
  150. package/dist/name-scrambling.js +138 -0
  151. package/dist/name-scrambling.test.js +16 -0
  152. package/dist/p3-observability.test.js +281 -0
  153. package/dist/p5-orchestrator.test.js +225 -0
  154. package/dist/pairwise-preference.js +294 -0
  155. package/dist/pairwise-preference.test.js +140 -0
  156. package/dist/planner-constraints.js +104 -0
  157. package/dist/planner-prompts.js +155 -0
  158. package/dist/planner-telemetry.js +415 -0
  159. package/dist/planner-trace.js +214 -0
  160. package/dist/planner.js +162 -167
  161. package/dist/plsb/artifact.js +116 -0
  162. package/dist/plsb/cli.js +71 -0
  163. package/dist/plsb/index.js +19 -0
  164. package/dist/plsb/leaderboard.js +249 -0
  165. package/dist/plsb/report-md.js +156 -0
  166. package/dist/plsb/schema.js +179 -0
  167. package/dist/plsb-benchmark.js +284 -0
  168. package/dist/plsb-benchmark.test.js +119 -0
  169. package/dist/policy/cli.js +134 -0
  170. package/dist/policy/engine.js +333 -0
  171. package/dist/policy/index.js +12 -0
  172. package/dist/policy/types.js +59 -0
  173. package/dist/policy-miner.js +505 -0
  174. package/dist/precision-analyze.js +229 -0
  175. package/dist/precision-benchmark.js +147 -0
  176. package/dist/precision-label-c.js +134 -0
  177. package/dist/precision-label.js +193 -0
  178. package/dist/precision-report-c.js +149 -0
  179. package/dist/precision-report.js +246 -0
  180. package/dist/progmune-status.js +108 -0
  181. package/dist/proof-engine.js +479 -0
  182. package/dist/proof-provenance.js +315 -0
  183. package/dist/protocol-coverage.js +294 -0
  184. package/dist/protocol-detector.js +1189 -0
  185. package/dist/protocol-embedding-expanded.js +297 -0
  186. package/dist/protocol-embedding-expanded.test.js +97 -0
  187. package/dist/protocol-embedding.js +195 -0
  188. package/dist/protocol-embedding.test.js +82 -0
  189. package/dist/protocol-extractor-v2.js +354 -0
  190. package/dist/protocol-extractor-v2.test.js +140 -0
  191. package/dist/protocol-extractor.js +310 -0
  192. package/dist/protocol-extractor.test.js +113 -0
  193. package/dist/protocol-foundation.js +322 -0
  194. package/dist/protocol-foundation.test.js +163 -0
  195. package/dist/protocol-frontier.js +243 -0
  196. package/dist/protocol-frontier.test.js +92 -0
  197. package/dist/protocol-gap-analyzer.js +228 -0
  198. package/dist/protocol-gap-analyzer.test.js +49 -0
  199. package/dist/protocol-invariants.js +276 -0
  200. package/dist/protocol-invariants.test.js +111 -0
  201. package/dist/protocol-knowledge.js +464 -0
  202. package/dist/protocol-miner.js +343 -0
  203. package/dist/protocol-mining.js +207 -0
  204. package/dist/protocol-mining.test.js +37 -0
  205. package/dist/protocol-registry.js +1 -1
  206. package/dist/protocol-security-benchmark.js +222 -0
  207. package/dist/protocol-vulnerability.js +257 -0
  208. package/dist/protocol-vulnerability.test.js +60 -0
  209. package/dist/python-benchmark.js +120 -0
  210. package/dist/python-emitter.js +163 -45
  211. package/dist/python-protocol-extractor.js +187 -0
  212. package/dist/python-protocol-extractor.test.js +116 -0
  213. package/dist/realworld-benchmark.js +646 -0
  214. package/dist/realworld-benchmark.test.js +36 -0
  215. package/dist/repair-arch.test.js +411 -0
  216. package/dist/repair-evolution.test.js +454 -0
  217. package/dist/repair-executor.js +719 -0
  218. package/dist/repair-proposal.js +4 -4
  219. package/dist/repair-ranker.js +141 -0
  220. package/dist/repair-strategies.js +419 -0
  221. package/dist/repair-taxonomy.js +234 -0
  222. package/dist/repair-types.js +12 -0
  223. package/dist/repo-evaluator.js +250 -0
  224. package/dist/repo-evaluator.test.js +128 -0
  225. package/dist/resource-abstraction.js +242 -0
  226. package/dist/resource-detector.js +211 -0
  227. package/dist/result.test.js +43 -0
  228. package/dist/reward-system.js +411 -0
  229. package/dist/reward-system.test.js +175 -0
  230. package/dist/risk-model.js +215 -0
  231. package/dist/rule-miner.js +234 -7
  232. package/dist/rule-specificity.js +254 -0
  233. package/dist/runtime-types.js +27 -0
  234. package/dist/scaffold.js +208 -0
  235. package/dist/scale-collector.test.js +101 -0
  236. package/dist/scale-trajectory-collector.js +128 -0
  237. package/dist/sdk.js +250 -0
  238. package/dist/search-planner.js +4 -41
  239. package/dist/semantic-snapshot.js +1 -1
  240. package/dist/semantic-topology.js +121 -0
  241. package/dist/semantic-trace.js +310 -317
  242. package/dist/sequence-extractor.js +343 -0
  243. package/dist/skill-library.js +245 -0
  244. package/dist/skill-planner.test.js +189 -0
  245. package/dist/software-physics.js +291 -0
  246. package/dist/software-physics.test.js +81 -0
  247. package/dist/ssg-precision.js +478 -0
  248. package/dist/ssg-validator.js +71 -21
  249. package/dist/state-inference-doubleblind.test.js +160 -0
  250. package/dist/state-inference.js +516 -0
  251. package/dist/state-inference.test.js +115 -0
  252. package/dist/state-machine-fingerprint.js +345 -0
  253. package/dist/state-machine-fingerprint.test.js +120 -0
  254. package/dist/state-miner.js +386 -0
  255. package/dist/state-name-inference.js +213 -0
  256. package/dist/state-name-inference.test.js +69 -0
  257. package/dist/strategy-planner.js +262 -96
  258. package/dist/strategy-planner.test.js +135 -0
  259. package/dist/telemetry-analytics.test.js +402 -0
  260. package/dist/terminal-format.js +68 -0
  261. package/dist/terminal-format.test.js +83 -0
  262. package/dist/topology-factory.js +196 -0
  263. package/dist/topology-representation.js +242 -0
  264. package/dist/topology-representation.test.js +27 -0
  265. package/dist/trajectory-augmentation.js +254 -0
  266. package/dist/trajectory-augmentation.test.js +63 -0
  267. package/dist/trajectory-corpus.js +440 -0
  268. package/dist/trajectory-corpus.test.js +32 -0
  269. package/dist/trajectory-feedback.test.js +116 -0
  270. package/dist/transition-synthesizer.js +286 -0
  271. package/dist/transition-synthesizer.test.js +123 -0
  272. package/dist/trust/api-semantic-mapper.js +809 -0
  273. package/dist/trust/call-graph-propagator.js +225 -0
  274. package/dist/trust/cli.js +122 -0
  275. package/dist/trust/compliance-scorer.js +283 -0
  276. package/dist/trust/confidence-calculator.js +261 -0
  277. package/dist/trust/engine.js +1145 -0
  278. package/dist/trust/explainability.js +85 -0
  279. package/dist/trust/formatters/ci.js +42 -0
  280. package/dist/trust/formatters/json.js +11 -0
  281. package/dist/trust/formatters/terminal.js +152 -0
  282. package/dist/trust/index.js +39 -0
  283. package/dist/trust/phase1-verify.js +171 -0
  284. package/dist/trust/protocol-domain-validator.js +697 -0
  285. package/dist/trust/score-calculator.js +282 -0
  286. package/dist/trust/ssg-bridge.js +641 -0
  287. package/dist/trust/ssg-bridge.test.js +269 -0
  288. package/dist/trust/types.js +67 -0
  289. package/dist/trust/violation-trace.js +335 -0
  290. package/dist/trust-api.js +179 -0
  291. package/dist/trust-calibration.js +279 -0
  292. package/dist/unknown-protocol-discovery.js +339 -0
  293. package/dist/unknown-protocol-discovery.test.js +102 -0
  294. package/dist/unsupervised-physics.js +230 -0
  295. package/dist/unsupervised-physics.test.js +95 -0
  296. package/dist/utils.test.js +37 -0
  297. package/dist/validator.js +187 -10
  298. package/dist/verification-intelligence.js +475 -0
  299. package/dist/verify-api.js +432 -0
  300. package/dist/vi-impact-report.js +293 -0
  301. package/dist/wl-fingerprint.js +162 -0
  302. package/dist/wl-fingerprint.test.js +130 -0
  303. package/dist/zeroshot-strategy.js +139 -0
  304. package/docs/Progmune_/346/212/225/350/265/204/344/272/272/347/231/275/347/232/256/344/271/246_v2.0.html +576 -0
  305. package/docs/Progmune_/351/241/271/347/233/256/345/205/250/350/247/243.html +721 -0
  306. package/package.json +73 -6
  307. package/protocols.json +1956 -50
  308. package/.dockerignore +0 -14
  309. package/.mcp.json +0 -11
  310. package/.progmune_allowlist +0 -50
  311. package/.test_report/test_report.md +0 -87
  312. package/Dockerfile +0 -9
  313. package/FAQ.md +0 -167
  314. package/WHITEPAPER.md +0 -540
  315. package/demo-project/auth.ts +0 -55
  316. package/demo-project/tsconfig.json +0 -8
  317. package/dist/acl-breakdown.js +0 -13
  318. package/dist/all-sessions.js +0 -11
  319. package/dist/antibody-stats.js +0 -11
  320. package/dist/branch-tree-count.js +0 -14
  321. package/dist/common-fixpath.js +0 -12
  322. package/dist/constraint-types.js +0 -12
  323. package/dist/exec-metrics.js +0 -11
  324. package/dist/failure-report.js +0 -11
  325. package/dist/fast-path-hits.js +0 -13
  326. package/dist/fingerprint-list.js +0 -15
  327. package/dist/gen-history-log.js +0 -13
  328. package/dist/heatmap-data.js +0 -11
  329. package/dist/recent-session.js +0 -12
  330. package/dist/svl-distribution.js +0 -11
  331. package/dist/terminal-status.js +0 -11
  332. package/dist/token-savings.js +0 -11
  333. package/dist/total-repairs.js +0 -12
  334. package/dist/unresolved-count.js +0 -12
  335. package/dist/valid-fingerprints.js +0 -13
  336. package/dist/verify-ledgers.js +0 -11
  337. package/docs/whitepaper-style.css +0 -77
  338. package/docs/whitepaper-v2.1.md +0 -609
  339. package/docs/whitepaper-v2.2.md +0 -1064
  340. package/docs/whitepaper-v2.2.pdf +0 -0
  341. package/fly.toml +0 -31
  342. package/public/dashboard.html +0 -119
  343. package/server/hub.js +0 -116
  344. package/test/replay-golden/sess_1780063202050_mgeld.json +0 -9
  345. package/test/replay-golden/sess_1780064032560_gocld.json +0 -354
  346. package/test/replay-golden/sess_1780064413331_s2709.json +0 -606
  347. package/test/replay-golden/sess_1780064792710_y3avo.json +0 -614
  348. package/test/replay-golden.ts +0 -84
  349. package/test_benchmark.js +0 -165
  350. package/test_comprehensive.mjs +0 -638
  351. package/test_concurrency.js +0 -129
  352. package/test_ir_robustness.js +0 -85
  353. package/test_semantic_contracts.js +0 -269
  354. package/test_ssg_stress.js +0 -156
  355. package/test_svl3.js +0 -58
  356. package/tsconfig.json +0 -17
@@ -0,0 +1,292 @@
1
+ "use strict";
2
+ /**
3
+ * P3: Batch Flywheel Runner
4
+ *
5
+ * Scans all benchmark repos with sequence files, auto-generates proposals,
6
+ * and produces a Flywheel Health Dashboard with operational metrics.
7
+ *
8
+ * Usage:
9
+ * npx ts-node --transpile-only src/flywheel-batch.ts
10
+ * npx ts-node --transpile-only src/flywheel-batch.ts --auto-accept
11
+ * npx ts-node --transpile-only src/flywheel-batch.ts --repos curl,libssh
12
+ */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ const fs = __importStar(require("fs"));
48
+ const path = __importStar(require("path"));
49
+ // ═══════════════════════════════════════════════════════════════
50
+ // Repo Scanner
51
+ // ═══════════════════════════════════════════════════════════════
52
+ const BENCHMARKS_DIR = path.resolve(process.cwd(), "benchmarks");
53
+ const PROPOSALS_DIR = path.resolve(process.cwd(), ".progmune_corpus", "flywheel");
54
+ function scanRepo(repoName, autoAccept = false) {
55
+ const seqFile = path.join(BENCHMARKS_DIR, `${repoName}-sequences.json`);
56
+ if (!fs.existsSync(seqFile)) {
57
+ // Try alternate names
58
+ const altFile = path.join(BENCHMARKS_DIR, `${repoName}-manual-sequences.json`);
59
+ if (!fs.existsSync(altFile)) {
60
+ return { repo: repoName, status: "no_sequences", proposals: 0, accepted: 0, rejected: 0, topMatches: [] };
61
+ }
62
+ }
63
+ try {
64
+ // Dynamically invoke the flywheel scanner
65
+ const { scanRepo: flywheelScan } = require("./knowledge-flywheel");
66
+ // The scanRepo function expects a path like "benchmarks/curl"
67
+ const repoPath = path.join("benchmarks", repoName);
68
+ let proposals;
69
+ try {
70
+ proposals = flywheelScan(repoPath);
71
+ }
72
+ catch (e) {
73
+ return {
74
+ repo: repoName,
75
+ status: "error",
76
+ error: e.message || String(e),
77
+ proposals: 0, accepted: 0, rejected: 0,
78
+ topMatches: [],
79
+ };
80
+ }
81
+ let accepted = 0;
82
+ let rejected = 0;
83
+ if (autoAccept && proposals.length > 0) {
84
+ try {
85
+ const { acceptProposal, getProposal } = require("./knowledge-flywheel");
86
+ for (const p of proposals) {
87
+ if (p.suggestion !== "insufficient") {
88
+ try {
89
+ acceptProposal(p.id, { autoApproved: true });
90
+ accepted++;
91
+ }
92
+ catch {
93
+ // Already accepted or error
94
+ }
95
+ }
96
+ else {
97
+ rejected++;
98
+ }
99
+ }
100
+ }
101
+ catch {
102
+ // Accept function might not exist or fail — proposals are still pending
103
+ }
104
+ }
105
+ const topMatches = proposals
106
+ .sort((a, b) => b.evidenceCount - a.evidenceCount)
107
+ .slice(0, 3)
108
+ .map((p) => ({ unit: p.unitName, count: p.evidenceCount }));
109
+ return {
110
+ repo: repoName,
111
+ status: "scanned",
112
+ proposals: proposals.length,
113
+ accepted,
114
+ rejected,
115
+ topMatches,
116
+ };
117
+ }
118
+ catch (e) {
119
+ return {
120
+ repo: repoName,
121
+ status: "error",
122
+ error: e.message || String(e),
123
+ proposals: 0, accepted: 0, rejected: 0,
124
+ topMatches: [],
125
+ };
126
+ }
127
+ }
128
+ // ═══════════════════════════════════════════════════════════════
129
+ // Dashboard Generator
130
+ // ═══════════════════════════════════════════════════════════════
131
+ function loadFlywheelState() {
132
+ let totalProposals = 0;
133
+ let accepted = 0;
134
+ let rejected = 0;
135
+ let pending = 0;
136
+ if (fs.existsSync(PROPOSALS_DIR)) {
137
+ const files = fs.readdirSync(PROPOSALS_DIR).filter(f => f.endsWith(".json"));
138
+ totalProposals = files.length;
139
+ for (const file of files) {
140
+ try {
141
+ const data = JSON.parse(fs.readFileSync(path.join(PROPOSALS_DIR, file), "utf-8"));
142
+ if (data.status === "accepted")
143
+ accepted++;
144
+ else if (data.status === "rejected")
145
+ rejected++;
146
+ else
147
+ pending++;
148
+ }
149
+ catch { /* skip */ }
150
+ }
151
+ }
152
+ return { totalProposals, accepted, rejected, pending };
153
+ }
154
+ function generateDashboard(results) {
155
+ const scanned = results.filter(r => r.status === "scanned");
156
+ const state = loadFlywheelState();
157
+ const totalProposals = results.reduce((s, r) => s + r.proposals, 0);
158
+ const reposWithProposals = results.filter(r => r.proposals > 0).length;
159
+ const knowledgeVelocity = scanned.length > 0
160
+ ? totalProposals / scanned.length
161
+ : 0;
162
+ const totalConfidenceGained = state.accepted * 3 + state.pending * 1.5;
163
+ let assessment = "IDLE";
164
+ if (scanned.length >= 3 && state.accepted >= 2) {
165
+ assessment = "FLYWHEEL SPINNING — knowledge growing";
166
+ }
167
+ else if (scanned.length >= 1 && state.pending >= 1) {
168
+ assessment = "BOOTSTRAPPING — proposals pending review";
169
+ }
170
+ else if (scanned.length === 0) {
171
+ assessment = "STALLED — no repos with sequences";
172
+ }
173
+ else {
174
+ assessment = "STARTING — scan complete, awaiting proposals";
175
+ }
176
+ const recommendations = [];
177
+ if (state.pending > 3) {
178
+ recommendations.push(`${state.pending} proposals pending — review and accept high-confidence ones`);
179
+ }
180
+ if (knowledgeVelocity < 0.5) {
181
+ recommendations.push("Knowledge velocity low — need more repos with high match rates");
182
+ }
183
+ if (state.accepted === 0 && state.pending > 0) {
184
+ recommendations.push("No proposals accepted yet — start reviewing to activate flywheel");
185
+ }
186
+ if (state.accepted > 0) {
187
+ recommendations.push("Flywheel active — continue scanning new repos to reinforce accepted knowledge");
188
+ }
189
+ return {
190
+ generated: new Date().toISOString(),
191
+ totalReposScanned: scanned.length,
192
+ reposWithProposals,
193
+ totalProposals,
194
+ acceptedProposals: state.accepted,
195
+ rejectedProposals: state.rejected,
196
+ pendingProposals: state.pending,
197
+ knowledgeVelocity: Math.round(knowledgeVelocity * 100) / 100,
198
+ totalConfidenceGained: Math.round(totalConfidenceGained),
199
+ byRepo: results,
200
+ assessment,
201
+ recommendations,
202
+ };
203
+ }
204
+ // ═══════════════════════════════════════════════════════════════
205
+ // Formatting
206
+ // ═══════════════════════════════════════════════════════════════
207
+ function formatDashboard(d) {
208
+ const lines = [];
209
+ lines.push("");
210
+ lines.push("╔══════════════════════════════════════════════════════════════╗");
211
+ lines.push("║ Knowledge Flywheel Health Dashboard ║");
212
+ lines.push("╠══════════════════════════════════════════════════════════════╣");
213
+ lines.push(`║ Generated: ${d.generated} ║`);
214
+ lines.push("╚══════════════════════════════════════════════════════════════╝");
215
+ lines.push("");
216
+ // Summary metrics
217
+ lines.push("── Flywheel Metrics ──");
218
+ lines.push(` Repos scanned: ${d.totalReposScanned}`);
219
+ lines.push(` Repos with proposals: ${d.reposWithProposals}`);
220
+ lines.push(` Total proposals: ${d.totalProposals}`);
221
+ lines.push(` Accepted: ${d.acceptedProposals} ★`);
222
+ lines.push(` Pending: ${d.pendingProposals}`);
223
+ lines.push(` Rejected: ${d.rejectedProposals}`);
224
+ lines.push(` Knowledge velocity: ${d.knowledgeVelocity} proposals/scan`);
225
+ lines.push(` Confidence gained: +${d.totalConfidenceGained}%`);
226
+ lines.push(` Assessment: ${d.assessment}`);
227
+ lines.push("");
228
+ // Per-repo table
229
+ lines.push("── Per-Repo Scan Results ──");
230
+ for (const repo of d.byRepo) {
231
+ if (repo.status === "no_sequences") {
232
+ lines.push(` ${repo.repo}: ⏭️ no sequences`);
233
+ }
234
+ else if (repo.status === "error") {
235
+ lines.push(` ${repo.repo}: ❌ ${repo.error}`);
236
+ }
237
+ else {
238
+ const icon = repo.proposals > 0 ? "📊" : "✓";
239
+ lines.push(` ${icon} ${repo.repo}: ${repo.proposals} proposals`);
240
+ if (repo.topMatches.length > 0) {
241
+ const matches = repo.topMatches.map(m => `${m.unit}(${m.count})`).join(", ");
242
+ lines.push(` Top matches: ${matches}`);
243
+ }
244
+ }
245
+ }
246
+ lines.push("");
247
+ lines.push("── Recommendations ──");
248
+ for (const r of d.recommendations) {
249
+ lines.push(` • ${r}`);
250
+ }
251
+ lines.push("");
252
+ return lines.join("\n");
253
+ }
254
+ // ═══════════════════════════════════════════════════════════════
255
+ // Save
256
+ // ═══════════════════════════════════════════════════════════════
257
+ function saveDashboard(dashboard) {
258
+ const metricsPath = path.resolve(process.cwd(), ".progmune_corpus", "flywheel-metrics.json");
259
+ fs.writeFileSync(metricsPath, JSON.stringify(dashboard, null, 2));
260
+ console.log(`Dashboard saved to ${metricsPath}`);
261
+ }
262
+ // ═══════════════════════════════════════════════════════════════
263
+ // Main
264
+ // ═══════════════════════════════════════════════════════════════
265
+ function main() {
266
+ const args = process.argv.slice(2);
267
+ const autoAccept = args.includes("--auto-accept");
268
+ const repoArg = args.find(a => a.startsWith("--repos="));
269
+ // Find all repos with sequence files
270
+ const allRepos = [];
271
+ if (fs.existsSync(BENCHMARKS_DIR)) {
272
+ const files = fs.readdirSync(BENCHMARKS_DIR);
273
+ const seqRepos = new Set();
274
+ for (const file of files) {
275
+ const match = file.match(/^(.+)-sequences\.json$/);
276
+ if (match)
277
+ seqRepos.add(match[1]);
278
+ }
279
+ allRepos.push(...seqRepos);
280
+ }
281
+ const repoNames = repoArg
282
+ ? repoArg.replace("--repos=", "").split(",")
283
+ : allRepos;
284
+ console.log(`Scanning ${repoNames.length} repos...`);
285
+ if (autoAccept)
286
+ console.log(` (auto-accepting proposals with sufficient evidence)`);
287
+ const results = repoNames.map(name => scanRepo(name, autoAccept));
288
+ const dashboard = generateDashboard(results);
289
+ console.log(formatDashboard(dashboard));
290
+ saveDashboard(dashboard);
291
+ }
292
+ main();
@@ -0,0 +1,237 @@
1
+ #!/usr/bin/env npx ts-node
2
+ "use strict";
3
+ /**
4
+ * Express Framework Adapter CLI
5
+ *
6
+ * Usage:
7
+ * npm run express <path> Analyze an Express project
8
+ * npm run express <path> -- --json JSON output
9
+ * npm run express <path> -- --help Show help
10
+ *
11
+ * Examples:
12
+ * npm run express src/server.ts
13
+ * npm run express .
14
+ * npm run express ~/my-express-app
15
+ */
16
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ var desc = Object.getOwnPropertyDescriptor(m, k);
19
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
+ desc = { enumerable: true, get: function() { return m[k]; } };
21
+ }
22
+ Object.defineProperty(o, k2, desc);
23
+ }) : (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ o[k2] = m[k];
26
+ }));
27
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29
+ }) : function(o, v) {
30
+ o["default"] = v;
31
+ });
32
+ var __importStar = (this && this.__importStar) || (function () {
33
+ var ownKeys = function(o) {
34
+ ownKeys = Object.getOwnPropertyNames || function (o) {
35
+ var ar = [];
36
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
37
+ return ar;
38
+ };
39
+ return ownKeys(o);
40
+ };
41
+ return function (mod) {
42
+ if (mod && mod.__esModule) return mod;
43
+ var result = {};
44
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
45
+ __setModuleDefault(result, mod);
46
+ return result;
47
+ };
48
+ })();
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ const fs = __importStar(require("fs"));
51
+ const path = __importStar(require("path"));
52
+ const express_detector_1 = require("./express-detector");
53
+ const args = process.argv.slice(2);
54
+ // ── Help ──
55
+ if (args.includes("--help") || args.includes("-h") || args.length === 0) {
56
+ console.log(`
57
+ ╔══════════════════════════════════════════════════════════╗
58
+ ║ Progmune Express Framework Adapter ║
59
+ ║ Protocol Detection for Express.js ║
60
+ ╚══════════════════════════════════════════════════════════╝
61
+
62
+ Usage:
63
+ npm run express <path> [options]
64
+
65
+ Arguments:
66
+ <path> File or directory to analyze
67
+ (auto-detects Express .ts/.js files)
68
+
69
+ Options:
70
+ --json Output as JSON
71
+ --summary Show summary only (no per-file details)
72
+ --help, -h Show this help
73
+
74
+ Examples:
75
+ npm run express src/server.ts
76
+ npm run express .
77
+ npm run express ~/my-express-app -- --json
78
+ npm run express . -- --summary
79
+ `);
80
+ process.exit(0);
81
+ }
82
+ // ── Parse options ──
83
+ const jsonOutput = args.includes("--json");
84
+ const summaryOnly = args.includes("--summary");
85
+ const targetPath = args.filter(a => !a.startsWith("--"))[0];
86
+ if (!targetPath) {
87
+ console.error("Error: path required. Use --help for usage.");
88
+ process.exit(1);
89
+ }
90
+ const resolvedPath = path.resolve(targetPath);
91
+ // ── Helpers ──
92
+ function findTsFiles(dir) {
93
+ const files = [];
94
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
95
+ for (const entry of entries) {
96
+ const fp = path.join(dir, entry.name);
97
+ if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
98
+ files.push(...findTsFiles(fp));
99
+ }
100
+ else if (/\.(ts|js|mjs)$/.test(entry.name) && !/\.test\./.test(entry.name)) {
101
+ files.push(fp);
102
+ }
103
+ }
104
+ return files;
105
+ }
106
+ // ── Main ──
107
+ async function main() {
108
+ if (!fs.existsSync(resolvedPath)) {
109
+ console.error(`Error: path not found: ${resolvedPath}`);
110
+ process.exit(1);
111
+ }
112
+ const stat = fs.statSync(resolvedPath);
113
+ const isDirectory = stat.isDirectory();
114
+ let result;
115
+ if (isDirectory) {
116
+ const tsFiles = findTsFiles(resolvedPath);
117
+ const fileResults = [];
118
+ for (const fp of tsFiles) {
119
+ const analysis = (0, express_detector_1.analyzeExpressFile)(fp);
120
+ if (analysis && analysis.hasExpress) {
121
+ fileResults.push({ file: fp, analysis });
122
+ }
123
+ }
124
+ result = {
125
+ files: tsFiles.length,
126
+ expressApps: fileResults.length,
127
+ totalRoutes: fileResults.reduce((sum, r) => sum + r.analysis.routes.length, 0),
128
+ issues: fileResults.flatMap(r => r.analysis.issues.map(i => ({ ...i, route: i.route ? `[${path.basename(r.file)}] ${i.route}` : `[${path.basename(r.file)}]` }))),
129
+ fileResults,
130
+ };
131
+ }
132
+ else {
133
+ const analysis = (0, express_detector_1.analyzeExpressFile)(resolvedPath);
134
+ if (!analysis || !analysis.hasExpress) {
135
+ console.log(`\n${path.basename(resolvedPath)}: Not an Express app (no express import found).\n`);
136
+ process.exit(0);
137
+ }
138
+ result = {
139
+ files: 1,
140
+ expressApps: 1,
141
+ totalRoutes: analysis.routes.length,
142
+ issues: analysis.issues,
143
+ fileResults: [{ file: resolvedPath, analysis }],
144
+ };
145
+ }
146
+ // ── JSON output ──
147
+ if (jsonOutput) {
148
+ const output = {
149
+ target: resolvedPath,
150
+ scannedFiles: result.files,
151
+ expressApps: result.expressApps,
152
+ totalRoutes: result.totalRoutes,
153
+ totalIssues: result.issues.length,
154
+ bySeverity: {
155
+ critical: result.issues.filter(i => i.severity === "critical").length,
156
+ high: result.issues.filter(i => i.severity === "high").length,
157
+ medium: result.issues.filter(i => i.severity === "medium").length,
158
+ low: result.issues.filter(i => i.severity === "low").length,
159
+ },
160
+ decision: result.issues.some(i => i.severity === "critical") ? "BLOCKED"
161
+ : result.issues.some(i => i.severity === "high") ? "NEEDS_REVIEW"
162
+ : "APPROVED",
163
+ issues: result.issues.map(i => ({
164
+ severity: i.severity,
165
+ rule: i.rule,
166
+ message: i.message,
167
+ route: i.route ?? null,
168
+ line: i.line,
169
+ fix: i.fix,
170
+ })),
171
+ };
172
+ console.log(JSON.stringify(output, null, 2));
173
+ process.exit(result.issues.some(i => i.severity === "critical") ? 1 : 0);
174
+ }
175
+ // ── Terminal output ──
176
+ console.log("\n╔══════════════════════════════════════════════════════════╗");
177
+ console.log("║ Progmune Express Framework Adapter ║");
178
+ console.log("╚══════════════════════════════════════════════════════════╝\n");
179
+ console.log(` Target: ${resolvedPath}`);
180
+ console.log(` Files: ${result.files} scanned`);
181
+ console.log(` Apps: ${result.expressApps} Express app(s) found`);
182
+ if (result.expressApps === 0) {
183
+ console.log("\n No Express apps found in this directory.\n");
184
+ process.exit(0);
185
+ }
186
+ console.log(` Routes: ${result.totalRoutes}`);
187
+ console.log(` Issues: ${result.issues.length}\n`);
188
+ // Severity summary bar
189
+ const crit = result.issues.filter(i => i.severity === "critical").length;
190
+ const high = result.issues.filter(i => i.severity === "high").length;
191
+ const med = result.issues.filter(i => i.severity === "medium").length;
192
+ const low = result.issues.filter(i => i.severity === "low").length;
193
+ const bar = [
194
+ crit > 0 ? `🔴 ${crit} critical` : "",
195
+ high > 0 ? `🟠 ${high} high` : "",
196
+ med > 0 ? `🟡 ${med} medium` : "",
197
+ low > 0 ? `🔵 ${low} low` : "",
198
+ ].filter(Boolean).join(" ");
199
+ if (bar) {
200
+ console.log(` ${bar}\n`);
201
+ }
202
+ // Decision
203
+ const decision = crit > 0 ? "❌ BLOCKED" : high > 0 ? "⚠️ NEEDS_REVIEW" : "✅ APPROVED";
204
+ console.log(` Decision: ${decision}\n`);
205
+ // Per-file details
206
+ if (!summaryOnly && result.fileResults && result.fileResults.length > 0) {
207
+ for (const { file, analysis } of result.fileResults) {
208
+ if (!analysis)
209
+ continue;
210
+ console.log(`── ${path.basename(file)} ──`);
211
+ console.log((0, express_detector_1.formatExpressReport)(analysis));
212
+ console.log("");
213
+ }
214
+ }
215
+ // Summary table
216
+ console.log("── Issues ──");
217
+ if (result.issues.length === 0) {
218
+ console.log(" ✅ No Express security issues detected.\n");
219
+ }
220
+ else {
221
+ for (const issue of result.issues) {
222
+ const emoji = issue.severity === "critical" ? "🔴" : issue.severity === "high" ? "🟠" : issue.severity === "medium" ? "🟡" : "🔵";
223
+ console.log(` ${emoji} [${issue.rule}]`);
224
+ console.log(` ${issue.message}`);
225
+ if (issue.route)
226
+ console.log(` Route: ${issue.route} (line ${issue.line})`);
227
+ console.log(` Fix: ${issue.fix}`);
228
+ console.log("");
229
+ }
230
+ }
231
+ // ── Exit code for CI ──
232
+ process.exit(crit > 0 ? 1 : 0);
233
+ }
234
+ main().catch(err => {
235
+ console.error("Fatal:", err.message);
236
+ process.exit(2);
237
+ });