@qlucent/fishi-core 0.8.0 → 0.9.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.
package/dist/index.d.ts CHANGED
@@ -643,10 +643,72 @@ declare function startDevServer(projectDir: string, config: DevServerConfig): Ch
643
643
  */
644
644
  declare function getVibeModeConfig(enabled: boolean): string;
645
645
 
646
+ interface DesignTokens {
647
+ colors: Record<string, string>;
648
+ typography: {
649
+ fontFamilies: string[];
650
+ scale: Record<string, string>;
651
+ };
652
+ spacing: Record<string, string>;
653
+ borderRadius: Record<string, string>;
654
+ shadows: Record<string, string>;
655
+ darkMode: boolean;
656
+ }
657
+ interface ComponentEntry {
658
+ name: string;
659
+ path: string;
660
+ type: 'ui' | 'layout' | 'form' | 'data' | 'navigation' | 'other';
661
+ }
662
+ interface ComponentRegistry {
663
+ components: ComponentEntry[];
664
+ library: string | null;
665
+ framework: string | null;
666
+ }
667
+ interface BrandGuardianIssue {
668
+ file: string;
669
+ line: number;
670
+ severity: 'error' | 'warning' | 'info';
671
+ rule: string;
672
+ message: string;
673
+ fix?: string;
674
+ }
675
+ interface BrandGuardianReport {
676
+ issues: BrandGuardianIssue[];
677
+ passed: boolean;
678
+ stats: {
679
+ errors: number;
680
+ warnings: number;
681
+ infos: number;
682
+ filesScanned: number;
683
+ };
684
+ }
685
+ /**
686
+ * Detect design tokens from a project's config files.
687
+ * Checks: tailwind.config, CSS custom properties, theme files.
688
+ */
689
+ declare function detectDesignTokens(projectDir: string): DesignTokens;
690
+ /**
691
+ * Generate default design tokens for a new project.
692
+ */
693
+ declare function generateDefaultTokens(): DesignTokens;
694
+ /**
695
+ * Detect component library and registry from a project.
696
+ */
697
+ declare function detectComponentRegistry(projectDir: string): ComponentRegistry;
698
+ /**
699
+ * Run Brand Guardian validation on project files.
700
+ * Checks for hardcoded colors, inconsistent spacing, missing a11y, etc.
701
+ */
702
+ declare function runBrandGuardian(projectDir: string, tokens: DesignTokens): BrandGuardianReport;
703
+ /**
704
+ * Generate a design system config file for the project.
705
+ */
706
+ declare function generateDesignSystemConfig(tokens: DesignTokens, registry: ComponentRegistry): string;
707
+
646
708
  declare function getSandboxPolicyTemplate(): string;
647
709
 
648
710
  declare function getDockerfileTemplate(): string;
649
711
 
650
712
  declare function getDashboardHtml(): string;
651
713
 
