@a-company/paradigm 3.34.0 → 3.43.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 (117) hide show
  1. package/dist/{accept-orchestration-XXANWJVZ.js → accept-orchestration-ZUWQUHSK.js} +6 -6
  2. package/dist/add-VSPZ6FM4.js +81 -0
  3. package/dist/{aggregate-XHQ6GI3Z.js → aggregate-SV3VGEIL.js} +2 -2
  4. package/dist/assess-UHBDYIK7.js +68 -0
  5. package/dist/{beacon-BTLQMYQL.js → beacon-3SJV4DAP.js} +2 -2
  6. package/dist/calibration-WWHK73WU.js +135 -0
  7. package/dist/{chunk-C5ZE6WEX.js → chunk-2SKXFXIT.js} +91 -1
  8. package/dist/{chunk-S5TDFT5Q.js → chunk-7COU5S2Z.js} +2 -2
  9. package/dist/{chunk-3BAMPB6I.js → chunk-7WEKMZ46.js} +2 -147
  10. package/dist/{chunk-H4TVBJD4.js → chunk-AKIMFN6I.js} +3 -3
  11. package/dist/{chunk-3DYYXGDC.js → chunk-CDMAMDSG.js} +33 -0
  12. package/dist/{chunk-PFLWLC6J.js → chunk-CZEIK3Y2.js} +855 -34
  13. package/dist/chunk-F3BCHPYT.js +143 -0
  14. package/dist/chunk-GT5QGC2H.js +253 -0
  15. package/dist/{chunk-UQNTJ5VB.js → chunk-HIKKOCXY.js} +1 -1
  16. package/dist/{chunk-J26YQVAK.js → chunk-J4E6K5MG.js} +1 -1
  17. package/dist/chunk-L27I3CPZ.js +357 -0
  18. package/dist/{chunk-WOONGZ3C.js → chunk-P7XSBJE3.js} +1 -1
  19. package/dist/{chunk-Z7W7HNRG.js → chunk-QDXI2DHR.js} +1 -1
  20. package/dist/{chunk-BRILIG7Z.js → chunk-QIOCFXDQ.js} +42 -0
  21. package/dist/{chunk-3BGSDKWD.js → chunk-QWA26UNO.js} +7 -7
  22. package/dist/{lore-server-ILPHKWLK.js → chunk-RAB5IKPR.js} +77 -112
  23. package/dist/{chunk-BKMNLROM.js → chunk-RGFANZ4Q.js} +448 -147
  24. package/dist/{chunk-R2SGQ22F.js → chunk-YW5OCVKB.js} +448 -2
  25. package/dist/{chunk-CTF6RHKG.js → chunk-ZGUAAVMA.js} +17 -2
  26. package/dist/{commands-KPT2T2OZ.js → commands-LEPFD7S5.js} +452 -1
  27. package/dist/config-schema-3YNIFJCJ.js +152 -0
  28. package/dist/{constellation-LZ6XIKDT.js → constellation-FAGT45TU.js} +2 -2
  29. package/dist/{context-audit-RI4R2WRH.js → context-audit-557EO6PK.js} +138 -8
  30. package/dist/{cost-4SZM7OUS.js → cost-UD3WPEKZ.js} +1 -1
  31. package/dist/{delete-YTASL4SM.js → delete-RRK4RL6Y.js} +1 -1
  32. package/dist/{diff-T6YJSAAC.js → diff-IP5CIARP.js} +6 -6
  33. package/dist/{dist-AG5JNIZU-HW2FWNTZ.js → dist-5QE2BB2B-X6DYVSUL.js} +59 -5
  34. package/dist/{dist-OH4DBV2O.js → dist-OGTSAZ55.js} +16 -1
  35. package/dist/{dist-IKBGY7FQ.js → dist-RVKYUCRU.js} +3 -1
  36. package/dist/{dist-QSBAGCZT.js → dist-UXWV4OKX.js} +2 -2
  37. package/dist/{dist-RMAIFRTW.js → dist-Y7I3CFY5.js} +5 -3
  38. package/dist/{doctor-INBOLZC7.js → doctor-GKZJU7QG.js} +1 -1
  39. package/dist/{edit-S7NZD7H7.js → edit-4CLNN5JG.js} +1 -1
  40. package/dist/{graph-ERNQQQ7C.js → graph-YYUXI3F7.js} +1 -1
  41. package/dist/graph-server-ZPXRSGCW.js +116 -0
  42. package/dist/{habits-7BORPC2F.js → habits-O37HTUKE.js} +2 -2
  43. package/dist/index.js +200 -86
  44. package/dist/integrity-MK2OP5TA.js +194 -0
  45. package/dist/integrity-checker-J7YXRTBT.js +11 -0
  46. package/dist/{lint-MTRZB5EC.js → lint-HYWGS3JJ.js} +1 -1
  47. package/dist/{list-QTFWN35D.js → list-BTLFHSRC.js} +1 -1
  48. package/dist/list-IUCYPGMK.js +57 -0
  49. package/dist/{lore-loader-S5BXMH27.js → lore-loader-VTEEZDX3.js} +3 -1
  50. package/dist/lore-server-NOOAHKJX.js +118 -0
  51. package/dist/mcp.js +2581 -112
  52. package/dist/{migrate-HRN5TUBQ.js → migrate-FQVGQNXZ.js} +21 -3
  53. package/dist/{migrate-assessments-FPR6C35Z.js → migrate-assessments-JP6Q5KME.js} +1 -1
  54. package/dist/{orchestrate-3SI6ON33.js → orchestrate-A226N6FC.js} +6 -6
  55. package/dist/platform-server-KK4OCRTV.js +891 -0
  56. package/dist/{probe-ABMGCXQG.js → probe-7JK7IDNI.js} +4 -4
  57. package/dist/{providers-YW3FG6DA.js → providers-YNFSL6HK.js} +1 -1
  58. package/dist/quiz-I75NU2QQ.js +99 -0
  59. package/dist/{record-UGN75GTB.js → record-46CLR4OG.js} +11 -2
  60. package/dist/{reindex-YC7LD4MN.js → reindex-NZQRGKPN.js} +3 -2
  61. package/dist/{remember-WR6ZVXLT.js → remember-4EUZKIIB.js} +1 -1
  62. package/dist/{retag-URLJLMSK.js → retag-KC4JVRLE.js} +1 -1
  63. package/dist/{review-725ZKA7U.js → review-Q7M4CRB5.js} +1 -1
  64. package/dist/{ripple-QTXKJCEI.js → ripple-RI3LOT6R.js} +2 -2
  65. package/dist/{sentinel-FUR3QKCJ.js → sentinel-BKYTBT7M.js} +1 -1
  66. package/dist/sentinel-bridge-IZTXYS5M.js +109 -0
  67. package/dist/sentinel-ui/assets/{index-Zh1YM0C9.css → index-CJ1Wx083.css} +1 -1
  68. package/dist/sentinel-ui/assets/index-S1VJ67dT.js +62 -0
  69. package/dist/sentinel-ui/assets/index-S1VJ67dT.js.map +1 -0
  70. package/dist/sentinel-ui/index.html +2 -2
  71. package/dist/sentinel.js +6 -6
  72. package/dist/{serve-DIALBCTU.js → serve-22A4XOIG.js} +1 -1
  73. package/dist/{university-A66BMZ4Z.js → serve-2YJ6D2Y6.js} +9 -8
  74. package/dist/serve-3V2WXLGM.js +33 -0
  75. package/dist/{server-2VICPDUR.js → server-OFEJ2HJP.js} +25 -2
  76. package/dist/{server-OWBK2WFS.js → server-RDLQ3DK7.js} +49 -4
  77. package/dist/{setup-ASR6OMKV.js → setup-M2ZKLKNN.js} +2 -2
  78. package/dist/{shift-7XLSBLDW.js → shift-LNMKFYLR.js} +63 -14
  79. package/dist/{show-GEVVQWWG.js → show-P7GYO43X.js} +1 -1
  80. package/dist/show-PKZMYKRN.js +82 -0
  81. package/dist/{snapshot-QZFD7YBI.js → snapshot-Y3COXK4T.js} +2 -2
  82. package/dist/{spawn-DIY7T4QW.js → spawn-SSXZX45U.js} +2 -2
  83. package/dist/status-KLHALGW4.js +71 -0
  84. package/dist/{summary-R4CSYNNP.js → summary-5NQNOD3F.js} +2 -2
  85. package/dist/{sweep-5POCF2E4.js → sweep-EZU3GU6S.js} +1 -1
  86. package/dist/symphony-ROEKK7VD.js +999 -0
  87. package/dist/{team-VH3HYABB.js → team-HGLJXWQG.js} +7 -7
  88. package/dist/{timeline-RKXNRMKF.js → timeline-ANC7LVDL.js} +1 -1
  89. package/dist/{triage-GJ6GK647.js → triage-POXJ2TIX.js} +2 -2
  90. package/dist/university-content/courses/.purpose +7 -1
  91. package/dist/university-content/courses/para-501.json +166 -0
  92. package/dist/university-content/plsat/.purpose +6 -0
  93. package/dist/university-content/plsat/v3.0.json +323 -1
  94. package/dist/university-content/reference.json +48 -0
  95. package/dist/university-ui/assets/{index-TcsCEBMo.js → index-tfi5xN4Q.js} +2 -2
  96. package/dist/university-ui/assets/{index-TcsCEBMo.js.map → index-tfi5xN4Q.js.map} +1 -1
  97. package/dist/university-ui/index.html +1 -1
  98. package/dist/validate-GD5XWILV.js +134 -0
  99. package/dist/{validate-OUHUBZPO.js → validate-ZVPNN4FL.js} +1 -1
  100. package/dist/{workspace-5RBSALXC.js → workspace-UIUTHZTD.js} +5 -5
  101. package/package.json +4 -2
  102. package/platform-ui/dist/assets/GitSection-C-GQWHcu.css +1 -0
  103. package/platform-ui/dist/assets/GitSection-DvyJBF_-.js +4 -0
  104. package/platform-ui/dist/assets/GraphSection-BiQrXqfs.js +8 -0
  105. package/platform-ui/dist/assets/GraphSection-BlgXTl53.css +1 -0
  106. package/platform-ui/dist/assets/LoreSection-BaH1FaRb.js +1 -0
  107. package/platform-ui/dist/assets/LoreSection-C3EixkjW.css +1 -0
  108. package/platform-ui/dist/assets/SentinelSection-BI-aIYKL.css +1 -0
  109. package/platform-ui/dist/assets/SentinelSection-DemAznjI.js +1 -0
  110. package/platform-ui/dist/assets/index-CfpZFjea.css +1 -0
  111. package/platform-ui/dist/assets/index-DDKhCt-w.js +57 -0
  112. package/platform-ui/dist/index.html +14 -0
  113. package/dist/graph-server-BZ73HTAT.js +0 -251
  114. package/dist/sentinel-ui/assets/index-C_Wstm64.js +0 -62
  115. package/dist/sentinel-ui/assets/index-C_Wstm64.js.map +0 -1
  116. /package/dist/{chunk-VUSCJJ4A.js → chunk-EDOAWN7J.js} +0 -0
  117. /package/dist/{chunk-5SXMV4SP.js → chunk-FS3WTUHY.js} +0 -0
