forgesmith 0.6.0 → 0.6.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.
package/dist/index.cjs CHANGED
@@ -1,15 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var fs = require('fs/promises');
4
- var path = require('path');
5
- var fs$1 = require('fs');
6
3
  var crypto = require('crypto');
7
4
 
8
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
-
10
- var fs__default = /*#__PURE__*/_interopDefault(fs);
11
- var path__default = /*#__PURE__*/_interopDefault(path);
12
-
13
5
  // src/generators/releaseNotes.ts
14
6
  function buildSystemPrompt() {
15
7
  return `You are a technical writer and developer-relations expert. You generate clear, accurate release notes from structured code-intelligence data. Write only the release notes \u2014 no preamble, no meta-commentary.`;
@@ -279,12 +271,12 @@ function detectImportCycles(edges) {
279
271
  const cycles = [];
280
272
  const visited = /* @__PURE__ */ new Set();
281
273
  const stack = /* @__PURE__ */ new Set();
282
- function dfs(node, path3) {
274
+ function dfs(node, path) {
283
275
  if (cycles.length >= 5) return;
284
276
  if (stack.has(node)) {
285
- const cycleStart = path3.indexOf(node);
277
+ const cycleStart = path.indexOf(node);
286
278
  if (cycleStart !== -1) {
287
- cycles.push(path3.slice(cycleStart).join(" \u2192 ") + " \u2192 " + node);
279
+ cycles.push(path.slice(cycleStart).join(" \u2192 ") + " \u2192 " + node);
288
280
  }
289
281
  return;
290
282
  }
@@ -292,7 +284,7 @@ function detectImportCycles(edges) {
292
284
  visited.add(node);
293
285
  stack.add(node);
294
286
  for (const neighbor of graph.get(node) ?? []) {
295
- dfs(neighbor, [...path3, node]);
287
+ dfs(neighbor, [...path, node]);
296
288
  }
297
289
  stack.delete(node);
298
290
  }
@@ -347,43 +339,6 @@ async function generateRefactoringReport(blueprint, opts, provider) {
347
339
  metadata: { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), usedTokens: response.usedTokens, generator: "forgesmith" }
348
340
  };
349
341
  }
350
- async function readJsonFiles(dir) {
351
- try {
352
- const entries = await fs__default.default.readdir(dir);
353
- const results = [];
354
- for (const entry of entries) {
355
- if (!entry.endsWith(".json")) continue;
356
- try {
357
- const raw = await fs__default.default.readFile(path__default.default.join(dir, entry), "utf-8");
358
- results.push(JSON.parse(raw));
359
- } catch {
360
- }
361
- }
362
- return results;
363
- } catch {
364
- return [];
365
- }
366
- }
367
- async function readPrismDirectory(prismPath) {
368
- const sessionsDir = path__default.default.join(prismPath, "sessions");
369
- const recsDir = path__default.default.join(prismPath, "recommendations");
370
- const insightsDir = path__default.default.join(prismPath, "green", "insights", "accepted");
371
- const [sessions, recommendations, insights] = await Promise.all([
372
- readJsonFiles(sessionsDir),
373
- readJsonFiles(recsDir),
374
- readJsonFiles(insightsDir)
375
- ]);
376
- return { sessions, recommendations, insights };
377
- }
378
- async function readBlueprintData(targetPath) {
379
- const snapshotPath = path__default.default.join(targetPath, ".prism", "blueprint", "snapshot.json");
380
- try {
381
- const raw = await fs__default.default.readFile(snapshotPath, "utf-8");
382
- return JSON.parse(raw);
383
- } catch {
384
- return null;
385
- }
386
- }
387
342
 
388
343
  // src/generators/askDrivenAsset.ts
389
344
  var NO_DATA_MSG5 = "No Blueprint data available. Run prism scan first.";
@@ -1007,6 +962,8 @@ function refineLimitState(usedRefines, softCap = REFINE_SESSION_SOFT_CAP) {
1007
962
  showCountdown: used >= REFINE_COUNTDOWN_THRESHOLD
1008
963
  };
1009
964
  }
965
+
966
+ // src/forge/brandKit.ts
1010
967
  var DEFAULT_BRAND_KIT_PALETTE = {
1011
968
  primary: "#f97316",
1012
969
  secondary: "#1e293b",
@@ -1150,60 +1107,6 @@ function parseBrandKitFromLlmResponse(text, hints) {
1150
1107
  prism_detected: false
1151
1108
  };
1152
1109
  }
1153
- function deriveTechnicalScore(categories, total) {
1154
- if (total === 0) return 50;
1155
- const techFiles = (categories.lib ?? 0) + (categories.hook ?? 0);
1156
- const appFiles = (categories.app ?? 0) + (categories.component ?? 0);
1157
- const techRatio = techFiles / total;
1158
- const appRatio = appFiles / total;
1159
- return Math.round(30 + techRatio * 50 - appRatio * 10);
1160
- }
1161
- function deriveAudienceMix(categories, paths) {
1162
- const hasAdminPaths = paths.some((p) => /admin|dashboard|ops/.test(p));
1163
- const hasApiPaths = paths.some((p) => /\/api\/|route\.ts/.test(p));
1164
- const hasFrontend = (categories.component ?? 0) > 5;
1165
- if (hasAdminPaths && hasApiPaths) return "developer+operator";
1166
- if (hasApiPaths && !hasFrontend) return "developer";
1167
- if (hasFrontend && !hasApiPaths) return "end-user";
1168
- return "developer+business";
1169
- }
1170
- async function extractBrandFromPrismBlueprint(targetPath) {
1171
- const snapshotPath = path__default.default.join(targetPath, ".prism", "blueprint", "snapshot.json");
1172
- let blueprint = {};
1173
- try {
1174
- const raw = await fs__default.default.readFile(snapshotPath, "utf-8");
1175
- blueprint = JSON.parse(raw);
1176
- } catch {
1177
- }
1178
- const categories = blueprint.categories ?? {};
1179
- const files = blueprint.files ?? [];
1180
- const paths = files.map((f) => f.path ?? "");
1181
- const total = blueprint.stats?.totalFiles ?? files.length;
1182
- const technicalScore = deriveTechnicalScore(categories, total);
1183
- const audienceMix = deriveAudienceMix(categories, paths);
1184
- const projectName = blueprint.targetPath ? path__default.default.basename(blueprint.targetPath) : "Project";
1185
- const formality = technicalScore > 60 ? 65 : 50;
1186
- const technicality = Math.min(95, technicalScore + 10);
1187
- return {
1188
- suggestedName: projectName,
1189
- voice: {
1190
- tone: technicalScore > 60 ? "technical" : "professional",
1191
- audience: audienceMix.includes("developer") ? "developers" : "business",
1192
- vocabulary: [],
1193
- avoid: [],
1194
- formality,
1195
- technicality
1196
- },
1197
- prism_detected: true,
1198
- blueprint_path: snapshotPath,
1199
- stats: {
1200
- totalFiles: total,
1201
- categories,
1202
- technicalScore,
1203
- audienceMix
1204
- }
1205
- };
1206
- }
1207
1110
 
1208
1111
  // src/forge/brandPalette.ts
1209
1112
  function isNonEmptyString(v) {
@@ -1443,63 +1346,63 @@ function initialFormValues(fields, source) {
1443
1346
  function isEmptyString(v) {
1444
1347
  return typeof v === "string" && v.trim().length === 0;
1445
1348
  }
1446
- function validateField(field, value, path3) {
1349
+ function validateField(field, value, path) {
1447
1350
  const errors = {};
1448
1351
  switch (field.kind) {
1449
1352
  case "string": {
1450
1353
  if (field.required && (value === void 0 || value === null || isEmptyString(value))) {
1451
- errors[path3] = `${field.label} ist erforderlich`;
1354
+ errors[path] = `${field.label} ist erforderlich`;
1452
1355
  break;
1453
1356
  }
1454
1357
  if (typeof value === "string") {
1455
1358
  if (field.minLength !== void 0 && value.length < field.minLength) {
1456
- errors[path3] = `${field.label} mindestens ${field.minLength} Zeichen`;
1359
+ errors[path] = `${field.label} mindestens ${field.minLength} Zeichen`;
1457
1360
  } else if (field.maxLength !== void 0 && value.length > field.maxLength) {
1458
- errors[path3] = `${field.label} h\xF6chstens ${field.maxLength} Zeichen`;
1361
+ errors[path] = `${field.label} h\xF6chstens ${field.maxLength} Zeichen`;
1459
1362
  } else if (field.enum && value.length > 0 && !field.enum.includes(value)) {
1460
- errors[path3] = `${field.label}: Wert nicht in der Auswahl`;
1363
+ errors[path] = `${field.label}: Wert nicht in der Auswahl`;
1461
1364
  }
1462
1365
  }
1463
1366
  break;
1464
1367
  }
1465
1368
  case "number": {
1466
1369
  if (value === "" || value === void 0 || value === null) {
1467
- if (field.required) errors[path3] = `${field.label} ist erforderlich`;
1370
+ if (field.required) errors[path] = `${field.label} ist erforderlich`;
1468
1371
  break;
1469
1372
  }
1470
1373
  const n = typeof value === "number" ? value : Number(value);
1471
1374
  if (!Number.isFinite(n)) {
1472
- errors[path3] = `${field.label} muss eine Zahl sein`;
1375
+ errors[path] = `${field.label} muss eine Zahl sein`;
1473
1376
  } else if (field.integer && !Number.isInteger(n)) {
1474
- errors[path3] = `${field.label} muss eine ganze Zahl sein`;
1377
+ errors[path] = `${field.label} muss eine ganze Zahl sein`;
1475
1378
  } else if (field.minimum !== void 0 && n < field.minimum) {
1476
- errors[path3] = `${field.label} >= ${field.minimum}`;
1379
+ errors[path] = `${field.label} >= ${field.minimum}`;
1477
1380
  } else if (field.maximum !== void 0 && n > field.maximum) {
1478
- errors[path3] = `${field.label} <= ${field.maximum}`;
1381
+ errors[path] = `${field.label} <= ${field.maximum}`;
1479
1382
  }
1480
1383
  break;
1481
1384
  }
1482
1385
  case "boolean":
1483
1386
  if (field.required && value !== true) {
1484
- errors[path3] = `${field.label} muss aktiviert sein`;
1387
+ errors[path] = `${field.label} muss aktiviert sein`;
1485
1388
  }
1486
1389
  break;
1487
1390
  case "array": {
1488
1391
  const arr = Array.isArray(value) ? value : [];
1489
1392
  if (field.required && arr.length === 0) {
1490
- errors[path3] = `${field.label}: mindestens ein Eintrag erforderlich`;
1393
+ errors[path] = `${field.label}: mindestens ein Eintrag erforderlich`;
1491
1394
  }
1492
1395
  if (field.minItems !== void 0 && arr.length < field.minItems) {
1493
- errors[path3] = `${field.label}: mindestens ${field.minItems} Eintr\xE4ge`;
1396
+ errors[path] = `${field.label}: mindestens ${field.minItems} Eintr\xE4ge`;
1494
1397
  } else if (field.maxItems !== void 0 && arr.length > field.maxItems) {
1495
- errors[path3] = `${field.label}: h\xF6chstens ${field.maxItems} Eintr\xE4ge`;
1398
+ errors[path] = `${field.label}: h\xF6chstens ${field.maxItems} Eintr\xE4ge`;
1496
1399
  }
1497
1400
  if (field.itemField) {
1498
1401
  arr.forEach((item, i) => {
1499
1402
  const sub = validateField(
1500
1403
  field.itemField,
1501
1404
  item,
1502
- `${path3}[${i}]`
1405
+ `${path}[${i}]`
1503
1406
  );
1504
1407
  Object.assign(errors, sub);
1505
1408
  });
@@ -1509,7 +1412,7 @@ function validateField(field, value, path3) {
1509
1412
  case "object": {
1510
1413
  const obj = isPlainObject5(value) ? value : {};
1511
1414
  for (const sub of field.fields) {
1512
- const subErrors = validateField(sub, obj[sub.name], `${path3}.${sub.name}`);
1415
+ const subErrors = validateField(sub, obj[sub.name], `${path}.${sub.name}`);
1513
1416
  Object.assign(errors, subErrors);
1514
1417
  }
1515
1418
  break;
@@ -2510,71 +2413,8 @@ var FORGE_TEMPLATES = [
2510
2413
  asset_slots: []
2511
2414
  }
2512
2415
  ];
2513
- var ALLOWED_BLUEPRINT_FILENAMES = /* @__PURE__ */ new Set(["blueprint.json", "snapshot.json"]);
2514
- function isAllowedBlueprintPath(targetPath, filePath) {
2515
- const resolvedTarget = path.resolve(targetPath);
2516
- const resolvedFile = path.resolve(filePath);
2517
- const allowedPrefix = path.join(resolvedTarget, ".prism", "blueprint");
2518
- if (!resolvedFile.startsWith(allowedPrefix + "/") && resolvedFile !== allowedPrefix) {
2519
- return false;
2520
- }
2521
- const basename = resolvedFile.slice(resolvedFile.lastIndexOf("/") + 1);
2522
- return ALLOWED_BLUEPRINT_FILENAMES.has(basename);
2523
- }
2524
- function readBlueprintFromTarget(targetPath) {
2525
- const candidates = [
2526
- path.join(targetPath, ".prism", "blueprint", "snapshot.json"),
2527
- path.join(targetPath, ".prism", "blueprint.json")
2528
- ];
2529
- for (const candidate of candidates) {
2530
- const normalized = path.normalize(candidate);
2531
- if (!isAllowedBlueprintPath(targetPath, normalized)) continue;
2532
- if (!fs$1.existsSync(normalized)) continue;
2533
- try {
2534
- const raw = fs$1.readFileSync(normalized, "utf-8");
2535
- return JSON.parse(raw);
2536
- } catch {
2537
- return null;
2538
- }
2539
- }
2540
- return null;
2541
- }
2542
- function zoneId(filePath) {
2543
- const parts = filePath.replace(/^\//, "").split("/");
2544
- return parts[0] || "root";
2545
- }
2546
- function extractZones(blueprint) {
2547
- const zoneMap = /* @__PURE__ */ new Map();
2548
- for (const file of blueprint.files) {
2549
- const id = zoneId(file.path);
2550
- if (!zoneMap.has(id)) zoneMap.set(id, { files: [], heat: 0 });
2551
- const z = zoneMap.get(id);
2552
- z.files.push(file.path);
2553
- z.heat += (file.importedByCount ?? 0) + (file.importCount ?? 0);
2554
- }
2555
- return Array.from(zoneMap.entries()).map(([id, { files, heat }]) => ({
2556
- id,
2557
- name: id,
2558
- files,
2559
- fileCount: files.length,
2560
- heat
2561
- })).sort((a, b) => b.heat - a.heat || b.fileCount - a.fileCount);
2562
- }
2563
- function toFileEntry(f) {
2564
- return {
2565
- path: f.path,
2566
- importCount: f.importCount ?? 0,
2567
- importedByCount: f.importedByCount ?? 0,
2568
- lineCount: f.lineCount ?? 0,
2569
- zone: zoneId(f.path)
2570
- };
2571
- }
2572
- function extractTopChurnFiles(blueprint, n = 10) {
2573
- return blueprint.files.map(toFileEntry).sort((a, b) => b.importedByCount - a.importedByCount || b.lineCount - a.lineCount).slice(0, n);
2574
- }
2575
- function extractDependencyHotspots(blueprint, n = 10) {
2576
- return blueprint.files.map(toFileEntry).sort((a, b) => b.importCount - a.importCount || b.importedByCount - a.importedByCount).slice(0, n);
2577
- }
2416
+
2417
+ // src/forge/secrets.ts
2578
2418
  var SECRET_PATTERNS = [
2579
2419
  /sk-ant-api03-[A-Za-z0-9_-]{80,}/,
2580
2420
  /sk-proj-[A-Za-z0-9_-]{40,}/,
@@ -2584,42 +2424,8 @@ var SECRET_PATTERNS = [
2584
2424
  function scanForSecrets(text) {
2585
2425
  return SECRET_PATTERNS.some((re) => re.test(text));
2586
2426
  }
2587
- var MAX_SUMMARY_CHARS = 2e3;
2588
- function deriveContextSummary(blueprint) {
2589
- const zones = extractZones(blueprint).slice(0, 8);
2590
- const churn = extractTopChurnFiles(blueprint, 5);
2591
- const deps = extractDependencyHotspots(blueprint, 5);
2592
- const scanAge = blueprint.scanTimestamp ? (() => {
2593
- const ageMs = Date.now() - blueprint.scanTimestamp * 1e3;
2594
- const ageMin = Math.round(ageMs / 6e4);
2595
- if (ageMin < 60) return `${ageMin}m ago`;
2596
- if (ageMin < 1440) return `${Math.round(ageMin / 60)}h ago`;
2597
- return `${Math.round(ageMin / 1440)}d ago`;
2598
- })() : "unknown";
2599
- const lines = [
2600
- `Blueprint snapshot (scanned ${scanAge}):`,
2601
- `Total files: ${blueprint.stats?.totalFiles ?? blueprint.files.length} | app:${blueprint.categories?.app ?? 0} component:${blueprint.categories?.component ?? 0} lib:${blueprint.categories?.lib ?? 0} hook:${blueprint.categories?.hook ?? 0}`,
2602
- "",
2603
- "Top zones (by activity):",
2604
- ...zones.map((z) => ` ${z.name}: ${z.fileCount} files, heat ${z.heat}`),
2605
- "",
2606
- "Hottest files (most imported by others):",
2607
- ...churn.map((f) => ` ${f.path} (importedBy:${f.importedByCount})`),
2608
- "",
2609
- "Most dependency-heavy files:",
2610
- ...deps.map((f) => ` ${f.path} (imports:${f.importCount})`)
2611
- ];
2612
- let summary = lines.join("\n");
2613
- if (summary.length > MAX_SUMMARY_CHARS) {
2614
- summary = summary.slice(0, MAX_SUMMARY_CHARS - 3) + "...";
2615
- }
2616
- if (scanForSecrets(summary)) {
2617
- throw new Error("Blueprint context summary contains unexpected secret-pattern match. Refusing to pass to LLM.");
2618
- }
2619
- return summary;
2620
- }
2621
2427
 
2622
- // src/forge/prismContext.ts
2428
+ // src/forge/prismContext.data.ts
2623
2429
  var PRISM_TEMPLATE_RELEASE_ANNOUNCEMENT = {
2624
2430
  id: "release-announcement",
2625
2431
  name: "Release Announcement",
@@ -2671,104 +2477,6 @@ var PRISM_TEMPLATES = [
2671
2477
  function getPrismTemplate(id) {
2672
2478
  return PRISM_TEMPLATES.find((t) => t.id === id);
2673
2479
  }
2674
- function releaseContextBlock(blueprint) {
2675
- const churn = extractTopChurnFiles(blueprint, 8);
2676
- const zones = extractZones(blueprint).slice(0, 6);
2677
- return [
2678
- "Recent activity (most active files by coupling):",
2679
- ...churn.map((f) => ` ${f.path} \u2014 importedBy:${f.importedByCount}`),
2680
- "",
2681
- "Most active zones:",
2682
- ...zones.map((z) => ` ${z.name}: ${z.fileCount} files, activity score ${z.heat}`)
2683
- ].join("\n");
2684
- }
2685
- function changelogContextBlock(blueprint) {
2686
- const zones = extractZones(blueprint).slice(0, 10);
2687
- const hotspots = extractDependencyHotspots(blueprint, 6);
2688
- return [
2689
- "Zone breakdown:",
2690
- ...zones.map((z) => ` ${z.name}: ${z.fileCount} files`),
2691
- "",
2692
- "High-coupling files (refactoring targets):",
2693
- ...hotspots.map((f) => ` ${f.path} \u2014 imports ${f.importCount} modules`)
2694
- ].join("\n");
2695
- }
2696
- function deepdiveContextBlock(blueprint) {
2697
- return deriveContextSummary(blueprint);
2698
- }
2699
- function zoneContextBlock(blueprint, zoneName) {
2700
- const allZones = extractZones(blueprint);
2701
- const zone = allZones.find((z) => z.id === zoneName || z.name === zoneName);
2702
- if (!zone) {
2703
- return `Zone "${zoneName}" not found. Available zones: ${allZones.map((z) => z.name).join(", ")}`;
2704
- }
2705
- const topFiles = zone.files.slice(0, 12);
2706
- const otherCount = Math.max(0, zone.fileCount - 12);
2707
- return [
2708
- `Zone: ${zone.name} (${zone.fileCount} files, heat score ${zone.heat})`,
2709
- "Files:",
2710
- ...topFiles.map((f) => ` ${f}`),
2711
- ...otherCount > 0 ? [` ... and ${otherCount} more`] : []
2712
- ].join("\n");
2713
- }
2714
- function moduleContextBlock(blueprint, modulePath) {
2715
- const file = blueprint.files.find((f) => f.path.includes(modulePath));
2716
- if (!file) {
2717
- return `Module path "${modulePath}" not found in blueprint.`;
2718
- }
2719
- const deps = extractDependencyHotspots(blueprint, 5);
2720
- return [
2721
- `Module: ${file.path}`,
2722
- ` importCount: ${file.importCount ?? 0}`,
2723
- ` importedByCount: ${file.importedByCount ?? 0}`,
2724
- ` lineCount: ${file.lineCount ?? 0}`,
2725
- "",
2726
- "Related high-activity files:",
2727
- ...deps.filter((d) => d.zone === (file.path.split("/")[0] || "root")).slice(0, 5).map((d) => ` ${d.path}`)
2728
- ].join("\n");
2729
- }
2730
- function buildPrismContextPrompt(blueprint, focus, highlight) {
2731
- const resolvedFocus = focus ?? "summary";
2732
- let contextBlock;
2733
- let systemFragment;
2734
- let suggestedAsk;
2735
- if (resolvedFocus === "release") {
2736
- contextBlock = releaseContextBlock(blueprint);
2737
- systemFragment = "You have access to a real codebase blueprint showing which files and zones saw the most recent activity. Use this to make the release announcement concrete \u2014 reference specific zone names and file roles.";
2738
- suggestedAsk = PRISM_TEMPLATE_RELEASE_ANNOUNCEMENT.suggestedAsk;
2739
- } else if (resolvedFocus === "changelog") {
2740
- contextBlock = changelogContextBlock(blueprint);
2741
- systemFragment = "You have access to a real codebase blueprint showing zone structure and dependency coupling. Use this to make the changelog specific and credible.";
2742
- suggestedAsk = PRISM_TEMPLATE_SHIPPING_DIGEST.suggestedAsk;
2743
- } else if (resolvedFocus === "deepdive") {
2744
- contextBlock = deepdiveContextBlock(blueprint);
2745
- systemFragment = "You have access to a complete blueprint of a real codebase. Use the zone names, file counts, and coupling metrics to write a concrete, non-generic technical explanation.";
2746
- suggestedAsk = PRISM_TEMPLATE_ARCHITECTURE_OVERVIEW.suggestedAsk;
2747
- } else if (resolvedFocus.startsWith("zone:")) {
2748
- const zoneName = resolvedFocus.slice(5);
2749
- contextBlock = zoneContextBlock(blueprint, zoneName);
2750
- systemFragment = `You have access to real file data for the "${zoneName}" zone of the codebase. Use specific file names and counts.`;
2751
- suggestedAsk = PRISM_TEMPLATE_ZONE_DEEPDIVE.suggestedAsk.replace(
2752
- "this codebase zone",
2753
- `the "${zoneName}" zone`
2754
- );
2755
- } else if (resolvedFocus.startsWith("module:")) {
2756
- const modulePath = resolvedFocus.slice(7);
2757
- contextBlock = moduleContextBlock(blueprint, modulePath);
2758
- systemFragment = `You have access to dependency data for the "${modulePath}" module. Reference specific metrics.`;
2759
- suggestedAsk = `Explain the role of ${modulePath} in the codebase architecture and why it matters.`;
2760
- } else {
2761
- contextBlock = deriveContextSummary(blueprint);
2762
- systemFragment = "You have access to a real codebase blueprint. Use specific zone names and file counts to make your content concrete and credible.";
2763
- suggestedAsk = "Summarize the structure and key areas of this codebase.";
2764
- }
2765
- if (highlight) {
2766
- contextBlock += `
2767
-
2768
- User wants to highlight: ${highlight}`;
2769
- }
2770
- return { systemFragment, contextBlock, suggestedAsk };
2771
- }
2772
2480
 
2773
2481
  // src/forge/channel.ts
2774
2482
  var DISPATCH_CHANNEL_TWEET = {
@@ -3299,7 +3007,6 @@ exports.asAudienceId = asAudienceId;
3299
3007
  exports.assembleBrandUrlExtractionPrompt = assembleBrandUrlExtractionPrompt;
3300
3008
  exports.assembleForgePrompt = assembleForgePrompt;
3301
3009
  exports.brandThemeConfigToEntry = brandThemeConfigToEntry;
3302
- exports.buildPrismContextPrompt = buildPrismContextPrompt;
3303
3010
  exports.buildRevertVersion = buildRevertVersion;
3304
3011
  exports.buildScheduledEntry = buildScheduledEntry;
3305
3012
  exports.buildVersion = buildVersion;
@@ -3308,16 +3015,11 @@ exports.clampAnimationDuration = clampAnimationDuration;
3308
3015
  exports.computeDiff = computeDiff;
3309
3016
  exports.defaultBrandKit = defaultBrandKit;
3310
3017
  exports.defaultValueForField = defaultValueForField;
3311
- exports.deriveContextSummary = deriveContextSummary;
3312
3018
  exports.distill = distill;
3313
3019
  exports.entryInRange = entryInRange;
3314
3020
  exports.exportToBufferCsv = exportToBufferCsv;
3315
3021
  exports.exportToHypefuryCsv = exportToHypefuryCsv;
3316
3022
  exports.exportToICalendar = exportToICalendar;
3317
- exports.extractBrandFromPrismBlueprint = extractBrandFromPrismBlueprint;
3318
- exports.extractDependencyHotspots = extractDependencyHotspots;
3319
- exports.extractTopChurnFiles = extractTopChurnFiles;
3320
- exports.extractZones = extractZones;
3321
3023
  exports.generateArchitectureWalkthrough = generateArchitectureWalkthrough;
3322
3024
  exports.generateAskDrivenAsset = generateAskDrivenAsset;
3323
3025
  exports.generateChangesSince = generateChangesSince;
@@ -3341,9 +3043,6 @@ exports.parseStyleFromTailwindConfig = parseStyleFromTailwindConfig;
3341
3043
  exports.parseStyleFromTokensJson = parseStyleFromTokensJson;
3342
3044
  exports.parseThemeConfigContent = parseThemeConfigContent;
3343
3045
  exports.previewExport = previewExport;
3344
- exports.readBlueprintData = readBlueprintData;
3345
- exports.readBlueprintFromTarget = readBlueprintFromTarget;
3346
- exports.readPrismDirectory = readPrismDirectory;
3347
3046
  exports.refineAsset = refineAsset;
3348
3047
  exports.refineLimitState = refineLimitState;
3349
3048
  exports.renderWidget = renderWidget;
package/dist/index.d.cts CHANGED
@@ -122,9 +122,6 @@ declare function generateOnboardingDoc(blueprint: BlueprintData | null, opts: On
122
122
 
123
123
  declare function generateRefactoringReport(blueprint: BlueprintData | null, opts: RefactoringReportOpts, provider: LlmProvider): Promise<GenerationResult>;
124
124
 
125
- declare function readPrismDirectory(prismPath: string): Promise<PrismData>;
126
- declare function readBlueprintData(targetPath: string): Promise<BlueprintData | null>;
127
-
128
125
  declare function generateAskDrivenAsset(blueprint: BlueprintData | null, question: string, opts: AskDrivenAssetOpts, provider: LlmProvider): Promise<GenerationResult>;
129
126
 
130
127
  type ScopeKind = "framework" | "app" | "tenant";
@@ -211,6 +208,20 @@ interface ForgeScope {
211
208
  env?: string | null;
212
209
  }
213
210
  type ForgeSubview = "signals" | "templates" | "audiences" | "outputs" | "walkthroughs";
211
+ interface Zone {
212
+ id: string;
213
+ name: string;
214
+ files: string[];
215
+ fileCount: number;
216
+ heat: number;
217
+ }
218
+ interface FileEntry {
219
+ path: string;
220
+ importCount: number;
221
+ importedByCount: number;
222
+ lineCount: number;
223
+ zone: string;
224
+ }
214
225
 
215
226
  interface BrandKitPalette {
216
227
  primary: string;
@@ -285,7 +296,6 @@ interface PrismBrandDraft {
285
296
  audienceMix: string;
286
297
  };
287
298
  }
288
- declare function extractBrandFromPrismBlueprint(targetPath: string): Promise<PrismBrandDraft>;
289
299
 
290
300
  type WidgetKind = "stat-card" | "feature-grid" | "testimonial" | "cta-banner" | "metric-badge" | "pricing-tier" | "changelog-row" | "social-proof";
291
301
  type WidgetSlotType = "text" | "number" | "color" | "url" | "image-url" | "multiline" | "select";
@@ -847,41 +857,8 @@ declare const FORGE_AUDIENCES: ForgeAudience[];
847
857
 
848
858
  declare const FORGE_TEMPLATES: ForgeTemplate[];
849
859
 
850
- /**
851
- * Reads a blueprint from the target project.
852
- * Tries: {targetPath}/.prism/blueprint/snapshot.json (preferred, legacy format)
853
- * then: {targetPath}/.prism/blueprint.json
854
- * Returns null if neither file exists or if path is unsafe.
855
- */
856
- declare function readBlueprintFromTarget(targetPath: string): BlueprintData | null;
857
- interface Zone {
858
- id: string;
859
- name: string;
860
- files: string[];
861
- fileCount: number;
862
- heat: number;
863
- }
864
- interface FileEntry {
865
- path: string;
866
- importCount: number;
867
- importedByCount: number;
868
- lineCount: number;
869
- zone: string;
870
- }
871
- /** Groups files into zones (top-level directory segments). Sorted by heat desc. */
872
- declare function extractZones(blueprint: BlueprintData): Zone[];
873
- /** Files with highest importedByCount — proxy for "most-changed / hottest" files. */
874
- declare function extractTopChurnFiles(blueprint: BlueprintData, n?: number): FileEntry[];
875
- /** Files with highest importCount — most dependency-heavy, highest coupling. */
876
- declare function extractDependencyHotspots(blueprint: BlueprintData, n?: number): FileEntry[];
877
860
  /** Defence-in-depth: scan derived text for secret patterns before sending to LLM. */
878
861
  declare function scanForSecrets(text: string): boolean;
879
- /**
880
- * Produces a compact LLM-ready summary of the blueprint.
881
- * Contains ONLY metrics, file paths, and category names — never raw file contents.
882
- * Scanned for secrets before return; throws if any found (should never happen).
883
- */
884
- declare function deriveContextSummary(blueprint: BlueprintData): string;
885
862
 
886
863
  type PrismFocus = "release" | "changelog" | "deepdive" | "summary" | `zone:${string}` | `module:${string}`;
887
864
  interface PrismContextPrompt {
@@ -905,7 +882,6 @@ declare const PRISM_TEMPLATE_ARCHITECTURE_OVERVIEW: PrismTemplate;
905
882
  declare const PRISM_TEMPLATE_REFACTOR_RATIONALE: PrismTemplate;
906
883
  declare const PRISM_TEMPLATES: PrismTemplate[];
907
884
  declare function getPrismTemplate(id: string): PrismTemplate | undefined;
908
- declare function buildPrismContextPrompt(blueprint: BlueprintData, focus?: PrismFocus, highlight?: string): PrismContextPrompt;
909
885
 
910
886
  interface RefineAssetInput {
911
887
  assetId: string;
@@ -939,4 +915,4 @@ declare function exportToICalendar(entries: ScheduledEntry[]): string;
939
915
  type ExportFormat = "buffer" | "hypefury" | "icalendar";
940
916
  declare function previewExport(entries: ScheduledEntry[], format: ExportFormat): string;
941
917
 
942
- export { ANIMATION_DURATION_PRESETS, type ArchitectureWalkthroughOpts, type ArrayField, type AskDrivenAssetFormat, type AskDrivenAssetOpts, type AssetKind, type AssetSlotsValidationErr, type AssetSlotsValidationOk, type AssetSlotsValidationResult, type AssetVersion, type AudienceId, BRAND_CONTENT_SLOT_KEYS, BUNDLED_DISPATCH_CHANNELS, BUNDLED_STYLE_PRESETS, BUNDLED_WIDGET_TEMPLATES, type BlueprintData, type BlueprintEdge, type BlueprintFile, type BooleanField, type BrandKit, type BrandKitFonts, type BrandKitLogo, type BrandKitPalette, type BrandKitSnapshot, type BrandKitVoice, type BrandPalette, type BrandThemeConfig, type ChangesSinceOpts, type Channel, type ChannelKind, type ChannelOutput, DEFAULT_ANIMATION_DURATION_SECONDS, DEFAULT_BRAND_KIT_FONTS, DEFAULT_BRAND_KIT_PALETTE, DEFAULT_BRAND_KIT_VOICE, DISPATCH_CHANNEL_BLOG, DISPATCH_CHANNEL_EMAIL, DISPATCH_CHANNEL_HN, DISPATCH_CHANNEL_INSTAGRAM, DISPATCH_CHANNEL_LINKEDIN, DISPATCH_CHANNEL_NEWSLETTER, DISPATCH_CHANNEL_REDDIT, DISPATCH_CHANNEL_SLACK, DISPATCH_CHANNEL_TWEET, type DiffEntry, type DiffResult, type DispatchAudienceContext, type DispatchBrandContext, type DispatchChannel, type DispatchRun, type ExportFormat, FORGE_AUDIENCES, FORGE_BRAND_THEME_ID, FORGE_TEMPLATES, FREE_TIER_WIDGET_IDS, type FileEntry, type ForgeAsset, type ForgeAudience, type ForgeGenerationDryRun, type ForgeGenerationError, type ForgeGenerationGenerated, type ForgeGenerationInput, type ForgeGenerationResult, type ForgeOutput, type ForgePrompt, type ForgeScope, type ForgeSignal, type ForgeStorage, type ForgeSubview, type ForgeTemplate, type ForgeThemeEntry, type FormErrors, type FormField, type FormSpec, type FormSpecOk, type FormSpecRaw, type Format, type GenerationResult, type Intent, type ListOutputsOpts, type LlmMessage, type LlmProvider, type LlmRequest, type LlmResponse, MAX_ANIMATION_DURATION_SECONDS, MIN_ANIMATION_DURATION_SECONDS, type Modality, type NumberField, type ObjectField, type OnboardingDocOpts, type OrchestrationInput, type OrchestrationResult, type OutputStatus, PRISM_TEMPLATES, PRISM_TEMPLATE_ARCHITECTURE_OVERVIEW, PRISM_TEMPLATE_REFACTOR_RATIONALE, PRISM_TEMPLATE_RELEASE_ANNOUNCEMENT, PRISM_TEMPLATE_SHIPPING_DIGEST, PRISM_TEMPLATE_ZONE_DEEPDIVE, type PrismBrandDraft, type PrismContextPrompt, type PrismData, type PrismFocus, type PrismInsight, type PrismRecommendation, type PrismSession, type PrismTemplate, type ProductTruth, type ProductTruthClaim, REFINE_COUNTDOWN_THRESHOLD, REFINE_SESSION_SOFT_CAP, REFINE_SUGGESTIONS, type ReadingLevel, type RefactoringReportOpts, type RefineAssetInput, type RefineAssetResult, type RefineLimitState, type RefineSuggestion, type ReleaseNotesOpts, type RenderWidgetInput, type ResolveBrandPaletteInput, type ResolvedTuple, STYLE_PRESET_BRUTALIST, STYLE_PRESET_DEFAULT, STYLE_PRESET_GLASSY, STYLE_PRESET_MINIMAL, type ScheduleRange, type ScheduledEntry, type ScheduledEntryMetadata, type ScheduledStatus, type SchemaDefinitionErr, type SchemaDefinitionOk, type SchemaDefinitionResult, type ScopeKind, type SignalKind, type StringField, type StyleTokens, TEMPLATE_SCHEMA_EXAMPLES, TEMPLATE_SCHEMA_GENERIC, type TokenUsage, type Tonality, type UrlBrandHints, type ValidationErr, type ValidationOk, type ValidationResult, WIDGET_TEMPLATE_CHANGELOG_ROW, WIDGET_TEMPLATE_CTA_BANNER, WIDGET_TEMPLATE_FEATURE_GRID, WIDGET_TEMPLATE_METRIC_BADGE, WIDGET_TEMPLATE_PRICING_TIER, WIDGET_TEMPLATE_SOCIAL_PROOF, WIDGET_TEMPLATE_STAT_CARD, WIDGET_TEMPLATE_TESTIMONIAL, type WidgetExportFormat, type WidgetInstance, type WidgetInstanceSnapshot, type WidgetKind, type WidgetSlotDef, type WidgetSlotType, type WidgetStyle, type WidgetStyleSnapshot, type WidgetTemplate, type Zone, applyEntryPatch, asAudienceId, assembleBrandUrlExtractionPrompt, assembleForgePrompt, brandThemeConfigToEntry, buildPrismContextPrompt, buildRevertVersion, buildScheduledEntry, buildVersion, cascadingScheduledFor, clampAnimationDuration, computeDiff, defaultBrandKit, defaultValueForField, deriveContextSummary, distill, entryInRange, exportToBufferCsv, exportToHypefuryCsv, exportToICalendar, extractBrandFromPrismBlueprint, extractDependencyHotspots, extractTopChurnFiles, extractZones, generateArchitectureWalkthrough, generateAskDrivenAsset, generateChangesSince, generateOnboardingDoc, generateRefactoringReport, generateReleaseNotes, getDispatchChannel, getPrismTemplate, getSlotValue, getStyleById, getWidgetTemplate, initialFormValues, next7DaysRange, nextVersionNumber, orchestrateDispatch, parseAndValidateSchemaDefinition, parseBrandKitFromLlmResponse, parseBrandThemeContent, parseStyleFromCss, parseStyleFromTailwindConfig, parseStyleFromTokensJson, parseThemeConfigContent, previewExport, readBlueprintData, readBlueprintFromTarget, readPrismDirectory, refineAsset, refineLimitState, renderWidget, resolveAnimatedChoice, resolveAnimationDuration, resolveBrandPalette, runForgeGeneration, scanForSecrets, schemaExampleFor, schemaToForm, templateAnimatedDefault, themeEntryToPalette, tryParseJsonObject, validateAgainstTemplateSchema, validateAssetSlots, validateFormValues, validateSchemaDefinition };
918
+ export { ANIMATION_DURATION_PRESETS, type ArchitectureWalkthroughOpts, type ArrayField, type AskDrivenAssetFormat, type AskDrivenAssetOpts, type AssetKind, type AssetSlotsValidationErr, type AssetSlotsValidationOk, type AssetSlotsValidationResult, type AssetVersion, type AudienceId, BRAND_CONTENT_SLOT_KEYS, BUNDLED_DISPATCH_CHANNELS, BUNDLED_STYLE_PRESETS, BUNDLED_WIDGET_TEMPLATES, type BlueprintData, type BlueprintEdge, type BlueprintFile, type BooleanField, type BrandKit, type BrandKitFonts, type BrandKitLogo, type BrandKitPalette, type BrandKitSnapshot, type BrandKitVoice, type BrandPalette, type BrandThemeConfig, type ChangesSinceOpts, type Channel, type ChannelKind, type ChannelOutput, DEFAULT_ANIMATION_DURATION_SECONDS, DEFAULT_BRAND_KIT_FONTS, DEFAULT_BRAND_KIT_PALETTE, DEFAULT_BRAND_KIT_VOICE, DISPATCH_CHANNEL_BLOG, DISPATCH_CHANNEL_EMAIL, DISPATCH_CHANNEL_HN, DISPATCH_CHANNEL_INSTAGRAM, DISPATCH_CHANNEL_LINKEDIN, DISPATCH_CHANNEL_NEWSLETTER, DISPATCH_CHANNEL_REDDIT, DISPATCH_CHANNEL_SLACK, DISPATCH_CHANNEL_TWEET, type DiffEntry, type DiffResult, type DispatchAudienceContext, type DispatchBrandContext, type DispatchChannel, type DispatchRun, type ExportFormat, FORGE_AUDIENCES, FORGE_BRAND_THEME_ID, FORGE_TEMPLATES, FREE_TIER_WIDGET_IDS, type FileEntry, type ForgeAsset, type ForgeAudience, type ForgeGenerationDryRun, type ForgeGenerationError, type ForgeGenerationGenerated, type ForgeGenerationInput, type ForgeGenerationResult, type ForgeOutput, type ForgePrompt, type ForgeScope, type ForgeSignal, type ForgeStorage, type ForgeSubview, type ForgeTemplate, type ForgeThemeEntry, type FormErrors, type FormField, type FormSpec, type FormSpecOk, type FormSpecRaw, type Format, type GenerationResult, type Intent, type ListOutputsOpts, type LlmMessage, type LlmProvider, type LlmRequest, type LlmResponse, MAX_ANIMATION_DURATION_SECONDS, MIN_ANIMATION_DURATION_SECONDS, type Modality, type NumberField, type ObjectField, type OnboardingDocOpts, type OrchestrationInput, type OrchestrationResult, type OutputStatus, PRISM_TEMPLATES, PRISM_TEMPLATE_ARCHITECTURE_OVERVIEW, PRISM_TEMPLATE_REFACTOR_RATIONALE, PRISM_TEMPLATE_RELEASE_ANNOUNCEMENT, PRISM_TEMPLATE_SHIPPING_DIGEST, PRISM_TEMPLATE_ZONE_DEEPDIVE, type PrismBrandDraft, type PrismContextPrompt, type PrismData, type PrismFocus, type PrismInsight, type PrismRecommendation, type PrismSession, type PrismTemplate, type ProductTruth, type ProductTruthClaim, REFINE_COUNTDOWN_THRESHOLD, REFINE_SESSION_SOFT_CAP, REFINE_SUGGESTIONS, type ReadingLevel, type RefactoringReportOpts, type RefineAssetInput, type RefineAssetResult, type RefineLimitState, type RefineSuggestion, type ReleaseNotesOpts, type RenderWidgetInput, type ResolveBrandPaletteInput, type ResolvedTuple, STYLE_PRESET_BRUTALIST, STYLE_PRESET_DEFAULT, STYLE_PRESET_GLASSY, STYLE_PRESET_MINIMAL, type ScheduleRange, type ScheduledEntry, type ScheduledEntryMetadata, type ScheduledStatus, type SchemaDefinitionErr, type SchemaDefinitionOk, type SchemaDefinitionResult, type ScopeKind, type SignalKind, type StringField, type StyleTokens, TEMPLATE_SCHEMA_EXAMPLES, TEMPLATE_SCHEMA_GENERIC, type TokenUsage, type Tonality, type UrlBrandHints, type ValidationErr, type ValidationOk, type ValidationResult, WIDGET_TEMPLATE_CHANGELOG_ROW, WIDGET_TEMPLATE_CTA_BANNER, WIDGET_TEMPLATE_FEATURE_GRID, WIDGET_TEMPLATE_METRIC_BADGE, WIDGET_TEMPLATE_PRICING_TIER, WIDGET_TEMPLATE_SOCIAL_PROOF, WIDGET_TEMPLATE_STAT_CARD, WIDGET_TEMPLATE_TESTIMONIAL, type WidgetExportFormat, type WidgetInstance, type WidgetInstanceSnapshot, type WidgetKind, type WidgetSlotDef, type WidgetSlotType, type WidgetStyle, type WidgetStyleSnapshot, type WidgetTemplate, type Zone, applyEntryPatch, asAudienceId, assembleBrandUrlExtractionPrompt, assembleForgePrompt, brandThemeConfigToEntry, buildRevertVersion, buildScheduledEntry, buildVersion, cascadingScheduledFor, clampAnimationDuration, computeDiff, defaultBrandKit, defaultValueForField, distill, entryInRange, exportToBufferCsv, exportToHypefuryCsv, exportToICalendar, generateArchitectureWalkthrough, generateAskDrivenAsset, generateChangesSince, generateOnboardingDoc, generateRefactoringReport, generateReleaseNotes, getDispatchChannel, getPrismTemplate, getSlotValue, getStyleById, getWidgetTemplate, initialFormValues, next7DaysRange, nextVersionNumber, orchestrateDispatch, parseAndValidateSchemaDefinition, parseBrandKitFromLlmResponse, parseBrandThemeContent, parseStyleFromCss, parseStyleFromTailwindConfig, parseStyleFromTokensJson, parseThemeConfigContent, previewExport, refineAsset, refineLimitState, renderWidget, resolveAnimatedChoice, resolveAnimationDuration, resolveBrandPalette, runForgeGeneration, scanForSecrets, schemaExampleFor, schemaToForm, templateAnimatedDefault, themeEntryToPalette, tryParseJsonObject, validateAgainstTemplateSchema, validateAssetSlots, validateFormValues, validateSchemaDefinition };