652
- export { type AgentDefinition, type AgentRole, type AgentTemplate, type BackupManifest, type BrownfieldAnalysisData, type ClaudeMdOptions, type CommandTemplate, type ConflictCategory, type ConflictMap, type ConflictResolution, type CostMode, type DetectionCheck, type DetectionResult, type DevServerConfig, type DynamicAgent, type DynamicAgentConfig, type ExecutionConfig, type FileConflict, type FileResolutionMap, type FishiConfig, type FishiYamlOptions, type GateConfig, type GateStatus, type GitConfig, type HookTemplate, type InitOptions, type McpConfig, type McpServerConfig, type ModelRoutingConfig, type ModelTier, type MonitorEvent, type MonitorState, type MonitorSummary, type ProjectConfig, type ProjectType, type ProjectYamlOptions, type SandboxConfig, type SandboxMode, type SandboxPolicy, type SandboxRunResult, type ScaffoldOptions, type ScaffoldResult, type SkillTemplate, type StateConfig, type TaskStatus, type TaskboardConfig, type TemplateContext, architectAgentTemplate, backendAgentTemplate, buildSandboxEnv, createBackup, detectConflicts, detectDevServer, detectDocker, devLeadTemplate, devopsAgentTemplate, docsAgentTemplate, emitEvent, frontendAgentTemplate, fullstackAgentTemplate, generateScaffold, getAdaptiveTaskGraphSkill, getAgentCompleteHook, getAgentFactoryTemplate, getAgentRegistryTemplate, getAgentSummary, getApiDesignSkill, getAutoCheckpointHook, getBoardCommand, getBrainstormingSkill, getBrownfieldAnalysisSkill, getBrownfieldDiscoverySkill, getClaudeMdTemplate, getCodeGenSkill, getCoordinatorFactoryTemplate, getDashboardHtml, getDebuggingSkill, getDeploymentSkill, getDocCheckerScript, getDockerfileTemplate, getDocumentationSkill, getFishiYamlTemplate, getGateCommand, getGateManagerScript, getGitignoreAdditions, getInitCommand, getLearningsManagerScript, getMasterOrchestratorTemplate, getMcpJsonTemplate, getMemoryManagerScript, getModelRoutingReference, getMonitorEmitterScript, getPhaseRunnerScript, getPostEditHook, getPrdCommand, getPrdSkill, getProjectYamlTemplate, getResetCommand, getResumeCommand, getSafetyCheckHook, getSandboxPolicyTemplate, getSessionStartHook, getSettingsJsonTemplate, getSprintCommand, getStatusCommand, getTaskboardOpsSkill, getTaskboardUpdateHook, getTestingSkill, getTodoManagerScript, getValidateScaffoldScript, getVibeModeConfig, getWorktreeManagerScript, getWorktreeSetupHook, marketingAgentTemplate, mergeClaudeMd, mergeClaudeMdTop, mergeGitignore, mergeMcpJson, mergeSettingsJson, opsLeadTemplate, planningAgentTemplate, planningLeadTemplate, qualityLeadTemplate, readMonitorState, readSandboxConfig, readSandboxPolicy, researchAgentTemplate, runInDockerSandbox, runInProcessSandbox, runInSandbox, securityAgentTemplate, startDevServer, testingAgentTemplate, uiuxAgentTemplate, writingAgentTemplate };
714
+ export { type AgentDefinition, type AgentRole, type AgentTemplate, type BackupManifest, type BrandGuardianIssue, type BrandGuardianReport, type BrownfieldAnalysisData, type ClaudeMdOptions, type CommandTemplate, type ComponentEntry, type ComponentRegistry, type ConflictCategory, type ConflictMap, type ConflictResolution, type CostMode, type DesignTokens, type DetectionCheck, type DetectionResult, type DevServerConfig, type DynamicAgent, type DynamicAgentConfig, type ExecutionConfig, type FileConflict, type FileResolutionMap, type FishiConfig, type FishiYamlOptions, type GateConfig, type GateStatus, type GitConfig, type HookTemplate, type InitOptions, type McpConfig, type McpServerConfig, type ModelRoutingConfig, type ModelTier, type MonitorEvent, type MonitorState, type MonitorSummary, type ProjectConfig, type ProjectType, type ProjectYamlOptions, type SandboxConfig, type SandboxMode, type SandboxPolicy, type SandboxRunResult, type ScaffoldOptions, type ScaffoldResult, type SkillTemplate, type StateConfig, type TaskStatus, type TaskboardConfig, type TemplateContext, architectAgentTemplate, backendAgentTemplate, buildSandboxEnv, createBackup, detectComponentRegistry, detectConflicts, detectDesignTokens, detectDevServer, detectDocker, devLeadTemplate, devopsAgentTemplate, docsAgentTemplate, emitEvent, frontendAgentTemplate, fullstackAgentTemplate, generateDefaultTokens, generateDesignSystemConfig, generateScaffold, getAdaptiveTaskGraphSkill, getAgentCompleteHook, getAgentFactoryTemplate, getAgentRegistryTemplate, getAgentSummary, getApiDesignSkill, getAutoCheckpointHook, getBoardCommand, getBrainstormingSkill, getBrownfieldAnalysisSkill, getBrownfieldDiscoverySkill, getClaudeMdTemplate, getCodeGenSkill, getCoordinatorFactoryTemplate, getDashboardHtml, getDebuggingSkill, getDeploymentSkill, getDocCheckerScript, getDockerfileTemplate, getDocumentationSkill, getFishiYamlTemplate, getGateCommand, getGateManagerScript, getGitignoreAdditions, getInitCommand, getLearningsManagerScript, getMasterOrchestratorTemplate, getMcpJsonTemplate, getMemoryManagerScript, getModelRoutingReference, getMonitorEmitterScript, getPhaseRunnerScript, getPostEditHook, getPrdCommand, getPrdSkill, getProjectYamlTemplate, getResetCommand, getResumeCommand, getSafetyCheckHook, getSandboxPolicyTemplate, getSessionStartHook, getSettingsJsonTemplate, getSprintCommand, getStatusCommand, getTaskboardOpsSkill, getTaskboardUpdateHook, getTestingSkill, getTodoManagerScript, getValidateScaffoldScript, getVibeModeConfig, getWorktreeManagerScript, getWorktreeSetupHook, marketingAgentTemplate, mergeClaudeMd, mergeClaudeMdTop, mergeGitignore, mergeMcpJson, mergeSettingsJson, opsLeadTemplate, planningAgentTemplate, planningLeadTemplate, qualityLeadTemplate, readMonitorState, readSandboxConfig, readSandboxPolicy, researchAgentTemplate, runBrandGuardian, runInDockerSandbox, runInProcessSandbox, runInSandbox, securityAgentTemplate, startDevServer, testingAgentTemplate, uiuxAgentTemplate, writingAgentTemplate };
package/dist/index.js CHANGED
@@ -11111,7 +11111,7 @@ async function createBackup(targetDir, conflictingFiles) {
11111
11111
  manifestFiles.push({ path: relPath, size: stat.size });
11112
11112
  }