@@ -8,8 +8,8 @@
8
8
  <link rel="preconnect" href="https://fonts.googleapis.com">
9
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
10
  <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet">
11
- <script type="module" crossorigin src="/assets/index-C_Wstm64.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-Zh1YM0C9.css">
11
+ <script type="module" crossorigin src="/assets/index-S1VJ67dT.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index-CJ1Wx083.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="root"></div>
package/dist/sentinel.js CHANGED
@@ -8,28 +8,28 @@ var { version: VERSION } = require2("../package.json");
8
8
  var program = new Command();
9
9
  program.name("sentinel").description("Semantic error monitoring \u2014 errors that speak your language").version(VERSION);
10
10
  program.command("defend", { isDefault: true }).description("Launch the Sentinel dashboard").option("-p, --port <port>", "Port number", "3838").option("--no-open", "Don't open browser").action(async (opts) => {
11
- const { launchDashboard } = await import("./commands-KPT2T2OZ.js");
11
+ const { launchDashboard } = await import("./commands-LEPFD7S5.js");
12
12
  await launchDashboard(opts);
13
13
  });
14
14
  program.command("init").description("Initialize Sentinel in current project").option("--detect", "Auto-detect symbols from codebase").action(async (opts) => {
15
- const { initProject } = await import("./commands-KPT2T2OZ.js");
15
+ const { initProject } = await import("./commands-LEPFD7S5.js");
16
16
  await initProject(opts);
17
17
  });
