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 +25 -326
- package/dist/index.d.cts +15 -39
- package/dist/index.d.ts +15 -39
- package/dist/index.mjs +26 -313
- package/dist/server.cjs +3373 -0
- package/dist/server.d.cts +947 -0
- package/dist/server.d.ts +947 -0
- package/dist/server.mjs +3253 -0
- package/package.json +7 -2
package/dist/index.d.ts
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,
|
|
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 };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import path, { join, normalize, resolve } from 'path';
|
|
3
|
-
import { existsSync, readFileSync } from 'fs';
|
|
4
1
|
import { randomUUID } from 'crypto';
|
|
5
2
|
|
|
6
3
|
// src/generators/releaseNotes.ts
|
|
@@ -272,12 +269,12 @@ function detectImportCycles(edges) {
|
|
|
272
269
|
const cycles = [];
|
|
273
270
|
const visited = /* @__PURE__ */ new Set();
|
|
274
271
|
const stack = /* @__PURE__ */ new Set();
|
|
275
|
-
function dfs(node,
|
|
272
|
+
function dfs(node, path) {
|
|
276
273
|
if (cycles.length >= 5) return;
|
|
277
274
|
if (stack.has(node)) {
|
|
278
|
-
const cycleStart =
|
|
275
|
+
const cycleStart = path.indexOf(node);
|
|
279
276
|
if (cycleStart !== -1) {
|
|
280
|
-
cycles.push(
|
|
277
|
+
cycles.push(path.slice(cycleStart).join(" \u2192 ") + " \u2192 " + node);
|
|
281
278
|
}
|
|
282
279
|
return;
|
|
283
280
|
}
|
|
@@ -285,7 +282,7 @@ function detectImportCycles(edges) {
|
|
|
285
282
|
visited.add(node);
|
|
286
283
|
stack.add(node);
|
|
287
284
|
for (const neighbor of graph.get(node) ?? []) {
|
|
288
|
-
dfs(neighbor, [...
|
|
285
|
+
dfs(neighbor, [...path, node]);
|
|
289
286
|
}
|
|
290
287
|
stack.delete(node);
|
|
291
288
|
}
|
|
@@ -340,43 +337,6 @@ async function generateRefactoringReport(blueprint, opts, provider) {
|
|
|
340
337
|
metadata: { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), usedTokens: response.usedTokens, generator: "forgesmith" }
|
|
341
338
|
};
|
|
342
339
|
}
|
|
343
|
-
async function readJsonFiles(dir) {
|
|
344
|
-
try {
|
|
345
|
-
const entries = await fs.readdir(dir);
|
|
346
|
-
const results = [];
|
|
347
|
-
for (const entry of entries) {
|
|
348
|
-
if (!entry.endsWith(".json")) continue;
|
|
349
|
-
try {
|
|
350
|
-
const raw = await fs.readFile(path.join(dir, entry), "utf-8");
|
|
351
|
-
results.push(JSON.parse(raw));
|
|
352
|
-
} catch {
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
return results;
|
|
356
|
-
} catch {
|
|
357
|
-
return [];
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
async function readPrismDirectory(prismPath) {
|
|
361
|
-
const sessionsDir = path.join(prismPath, "sessions");
|
|
362
|
-
const recsDir = path.join(prismPath, "recommendations");
|
|
363
|
-
const insightsDir = path.join(prismPath, "green", "insights", "accepted");
|
|
364
|
-
const [sessions, recommendations, insights] = await Promise.all([
|
|
365
|
-
readJsonFiles(sessionsDir),
|
|
366
|
-
readJsonFiles(recsDir),
|
|
367
|
-
readJsonFiles(insightsDir)
|
|
368
|
-
]);
|
|
369
|
-
return { sessions, recommendations, insights };
|
|
370
|
-
}
|
|
371
|
-
async function readBlueprintData(targetPath) {
|
|
372
|
-
const snapshotPath = path.join(targetPath, ".prism", "blueprint", "snapshot.json");
|
|
373
|
-
try {
|
|
374
|
-
const raw = await fs.readFile(snapshotPath, "utf-8");
|
|
375
|
-
return JSON.parse(raw);
|
|
376
|
-
} catch {
|
|
377
|
-
return null;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
340
|
|
|
381
341
|
// src/generators/askDrivenAsset.ts
|
|
382
342
|
var NO_DATA_MSG5 = "No Blueprint data available. Run prism scan first.";
|
|
@@ -1000,6 +960,8 @@ function refineLimitState(usedRefines, softCap = REFINE_SESSION_SOFT_CAP) {
|
|
|
1000
960
|
showCountdown: used >= REFINE_COUNTDOWN_THRESHOLD
|
|
1001
961
|
};
|
|
1002
962
|
}
|
|
963
|
+
|
|
964
|
+
// src/forge/brandKit.ts
|
|
1003
965
|
var DEFAULT_BRAND_KIT_PALETTE = {
|
|
1004
966
|
primary: "#f97316",
|
|
1005
967
|
secondary: "#1e293b",
|
|
@@ -1143,60 +1105,6 @@ function parseBrandKitFromLlmResponse(text, hints) {
|
|
|
1143
1105
|
prism_detected: false
|
|
1144
1106
|
};
|
|
1145
1107
|
}
|
|
1146
|
-
function deriveTechnicalScore(categories, total) {
|
|
1147
|
-
if (total === 0) return 50;
|
|
1148
|
-
const techFiles = (categories.lib ?? 0) + (categories.hook ?? 0);
|
|
1149
|
-
const appFiles = (categories.app ?? 0) + (categories.component ?? 0);
|
|
1150
|
-
const techRatio = techFiles / total;
|
|
1151
|
-
const appRatio = appFiles / total;
|
|
1152
|
-
return Math.round(30 + techRatio * 50 - appRatio * 10);
|
|
1153
|
-
}
|
|
1154
|
-
function deriveAudienceMix(categories, paths) {
|
|
1155
|
-
const hasAdminPaths = paths.some((p) => /admin|dashboard|ops/.test(p));
|
|
1156
|
-
const hasApiPaths = paths.some((p) => /\/api\/|route\.ts/.test(p));
|
|
1157
|
-
const hasFrontend = (categories.component ?? 0) > 5;
|
|
1158
|
-
if (hasAdminPaths && hasApiPaths) return "developer+operator";
|
|
1159
|
-
if (hasApiPaths && !hasFrontend) return "developer";
|
|
1160
|
-
if (hasFrontend && !hasApiPaths) return "end-user";
|
|
1161
|
-
return "developer+business";
|
|
1162
|
-
}
|
|
1163
|
-
async function extractBrandFromPrismBlueprint(targetPath) {
|
|
1164
|
-
const snapshotPath = path.join(targetPath, ".prism", "blueprint", "snapshot.json");
|
|
1165
|
-
let blueprint = {};
|
|
1166
|
-
try {
|
|
1167
|
-
const raw = await fs.readFile(snapshotPath, "utf-8");
|
|
1168
|
-
blueprint = JSON.parse(raw);
|
|
1169
|
-
} catch {
|
|
1170
|
-
}
|
|
1171
|
-
const categories = blueprint.categories ?? {};
|
|
1172
|
-
const files = blueprint.files ?? [];
|
|
1173
|
-
const paths = files.map((f) => f.path ?? "");
|
|
1174
|
-
const total = blueprint.stats?.totalFiles ?? files.length;
|
|
1175
|
-
const technicalScore = deriveTechnicalScore(categories, total);
|
|
1176
|
-
const audienceMix = deriveAudienceMix(categories, paths);
|
|
1177
|
-
const projectName = blueprint.targetPath ? path.basename(blueprint.targetPath) : "Project";
|
|
1178
|
-
const formality = technicalScore > 60 ? 65 : 50;
|
|
1179
|
-
const technicality = Math.min(95, technicalScore + 10);
|
|
1180
|
-
return {
|
|
1181
|
-
suggestedName: projectName,
|
|
1182
|
-
voice: {
|
|
1183
|
-
tone: technicalScore > 60 ? "technical" : "professional",
|
|
1184
|
-
audience: audienceMix.includes("developer") ? "developers" : "business",
|
|
1185
|
-
vocabulary: [],
|
|
1186
|
-
avoid: [],
|
|
1187
|
-
formality,
|
|
1188
|
-
technicality
|
|
1189
|
-
},
|
|
1190
|
-
prism_detected: true,
|
|
1191
|
-
blueprint_path: snapshotPath,
|
|
1192
|
-
stats: {
|
|
1193
|
-
totalFiles: total,
|
|
1194
|
-
categories,
|
|
1195
|
-
technicalScore,
|
|
1196
|
-
audienceMix
|
|
1197
|
-
}
|
|
1198
|
-
};
|
|
1199
|
-
}
|
|
1200
1108
|
|
|
1201
1109
|
// src/forge/brandPalette.ts
|
|
1202
1110
|
function isNonEmptyString(v) {
|
|
@@ -1436,63 +1344,63 @@ function initialFormValues(fields, source) {
|
|
|
1436
1344
|
function isEmptyString(v) {
|
|
1437
1345
|
return typeof v === "string" && v.trim().length === 0;
|
|
1438
1346
|
}
|
|
1439
|
-
function validateField(field, value,
|
|
1347
|
+
function validateField(field, value, path) {
|
|
1440
1348
|
const errors = {};
|
|
1441
1349
|
switch (field.kind) {
|
|
1442
1350
|
case "string": {
|
|
1443
1351
|
if (field.required && (value === void 0 || value === null || isEmptyString(value))) {
|
|
1444
|
-
errors[
|
|
1352
|
+
errors[path] = `${field.label} ist erforderlich`;
|
|
1445
1353
|
break;
|
|
1446
1354
|
}
|
|
1447
1355
|
if (typeof value === "string") {
|
|
1448
1356
|
if (field.minLength !== void 0 && value.length < field.minLength) {
|
|
1449
|
-
errors[
|
|
1357
|
+
errors[path] = `${field.label} mindestens ${field.minLength} Zeichen`;
|
|
1450
1358
|
} else if (field.maxLength !== void 0 && value.length > field.maxLength) {
|
|
1451
|
-
errors[
|
|
1359
|
+
errors[path] = `${field.label} h\xF6chstens ${field.maxLength} Zeichen`;
|
|
1452
1360
|
} else if (field.enum && value.length > 0 && !field.enum.includes(value)) {
|
|
1453
|
-
errors[
|
|
1361
|
+
errors[path] = `${field.label}: Wert nicht in der Auswahl`;
|
|
1454
1362
|
}
|
|
1455
1363
|
}
|
|
1456
1364
|
break;
|
|
1457
1365
|
}
|
|
1458
1366
|
case "number": {
|
|
1459
1367
|
if (value === "" || value === void 0 || value === null) {
|
|
1460
|
-
if (field.required) errors[
|
|
1368
|
+
if (field.required) errors[path] = `${field.label} ist erforderlich`;
|
|
1461
1369
|
break;
|
|
1462
1370
|
}
|
|
1463
1371
|
const n = typeof value === "number" ? value : Number(value);
|
|
1464
1372
|
if (!Number.isFinite(n)) {
|
|
1465
|
-
errors[
|
|
1373
|
+
errors[path] = `${field.label} muss eine Zahl sein`;
|
|
1466
1374
|
} else if (field.integer && !Number.isInteger(n)) {
|
|
1467
|
-
errors[
|
|
1375
|
+
errors[path] = `${field.label} muss eine ganze Zahl sein`;
|
|
1468
1376
|
} else if (field.minimum !== void 0 && n < field.minimum) {
|
|
1469
|
-
errors[
|
|
1377
|
+
errors[path] = `${field.label} >= ${field.minimum}`;
|
|
1470
1378
|
} else if (field.maximum !== void 0 && n > field.maximum) {
|
|
1471
|
-
errors[
|
|
1379
|
+
errors[path] = `${field.label} <= ${field.maximum}`;
|
|
1472
1380
|
}
|
|
1473
1381
|
break;
|
|
1474
1382
|
}
|
|
1475
1383
|
case "boolean":
|
|
1476
1384
|
if (field.required && value !== true) {
|
|
1477
|
-
errors[
|
|
1385
|
+
errors[path] = `${field.label} muss aktiviert sein`;
|
|
1478
1386
|
}
|
|
1479
1387
|
break;
|
|
1480
1388
|
case "array": {
|
|
1481
1389
|
const arr = Array.isArray(value) ? value : [];
|
|
1482
1390
|
if (field.required && arr.length === 0) {
|
|
1483
|
-
errors[
|
|
1391
|
+
errors[path] = `${field.label}: mindestens ein Eintrag erforderlich`;
|
|
1484
1392
|
}
|
|
1485
1393
|
if (field.minItems !== void 0 && arr.length < field.minItems) {
|
|
1486
|
-
errors[
|
|
1394
|
+
errors[path] = `${field.label}: mindestens ${field.minItems} Eintr\xE4ge`;
|
|
1487
1395
|
} else if (field.maxItems !== void 0 && arr.length > field.maxItems) {
|
|
1488
|
-
errors[
|
|
1396
|
+
errors[path] = `${field.label}: h\xF6chstens ${field.maxItems} Eintr\xE4ge`;
|
|
1489
1397
|
}
|
|
1490
1398
|
if (field.itemField) {
|
|
1491
1399
|
arr.forEach((item, i) => {
|
|
1492
1400
|
const sub = validateField(
|
|
1493
1401
|
field.itemField,
|
|
1494
1402
|
item,
|
|
1495
|
-
`${
|
|
1403
|
+
`${path}[${i}]`
|
|
1496
1404
|
);
|
|
1497
1405
|
Object.assign(errors, sub);
|
|
1498
1406
|
});
|
|
@@ -1502,7 +1410,7 @@ function validateField(field, value, path3) {
|
|
|
1502
1410
|
case "object": {
|
|
1503
1411
|
const obj = isPlainObject5(value) ? value : {};
|
|
1504
1412
|
for (const sub of field.fields) {
|
|
1505
|
-
const subErrors = validateField(sub, obj[sub.name], `${
|
|
1413
|
+
const subErrors = validateField(sub, obj[sub.name], `${path}.${sub.name}`);
|
|
1506
1414
|
Object.assign(errors, subErrors);
|
|
1507
1415
|
}
|
|
1508
1416
|
break;
|
|
@@ -2503,71 +2411,8 @@ var FORGE_TEMPLATES = [
|
|
|
2503
2411
|
asset_slots: []
|
|
2504
2412
|
}
|
|
2505
2413
|
];
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
const resolvedTarget = resolve(targetPath);
|
|
2509
|
-
const resolvedFile = resolve(filePath);
|
|
2510
|
-
const allowedPrefix = join(resolvedTarget, ".prism", "blueprint");
|
|
2511
|
-
if (!resolvedFile.startsWith(allowedPrefix + "/") && resolvedFile !== allowedPrefix) {
|
|
2512
|
-
return false;
|
|
2513
|
-
}
|
|
2514
|
-
const basename = resolvedFile.slice(resolvedFile.lastIndexOf("/") + 1);
|
|
2515
|
-
return ALLOWED_BLUEPRINT_FILENAMES.has(basename);
|
|
2516
|
-
}
|
|
2517
|
-
function readBlueprintFromTarget(targetPath) {
|
|
2518
|
-
const candidates = [
|
|
2519
|
-
join(targetPath, ".prism", "blueprint", "snapshot.json"),
|
|
2520
|
-
join(targetPath, ".prism", "blueprint.json")
|
|
2521
|
-
];
|
|
2522
|
-
for (const candidate of candidates) {
|
|
2523
|
-
const normalized = normalize(candidate);
|
|
2524
|
-
if (!isAllowedBlueprintPath(targetPath, normalized)) continue;
|
|
2525
|
-
if (!existsSync(normalized)) continue;
|
|
2526
|
-
try {
|
|
2527
|
-
const raw = readFileSync(normalized, "utf-8");
|
|
2528
|
-
return JSON.parse(raw);
|
|
2529
|
-
} catch {
|
|
2530
|
-
return null;
|
|
2531
|
-
}
|
|
2532
|
-
}
|
|
2533
|
-
return null;
|
|
2534
|
-
}
|
|
2535
|
-
function zoneId(filePath) {
|
|
2536
|
-
const parts = filePath.replace(/^\//, "").split("/");
|
|
2537
|
-
return parts[0] || "root";
|
|
2538
|
-
}
|
|
2539
|
-
function extractZones(blueprint) {
|
|
2540
|
-
const zoneMap = /* @__PURE__ */ new Map();
|
|
2541
|
-
for (const file of blueprint.files) {
|
|
2542
|
-
const id = zoneId(file.path);
|
|
2543
|
-
if (!zoneMap.has(id)) zoneMap.set(id, { files: [], heat: 0 });
|
|
2544
|
-
const z = zoneMap.get(id);
|
|
2545
|
-
z.files.push(file.path);
|
|
2546
|
-
z.heat += (file.importedByCount ?? 0) + (file.importCount ?? 0);
|
|
2547
|
-
}
|
|
2548
|
-
return Array.from(zoneMap.entries()).map(([id, { files, heat }]) => ({
|
|
2549
|
-
id,
|
|
2550
|
-
name: id,
|
|
2551
|
-
files,
|
|
2552
|
-
fileCount: files.length,
|
|
2553
|
-
heat
|
|
2554
|
-
})).sort((a, b) => b.heat - a.heat || b.fileCount - a.fileCount);
|
|
2555
|
-
}
|
|
2556
|
-
function toFileEntry(f) {
|
|
2557
|
-
return {
|
|
2558
|
-
path: f.path,
|
|
2559
|
-
importCount: f.importCount ?? 0,
|
|
2560
|
-
importedByCount: f.importedByCount ?? 0,
|
|
2561
|
-
lineCount: f.lineCount ?? 0,
|
|
2562
|
-
zone: zoneId(f.path)
|
|
2563
|
-
};
|
|
2564
|
-
}
|
|
2565
|
-
function extractTopChurnFiles(blueprint, n = 10) {
|
|
2566
|
-
return blueprint.files.map(toFileEntry).sort((a, b) => b.importedByCount - a.importedByCount || b.lineCount - a.lineCount).slice(0, n);
|
|
2567
|
-
}
|
|
2568
|
-
function extractDependencyHotspots(blueprint, n = 10) {
|
|
2569
|
-
return blueprint.files.map(toFileEntry).sort((a, b) => b.importCount - a.importCount || b.importedByCount - a.importedByCount).slice(0, n);
|
|
2570
|
-
}
|
|
2414
|
+
|
|
2415
|
+
// src/forge/secrets.ts
|
|
2571
2416
|
var SECRET_PATTERNS = [
|
|
2572
2417
|
/sk-ant-api03-[A-Za-z0-9_-]{80,}/,
|
|
2573
2418
|
/sk-proj-[A-Za-z0-9_-]{40,}/,
|
|
@@ -2577,42 +2422,8 @@ var SECRET_PATTERNS = [
|
|
|
2577
2422
|
function scanForSecrets(text) {
|
|
2578
2423
|
return SECRET_PATTERNS.some((re) => re.test(text));
|
|
2579
2424
|
}
|
|
2580
|
-
var MAX_SUMMARY_CHARS = 2e3;
|
|
2581
|
-
function deriveContextSummary(blueprint) {
|
|
2582
|
-
const zones = extractZones(blueprint).slice(0, 8);
|
|
2583
|
-
const churn = extractTopChurnFiles(blueprint, 5);
|
|
2584
|
-
const deps = extractDependencyHotspots(blueprint, 5);
|
|
2585
|
-
const scanAge = blueprint.scanTimestamp ? (() => {
|
|
2586
|
-
const ageMs = Date.now() - blueprint.scanTimestamp * 1e3;
|
|
2587
|
-
const ageMin = Math.round(ageMs / 6e4);
|
|
2588
|
-
if (ageMin < 60) return `${ageMin}m ago`;
|
|
2589
|
-
if (ageMin < 1440) return `${Math.round(ageMin / 60)}h ago`;
|
|
2590
|
-
return `${Math.round(ageMin / 1440)}d ago`;
|
|
2591
|
-
})() : "unknown";
|
|
2592
|
-
const lines = [
|
|
2593
|
-
`Blueprint snapshot (scanned ${scanAge}):`,
|
|
2594
|
-
`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}`,
|
|
2595
|
-
"",
|
|
2596
|
-
"Top zones (by activity):",
|
|
2597
|
-
...zones.map((z) => ` ${z.name}: ${z.fileCount} files, heat ${z.heat}`),
|
|
2598
|
-
"",
|
|
2599
|
-
"Hottest files (most imported by others):",
|
|
2600
|
-
...churn.map((f) => ` ${f.path} (importedBy:${f.importedByCount})`),
|
|
2601
|
-
"",
|
|
2602
|
-
"Most dependency-heavy files:",
|
|
2603
|
-
...deps.map((f) => ` ${f.path} (imports:${f.importCount})`)
|
|
2604
|
-
];
|
|
2605
|
-
let summary = lines.join("\n");
|
|
2606
|
-
if (summary.length > MAX_SUMMARY_CHARS) {
|
|
2607
|
-
summary = summary.slice(0, MAX_SUMMARY_CHARS - 3) + "...";
|
|
2608
|
-
}
|
|
2609
|
-
if (scanForSecrets(summary)) {
|
|
2610
|
-
throw new Error("Blueprint context summary contains unexpected secret-pattern match. Refusing to pass to LLM.");
|
|
2611
|
-
}
|
|
2612
|
-
return summary;
|
|
2613
|
-
}
|
|
2614
2425
|
|
|
2615
|
-
// src/forge/prismContext.ts
|
|
2426
|
+
// src/forge/prismContext.data.ts
|
|
2616
2427
|
var PRISM_TEMPLATE_RELEASE_ANNOUNCEMENT = {
|
|
2617
2428
|
id: "release-announcement",
|
|
2618
2429
|
name: "Release Announcement",
|
|
@@ -2664,104 +2475,6 @@ var PRISM_TEMPLATES = [
|
|
|
2664
2475
|
function getPrismTemplate(id) {
|
|
2665
2476
|
return PRISM_TEMPLATES.find((t) => t.id === id);
|
|
2666
2477
|
}
|
|
2667
|
-
function releaseContextBlock(blueprint) {
|
|
2668
|
-
const churn = extractTopChurnFiles(blueprint, 8);
|
|
2669
|
-
const zones = extractZones(blueprint).slice(0, 6);
|
|
2670
|
-
return [
|
|
2671
|
-
"Recent activity (most active files by coupling):",
|
|
2672
|
-
...churn.map((f) => ` ${f.path} \u2014 importedBy:${f.importedByCount}`),
|
|
2673
|
-
"",
|
|
2674
|
-
"Most active zones:",
|
|
2675
|
-
...zones.map((z) => ` ${z.name}: ${z.fileCount} files, activity score ${z.heat}`)
|
|
2676
|
-
].join("\n");
|
|
2677
|
-
}
|
|
2678
|
-
function changelogContextBlock(blueprint) {
|
|
2679
|
-
const zones = extractZones(blueprint).slice(0, 10);
|
|
2680
|
-
const hotspots = extractDependencyHotspots(blueprint, 6);
|
|
2681
|
-
return [
|
|
2682
|
-
"Zone breakdown:",
|
|
2683
|
-
...zones.map((z) => ` ${z.name}: ${z.fileCount} files`),
|
|
2684
|
-
"",
|
|
2685
|
-
"High-coupling files (refactoring targets):",
|
|
2686
|
-
...hotspots.map((f) => ` ${f.path} \u2014 imports ${f.importCount} modules`)
|
|
2687
|
-
].join("\n");
|
|
2688
|
-
}
|
|
2689
|
-
function deepdiveContextBlock(blueprint) {
|
|
2690
|
-
return deriveContextSummary(blueprint);
|
|
2691
|
-
}
|
|
2692
|
-
function zoneContextBlock(blueprint, zoneName) {
|
|
2693
|
-
const allZones = extractZones(blueprint);
|
|
2694
|
-
const zone = allZones.find((z) => z.id === zoneName || z.name === zoneName);
|
|
2695
|
-
if (!zone) {
|
|
2696
|
-
return `Zone "${zoneName}" not found. Available zones: ${allZones.map((z) => z.name).join(", ")}`;
|
|
2697
|
-
}
|
|
2698
|
-
const topFiles = zone.files.slice(0, 12);
|
|
2699
|
-
const otherCount = Math.max(0, zone.fileCount - 12);
|
|
2700
|
-
return [
|
|
2701
|
-
`Zone: ${zone.name} (${zone.fileCount} files, heat score ${zone.heat})`,
|
|
2702
|
-
"Files:",
|
|
2703
|
-
...topFiles.map((f) => ` ${f}`),
|
|
2704
|
-
...otherCount > 0 ? [` ... and ${otherCount} more`] : []
|
|
2705
|
-
].join("\n");
|
|
2706
|
-
}
|
|
2707
|
-
function moduleContextBlock(blueprint, modulePath) {
|
|
2708
|
-
const file = blueprint.files.find((f) => f.path.includes(modulePath));
|
|
2709
|
-
if (!file) {
|
|
2710
|
-
return `Module path "${modulePath}" not found in blueprint.`;
|
|
2711
|
-
}
|
|
2712
|
-
const deps = extractDependencyHotspots(blueprint, 5);
|
|
2713
|
-
return [
|
|
2714
|
-
`Module: ${file.path}`,
|
|
2715
|
-
` importCount: ${file.importCount ?? 0}`,
|
|
2716
|
-
` importedByCount: ${file.importedByCount ?? 0}`,
|
|
2717
|
-
` lineCount: ${file.lineCount ?? 0}`,
|
|
2718
|
-
"",
|
|
2719
|
-
"Related high-activity files:",
|
|
2720
|
-
...deps.filter((d) => d.zone === (file.path.split("/")[0] || "root")).slice(0, 5).map((d) => ` ${d.path}`)
|
|
2721
|
-
].join("\n");
|
|
2722
|
-
}
|
|
2723
|
-
function buildPrismContextPrompt(blueprint, focus, highlight) {
|
|
2724
|
-
const resolvedFocus = focus ?? "summary";
|
|
2725
|
-
let contextBlock;
|
|
2726
|
-
let systemFragment;
|
|
2727
|
-
let suggestedAsk;
|
|
2728
|
-
if (resolvedFocus === "release") {
|
|
2729
|
-
contextBlock = releaseContextBlock(blueprint);
|
|
2730
|
-
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.";
|
|
2731
|
-
suggestedAsk = PRISM_TEMPLATE_RELEASE_ANNOUNCEMENT.suggestedAsk;
|
|
2732
|
-
} else if (resolvedFocus === "changelog") {
|
|
2733
|
-
contextBlock = changelogContextBlock(blueprint);
|
|
2734
|
-
systemFragment = "You have access to a real codebase blueprint showing zone structure and dependency coupling. Use this to make the changelog specific and credible.";
|
|
2735
|
-
suggestedAsk = PRISM_TEMPLATE_SHIPPING_DIGEST.suggestedAsk;
|
|
2736
|
-
} else if (resolvedFocus === "deepdive") {
|
|
2737
|
-
contextBlock = deepdiveContextBlock(blueprint);
|
|
2738
|
-
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.";
|
|
2739
|
-
suggestedAsk = PRISM_TEMPLATE_ARCHITECTURE_OVERVIEW.suggestedAsk;
|
|
2740
|
-
} else if (resolvedFocus.startsWith("zone:")) {
|
|
2741
|
-
const zoneName = resolvedFocus.slice(5);
|
|
2742
|
-
contextBlock = zoneContextBlock(blueprint, zoneName);
|
|
2743
|
-
systemFragment = `You have access to real file data for the "${zoneName}" zone of the codebase. Use specific file names and counts.`;
|
|
2744
|
-
suggestedAsk = PRISM_TEMPLATE_ZONE_DEEPDIVE.suggestedAsk.replace(
|
|
2745
|
-
"this codebase zone",
|
|
2746
|
-
`the "${zoneName}" zone`
|
|
2747
|
-
);
|
|
2748
|
-
} else if (resolvedFocus.startsWith("module:")) {
|
|
2749
|
-
const modulePath = resolvedFocus.slice(7);
|
|
2750
|
-
contextBlock = moduleContextBlock(blueprint, modulePath);
|
|
2751
|
-
systemFragment = `You have access to dependency data for the "${modulePath}" module. Reference specific metrics.`;
|
|
2752
|
-
suggestedAsk = `Explain the role of ${modulePath} in the codebase architecture and why it matters.`;
|
|
2753
|
-
} else {
|
|
2754
|
-
contextBlock = deriveContextSummary(blueprint);
|
|
2755
|
-
systemFragment = "You have access to a real codebase blueprint. Use specific zone names and file counts to make your content concrete and credible.";
|
|
2756
|
-
suggestedAsk = "Summarize the structure and key areas of this codebase.";
|
|
2757
|
-
}
|
|
2758
|
-
if (highlight) {
|
|
2759
|
-
contextBlock += `
|
|
2760
|
-
|
|
2761
|
-
User wants to highlight: ${highlight}`;
|
|
2762
|
-
}
|
|
2763
|
-
return { systemFragment, contextBlock, suggestedAsk };
|
|
2764
|
-
}
|
|
2765
2478
|
|
|
2766
2479
|
// src/forge/channel.ts
|
|
2767
2480
|
var DISPATCH_CHANNEL_TWEET = {
|
|
@@ -3240,4 +2953,4 @@ function previewExport(entries, format) {
|
|
|
3240
2953
|
}
|
|
3241
2954
|
}
|
|
3242
2955
|
|
|
3243
|
-
export { ANIMATION_DURATION_PRESETS, BRAND_CONTENT_SLOT_KEYS, BUNDLED_DISPATCH_CHANNELS, BUNDLED_STYLE_PRESETS, BUNDLED_WIDGET_TEMPLATES, 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, FORGE_AUDIENCES, FORGE_BRAND_THEME_ID, FORGE_TEMPLATES, FREE_TIER_WIDGET_IDS, MAX_ANIMATION_DURATION_SECONDS, MIN_ANIMATION_DURATION_SECONDS, PRISM_TEMPLATES, PRISM_TEMPLATE_ARCHITECTURE_OVERVIEW, PRISM_TEMPLATE_REFACTOR_RATIONALE, PRISM_TEMPLATE_RELEASE_ANNOUNCEMENT, PRISM_TEMPLATE_SHIPPING_DIGEST, PRISM_TEMPLATE_ZONE_DEEPDIVE, REFINE_COUNTDOWN_THRESHOLD, REFINE_SESSION_SOFT_CAP, REFINE_SUGGESTIONS, STYLE_PRESET_BRUTALIST, STYLE_PRESET_DEFAULT, STYLE_PRESET_GLASSY, STYLE_PRESET_MINIMAL, TEMPLATE_SCHEMA_EXAMPLES, TEMPLATE_SCHEMA_GENERIC, 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, applyEntryPatch, asAudienceId, assembleBrandUrlExtractionPrompt, assembleForgePrompt, brandThemeConfigToEntry,
|
|
2956
|
+
export { ANIMATION_DURATION_PRESETS, BRAND_CONTENT_SLOT_KEYS, BUNDLED_DISPATCH_CHANNELS, BUNDLED_STYLE_PRESETS, BUNDLED_WIDGET_TEMPLATES, 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, FORGE_AUDIENCES, FORGE_BRAND_THEME_ID, FORGE_TEMPLATES, FREE_TIER_WIDGET_IDS, MAX_ANIMATION_DURATION_SECONDS, MIN_ANIMATION_DURATION_SECONDS, PRISM_TEMPLATES, PRISM_TEMPLATE_ARCHITECTURE_OVERVIEW, PRISM_TEMPLATE_REFACTOR_RATIONALE, PRISM_TEMPLATE_RELEASE_ANNOUNCEMENT, PRISM_TEMPLATE_SHIPPING_DIGEST, PRISM_TEMPLATE_ZONE_DEEPDIVE, REFINE_COUNTDOWN_THRESHOLD, REFINE_SESSION_SOFT_CAP, REFINE_SUGGESTIONS, STYLE_PRESET_BRUTALIST, STYLE_PRESET_DEFAULT, STYLE_PRESET_GLASSY, STYLE_PRESET_MINIMAL, TEMPLATE_SCHEMA_EXAMPLES, TEMPLATE_SCHEMA_GENERIC, 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, 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 };
|