11113
11113
  }
11114
- const fishiVersion = "0.8.0";
11114
+ const fishiVersion = "0.9.0";
11115
11115
  const manifest = {
11116
11116
  timestamp: now.toISOString(),
11117
11117
  fishi_version: fishiVersion,
@@ -11466,6 +11466,320 @@ vibe_mode:
11466
11466
  `;
11467
11467
  }
11468
11468
 
11469
+ // src/generators/design-system.ts
11470
+ import { existsSync as existsSync7, readFileSync as readFileSync4, readdirSync } from "fs";
11471
+ import { join as join7 } from "path";
11472
+ function detectDesignTokens(projectDir) {
11473
+ const tokens = {
11474
+ colors: {},
11475
+ typography: { fontFamilies: [], scale: {} },
11476
+ spacing: {},
11477
+ borderRadius: {},
11478
+ shadows: {},
11479
+ darkMode: false
11480
+ };
11481
+ const tailwindFiles = ["tailwind.config.js", "tailwind.config.ts", "tailwind.config.mjs", "tailwind.config.cjs"];
11482
+ for (const file of tailwindFiles) {
11483
+ const p = join7(projectDir, file);
11484
+ if (existsSync7(p)) {
11485
+ const content = readFileSync4(p, "utf-8");
11486
+ const colorMatches = content.matchAll(/['"]?([\w-]+)['"]?\s*:\s*['"]?(#[0-9a-fA-F]{3,8})['"]?/g);
11487
+ for (const m of colorMatches) {
11488
+ tokens.colors[m[1]] = m[2];
11489
+ }
11490
+ if (content.includes("darkMode")) tokens.darkMode = true;
11491
+ break;
11492
+ }
11493
+ }
11494
+ const cssFiles = findFiles(projectDir, ["src", "styles", "app"], [".css"]);
11495
+ for (const file of cssFiles.slice(0, 10)) {
11496
+ try {
11497
+ const content = readFileSync4(file, "utf-8");
11498
+ const varMatches = content.matchAll(/--(\w[\w-]*)\s*:\s*([^;]+)/g);
11499
+ for (const m of varMatches) {
11500
+ const name = m[1];
11501
+ const value = m[2].trim();
11502
+ if (name.includes("color") || name.includes("bg") || value.startsWith("#") || value.startsWith("rgb") || value.startsWith("hsl")) {
11503
+ tokens.colors[name] = value;
11504
+ } else if (name.includes("font")) {
11505
+ if (name.includes("size")) tokens.typography.scale[name] = value;
11506
+ else if (name.includes("family")) tokens.typography.fontFamilies.push(value);
11507
+ } else if (name.includes("spacing") || name.includes("gap") || name.includes("padding") || name.includes("margin")) {
11508
+ tokens.spacing[name] = value;
11509
+ } else if (name.includes("radius")) {
11510
+ tokens.borderRadius[name] = value;
11511
+ } else if (name.includes("shadow")) {
11512
+ tokens.shadows[name] = value;
11513
+ }
11514
+ }
11515
+ if (content.includes("prefers-color-scheme: dark") || content.includes(".dark")) {
11516
+ tokens.darkMode = true;
11517
+ }
11518
+ } catch {
11519
+ }
11520
+ }
11521
+ const themeFiles = ["theme.ts", "theme.js", "theme.json", "src/theme.ts", "src/theme.js", "src/styles/theme.ts"];
11522
+ for (const file of themeFiles) {
11523
+ if (existsSync7(join7(projectDir, file))) {
11524
+ try {
11525
+ const content = readFileSync4(join7(projectDir, file), "utf-8");
11526
+ const colorMatches = content.matchAll(/['"]?([\w-]+)['"]?\s*:\s*['"]?(#[0-9a-fA-F]{3,8})['"]?/g);
11527
+ for (const m of colorMatches) {
11528
+ tokens.colors[m[1]] = m[2];
11529
+ }
11530
+ } catch {
11531
+ }
11532
+ break;
11533
+ }
11534
+ }
11535
+ return tokens;
11536
+ }
11537
+ function generateDefaultTokens() {
11538
+ return {
11539
+ colors: {
11540
+ "brand-50": "#f0f7ff",
11541
+ "brand-100": "#e0efff",
11542
+ "brand-200": "#b8d9ff",
11543
+ "brand-500": "#0066cc",
11544
+ "brand-600": "#0052a3",
11545
+ "brand-700": "#003d7a",
11546
+ "brand-900": "#001f3f",
11547
+ "gray-50": "#f9fafb",
11548
+ "gray-100": "#f3f4f6",
11549
+ "gray-200": "#e5e7eb",
11550
+ "gray-500": "#6b7280",
11551
+ "gray-700": "#374151",
11552
+ "gray-900": "#111827",
11553
+ "success": "#22c55e",
11554
+ "warning": "#f59e0b",
11555
+ "error": "#ef4444"
11556
+ },
11557
+ typography: {
11558
+ fontFamilies: ['-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'],
11559
+ scale: {
11560
+ "xs": "0.75rem",
11561
+ "sm": "0.875rem",
11562
+ "base": "1rem",
11563
+ "lg": "1.125rem",
11564
+ "xl": "1.25rem",
11565
+ "2xl": "1.5rem",
11566
+ "3xl": "1.875rem",
11567
+ "4xl": "2.25rem"
11568
+ }
11569
+ },
11570
+ spacing: {
11571
+ "xs": "0.25rem",
11572
+ "sm": "0.5rem",
11573
+ "md": "1rem",
11574
+ "lg": "1.5rem",
11575
+ "xl": "2rem",
11576
+ "2xl": "3rem",
11577
+ "3xl": "4rem"
11578
+ },
11579
+ borderRadius: {
11580
+ "sm": "0.25rem",
11581
+ "md": "0.375rem",
11582
+ "lg": "0.5rem",
11583
+ "xl": "0.75rem",
11584
+ "full": "9999px"
11585
+ },
11586
+ shadows: {
11587
+ "sm": "0 1px 2px rgba(0,0,0,0.05)",
11588
+ "md": "0 4px 6px rgba(0,0,0,0.1)",
11589
+ "lg": "0 10px 15px rgba(0,0,0,0.1)"
11590
+ },
11591
+ darkMode: true
11592
+ };
11593
+ }
11594
+ function detectComponentRegistry(projectDir) {
11595
+ const registry = {
11596
+ components: [],
11597
+ library: null,
11598
+ framework: null
11599
+ };
11600
+ const pkgPath = join7(projectDir, "package.json");
11601
+ if (existsSync7(pkgPath)) {
11602
+ const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
11603
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
11604
+ if (deps["@shadcn/ui"] || existsSync7(join7(projectDir, "components.json"))) registry.library = "shadcn";
11605
+ else if (deps["@radix-ui/react-dialog"] || deps["@radix-ui/themes"]) registry.library = "radix";
11606
+ else if (deps["@mui/material"]) registry.library = "mui";
11607
+ else if (deps["antd"]) registry.library = "antd";
11608
+ else if (deps["@chakra-ui/react"]) registry.library = "chakra";
11609
+ else if (deps["@headlessui/react"]) registry.library = "headlessui";
11610
+ if (deps["react"] || deps["react-dom"]) registry.framework = "react";
11611
+ else if (deps["vue"]) registry.framework = "vue";
11612
+ else if (deps["svelte"]) registry.framework = "svelte";
11613
+ else if (deps["@angular/core"]) registry.framework = "angular";
11614
+ }
11615
+ const componentDirs = ["src/components", "components", "src/ui", "app/components", "src/components/ui"];
11616
+ for (const dir of componentDirs) {
11617
+ const fullDir = join7(projectDir, dir);
11618
+ if (existsSync7(fullDir)) {
11619
+ try {
11620
+ scanComponents(fullDir, dir, registry.components);
11621
+ } catch {
11622
+ }
11623
+ }
11624
+ }
11625
+ return registry;
11626
+ }
11627
+ function scanComponents(dir, relBase, components) {
11628
+ try {
11629
+ const entries = readdirSync(dir, { withFileTypes: true });
11630
+ for (const entry of entries) {
11631
+ if (entry.isDirectory()) {
11632
+ scanComponents(join7(dir, entry.name), `${relBase}/${entry.name}`, components);
11633
+ } else if (entry.name.match(/\.(tsx|jsx|vue|svelte)$/)) {
11634
+ const name = entry.name.replace(/\.(tsx|jsx|vue|svelte)$/, "");
11635
+ if (name === "index") continue;
11636
+ const type = classifyComponent(name);
11637
+ components.push({ name, path: `${relBase}/${entry.name}`, type });
11638
+ }
11639
+ }
11640
+ } catch {
11641
+ }
11642
+ }
11643
+ function classifyComponent(name) {
11644
+ const lower = name.toLowerCase();
11645
+ if (/button|badge|avatar|icon|tag|chip|tooltip/i.test(lower)) return "ui";
11646
+ if (/layout|header|footer|sidebar|menu/i.test(lower)) return "layout";
11647
+ if (/input|form|select|checkbox|radio|textarea|switch|slider/i.test(lower)) return "form";
11648
+ if (/table|list|card|grid|chart|graph|stat/i.test(lower)) return "data";
11649
+ if (/link|breadcrumb|tab|pagination|stepper|nav|navbar/i.test(lower)) return "navigation";
11650
+ return "other";
11651
+ }
11652
+ function runBrandGuardian(projectDir, tokens) {
11653
+ const issues = [];
11654
+ let filesScanned = 0;
11655
+ const files = findFiles(projectDir, ["src", "app", "pages", "components"], [".tsx", ".jsx", ".vue", ".svelte", ".css"]);
11656
+ for (const file of files.slice(0, 100)) {
11657
+ try {
11658
+ const content = readFileSync4(file, "utf-8");
11659
+ const lines = content.split("\n");
11660
+ const relPath = file.replace(projectDir, "").replace(/\\/g, "/").replace(/^\//, "");
11661
+ filesScanned++;
11662
+ for (let i = 0; i < lines.length; i++) {
11663
+ const line = lines[i];
11664
+ const lineNum = i + 1;
11665
+ if (file.match(/\.(tsx|jsx|vue|svelte)$/)) {
11666
+ const hexMatches = line.matchAll(/#[0-9a-fA-F]{3,8}\b/g);
11667
+ for (const m of hexMatches) {
11668
+ if (line.trimStart().startsWith("//") || line.trimStart().startsWith("*")) continue;
11669
+ if (line.includes("--")) continue;
11670
+ issues.push({
11671
+ file: relPath,
11672
+ line: lineNum,
11673
+ severity: "warning",
11674
+ rule: "no-hardcoded-colors",
11675
+ message: `Hardcoded color ${m[0]} \u2014 use design tokens instead`,
11676
+ fix: "Replace with a CSS variable or Tailwind class from your design system"
11677
+ });
11678
+ }
11679
+ }
11680
+ if (line.includes("style=") && line.match(/\d+px/)) {
11681
+ issues.push({
11682
+ file: relPath,
11683
+ line: lineNum,
11684
+ severity: "warning",
11685
+ rule: "no-inline-px",
11686
+ message: "Inline px values \u2014 use spacing tokens or Tailwind classes",
11687
+ fix: "Replace px values with spacing scale (xs, sm, md, lg, xl)"
11688
+ });
11689
+ }
11690
+ if (line.match(/<img\b/) && !line.includes("alt=") && !line.includes("alt =")) {
11691
+ issues.push({
11692
+ file: relPath,
11693
+ line: lineNum,
11694
+ severity: "error",
11695
+ rule: "img-alt-text",
11696
+ message: "Image missing alt attribute \u2014 accessibility violation",
11697
+ fix: 'Add alt="descriptive text" or alt="" for decorative images'
11698
+ });
11699
+ }
11700
+ if (line.includes("onClick") && !line.includes("onKeyDown") && !line.includes("onKeyUp") && !line.includes("onKeyPress")) {
11701
+ if (line.includes("<div") || line.includes("<span")) {
11702
+ issues.push({
11703
+ file: relPath,
11704
+ line: lineNum,
11705
+ severity: "warning",
11706
+ rule: "keyboard-accessible",
11707
+ message: "Click handler on non-interactive element without keyboard support",
11708
+ fix: 'Add onKeyDown handler and role="button" tabIndex={0}, or use <button>'
11709
+ });
11710
+ }
11711
+ }
11712
+ if (line.match(/font-size:\s*\d+px/) && !line.includes("--")) {
11713
+ issues.push({
11714
+ file: relPath,
11715
+ line: lineNum,
11716
+ severity: "info",
11717
+ rule: "use-typography-scale",
11718
+ message: "Hardcoded font-size \u2014 use typography scale tokens",
11719
+ fix: "Replace with typography scale class (text-xs, text-sm, text-base, etc.)"
11720
+ });
11721
+ }
11722
+ if (line.match(/<html\b/) && !line.includes("lang=")) {
11723
+ issues.push({
11724
+ file: relPath,
11725
+ line: lineNum,
11726
+ severity: "error",
11727
+ rule: "html-lang",
11728
+ message: "HTML element missing lang attribute \u2014 accessibility violation",
11729
+ fix: 'Add lang="en" (or appropriate language code) to <html>'
11730
+ });
11731
+ }
11732
+ }
11733
+ } catch {
11734
+ }
11735
+ }
11736
+ const errors = issues.filter((i) => i.severity === "error").length;
11737
+ const warnings = issues.filter((i) => i.severity === "warning").length;
11738
+ const infos = issues.filter((i) => i.severity === "info").length;
11739
+ return {
11740
+ issues,
11741
+ passed: errors === 0,
11742
+ stats: { errors, warnings, infos, filesScanned }
11743
+ };
11744
+ }
11745
+ function generateDesignSystemConfig(tokens, registry) {
11746
+ return JSON.stringify({
11747
+ version: "1.0",
11748
+ tokens,
11749
+ components: {
11750
+ library: registry.library,
11751
+ framework: registry.framework,
11752
+ count: registry.components.length,
11753
+ entries: registry.components
11754
+ }
11755
+ }, null, 2) + "\n";
11756
+ }
11757
+ function findFiles(base, dirs, extensions) {
11758
+ const files = [];
11759
+ for (const dir of dirs) {
11760
+ const fullDir = join7(base, dir);
11761
+ if (existsSync7(fullDir)) {
11762
+ walkDir(fullDir, extensions, files);
11763
+ }
11764
+ }
11765
+ return files;
11766
+ }
11767
+ function walkDir(dir, extensions, result) {
11768
+ try {
11769
+ const entries = readdirSync(dir, { withFileTypes: true });
11770
+ for (const entry of entries) {
11771
+ const full = join7(dir, entry.name);
11772
+ if (entry.isDirectory()) {
11773
+ if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist" || entry.name === ".git") continue;
11774
+ walkDir(full, extensions, result);
11775
+ } else if (extensions.some((ext) => entry.name.endsWith(ext))) {
11776
+ result.push(full);
11777
+ }
11778
+ }
11779
+ } catch {
11780
+ }
11781
+ }
11782
+
11469
11783
  // src/templates/configs/sandbox-policy.ts
11470
11784
  function getSandboxPolicyTemplate() {
11471
11785
  return `# FISHI Sandbox Policy
@@ -11862,7 +12176,9 @@ export {
11862
12176
  backendAgentTemplate,
11863
12177
  buildSandboxEnv,
11864
12178
  createBackup,
12179
+ detectComponentRegistry,
11865
12180
  detectConflicts,
12181
+ detectDesignTokens,
11866
12182
  detectDevServer,
11867
12183
  detectDocker,
11868
12184
  devLeadTemplate,
@@ -11871,6 +12187,8 @@ export {
11871
12187
  emitEvent,
11872
12188
  frontendAgentTemplate,
11873
12189
  fullstackAgentTemplate,
12190
+ generateDefaultTokens,
12191
+ generateDesignSystemConfig,
11874
12192
  generateScaffold,
11875
12193
  getAdaptiveTaskGraphSkill,
11876
12194
  getAgentCompleteHook,
@@ -11938,6 +12256,7 @@ export {
11938
12256
  readSandboxConfig,
11939
12257
  readSandboxPolicy,
11940
12258
  researchAgentTemplate,
12259
+ runBrandGuardian,
11941
12260
  runInDockerSandbox,
11942
12261
  runInProcessSandbox,
11943
12262
  runInSandbox,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qlucent/fishi-core",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Shared templates, types, and generators for the FISHI framework",
5
5
  "license": "MIT",
6
6
  "type": "module",