18
18
  var triage = program.command("triage").description("Incident triage");
19
19
  triage.command("list").description("List incidents").option("-s, --status <status>", "Filter by status (open, investigating, resolved, wont-fix)").option("-e, --env <env>", "Filter by environment").option("--symbol <symbol>", "Filter by symbol").option("-n, --limit <n>", "Max results", "10").action(async (opts) => {
20
- const { triageList } = await import("./commands-KPT2T2OZ.js");
20
+ const { triageList } = await import("./commands-LEPFD7S5.js");
21
21
  await triageList(opts);
22
22
  });
23
23
  triage.command("show <id>").description("Show incident details").option("--timeline", "Include flow timeline").action(async (id, opts) => {
24
- const { triageShow } = await import("./commands-KPT2T2OZ.js");
24
+ const { triageShow } = await import("./commands-LEPFD7S5.js");
25
25
  await triageShow(id, opts);
26
26
  });
27
27
  triage.command("resolve <id>").description("Resolve an incident").option("--pattern <id>", "Pattern that resolved it").option("--commit <hash>", "Fix commit").option("--notes <text>", "Resolution notes").action(async (id, opts) => {
28
- const { triageResolve } = await import("./commands-KPT2T2OZ.js");
28
+ const { triageResolve } = await import("./commands-LEPFD7S5.js");
29
29
  await triageResolve(id, opts);
30
30
  });
31
31
  triage.command("stats").description("Show incident statistics").option("-p, --period <period>", "Period (7d, 30d, 90d)", "7d").action(async (opts) => {
32
- const { triageStats } = await import("./commands-KPT2T2OZ.js");
32
+ const { triageStats } = await import("./commands-LEPFD7S5.js");
33
33
  await triageStats(opts);
34
34
  });
35
35
  program.parse();
@@ -9,7 +9,7 @@ async function loreServeCommand(path, options) {
9
9
  const shouldOpen = options.open !== false;
10
10
  console.log(chalk.cyan("\nStarting Lore Timeline...\n"));
11
11
  try {
12
- const { startLoreServer } = await import("./lore-server-ILPHKWLK.js");
12
+ const { startLoreServer } = await import("./lore-server-NOOAHKJX.js");
13
13
  console.log(chalk.gray(`Project: ${projectDir}`));
14
14
  console.log(chalk.gray(`Port: ${port}`));
15
15
  console.log();
@@ -1,27 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
  import "./chunk-ZXMDA7VB.js";
3
3
 
4
- // src/commands/university.ts
4
+ // src/commands/university/serve.ts
5
5
  import chalk from "chalk";
6
6
  import * as path from "path";
7
7
  import { fileURLToPath } from "url";
8
8
  var __filename = fileURLToPath(import.meta.url);
9
9
  var __dirname = path.dirname(__filename);
10
- async function universityCommand(_path, options) {
10
+ async function universityServeCommand(_path, options) {
11
11
  const port = parseInt(options.port || "3839", 10);
12
12
  const shouldOpen = options.open !== false;
13
13
  console.log(chalk.cyan("\nOpening the campus gates...\n"));
14
14
  try {
15
- const { startServer } = await import("./server-OWBK2WFS.js");
16
- const contentDir = path.resolve(__dirname, "university-content");
17
- const uiDistPath = path.resolve(__dirname, "university-ui");
15
+ const { startServer } = await import("./server-RDLQ3DK7.js");
16
+ const contentDir = path.resolve(__dirname, "../university-content");
17
+ const uiDistPath = path.resolve(__dirname, "../university-ui");
18
18
  console.log(chalk.gray(`Port: ${port}`));
19
19
  console.log();
20
20
  await startServer({
21
21
  port,
22
22
  open: shouldOpen,
23
23
  contentDir,
24
- uiDistPath
24
+ uiDistPath,
25
+ projectDir: process.cwd()
25
26
  });
26
27
  console.log(chalk.green(`
27
28
  Paradigm University is running at http://localhost:${port}`));
@@ -35,7 +36,7 @@ Paradigm University is running at http://localhost:${port}`));
35
36
  } else if (error.code === "EADDRINUSE") {
36
37
  console.error(chalk.red(`
37
38
  Error: Port ${port} is already in use.`));
38
- console.log(chalk.gray(`Try a different port with: paradigm university --port ${port + 1}
39
+ console.log(chalk.gray(`Try a different port with: paradigm university serve --port ${port + 1}
39
40
  `));
40
41
  } else {
41
42
  console.error(chalk.red("\nFailed to start Paradigm University:"), error);
@@ -44,5 +45,5 @@ Error: Port ${port} is already in use.`));
44
45
  }
45
46
  }
46
47
  export {
47
- universityCommand
48
+ universityServeCommand
48
49
  };
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ import "./chunk-ZXMDA7VB.js";
3
+
4
+ // src/commands/serve.ts
5
+ import chalk from "chalk";
6
+ async function serveCommand(options) {
7
+ const projectDir = process.cwd();
8
+ const port = parseInt(options.port || "3850", 10);
9
+ const shouldOpen = options.open !== false;
10
+ const sections = options.sections ? options.sections.split(",").map((s) => s.trim()) : void 0;
11
+ console.log(chalk.cyan("\n Starting Paradigm Platform...\n"));
12
+ try {
13
+ const { startPlatformServer } = await import("./platform-server-KK4OCRTV.js");
14
+ await startPlatformServer({ port, projectDir, open: shouldOpen, sections });
15
+ console.log(chalk.green(` Platform running at ${chalk.bold(`http://localhost:${port}`)}`));
16
+ console.log(chalk.gray(" Press Ctrl+C to stop\n"));
17
+ await new Promise(() => {
18
+ });
19
+ } catch (error) {
20
+ if (error.code === "EADDRINUSE") {
21
+ console.error(chalk.red(`
22
+ Error: Port ${port} is already in use.`));
23
+ console.log(chalk.gray(` Try: paradigm serve --port ${port + 1}
24
+ `));
25
+ } else {
26
+ console.error(chalk.red("\n Failed to start Platform:"), error);
27
+ }
28
+ process.exit(1);
29
+ }
30
+ }
31
+ export {
32
+ serveCommand
33
+ };
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ PARADIGM_SCHEMA,
4
+ SYMPHONY_SCHEMA,
3
5
  SentinelStorage,
4
6
  loadServerConfig
5
- } from "./chunk-R2SGQ22F.js";
7
+ } from "./chunk-YW5OCVKB.js";
6
8
  import "./chunk-ZXMDA7VB.js";
7
9
 
8
10
  // ../sentinel/dist/server/index.js
@@ -118,7 +120,7 @@ async function loadParadigmConfig(projectDir) {
118
120
  }
119
121
  async function loadWithPremiseCore(projectDir) {
120
122
  try {
121
- const { aggregateFromDirectory } = await import("./dist-AG5JNIZU-HW2FWNTZ.js");
123
+ const { aggregateFromDirectory } = await import("./dist-5QE2BB2B-X6DYVSUL.js");
122
124
  log.flow("load-symbols").info("Using premise-core aggregator", { path: projectDir });
123
125
  const result = await aggregateFromDirectory(projectDir);
124
126
  const counts = {};
@@ -1486,6 +1488,9 @@ async function startServer(options) {
1486
1488
  }
1487
1489
  const storage = new SentinelStorage(options.dbPath);
1488
1490
  await storage.ensureReady();
1491
+ storage.registerSchema(PARADIGM_SCHEMA);
1492
+ storage.registerSchema(SYMPHONY_SCHEMA);
1493
+ log3.component("sentinel-server").info("Registered builtin schemas", { schemas: "paradigm-logger, paradigm-symphony" });
1489
1494
  let symbolIndex = [];
1490
1495
  try {
1491
1496
  symbolIndex = await loadSymbolIndex(options.projectDir);
@@ -1614,11 +1619,29 @@ async function startServer(options) {
1614
1619
  });
1615
1620
  }
1616
1621
  export {
1622
+ PARADIGM_SCHEMA,
1623
+ SYMPHONY_SCHEMA,
1624
+ SentinelStorage,
1617
1625
  createApp,
1626
+ createAuthMiddleware,
1627
+ createCommitsRouter,
1628
+ createEventsRouter,
1629
+ createIncidentsRouter,
1630
+ createInfoRouter,
1631
+ createLogsRouter,
1632
+ createMetricsRouter,
1633
+ createPatternsRouter,
1634
+ createRateLimiter,
1635
+ createSchemasRouter,
1636
+ createServicesRouter,
1637
+ createStateRouter,
1638
+ createSymbolsRouter,
1639
+ createTracesRouter,
1618
1640
  getSymbolCount,
1619
1641
  getSymbolsAtCommit,
1620
1642
  loadGitHistory,
1621
1643
  loadParadigmConfig,
1644
+ loadServerConfig,
1622
1645
  loadSymbolIndex,
1623
1646
  startServer
1624
1647
  };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import "./chunk-ZXMDA7VB.js";
3
3
 
4
- // ../university/dist/chunk-ZBOD7HIK.js
4
+ // ../university/dist/chunk-CXHK3FVZ.js
5
5
  import express from "express";
6
6
  import * as path3 from "path";
7
7
  import * as fs3 from "fs";
@@ -116,7 +116,7 @@ function countV3Questions(data) {
116
116
  }
117
117
  return count;
118
118
  }
119
- function createPlsatRouter(contentDir) {
119
+ function createPlsatRouter(contentDir, projectDir) {
120
120
  const router = Router2();
121
121
  router.get("/", (_req, res) => {
122
122
  const plsatDir = path2.join(contentDir, "plsat");
@@ -168,6 +168,50 @@ function createPlsatRouter(contentDir) {
168
168
  return res.status(500).json({ error: `Failed to load PLSAT exam: ${msg}` });
169
169
  }
170
170
  });
171
+ router.post("/diploma", (req, res) => {
172
+ if (!projectDir) {
173
+ return res.status(400).json({ error: "No project directory configured" });
174
+ }
175
+ const diplomaDir = path2.join(projectDir, ".paradigm", "university", "diplomas");
176
+ if (!fs2.existsSync(diplomaDir)) {
177
+ return res.json({ saved: false, reason: "university directory not found" });
178
+ }
179
+ try {
180
+ const { student, version, score, total, percentage, passed } = req.body;
181
+ if (!student || !version || score == null || total == null) {
182
+ return res.status(400).json({ error: "Missing required fields: student, version, score, total" });
183
+ }
184
+ const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
185
+ const sanitizedStudent = String(student).toLowerCase().replace(/[^a-z0-9-]/g, "-").slice(0, 20);
186
+ const id = `D-${today}-${sanitizedStudent}-plsat-v${version}`;
187
+ const diploma = {
188
+ id,
189
+ type: "plsat",
190
+ student: sanitizedStudent,
191
+ earnedAt: (/* @__PURE__ */ new Date()).toISOString(),
192
+ source: `plsat:v${version}`,
193
+ score,
194
+ total,
195
+ percentage: percentage ?? (total > 0 ? Math.round(score / total * 1e4) / 100 : 0),
196
+ passed: passed ?? false,
197
+ details: { plsatVersion: version }
198
+ };
199
+ const filePath = path2.join(diplomaDir, `${id}.yaml`);
200
+ const yamlLines = Object.entries(diploma).map(([k, v]) => {
201
+ if (typeof v === "object" && v !== null) {
202
+ const nested = Object.entries(v).map(([nk, nv]) => ` ${nk}: ${JSON.stringify(nv)}`).join("\n");
203
+ return `${k}:
204
+ ${nested}`;
205
+ }
206
+ return `${k}: ${JSON.stringify(v)}`;
207
+ });
208
+ fs2.writeFileSync(filePath, yamlLines.join("\n") + "\n", "utf8");
209
+ return res.json({ saved: true, diplomaId: id });
210
+ } catch (err) {
211
+ const msg = err instanceof Error ? err.message : "Internal error";
212
+ return res.status(500).json({ error: `Failed to save diploma: ${msg}` });
213
+ }
214
+ });
171
215
  return router;
172
216
  }
173
217
  var __filename = fileURLToPath(import.meta.url);
@@ -235,7 +279,7 @@ function createApp(options) {
235
279
  });
236
280
  const { contentDir, uiDistPath } = resolveAssetPaths(options);
237
281
  app.use("/api/courses", createCoursesRouter(contentDir));
238
- app.use("/api/plsat", createPlsatRouter(contentDir));
282
+ app.use("/api/plsat", createPlsatRouter(contentDir, options?.projectDir));
239
283
  app.get("/api/reference", (_req, res) => {
240
284
  const refPath = path3.join(contentDir, "reference.json");
241
285
  if (fs3.existsSync(refPath)) {
@@ -261,7 +305,8 @@ function createApp(options) {
261
305
  async function startServer(options) {
262
306
  const app = createApp({
263
307
  contentDir: options.contentDir,
264
- uiDistPath: options.uiDistPath
308
+ uiDistPath: options.uiDistPath,
309
+ projectDir: options.projectDir
265
310
  });
266
311
  log.component("university-server").info("Starting server", { port: options.port });
267
312
  return new Promise((resolve, reject) => {
@@ -6,10 +6,10 @@ import {
6
6
  import "./chunk-36TKPM5Z.js";
7
7
  import {
8
8
  getDefaultPremiseContent
9
- } from "./chunk-CTF6RHKG.js";
9
+ } from "./chunk-ZGUAAVMA.js";
10
10
  import {
11
11
  getDefaultPurposeContent
12
- } from "./chunk-VUSCJJ4A.js";
12
+ } from "./chunk-EDOAWN7J.js";
13
13
  import "./chunk-IRKUEJVW.js";
14
14
  import {
15
15
  DEFAULT_CONVENTIONS,
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  teamInitCommand
4
- } from "./chunk-UQNTJ5VB.js";
5
- import "./chunk-3BGSDKWD.js";
6
- import "./chunk-6QC3YGB6.js";
7
- import "./chunk-J26YQVAK.js";
4
+ } from "./chunk-HIKKOCXY.js";
5
+ import "./chunk-QWA26UNO.js";
6
+ import "./chunk-J4E6K5MG.js";
8
7
  import "./chunk-PBHIFAL4.js";
9
- import "./chunk-5SXMV4SP.js";
8
+ import "./chunk-FS3WTUHY.js";
9
+ import "./chunk-6QC3YGB6.js";
10
10
  import {
11
11
  agentsConfigured
12
12
  } from "./chunk-PMXRGPRQ.js";
@@ -15,23 +15,23 @@ import {
15
15
  } from "./chunk-DS5QY37M.js";
16
16
  import {
17
17
  detectProjectRole
18
- } from "./chunk-WOONGZ3C.js";
18
+ } from "./chunk-P7XSBJE3.js";
19
19
  import "./chunk-MW5DMGBB.js";
20
20
  import {
21
21
  doctorCommand
22
- } from "./chunk-C5ZE6WEX.js";
22
+ } from "./chunk-2SKXFXIT.js";
23
23
  import "./chunk-5JGJACDU.js";
24
24
  import {
25
25
  initCommand
26
- } from "./chunk-H4TVBJD4.js";
26
+ } from "./chunk-AKIMFN6I.js";
27
27
  import {
28
28
  indexCommand
29
- } from "./chunk-S5TDFT5Q.js";
29
+ } from "./chunk-7COU5S2Z.js";
30
30
  import "./chunk-36TKPM5Z.js";
31
- import "./chunk-CTF6RHKG.js";
32
- import "./chunk-VUSCJJ4A.js";
31
+ import "./chunk-ZGUAAVMA.js";
32
+ import "./chunk-EDOAWN7J.js";
33
33
  import "./chunk-IRKUEJVW.js";
34
- import "./chunk-Z7W7HNRG.js";
34
+ import "./chunk-QDXI2DHR.js";
35
35
  import {
36
36
  detectDiscipline
37
37
  } from "./chunk-UPLDI7CN.js";
@@ -119,7 +119,7 @@ discipline: ${detected}`
119
119
  if (isInitialized) {
120
120
  spinner.start("Step 1b/6: Checking for migrations...");
121
121
  try {
122
- const { migrateCommand } = await import("./migrate-HRN5TUBQ.js");
122
+ const { migrateCommand } = await import("./migrate-FQVGQNXZ.js");
123
123
  await migrateCommand({ apply: true, quiet: true, noSync: true });
124
124
  spinner.succeed(chalk.green("Migrations applied"));
125
125
  } catch (error) {
@@ -266,7 +266,7 @@ workspace: "${relPath}"
266
266
  if (configForWs.workspace) {
267
267
  spinner.start("Step 3b/6: Reindexing workspace members...");
268
268
  try {
269
- const { workspaceReindexCommand } = await import("./workspace-5RBSALXC.js");
269
+ const { workspaceReindexCommand } = await import("./workspace-UIUTHZTD.js");
270
270
  await workspaceReindexCommand({ quiet: true });
271
271
  spinner.succeed(chalk.green("Workspace members reindexed"));
272
272
  } catch (e) {
@@ -282,6 +282,55 @@ workspace: "${relPath}"
282
282
  if (!fs.existsSync(lorePath)) {
283
283
  fs.mkdirSync(lorePath, { recursive: true });
284
284
  }
285
+ const uniBase = path.join(cwd, ".paradigm", "university");
286
+ for (const subdir of ["content/notes", "content/policies", "content/quizzes", "content/paths", "diplomas"]) {
287
+ const dirPath = path.join(uniBase, subdir);
288
+ if (!fs.existsSync(dirPath)) {
289
+ fs.mkdirSync(dirPath, { recursive: true });
290
+ }
291
+ }
292
+ const uniConfigPath = path.join(uniBase, "config.yaml");
293
+ if (!fs.existsSync(uniConfigPath)) {
294
+ let projectName2 = "Project";
295
+ try {
296
+ const configPath = path.join(cwd, ".paradigm", "config.yaml");
297
+ if (fs.existsSync(configPath)) {
298
+ const configData = yaml.load(fs.readFileSync(configPath, "utf8"));
299
+ if (configData.project && typeof configData.project === "string") {
300
+ projectName2 = configData.project;
301
+ }
302
+ }
303
+ } catch {
304
+ }
305
+ const uniConfig = {
306
+ branding: {
307
+ name: `${projectName2} University`,
308
+ tagline: `Learn the ${projectName2} codebase`,
309
+ institution: projectName2
310
+ },
311
+ theme: {
312
+ primary: "#6366f1",
313
+ secondary: "#8b5cf6",
314
+ accent: "#f59e0b",
315
+ background: "#0f172a",
316
+ surface: "#1e293b",
317
+ text: "#f8fafc",
318
+ textMuted: "#94a3b8",
319
+ success: "#22c55e",
320
+ error: "#ef4444",
321
+ font: "Inter, system-ui, sans-serif"
322
+ },
323
+ content: {
324
+ categories: [],
325
+ defaultDifficulty: "beginner",
326
+ requireApproval: false
327
+ },
328
+ diplomas: {
329
+ includeGlobalPLSAT: true
330
+ }
331
+ };
332
+ fs.writeFileSync(uniConfigPath, yaml.dump(uniConfig, { lineWidth: -1, noRefs: true }), "utf8");
333
+ }
285
334
  spinner.start("Step 4/6: Syncing IDE configurations...");
286
335
  try {
287
336
  const ideTargets = options.ide ? [options.ide] : ["claude", "cursor", "copilot", "windsurf", "agents"];
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  loadLoreEntry
4
- } from "./chunk-BRILIG7Z.js";
4
+ } from "./chunk-QIOCFXDQ.js";
5
5
  import "./chunk-ZXMDA7VB.js";
6
6
 
7
7
  // src/commands/lore/show.ts
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ loadNote,
4
+ loadPath,
5
+ loadQuiz
6
+ } from "./chunk-GT5QGC2H.js";
7
+ import "./chunk-ZXMDA7VB.js";
8
+
9
+ // src/commands/university/show.ts
10
+ import chalk from "chalk";
11
+ async function universityShowCommand(id, options) {
12
+ const rootDir = process.cwd();
13
+ const note = loadNote(rootDir, id);
14
+ if (note) {
15
+ if (options.json) {
16
+ console.log(JSON.stringify({ ...note.frontmatter, body: note.body }, null, 2));
17
+ return;
18
+ }
19
+ console.log(chalk.blue(`
20
+ ${note.frontmatter.title}`));
21
+ console.log(chalk.gray(` ${note.frontmatter.type} \xB7 ${note.frontmatter.difficulty} \xB7 ${note.frontmatter.author}`));
22
+ if (note.frontmatter.tags.length > 0) {
23
+ console.log(chalk.gray(` Tags: ${note.frontmatter.tags.join(", ")}`));
24
+ }
25
+ if (note.frontmatter.symbols.length > 0) {
26
+ console.log(chalk.gray(` Symbols: ${note.frontmatter.symbols.join(", ")}`));
27
+ }
28
+ console.log();
29
+ console.log(note.body);
30
+ console.log();
31
+ return;
32
+ }
33
+ const quiz = loadQuiz(rootDir, id);
34
+ if (quiz) {
35
+ if (options.json) {
36
+ console.log(JSON.stringify(quiz, null, 2));
37
+ return;
38
+ }
39
+ console.log(chalk.blue(`
40
+ ${quiz.title}`));
41
+ console.log(chalk.gray(` quiz \xB7 ${quiz.difficulty} \xB7 ${quiz.questions.length} questions \xB7 pass: ${quiz.passThreshold * 100}%`));
42
+ if (quiz.description) console.log(chalk.gray(` ${quiz.description}`));
43
+ console.log();
44
+ for (const q of quiz.questions) {
45
+ console.log(` ${chalk.cyan(q.id)}: ${q.question}`);
46
+ for (const [key, val] of Object.entries(q.choices)) {
47
+ const marker = key === q.correct ? chalk.green("*") : " ";
48
+ console.log(` ${marker} ${key}: ${val}`);
49
+ }
50
+ if (q.explanation) console.log(chalk.gray(` \u2192 ${q.explanation}`));
51
+ console.log();
52
+ }
53
+ return;
54
+ }
55
+ const lp = loadPath(rootDir, id);
56
+ if (lp) {
57
+ if (options.json) {
58
+ console.log(JSON.stringify(lp, null, 2));
59
+ return;
60
+ }
61
+ console.log(chalk.blue(`
62
+ ${lp.title}`));
63
+ console.log(chalk.gray(` learning path \xB7 ${lp.steps.length} steps \xB7 ${lp.ordered ? "ordered" : "unordered"}`));
64
+ if (lp.description) console.log(chalk.gray(` ${lp.description}`));
65
+ console.log();
66
+ for (let i = 0; i < lp.steps.length; i++) {
67
+ const step = lp.steps[i];
68
+ const req = step.required ? chalk.red("required") : chalk.gray("optional");
69
+ console.log(` ${i + 1}. ${chalk.cyan(step.content)} (${req})`);
70
+ if (step.note) console.log(chalk.gray(` ${step.note}`));
71
+ }
72
+ console.log();
73
+ return;
74
+ }
75
+ console.error(chalk.red(`
76
+ Content "${id}" not found
77
+ `));
78
+ process.exit(1);
79
+ }
80
+ export {
81
+ universityShowCommand
82
+ };
@@ -3,8 +3,8 @@ import {
3
3
  createSnapshot,
4
4
  parsePremiseFile,
5
5
  serializePremiseFile
6
- } from "./chunk-CTF6RHKG.js";
7
- import "./chunk-VUSCJJ4A.js";
6
+ } from "./chunk-ZGUAAVMA.js";
7
+ import "./chunk-EDOAWN7J.js";
8
8
  import "./chunk-IRKUEJVW.js";
9
9
  import "./chunk-ZXMDA7VB.js";
10
10
 
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  AgentSpawner
4
- } from "./chunk-J26YQVAK.js";
4
+ } from "./chunk-J4E6K5MG.js";
5
5
  import "./chunk-PBHIFAL4.js";
6
6
  import {
7
7
  getBestProvider
8
- } from "./chunk-5SXMV4SP.js";
8
+ } from "./chunk-FS3WTUHY.js";
9
9
  import {
10
10
  loadAgentsManifest
11
11
  } from "./chunk-PMXRGPRQ.js";
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ loadDiplomas,
4
+ loadUniversityIndex
5
+ } from "./chunk-GT5QGC2H.js";
6
+ import "./chunk-ZXMDA7VB.js";
7
+
8
+ // src/commands/university/status.ts
9
+ import chalk from "chalk";
10
+ async function universityStatusCommand(options) {
11
+ const rootDir = process.cwd();
12
+ const index = loadUniversityIndex(rootDir);
13
+ if (!index || index.totalContent === 0) {
14
+ console.log(chalk.yellow("\n No university content found."));
15
+ console.log(chalk.gray(' Create content with: paradigm university add note --title "My Note"\n'));
16
+ return;
17
+ }
18
+ const diplomas = loadDiplomas(rootDir);
19
+ const typeCounts = {};
20
+ const tagCounts = {};
21
+ const difficultyCounts = {};
22
+ for (const entry of index.entries) {
23
+ typeCounts[entry.type] = (typeCounts[entry.type] || 0) + 1;
24
+ if (entry.difficulty) {
25
+ difficultyCounts[entry.difficulty] = (difficultyCounts[entry.difficulty] || 0) + 1;
26
+ }
27
+ for (const tag of entry.tags) {
28
+ tagCounts[tag] = (tagCounts[tag] || 0) + 1;
29
+ }
30
+ }
31
+ if (options.json) {
32
+ console.log(JSON.stringify({ totalContent: index.totalContent, typeCounts, difficultyCounts, tagCounts, diplomaCount: diplomas.length }, null, 2));
33
+ return;
34
+ }
35
+ console.log(chalk.blue("\n University Status\n"));
36
+ console.log(chalk.white(` Total content: ${index.totalContent}`));
37
+ for (const [type, count] of Object.entries(typeCounts).sort()) {
38
+ console.log(` ${chalk.cyan(type)}: ${count}`);
39
+ }
40
+ if (Object.keys(difficultyCounts).length > 0) {
41
+ console.log();
42
+ console.log(chalk.white(" By difficulty:"));
43
+ for (const [diff, count] of Object.entries(difficultyCounts)) {
44
+ const color = diff === "advanced" ? chalk.red : diff === "intermediate" ? chalk.yellow : chalk.green;
45
+ console.log(` ${color(diff)}: ${count}`);
46
+ }
47
+ }
48
+ if (Object.keys(tagCounts).length > 0) {
49
+ console.log();
50
+ console.log(chalk.white(" Top tags:"));
51
+ const topTags = Object.entries(tagCounts).sort((a, b) => b[1] - a[1]).slice(0, 8);
52
+ for (const [tag, count] of topTags) {
53
+ console.log(` ${chalk.gray(tag)}: ${count}`);
54
+ }
55
+ }
56
+ console.log();
57
+ console.log(chalk.white(` Diplomas earned: ${diplomas.length}`));
58
+ if (diplomas.length > 0) {
59
+ for (const d of diplomas.slice(0, 5)) {
60
+ const status = d.passed ? chalk.green("PASS") : chalk.red("FAIL");
61
+ console.log(` ${status} ${d.source} \u2014 ${d.student} (${d.percentage}%) ${chalk.gray(d.earnedAt.slice(0, 10))}`);
62
+ }
63
+ if (diplomas.length > 5) {
64
+ console.log(chalk.gray(` ... and ${diplomas.length - 5} more`));
65
+ }
66
+ }
67
+ console.log();
68
+ }
69
+ export {
70
+ universityStatusCommand
71
+ };
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  aggregateFromDirectory
4
- } from "./chunk-CTF6RHKG.js";
5
- import "./chunk-VUSCJJ4A.js";
4
+ } from "./chunk-ZGUAAVMA.js";
5
+ import "./chunk-EDOAWN7J.js";
6
6
  import "./chunk-IRKUEJVW.js";
7
7
  import {
8
8
  detectIDE,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  recordLore,
4
4
  resolveAuthor
5
- } from "./chunk-BRILIG7Z.js";
5
+ } from "./chunk-QIOCFXDQ.js";
6
6
  import {
7
7
  log
8
8
  } from "./chunk-4NCFWYGG.js";