2sagaco48 1.0.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/diagnostics.mjs +141 -0
- package/dist/compute.worker-j5ahIpF-.js +1 -0
- package/dist/graph.worker-DG6iGCB9.js +1 -0
- package/dist/index.html +2314 -0
- package/flatten-guide.md +248 -0
- package/index.html +12 -0
- package/package.json +38 -0
- package/src/App.orig.tsx +204 -0
- package/src/App.orig1.tsx +27 -0
- package/src/App.orig2.tsx +25 -0
- package/src/App.tsx +3 -0
- package/src/BaseApp.tsx +18 -0
- package/src/INTEGRATION_LEDGER.md +22 -0
- package/src/PERSIST_CANARY.orig.txt +1 -0
- package/src/PERSIST_CANARY.txt +1 -0
- package/src/REGRESSION_LEDGER.md +651 -0
- package/src/TEMPLATE_PIPELINE_AUDIT.md +208 -0
- package/src/WILLIAMS_PERSONA_GUIDE.md +62 -0
- package/src/chat/VeritasChat.tsx +69 -0
- package/src/chat/synthesis.ts +31 -0
- package/src/chat/tier.ts +45 -0
- package/src/components/AdaptersPage.orig.tsx +99 -0
- package/src/components/AdaptersPage.tsx +3 -0
- package/src/components/AdversarialPanel.tsx +136 -0
- package/src/components/AnchorBaselinePanel.tsx +75 -0
- package/src/components/AnswerPanel.tsx +60 -0
- package/src/components/ArtifactPanel.tsx +43 -0
- package/src/components/ChatApp.orig.tsx +1582 -0
- package/src/components/ChatApp.orig1.tsx +722 -0
- package/src/components/ChatApp.tsx +95 -0
- package/src/components/ChatAugmentPanels.tsx +73 -0
- package/src/components/CitationLedgerPanel.tsx +313 -0
- package/src/components/ComputeSandboxPanel.tsx +130 -0
- package/src/components/ConfigPanel.tsx +110 -0
- package/src/components/ControlPlanePage.tsx +195 -0
- package/src/components/CreativeTreeLifePage.tsx +234 -0
- package/src/components/CreativeTreeOfLifePanel.tsx +149 -0
- package/src/components/DebugTracePanel.tsx +137 -0
- package/src/components/DeepReasoningTrace.tsx +48 -0
- package/src/components/EntitySheetPanel.tsx +51 -0
- package/src/components/FailureModesPanel.tsx +104 -0
- package/src/components/GBSDashboard.tsx +239 -0
- package/src/components/GraphView.tsx +116 -0
- package/src/components/HUD.tsx +125 -0
- package/src/components/HypothesisPanel.tsx +67 -0
- package/src/components/InnovationGenomeEngine.tsx +792 -0
- package/src/components/InnovationPersonaGuide.tsx +348 -0
- package/src/components/InnovationPersonaPanel.tsx +289 -0
- package/src/components/LiveResourceHUD.tsx +109 -0
- package/src/components/LongWriterPanel.tsx +112 -0
- package/src/components/MainPipelineV10Bridge.tsx +72 -0
- package/src/components/MarkdownLite.tsx +63 -0
- package/src/components/MemoryInspector.tsx +38 -0
- package/src/components/MemoryMonitor.tsx +52 -0
- package/src/components/MemoryStressPanel.tsx +176 -0
- package/src/components/ModulesPage.tsx +171 -0
- package/src/components/PipelineDebugConsole.orig.tsx +1856 -0
- package/src/components/PipelineDebugConsole.tsx +3 -0
- package/src/components/PreFlightHUD.tsx +67 -0
- package/src/components/PrismaFetchTracePanel.tsx +87 -0
- package/src/components/ReportOSPanel.tsx +165 -0
- package/src/components/ResourceEstimatorPage.tsx +327 -0
- package/src/components/RichText.tsx +181 -0
- package/src/components/SagaOsPanel.tsx +605 -0
- package/src/components/SagaOsReference.tsx +421 -0
- package/src/components/SagaOsV2Panel.tsx +594 -0
- package/src/components/SagaStyleTab.tsx +382 -0
- package/src/components/SageBlueprintPanel.tsx +416 -0
- package/src/components/SharedChatInput.tsx +77 -0
- package/src/components/StatFinancePanel.tsx +190 -0
- package/src/components/StylePersonaPanel.tsx +128 -0
- package/src/components/TemplatesPage.tsx +300 -0
- package/src/components/TestPanel.tsx +63 -0
- package/src/components/TraceLog.tsx +89 -0
- package/src/components/V15CalibrationAugment.tsx +1134 -0
- package/src/components/V15CalibrationDialog.tsx +1871 -0
- package/src/components/V15Overlay.orig.tsx +120 -0
- package/src/components/V15Overlay.tsx +4 -0
- package/src/components/V15OverlayWrapper.tsx +362 -0
- package/src/components/V15Toggle.tsx +34 -0
- package/src/console/DiagnosticRecoveryPanel.tsx +358 -0
- package/src/console/EngineeringConsole.tsx +103 -0
- package/src/console/FictionSystemPanels.tsx +882 -0
- package/src/console/InspectorPanels.tsx +254 -0
- package/src/console/ManuscriptGraderPanel.tsx +182 -0
- package/src/console/RecursiveReviserPanel.tsx +245 -0
- package/src/console/SeedControlPanel.tsx +135 -0
- package/src/console/StoryControllerPanel.tsx +443 -0
- package/src/console/engineBridge.ts +258 -0
- package/src/console/gemini.ts +106 -0
- package/src/console/grading.ts +250 -0
- package/src/console/util.ts +45 -0
- package/src/fiction/continuity.ts +372 -0
- package/src/fiction/crash-protection.ts +111 -0
- package/src/fiction/diagnostics.ts +208 -0
- package/src/fiction/diff.ts +74 -0
- package/src/fiction/entity-state-machine.ts +214 -0
- package/src/fiction/nive-engine.ts +404 -0
- package/src/fiction/pipeline-selftest.ts +132 -0
- package/src/fiction/seed-control.ts +193 -0
- package/src/fiction/story-engine.ts +326 -0
- package/src/fiction/types.ts +68 -0
- package/src/flatten-guide.md +379 -0
- package/src/index.css +14 -0
- package/src/index.orig.css +13 -0
- package/src/lib/academic-sources.base.ts +188 -0
- package/src/lib/academic-sources.orig.ts +28 -0
- package/src/lib/academic-sources.ts +10 -0
- package/src/lib/advanced-math.ts +119 -0
- package/src/lib/adversarial-engine.base.ts +409 -0
- package/src/lib/adversarial-engine.ts +82 -0
- package/src/lib/ai-revision.ts +623 -0
- package/src/lib/app-state.tsx +426 -0
- package/src/lib/artifact-registry.ts +97 -0
- package/src/lib/artifacts.ts +180 -0
- package/src/lib/atlas-dr.ts +167 -0
- package/src/lib/browser-mtls.ts +127 -0
- package/src/lib/browser-queue.ts +221 -0
- package/src/lib/browser-search-scraper.base.ts +382 -0
- package/src/lib/browser-search-scraper.orig.ts +90 -0
- package/src/lib/browser-search-scraper.ts +10 -0
- package/src/lib/calc-interceptor.ts +82 -0
- package/src/lib/citation-lane-tap.ts +78 -0
- package/src/lib/citation-ledger-store.ts +369 -0
- package/src/lib/citation-ledger.ts +203 -0
- package/src/lib/compute-sandbox.ts +215 -0
- package/src/lib/compute.worker.ts +153 -0
- package/src/lib/connectors/gemini.ts +120 -0
- package/src/lib/connectors/jina.ts +233 -0
- package/src/lib/connectors/marketdata.ts +51 -0
- package/src/lib/connectors/prismafetch.base.ts +175 -0
- package/src/lib/connectors/prismafetch.ts +1 -0
- package/src/lib/connectors/serpapi.ts +65 -0
- package/src/lib/connectors/wikidata.ts +44 -0
- package/src/lib/constraints.ts +331 -0
- package/src/lib/continuation-detector.base.ts +153 -0
- package/src/lib/continuation-detector.ts +48 -0
- package/src/lib/contradraft.ts +168 -0
- package/src/lib/cors-proxy.ts +120 -0
- package/src/lib/coverage.ts +81 -0
- package/src/lib/debug/architecture-prescription.ts +556 -0
- package/src/lib/debug/covea-repair.ts +543 -0
- package/src/lib/debug/helios-ground.ts +319 -0
- package/src/lib/debug/intent-decomposer.ts +281 -0
- package/src/lib/debug/intent-lattice.ts +349 -0
- package/src/lib/debug/pipeline-diagnosis.ts +1149 -0
- package/src/lib/debug/pipeline-trace-bus.ts +424 -0
- package/src/lib/debug/prompt-forge.ts +678 -0
- package/src/lib/debug/repair-sites.ts +513 -0
- package/src/lib/debug/research-phase.ts +266 -0
- package/src/lib/debug/retrieval-context.ts +76 -0
- package/src/lib/debug/retrieval-hardener.ts +142 -0
- package/src/lib/debug/scraper-debug-runner.ts +576 -0
- package/src/lib/debug/scraper-forensics.ts +418 -0
- package/src/lib/debug/scraper-lane-roadmap.ts +136 -0
- package/src/lib/debug/self-test.ts +415 -0
- package/src/lib/debug/step-attribution.ts +211 -0
- package/src/lib/debug/template-rubric.ts +301 -0
- package/src/lib/debug/unified-innovation.ts +126 -0
- package/src/lib/debug/veritas-hybrid-scraper.ts +335 -0
- package/src/lib/defense-registry.ts +104 -0
- package/src/lib/defenses.ts +162 -0
- package/src/lib/deterministic-citation-ledger.ts +174 -0
- package/src/lib/elo-registry.base.ts +117 -0
- package/src/lib/elo-registry.ts +1 -0
- package/src/lib/entity-resolver.ts +291 -0
- package/src/lib/failure-modes.ts +267 -0
- package/src/lib/feature-registry.ts +69 -0
- package/src/lib/flaw-registry.ts +143 -0
- package/src/lib/flaws/_template.ts +52 -0
- package/src/lib/flaws/builtins.ts +63 -0
- package/src/lib/flaws/finance.ts +169 -0
- package/src/lib/flaws/fixers.ts +10 -0
- package/src/lib/flaws/index.ts +32 -0
- package/src/lib/flaws/legal.ts +157 -0
- package/src/lib/flaws/medical.ts +188 -0
- package/src/lib/flaws/original-defenses-pack.ts +81 -0
- package/src/lib/flaws/sample-declarative-pack.json +38 -0
- package/src/lib/flaws/selftest.ts +201 -0
- package/src/lib/flaws/software-extended.ts +125 -0
- package/src/lib/flaws/software-rn-webgl.ts +182 -0
- package/src/lib/flaws/statistics-advanced.ts +46 -0
- package/src/lib/flaws/statistics.ts +61 -0
- package/src/lib/gbse/config.ts +20 -0
- package/src/lib/gbse/engine.ts +226 -0
- package/src/lib/gbse/graph.ts +118 -0
- package/src/lib/gbse/graph.worker.ts +21 -0
- package/src/lib/gbse/tests.ts +117 -0
- package/src/lib/gbse/tiers.ts +65 -0
- package/src/lib/gbse/types.ts +94 -0
- package/src/lib/innovation-genome-engine-v2.orig.ts +1001 -0
- package/src/lib/innovation-genome-engine-v2.ts +3 -0
- package/src/lib/innovation-genome-engine.orig.ts +330 -0
- package/src/lib/innovation-genome-engine.ts +3 -0
- package/src/lib/innovation-genome-v10.orig.ts +314 -0
- package/src/lib/innovation-genome-v10.ts +2 -0
- package/src/lib/innovation-genome-v3.orig.ts +2015 -0
- package/src/lib/innovation-genome-v3.ts +2 -0
- package/src/lib/innovation-genome-v4.orig.ts +1959 -0
- package/src/lib/innovation-genome-v4.ts +2 -0
- package/src/lib/innovation-genome-v5.orig.ts +1210 -0
- package/src/lib/innovation-genome-v5.ts +2 -0
- package/src/lib/innovation-genome-v7.orig.ts +2549 -0
- package/src/lib/innovation-genome-v7.ts +2 -0
- package/src/lib/innovation-genome-v8.orig.ts +1485 -0
- package/src/lib/innovation-genome-v8.ts +2 -0
- package/src/lib/innovation-genome-v9.orig.ts +643 -0
- package/src/lib/innovation-genome-v9.ts +2 -0
- package/src/lib/jina.base.ts +293 -0
- package/src/lib/jina.ts +1 -0
- package/src/lib/live-telemetry.ts +61 -0
- package/src/lib/longwriter.ts +84 -0
- package/src/lib/manuscript-grade-v2.ts +298 -0
- package/src/lib/memory-governor.ts +173 -0
- package/src/lib/memory-stress-tests.ts +248 -0
- package/src/lib/model-intelligence.ts +48 -0
- package/src/lib/model-rotator.ts +75 -0
- package/src/lib/models.orig.ts +513 -0
- package/src/lib/models.ts +151 -0
- package/src/lib/n-deep.base.ts +592 -0
- package/src/lib/n-deep.ts +51 -0
- package/src/lib/nih-simulator.ts +56 -0
- package/src/lib/nih-vulnerability-fixes.ts +460 -0
- package/src/lib/omega-templates.base.ts +294 -0
- package/src/lib/omega-templates.ts +225 -0
- package/src/lib/omni-nexus.ts +64 -0
- package/src/lib/oracle-adapters.ts +67 -0
- package/src/lib/oracle-registry.ts +163 -0
- package/src/lib/orchestrator.ts +357 -0
- package/src/lib/output-boundary.ts +235 -0
- package/src/lib/overrides/vite-native-chaos-harness.ts +154 -0
- package/src/lib/overrides/vite-native-contract-plane.ts +245 -0
- package/src/lib/overrides/vite-native-doctor-plane.ts +208 -0
- package/src/lib/overrides/vite-native-knowledge-store.ts +267 -0
- package/src/lib/overrides/vite-native-policy-plane.ts +190 -0
- package/src/lib/overrides/vite-native-replay-plane.ts +197 -0
- package/src/lib/overrides/vite-native-runtime-plane.ts +106 -0
- package/src/lib/overrides/vite-native-scraper.ts +848 -0
- package/src/lib/overrides/vite-native-selftest-functional.ts +217 -0
- package/src/lib/overrides/vite-native-selftest.ts +183 -0
- package/src/lib/overrides/vite-native-snapshot-plane.ts +123 -0
- package/src/lib/philosophy-toolkit.ts +75 -0
- package/src/lib/pipeline.orig.ts +659 -0
- package/src/lib/pipeline.ts +42 -0
- package/src/lib/precache.ts +128 -0
- package/src/lib/py-sandbox.ts +205 -0
- package/src/lib/quality-score.ts +96 -0
- package/src/lib/quant-engine.ts +231 -0
- package/src/lib/quant-lib.ts +80 -0
- package/src/lib/reportos.ts +175 -0
- package/src/lib/research-os.ts +306 -0
- package/src/lib/resource-estimator.ts +114 -0
- package/src/lib/rpm-governor.ts +93 -0
- package/src/lib/runtime-estimator.ts +135 -0
- package/src/lib/sage/empty-space-v6.ts +560 -0
- package/src/lib/sage/empty-space-v7.ts +222 -0
- package/src/lib/sage/empty-space.ts +733 -0
- package/src/lib/sage/engine.ts +786 -0
- package/src/lib/sage/index.ts +17 -0
- package/src/lib/sage/judge.ts +246 -0
- package/src/lib/sage/prng.ts +53 -0
- package/src/lib/sage/reality-grounding.ts +380 -0
- package/src/lib/sage/repetition.ts +151 -0
- package/src/lib/sage/saga-os-v2-engines.ts +1870 -0
- package/src/lib/sage/saga-os-v2.ts +274 -0
- package/src/lib/sage/saga-os-v3-core.ts +1491 -0
- package/src/lib/sage/saga-os-v3-release.ts +739 -0
- package/src/lib/sage/saga-os-v4-aureate.ts +1161 -0
- package/src/lib/sage/saga-os-v4.ts +212 -0
- package/src/lib/sage/saga-os-v5.ts +205 -0
- package/src/lib/sage/saga-os-v6.ts +346 -0
- package/src/lib/sage/saga-os-v7.ts +314 -0
- package/src/lib/sage/saga-os-v8.ts +505 -0
- package/src/lib/sage/saga-os.ts +329 -0
- package/src/lib/sage/taxonomy.ts +403 -0
- package/src/lib/sage/unified-roll.ts +524 -0
- package/src/lib/sage/worked-sketches.ts +44 -0
- package/src/lib/sage.ts +166 -0
- package/src/lib/scraper-debug-bus.ts +53 -0
- package/src/lib/scraper-enhanced.orig.ts +153 -0
- package/src/lib/scraper-enhanced.ts +10 -0
- package/src/lib/scraper-hardener.base.orig.ts +155 -0
- package/src/lib/scraper-hardener.base.ts +317 -0
- package/src/lib/scraper-hardener.ts +1 -0
- package/src/lib/scraper-palisade/palisade-adjudicator.orig.ts +419 -0
- package/src/lib/scraper-palisade/palisade-adjudicator.ts +13 -0
- package/src/lib/scraper-vnext/arbiter-omega.orig.ts +688 -0
- package/src/lib/scraper-vnext/arbiter-omega.ts +13 -0
- package/src/lib/scraper-vnext/canonical-portfolio-augments.ts +479 -0
- package/src/lib/scraper-vnext/canonical-portfolio-orchestrator.orig.ts +1529 -0
- package/src/lib/scraper-vnext/canonical-portfolio-orchestrator.ts +13 -0
- package/src/lib/scraper-vnext/conclave-omega.ts +1830 -0
- package/src/lib/scraper-vnext/content-extractor-v2.ts +226 -0
- package/src/lib/scraper-vnext/diagnostics-suite.ts +36 -0
- package/src/lib/scraper-vnext/epistemic-packer.ts +97 -0
- package/src/lib/scraper-vnext/fusion-v2.ts +65 -0
- package/src/lib/scraper-vnext/hydra-reader.orig.ts +1216 -0
- package/src/lib/scraper-vnext/hydra-reader.ts +13 -0
- package/src/lib/scraper-vnext/native-scraper-browser-vnext.orig.ts +91 -0
- package/src/lib/scraper-vnext/native-scraper-browser-vnext.ts +13 -0
- package/src/lib/scraper-vnext/nexus-consensus.orig.ts +905 -0
- package/src/lib/scraper-vnext/nexus-consensus.ts +13 -0
- package/src/lib/scraper-vnext/portfolio-consensus-adjudicator.ts +804 -0
- package/src/lib/scraper-vnext/portfolio-consensus-memory.ts +377 -0
- package/src/lib/scraper-vnext/portfolio-terminal-governor.ts +548 -0
- package/src/lib/scraper-vnext/query-strategist.orig.ts +224 -0
- package/src/lib/scraper-vnext/query-strategist.ts +423 -0
- package/src/lib/scraper-vnext/retrieval-accelerator.ts +708 -0
- package/src/lib/scraper-vnext/retrieval-audit-augments.ts +477 -0
- package/src/lib/scraper-vnext/retrieval-control-plane.ts +904 -0
- package/src/lib/scraper-vnext/retrieval-policy-augments.ts +358 -0
- package/src/lib/scraper-vnext/safe-fetch-v2.ts +157 -0
- package/src/lib/scraper-vnext/sentinel-omega.ts +56 -0
- package/src/lib/scraper-vnext/sentinel-orchestrator.ts +69 -0
- package/src/lib/scraper-vnext/sibyl-oracle.orig.ts +413 -0
- package/src/lib/scraper-vnext/sibyl-oracle.ts +13 -0
- package/src/lib/scraper-vnext/smart-read-v2.ts +55 -0
- package/src/lib/scraper-vnext/spa-rescue-bridge.ts +608 -0
- package/src/lib/scraper-vnext/strata-engine.orig.ts +2666 -0
- package/src/lib/scraper-vnext/strata-engine.ts +13 -0
- package/src/lib/scraper-vnext/structured-source-adapter.orig.ts +369 -0
- package/src/lib/scraper-vnext/structured-source-adapter.ts +34 -0
- package/src/lib/scraper-vnext/terminal-complete.ts +224 -0
- package/src/lib/scraper-vnext/terminal-final.ts +277 -0
- package/src/lib/scraper-vnext/terminal-saturation.ts +345 -0
- package/src/lib/scraper-vnext/terminal-wire.ts +425 -0
- package/src/lib/scraper-vnext/vanguard-titanium.orig.ts +467 -0
- package/src/lib/scraper-vnext/vanguard-titanium.ts +17 -0
- package/src/lib/search-cache.ts +138 -0
- package/src/lib/sloop-runner.base.ts +223 -0
- package/src/lib/sloop-runner.ts +104 -0
- package/src/lib/sloop.ts +114 -0
- package/src/lib/small-model-adapters.ts +82 -0
- package/src/lib/sscp.ts +86 -0
- package/src/lib/system-map.ts +54 -0
- package/src/lib/uni-node.ts +86 -0
- package/src/lib/universal-rigor-guard.ts +433 -0
- package/src/lib/v15-gate-testbed.ts +274 -0
- package/src/lib/v15-gemini.base.ts +89 -0
- package/src/lib/v15-gemini.ts +1 -0
- package/src/lib/v15-grounding.orig.ts +241 -0
- package/src/lib/v15-grounding.ts +79 -0
- package/src/lib/v15-pipeline.base.ts +769 -0
- package/src/lib/v15-pipeline.orig.ts +1154 -0
- package/src/lib/v15-pipeline.ts +674 -0
- package/src/lib/v15-questions.ts +64 -0
- package/src/lib/v15-rate-limiter.orig.ts +91 -0
- package/src/lib/v15-rate-limiter.ts +48 -0
- package/src/lib/v15-state.base.ts +87 -0
- package/src/lib/v15-state.ts +28 -0
- package/src/lib/visual-table-generator.tsx +207 -0
- package/src/lib/wasm-runtime.ts +133 -0
- package/src/lib/williams-persona-guide.ts +265 -0
- package/src/lib/williams-style.base.ts +464 -0
- package/src/lib/williams-style.ts +59 -0
- package/src/lib/worker-pool.ts +96 -0
- package/src/lib/writing-tiers.ts +125 -0
- package/src/main.orig.tsx +10 -0
- package/src/main.tsx +10 -0
- package/src/utils/cn.orig.ts +6 -0
- package/src/utils/cn.ts +6 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +31 -0
- package/unify.mjs +537 -0
- package/vite.config.ts +18 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { useState, useCallback } from "react";
|
|
2
|
+
import { getWorkerPool } from "../lib/worker-pool";
|
|
3
|
+
|
|
4
|
+
type Tab = "finance" | "causal" | "power";
|
|
5
|
+
|
|
6
|
+
export function StatFinancePanel() {
|
|
7
|
+
const [tab, setTab] = useState<Tab>("finance");
|
|
8
|
+
const [loading, setLoading] = useState(false);
|
|
9
|
+
const [results, setResults] = useState<any>(null);
|
|
10
|
+
|
|
11
|
+
const executeCompute = useCallback(async (fn: string, args: any[]) => {
|
|
12
|
+
setLoading(true);
|
|
13
|
+
try {
|
|
14
|
+
const pool = getWorkerPool();
|
|
15
|
+
const result = await pool.enqueue({
|
|
16
|
+
id: crypto.randomUUID(),
|
|
17
|
+
type: "compute",
|
|
18
|
+
payload: { fn, args },
|
|
19
|
+
});
|
|
20
|
+
setResults(result.result);
|
|
21
|
+
} catch (error: any) {
|
|
22
|
+
setResults({ error: error.message });
|
|
23
|
+
} finally {
|
|
24
|
+
setLoading(false);
|
|
25
|
+
}
|
|
26
|
+
}, []);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div className="rounded-2xl border border-zinc-200 bg-white shadow-sm overflow-hidden">
|
|
30
|
+
<div className="border-b border-zinc-200 px-4 py-2.5 flex items-center justify-between bg-zinc-50">
|
|
31
|
+
<span className="text-sm font-bold text-zinc-900 uppercase tracking-widest">Stat & Finance Engine</span>
|
|
32
|
+
<div className="flex gap-1">
|
|
33
|
+
{([["finance", "Finance"], ["causal", "Causal"], ["power", "NIH Power"]] as const).map(([id, label]) => (
|
|
34
|
+
<button key={id} onClick={() => setTab(id)}
|
|
35
|
+
className={`rounded-lg px-2.5 py-1 text-[10px] font-bold uppercase tracking-wider transition-all ${tab === id ? "bg-zinc-900 text-white" : "text-zinc-500 hover:bg-zinc-100"}`}>
|
|
36
|
+
{label}
|
|
37
|
+
</button>
|
|
38
|
+
))}
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<div className="p-4">
|
|
43
|
+
{tab === "finance" && <FinanceTab execute={executeCompute} loading={loading} results={results} />}
|
|
44
|
+
{tab === "causal" && <CausalTab execute={executeCompute} loading={loading} results={results} />}
|
|
45
|
+
{tab === "power" && <PowerTab execute={executeCompute} loading={loading} results={results} />}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function FinanceTab({ execute, loading, results }: { execute: (fn: string, args: any[]) => void, loading: boolean, results: any }) {
|
|
52
|
+
const [heston, setHeston] = useState({ s0: 100, k: 100, v0: 0.04, kappa: 2.0, theta: 0.04, sigma: 0.3, rho: -0.7, tau: 0.5, r: 0.05 });
|
|
53
|
+
const [sabr, setSabr] = useState({ f: 0.05, k: 0.05, t: 1.0, alpha: 0.2, beta: 0.5, rho: -0.3, nu: 0.4 });
|
|
54
|
+
|
|
55
|
+
const runHeston = () => execute("heston", [heston.s0, heston.k, heston.v0, heston.kappa, heston.theta, heston.sigma, heston.rho, heston.tau, heston.r]);
|
|
56
|
+
const runSabr = () => execute("sabr", [sabr.f, sabr.k, sabr.t, sabr.alpha, sabr.beta, sabr.rho, sabr.nu]);
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<div className="grid gap-6 md:grid-cols-2">
|
|
60
|
+
<div className="space-y-3">
|
|
61
|
+
<div className="text-xs font-bold text-zinc-900 uppercase">Heston Stochastic Volatility</div>
|
|
62
|
+
<div className="grid grid-cols-2 gap-2">
|
|
63
|
+
<Input label="S0 (Spot)" v={heston.s0} setV={v => setHeston({...heston, s0: v})} />
|
|
64
|
+
<Input label="K (Strike)" v={heston.k} setV={v => setHeston({...heston, k: v})} />
|
|
65
|
+
<Input label="v0 (Initial Var)" v={heston.v0} setV={v => setHeston({...heston, v0: v})} step={0.01} />
|
|
66
|
+
<Input label="kappa (Mean Rev)" v={heston.kappa} setV={v => setHeston({...heston, kappa: v})} step={0.1} />
|
|
67
|
+
</div>
|
|
68
|
+
<button onClick={runHeston} disabled={loading} className="w-full rounded-lg bg-zinc-900 px-4 py-2 text-xs font-bold text-white hover:bg-zinc-800 disabled:opacity-50">
|
|
69
|
+
{loading ? "Computing..." : "Compute Heston Price"}
|
|
70
|
+
</button>
|
|
71
|
+
{results && !loading && (
|
|
72
|
+
<div className="rounded-xl border border-emerald-100 bg-emerald-50 p-3">
|
|
73
|
+
<div className="text-xs font-bold text-zinc-500 uppercase mb-1">Heston Call Price</div>
|
|
74
|
+
<div className="text-lg font-mono font-bold text-emerald-700">
|
|
75
|
+
${typeof results === "number" ? results.toFixed(4) : "Computation Error"}
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
)}
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div className="space-y-3">
|
|
82
|
+
<div className="text-xs font-bold text-zinc-900 uppercase">SABR Volatility Smile</div>
|
|
83
|
+
<div className="grid grid-cols-2 gap-2">
|
|
84
|
+
<Input label="F (Forward)" v={sabr.f} setV={v => setSabr({...sabr, f: v})} step={0.005} />
|
|
85
|
+
<Input label="K (Strike)" v={sabr.k} setV={v => setSabr({...sabr, k: v})} step={0.005} />
|
|
86
|
+
<Input label="alpha (Vol level)" v={sabr.alpha} setV={v => setSabr({...sabr, alpha: v})} step={0.01} />
|
|
87
|
+
<Input label="nu (Vol-of-Vol)" v={sabr.nu} setV={v => setSabr({...sabr, nu: v})} step={0.05} />
|
|
88
|
+
</div>
|
|
89
|
+
<button onClick={runSabr} disabled={loading} className="w-full rounded-lg bg-zinc-900 px-4 py-2 text-xs font-bold text-white hover:bg-zinc-800 disabled:opacity-50">
|
|
90
|
+
{loading ? "Computing..." : "Compute SABR Vol"}
|
|
91
|
+
</button>
|
|
92
|
+
{results && !loading && (
|
|
93
|
+
<div className="rounded-xl border border-sky-100 bg-sky-50 p-3">
|
|
94
|
+
<div className="text-xs font-bold text-zinc-500 uppercase mb-1">SABR Implied Volatility</div>
|
|
95
|
+
<div className="text-lg font-mono font-bold text-sky-700">
|
|
96
|
+
{(typeof results === "number" ? results * 100 : 0).toFixed(2)}%
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function CausalTab({ execute, loading, results }: { execute: (fn: string, args: any[]) => void, loading: boolean, results: any }) {
|
|
106
|
+
const [n, setN] = useState(200);
|
|
107
|
+
const [ate, setAte] = useState(0.35);
|
|
108
|
+
|
|
109
|
+
const runDML = () => execute("dml", [[], [], []]); // Simplified for demo
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<div className="space-y-4">
|
|
113
|
+
<div className="text-xs font-bold text-zinc-900 uppercase">Double Machine Learning (DML)</div>
|
|
114
|
+
<p className="text-[11px] text-zinc-500">Estimates Average Treatment Effect (ATE) while partialing out high-dimensional confounders.</p>
|
|
115
|
+
<div className="grid gap-2 sm:grid-cols-2">
|
|
116
|
+
<Input label="Sample Size (N)" v={n} setV={setN} step={50} />
|
|
117
|
+
<Input label="Target ATE" v={ate} setV={setAte} step={0.05} />
|
|
118
|
+
</div>
|
|
119
|
+
<button onClick={runDML} disabled={loading} className="w-full rounded-lg bg-zinc-900 px-4 py-2 text-xs font-bold text-white hover:bg-zinc-800 disabled:opacity-50">
|
|
120
|
+
{loading ? "Computing..." : "Run DML"}
|
|
121
|
+
</button>
|
|
122
|
+
{results && !loading && (
|
|
123
|
+
<div className="rounded-xl border border-indigo-100 bg-indigo-50 p-3 text-xs">
|
|
124
|
+
<div className="font-bold text-zinc-500 uppercase mb-2">Double ML Results</div>
|
|
125
|
+
<div className="space-y-1">
|
|
126
|
+
<div className="flex justify-between">
|
|
127
|
+
<span className="text-zinc-500">Estimated ATE:</span>
|
|
128
|
+
<span className="font-mono font-bold text-indigo-700">{results.ate?.toFixed(4) || "N/A"}</span>
|
|
129
|
+
</div>
|
|
130
|
+
<div className="flex justify-between">
|
|
131
|
+
<span className="text-zinc-500">p-value:</span>
|
|
132
|
+
<span className="font-mono font-bold text-indigo-700">{results.pValue?.toFixed(4) || "N/A"}</span>
|
|
133
|
+
</div>
|
|
134
|
+
<div className="flex justify-between">
|
|
135
|
+
<span className="text-zinc-500">95% CI:</span>
|
|
136
|
+
<span className="font-mono font-bold text-indigo-700">[{results.ci?.[0]?.toFixed(4) || "N/A"}, {results.ci?.[1]?.toFixed(4) || "N/A"}]</span>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
)}
|
|
141
|
+
</div>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function PowerTab({ execute, loading, results }: { execute: (fn: string, args: any[]) => void, loading: boolean, results: any }) {
|
|
146
|
+
const [n, setN] = useState(400);
|
|
147
|
+
const [m, setM] = useState(20);
|
|
148
|
+
const [icc, setIcc] = useState(0.05);
|
|
149
|
+
|
|
150
|
+
const runPower = () => execute("power", [n, m, icc, 0.5]);
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<div className="space-y-4">
|
|
154
|
+
<div className="text-xs font-bold text-zinc-900 uppercase">ICC-Adjusted Sample Size (NIH Fix)</div>
|
|
155
|
+
<p className="text-[11px] text-rose-700 bg-rose-50 border border-rose-100 rounded-lg p-2">
|
|
156
|
+
<strong>Red Team Note:</strong> Without adjusting for Intraclass Correlation (ICC) in multi-site designs, power is overestimated.
|
|
157
|
+
</p>
|
|
158
|
+
<div className="grid gap-2 sm:grid-cols-3">
|
|
159
|
+
<Input label="Nominal N" v={n} setV={setN} step={50} />
|
|
160
|
+
<Input label="Cluster Size (m)" v={m} setV={setM} step={5} />
|
|
161
|
+
<Input label="ICC (rho)" v={icc} setV={setIcc} step={0.01} max={1} />
|
|
162
|
+
</div>
|
|
163
|
+
<button onClick={runPower} disabled={loading} className="w-full rounded-lg bg-zinc-900 px-4 py-2 text-xs font-bold text-white hover:bg-zinc-800 disabled:opacity-50">
|
|
164
|
+
{loading ? "Computing..." : "Calculate Power"}
|
|
165
|
+
</button>
|
|
166
|
+
{results && !loading && (
|
|
167
|
+
<div className="grid gap-3 sm:grid-cols-2">
|
|
168
|
+
<div className="rounded-xl border border-zinc-200 p-3">
|
|
169
|
+
<div className="text-[10px] uppercase text-zinc-400 font-bold mb-1">Effective N</div>
|
|
170
|
+
<div className="text-lg font-mono font-bold text-zinc-900">{results.nEffective?.toFixed(1) || "N/A"}</div>
|
|
171
|
+
</div>
|
|
172
|
+
<div className="rounded-xl border border-zinc-200 p-3">
|
|
173
|
+
<div className="text-[10px] uppercase text-zinc-400 font-bold mb-1">Design Effect (DEFF)</div>
|
|
174
|
+
<div className="text-lg font-mono font-bold text-zinc-900">{results.deff?.toFixed(2) || "N/A"}</div>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
)}
|
|
178
|
+
</div>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function Input({ label, v, setV, step = 1, max }: { label: string, v: number, setV: (n: number) => void, step?: number, max?: number }) {
|
|
183
|
+
return (
|
|
184
|
+
<label className="block">
|
|
185
|
+
<span className="text-[10px] font-bold text-zinc-400 uppercase">{label}</span>
|
|
186
|
+
<input type="number" value={v} step={step} max={max} onChange={e => setV(Number(e.target.value))}
|
|
187
|
+
className="mt-0.5 w-full rounded-lg border border-zinc-200 bg-zinc-50 px-2 py-1 text-xs font-mono" />
|
|
188
|
+
</label>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { newSessionSeed, type WilliamsPersona } from "../lib/williams-style";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
persona: WilliamsPersona;
|
|
6
|
+
onReseed: (seed: number) => void;
|
|
7
|
+
/** Legacy/optional callback so existing callers can react to persona changes. */
|
|
8
|
+
onPersonaChange?: (p: WilliamsPersona) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function StylePersonaPanel({ persona, onReseed }: Props) {
|
|
12
|
+
const [pinned, setPinned] = useState(false);
|
|
13
|
+
const [expanded, setExpanded] = useState(false);
|
|
14
|
+
const [seedInput, setSeedInput] = useState(persona.seed);
|
|
15
|
+
|
|
16
|
+
function reroll() {
|
|
17
|
+
if (pinned) return;
|
|
18
|
+
const seed = newSessionSeed();
|
|
19
|
+
setSeedInput(seed);
|
|
20
|
+
onReseed(seed);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function applyManualSeed(s: number) {
|
|
24
|
+
setSeedInput(s);
|
|
25
|
+
onReseed(s);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<section className="rounded-2xl border border-zinc-200 bg-white shadow-sm">
|
|
30
|
+
<button
|
|
31
|
+
onClick={() => setExpanded(!expanded)}
|
|
32
|
+
className="flex w-full items-center justify-between px-5 py-3 text-left"
|
|
33
|
+
>
|
|
34
|
+
<div className="flex items-center gap-3">
|
|
35
|
+
<div className="grid h-8 w-8 place-items-center rounded-lg bg-gradient-to-br from-violet-100 to-indigo-100 text-lg">✍️</div>
|
|
36
|
+
<div>
|
|
37
|
+
<div className="flex items-center gap-2">
|
|
38
|
+
<div className="text-sm font-bold text-zinc-900">Style Persona: <span className="text-indigo-700">{persona.archetype.name}</span></div>
|
|
39
|
+
<span className={`rounded px-1.5 py-0.5 text-[10px] font-bold ${
|
|
40
|
+
persona.rarityTier === "Legendary" ? "bg-amber-100 text-amber-800" :
|
|
41
|
+
persona.rarityTier === "Epic" ? "bg-fuchsia-100 text-fuchsia-800" :
|
|
42
|
+
persona.rarityTier === "Rare" ? "bg-sky-100 text-sky-800" :
|
|
43
|
+
persona.rarityTier === "Uncommon" ? "bg-emerald-100 text-emerald-800" :
|
|
44
|
+
"bg-zinc-100 text-zinc-600"
|
|
45
|
+
}`}>{persona.rarityTier} ({persona.rarityPercent}%)</span>
|
|
46
|
+
</div>
|
|
47
|
+
<div className="text-xs text-zinc-500">{persona.archetype.desc}</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
<div className="flex items-center gap-2">
|
|
51
|
+
<span className="rounded bg-zinc-100 px-2 py-1 font-mono text-[10px] text-zinc-600">seed {persona.seed}</span>
|
|
52
|
+
<span className="text-zinc-400">{expanded ? "−" : "+"}</span>
|
|
53
|
+
</div>
|
|
54
|
+
</button>
|
|
55
|
+
|
|
56
|
+
{expanded && (
|
|
57
|
+
<div className="border-t border-zinc-100 px-5 py-4">
|
|
58
|
+
<div className="mb-4 flex flex-wrap items-center gap-2">
|
|
59
|
+
<button
|
|
60
|
+
onClick={reroll}
|
|
61
|
+
disabled={pinned}
|
|
62
|
+
className="rounded-lg bg-indigo-600 px-3 py-1.5 text-xs font-bold text-white hover:bg-indigo-700 disabled:opacity-40"
|
|
63
|
+
>
|
|
64
|
+
Reroll persona
|
|
65
|
+
</button>
|
|
66
|
+
<label className="flex items-center gap-2 text-xs font-semibold text-zinc-600">
|
|
67
|
+
<input type="checkbox" checked={pinned} onChange={(e) => setPinned(e.target.checked)} />
|
|
68
|
+
Pin seed
|
|
69
|
+
</label>
|
|
70
|
+
<label className="flex items-center gap-2 text-xs text-zinc-500">
|
|
71
|
+
Custom seed:
|
|
72
|
+
<input
|
|
73
|
+
type="number"
|
|
74
|
+
value={seedInput}
|
|
75
|
+
onChange={(e) => applyManualSeed(Number(e.target.value) >>> 0)}
|
|
76
|
+
className="w-28 rounded border border-zinc-300 px-2 py-1 font-mono text-xs"
|
|
77
|
+
/>
|
|
78
|
+
</label>
|
|
79
|
+
<button
|
|
80
|
+
onClick={() => navigator.clipboard.writeText(String(persona.seed))}
|
|
81
|
+
className="rounded-lg border border-zinc-200 bg-white px-3 py-1.5 text-xs font-bold text-zinc-700 hover:bg-zinc-50"
|
|
82
|
+
title="Export this persona by copying its seed"
|
|
83
|
+
>
|
|
84
|
+
Export
|
|
85
|
+
</button>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<div className="mb-4">
|
|
89
|
+
<div className="text-[10px] font-bold uppercase tracking-[0.2em] text-zinc-400">19 stylistic dimensions</div>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
|
|
93
|
+
{persona.dimensionLabels.map((dim) => (
|
|
94
|
+
<div key={dim.name} className="rounded-xl border border-zinc-100 bg-zinc-50 p-3">
|
|
95
|
+
<div className="flex items-center justify-between">
|
|
96
|
+
<div className="text-xs font-bold text-zinc-900">{dim.name}</div>
|
|
97
|
+
<div className="rounded bg-indigo-50 px-1.5 py-0.5 font-mono text-[9px] text-indigo-700">{dim.lesson}</div>
|
|
98
|
+
</div>
|
|
99
|
+
<div className="mt-2 flex items-center gap-2">
|
|
100
|
+
<span className="w-16 text-right text-[9px] text-zinc-500 leading-tight">{dim.lowLabel}</span>
|
|
101
|
+
<div className="relative h-2 flex-1 overflow-hidden rounded-full bg-zinc-200">
|
|
102
|
+
<div
|
|
103
|
+
className="absolute top-0 left-0 h-full rounded-full bg-gradient-to-r from-sky-500 to-indigo-500"
|
|
104
|
+
style={{ width: `${dim.value * 100}%` }}
|
|
105
|
+
/>
|
|
106
|
+
<div
|
|
107
|
+
className="absolute top-[-2px] h-3 w-1 rounded-full bg-zinc-900"
|
|
108
|
+
style={{ left: `calc(${dim.value * 100}% - 2px)` }}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
<span className="w-16 text-[9px] text-zinc-500 leading-tight">{dim.highLabel}</span>
|
|
112
|
+
</div>
|
|
113
|
+
<div className="mt-1 text-right font-mono text-[10px] text-zinc-400">{dim.value.toFixed(2)}</div>
|
|
114
|
+
</div>
|
|
115
|
+
))}
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<details className="mt-4">
|
|
119
|
+
<summary className="cursor-pointer text-xs font-bold text-zinc-600 hover:text-zinc-900">View generated style instructions</summary>
|
|
120
|
+
<pre className="mt-2 max-h-64 overflow-auto whitespace-pre-wrap rounded-xl border border-zinc-200 bg-white p-4 font-mono text-xs leading-relaxed text-zinc-800">
|
|
121
|
+
{persona.systemPromptFragment}
|
|
122
|
+
</pre>
|
|
123
|
+
</details>
|
|
124
|
+
</div>
|
|
125
|
+
)}
|
|
126
|
+
</section>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { useAppState } from "../lib/app-state";
|
|
3
|
+
import {
|
|
4
|
+
OMEGA_TEMPLATES,
|
|
5
|
+
STYLE_OVERRIDES,
|
|
6
|
+
SELECTION_MATRIX,
|
|
7
|
+
unifiedHeaderBlock,
|
|
8
|
+
buildTemplatePrompt,
|
|
9
|
+
type OmegaTemplate,
|
|
10
|
+
type OmegaSection,
|
|
11
|
+
} from "../lib/omega-templates";
|
|
12
|
+
|
|
13
|
+
function uid() { return "tpl-" + Math.random().toString(36).slice(2, 9); }
|
|
14
|
+
|
|
15
|
+
export function TemplatesPage() {
|
|
16
|
+
const { settings, setSetting, templates, addTemplate, deleteTemplate, sscpReceipt } = useAppState();
|
|
17
|
+
const [preview, setPreview] = useState<string>(settings.activeTemplateId);
|
|
18
|
+
const [tab, setTab] = useState<"masters" | "overrides" | "matrix" | "custom">("masters");
|
|
19
|
+
|
|
20
|
+
// Custom template builder
|
|
21
|
+
const [draft, setDraft] = useState<OmegaTemplate>({
|
|
22
|
+
id: uid(), name: "", tagline: "", replaces: "Custom", sections: [], styleHooks: [], custom: true,
|
|
23
|
+
});
|
|
24
|
+
const [secDraft, setSecDraft] = useState<OmegaSection>({ id: "§1", title: "", hint: "", pages: "" });
|
|
25
|
+
|
|
26
|
+
const selected = templates.find(t => t.id === preview) ?? OMEGA_TEMPLATES[0];
|
|
27
|
+
const customTemplates = templates.filter(t => t.custom);
|
|
28
|
+
|
|
29
|
+
function addSection() {
|
|
30
|
+
if (!secDraft.title.trim()) return;
|
|
31
|
+
setDraft(d => ({ ...d, sections: [...d.sections, { ...secDraft }] }));
|
|
32
|
+
setSecDraft({ id: `§${draft.sections.length + 2}`, title: "", hint: "", pages: "" });
|
|
33
|
+
}
|
|
34
|
+
function saveDraft() {
|
|
35
|
+
if (!draft.name.trim() || draft.sections.length === 0) return;
|
|
36
|
+
addTemplate({ ...draft, id: draft.id || uid(), custom: true });
|
|
37
|
+
setDraft({ id: uid(), name: "", tagline: "", replaces: "Custom", sections: [], styleHooks: [], custom: true });
|
|
38
|
+
setSecDraft({ id: "§1", title: "", hint: "", pages: "" });
|
|
39
|
+
setTab("masters");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const headerPreview = unifiedHeaderBlock({
|
|
43
|
+
title: "[REPORT TITLE — ACTION-ORIENTED]",
|
|
44
|
+
audience: "[CLIENT/AUDIENCE]",
|
|
45
|
+
date: new Date().toLocaleDateString("en-US"),
|
|
46
|
+
classification: "INTERNAL",
|
|
47
|
+
sscpHash: sscpReceipt ? sscpReceipt.stateRootHash.slice(0, 16) + "…" : "[computed at runtime]",
|
|
48
|
+
evidenceTier: sscpReceipt ? sscpReceipt.evidenceTier : "TOOL",
|
|
49
|
+
model: settings.activeTemplateId ? "Gemma 4 31B / Gemini" : "[model/version]",
|
|
50
|
+
cutoff: "2026",
|
|
51
|
+
styleMode: settings.styleMode,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className="bg-zinc-50 pb-10">
|
|
56
|
+
<div className="mx-auto max-w-6xl space-y-5 px-4 py-6">
|
|
57
|
+
{/* Header */}
|
|
58
|
+
<section className="rounded-2xl border border-zinc-200 bg-white p-5 shadow-sm">
|
|
59
|
+
<div className="flex flex-wrap items-start justify-between gap-3">
|
|
60
|
+
<div>
|
|
61
|
+
<div className="text-xs font-bold uppercase tracking-[0.2em] text-indigo-600">OMEGA Templates</div>
|
|
62
|
+
<h1 className="mt-1 text-2xl font-bold tracking-tight text-zinc-900">7 master templates · 40 legacy overrides · custom builder</h1>
|
|
63
|
+
<p className="mt-2 max-w-3xl text-sm text-zinc-600">
|
|
64
|
+
Templates inject a section skeleton + style-modulation hooks into synthesis. The anti-hallucination stack
|
|
65
|
+
(constraints, temporal anchor, sanitizer, SSCP receipt) still wraps every stage.
|
|
66
|
+
</p>
|
|
67
|
+
</div>
|
|
68
|
+
<label className="flex items-center gap-2 rounded-xl border border-indigo-200 bg-indigo-50 px-3 py-2 text-sm font-semibold text-indigo-800">
|
|
69
|
+
<input type="checkbox" checked={settings.templateEnabled} onChange={e => setSetting("templateEnabled", e.target.checked)} className="h-4 w-4 rounded" />
|
|
70
|
+
Apply template to outputs
|
|
71
|
+
</label>
|
|
72
|
+
</div>
|
|
73
|
+
{/* Active template selector */}
|
|
74
|
+
<div className="mt-4 grid gap-3 sm:grid-cols-2">
|
|
75
|
+
<label className="text-xs font-semibold text-zinc-600">
|
|
76
|
+
Active template
|
|
77
|
+
<select value={settings.activeTemplateId} onChange={e => { setSetting("activeTemplateId", e.target.value); setPreview(e.target.value); }}
|
|
78
|
+
className="mt-1 w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm">
|
|
79
|
+
{templates.map(t => <option key={t.id} value={t.id}>{t.name}{t.custom ? " (custom)" : ""} — {t.tagline}</option>)}
|
|
80
|
+
</select>
|
|
81
|
+
</label>
|
|
82
|
+
<label className="text-xs font-semibold text-zinc-600">
|
|
83
|
+
Style mode (override token)
|
|
84
|
+
<select value={settings.styleMode} onChange={e => setSetting("styleMode", e.target.value)}
|
|
85
|
+
className="mt-1 w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm">
|
|
86
|
+
<option value="OMEGA-DEFAULT">OMEGA-DEFAULT</option>
|
|
87
|
+
{STYLE_OVERRIDES.map(o => <option key={o.token} value={o.token}>{o.token} — {o.legacy}</option>)}
|
|
88
|
+
</select>
|
|
89
|
+
</label>
|
|
90
|
+
</div>
|
|
91
|
+
</section>
|
|
92
|
+
|
|
93
|
+
{/* Unified header block preview */}
|
|
94
|
+
<section className="rounded-2xl border border-zinc-200 bg-zinc-950 p-4 shadow-sm">
|
|
95
|
+
<div className="mb-2 text-xs font-bold uppercase tracking-wider text-emerald-400">Unified header block (injected into every templated output)</div>
|
|
96
|
+
<pre className="overflow-x-auto whitespace-pre font-mono text-[11px] leading-snug text-emerald-200">{headerPreview}</pre>
|
|
97
|
+
</section>
|
|
98
|
+
|
|
99
|
+
{/* Tabs */}
|
|
100
|
+
<div className="flex flex-wrap gap-1 rounded-xl border border-zinc-200 bg-white p-1 w-fit">
|
|
101
|
+
{([["masters", "7 Masters"], ["overrides", "40 Overrides"], ["matrix", "Decision Matrix"], ["custom", "Custom Builder"]] as const).map(([id, label]) => (
|
|
102
|
+
<button key={id} onClick={() => setTab(id)} className={`rounded-lg px-3 py-1.5 text-xs font-semibold ${tab === id ? "bg-zinc-900 text-white" : "text-zinc-600 hover:bg-zinc-100"}`}>{label}</button>
|
|
103
|
+
))}
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
{/* Masters */}
|
|
107
|
+
{tab === "masters" && (
|
|
108
|
+
<div className="grid gap-4 lg:grid-cols-[1fr_1.4fr]">
|
|
109
|
+
<div className="space-y-2">
|
|
110
|
+
{OMEGA_TEMPLATES.map(t => (
|
|
111
|
+
<button key={t.id} onClick={() => setPreview(t.id)}
|
|
112
|
+
className={`block w-full rounded-xl border p-3 text-left transition-colors ${preview === t.id ? "border-indigo-300 bg-indigo-50" : "border-zinc-200 bg-white hover:bg-zinc-50"}`}>
|
|
113
|
+
<div className="flex items-center justify-between">
|
|
114
|
+
<span className="text-sm font-bold text-zinc-900">{t.name}</span>
|
|
115
|
+
<span className="text-[10px] text-zinc-400">{t.sections.length} sections</span>
|
|
116
|
+
</div>
|
|
117
|
+
<div className="text-xs text-indigo-700">{t.tagline}</div>
|
|
118
|
+
<div className="mt-1 text-[11px] text-zinc-500 line-clamp-1">Replaces: {t.replaces}</div>
|
|
119
|
+
</button>
|
|
120
|
+
))}
|
|
121
|
+
</div>
|
|
122
|
+
<TemplateDetail t={selected} styleMode={settings.styleMode} />
|
|
123
|
+
</div>
|
|
124
|
+
)}
|
|
125
|
+
|
|
126
|
+
{/* Overrides */}
|
|
127
|
+
{tab === "overrides" && (
|
|
128
|
+
<section className="rounded-2xl border border-zinc-200 bg-white shadow-sm overflow-hidden">
|
|
129
|
+
<div className="border-b border-zinc-200 px-4 py-2.5 text-sm font-bold text-zinc-900">Style Override Registry — 40 legacy templates</div>
|
|
130
|
+
<div className="max-h-[28rem] overflow-y-auto">
|
|
131
|
+
<table className="w-full text-xs">
|
|
132
|
+
<thead className="sticky top-0 bg-zinc-50">
|
|
133
|
+
<tr className="border-b border-zinc-200">
|
|
134
|
+
<th className="px-3 py-2 text-left font-semibold text-zinc-500">Token</th>
|
|
135
|
+
<th className="px-3 py-2 text-left font-semibold text-zinc-500">Legacy template</th>
|
|
136
|
+
<th className="px-3 py-2 text-left font-semibold text-zinc-500">Maps to</th>
|
|
137
|
+
<th className="px-3 py-2 text-left font-semibold text-zinc-500">Preservation hooks</th>
|
|
138
|
+
<th className="px-3 py-2"></th>
|
|
139
|
+
</tr>
|
|
140
|
+
</thead>
|
|
141
|
+
<tbody className="divide-y divide-zinc-100">
|
|
142
|
+
{STYLE_OVERRIDES.map(o => (
|
|
143
|
+
<tr key={o.token} className="hover:bg-zinc-50">
|
|
144
|
+
<td className="whitespace-nowrap px-3 py-2 font-mono font-bold text-indigo-700">{o.token}</td>
|
|
145
|
+
<td className="px-3 py-2 text-zinc-900">{o.legacy}</td>
|
|
146
|
+
<td className="whitespace-nowrap px-3 py-2 font-mono text-[10px] text-emerald-700">{o.mapsTo}</td>
|
|
147
|
+
<td className="px-3 py-2 text-zinc-600">{o.hooks}</td>
|
|
148
|
+
<td className="px-3 py-2">
|
|
149
|
+
<button onClick={() => setSetting("styleMode", o.token)} className="rounded bg-zinc-900 px-2 py-1 text-[10px] font-bold text-white hover:bg-zinc-700">Use</button>
|
|
150
|
+
</td>
|
|
151
|
+
</tr>
|
|
152
|
+
))}
|
|
153
|
+
</tbody>
|
|
154
|
+
</table>
|
|
155
|
+
</div>
|
|
156
|
+
</section>
|
|
157
|
+
)}
|
|
158
|
+
|
|
159
|
+
{/* Matrix */}
|
|
160
|
+
{tab === "matrix" && (
|
|
161
|
+
<section className="rounded-2xl border border-zinc-200 bg-white shadow-sm overflow-hidden">
|
|
162
|
+
<div className="border-b border-zinc-200 px-4 py-2.5 text-sm font-bold text-zinc-900">Selection Decision Matrix</div>
|
|
163
|
+
<table className="w-full text-sm">
|
|
164
|
+
<thead className="bg-zinc-50">
|
|
165
|
+
<tr className="border-b border-zinc-200">
|
|
166
|
+
<th className="px-4 py-2 text-left font-semibold text-zinc-500">If your task is…</th>
|
|
167
|
+
<th className="px-4 py-2 text-left font-semibold text-zinc-500">Default template</th>
|
|
168
|
+
<th className="px-4 py-2 text-left font-semibold text-zinc-500">Override if…</th>
|
|
169
|
+
</tr>
|
|
170
|
+
</thead>
|
|
171
|
+
<tbody className="divide-y divide-zinc-100">
|
|
172
|
+
{SELECTION_MATRIX.map(r => (
|
|
173
|
+
<tr key={r.task} className="hover:bg-zinc-50">
|
|
174
|
+
<td className="px-4 py-2.5 text-zinc-800">"{r.task}"</td>
|
|
175
|
+
<td className="px-4 py-2.5"><span className="rounded bg-indigo-50 px-2 py-0.5 font-mono text-xs font-bold text-indigo-700">{r.def}</span></td>
|
|
176
|
+
<td className="px-4 py-2.5 text-zinc-600">{r.override}</td>
|
|
177
|
+
</tr>
|
|
178
|
+
))}
|
|
179
|
+
</tbody>
|
|
180
|
+
</table>
|
|
181
|
+
</section>
|
|
182
|
+
)}
|
|
183
|
+
|
|
184
|
+
{/* Custom builder */}
|
|
185
|
+
{tab === "custom" && (
|
|
186
|
+
<div className="grid gap-4 lg:grid-cols-2">
|
|
187
|
+
<section className="rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm space-y-3">
|
|
188
|
+
<h2 className="text-sm font-bold text-zinc-900">Build a custom template</h2>
|
|
189
|
+
<input value={draft.name} onChange={e => setDraft(d => ({ ...d, name: e.target.value }))} placeholder="Template name (e.g. OMEGA-LEGAL-MEMO)"
|
|
190
|
+
className="w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm" />
|
|
191
|
+
<input value={draft.tagline} onChange={e => setDraft(d => ({ ...d, tagline: e.target.value }))} placeholder="Tagline (e.g. Litigation risk memo)"
|
|
192
|
+
className="w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm" />
|
|
193
|
+
<input value={draft.styleHooks.join(", ")} onChange={e => setDraft(d => ({ ...d, styleHooks: e.target.value.split(",").map(s => s.trim()).filter(Boolean) }))}
|
|
194
|
+
placeholder="Style hooks, comma-separated"
|
|
195
|
+
className="w-full rounded-xl border border-zinc-300 px-3 py-2 text-sm" />
|
|
196
|
+
|
|
197
|
+
<div className="rounded-xl border border-zinc-200 bg-zinc-50 p-3 space-y-2">
|
|
198
|
+
<div className="text-xs font-bold text-zinc-700">Add section</div>
|
|
199
|
+
<div className="grid grid-cols-[60px_1fr] gap-2">
|
|
200
|
+
<input value={secDraft.id} onChange={e => setSecDraft(s => ({ ...s, id: e.target.value }))} placeholder="§1" className="rounded-lg border border-zinc-300 px-2 py-1.5 text-sm" />
|
|
201
|
+
<input value={secDraft.title} onChange={e => setSecDraft(s => ({ ...s, title: e.target.value }))} placeholder="Section title" className="rounded-lg border border-zinc-300 px-2 py-1.5 text-sm" />
|
|
202
|
+
</div>
|
|
203
|
+
<input value={secDraft.hint} onChange={e => setSecDraft(s => ({ ...s, hint: e.target.value }))} placeholder="What goes here (hint)" className="w-full rounded-lg border border-zinc-300 px-2 py-1.5 text-sm" />
|
|
204
|
+
<input value={secDraft.pages} onChange={e => setSecDraft(s => ({ ...s, pages: e.target.value }))} placeholder="Pages (e.g. 1-2 pages)" className="w-full rounded-lg border border-zinc-300 px-2 py-1.5 text-sm" />
|
|
205
|
+
<button onClick={addSection} className="rounded-lg bg-indigo-600 px-3 py-1.5 text-xs font-bold text-white hover:bg-indigo-700">+ Add section</button>
|
|
206
|
+
</div>
|
|
207
|
+
|
|
208
|
+
{draft.sections.length > 0 && (
|
|
209
|
+
<div className="rounded-xl border border-zinc-200 p-3 space-y-1">
|
|
210
|
+
<div className="text-xs font-bold text-zinc-700">{draft.sections.length} sections</div>
|
|
211
|
+
{draft.sections.map((s, i) => (
|
|
212
|
+
<div key={i} className="flex items-center justify-between text-xs">
|
|
213
|
+
<span className="text-zinc-700"><span className="font-mono text-indigo-700">{s.id}</span> {s.title}</span>
|
|
214
|
+
<button onClick={() => setDraft(d => ({ ...d, sections: d.sections.filter((_, j) => j !== i) }))} className="text-rose-500 hover:text-rose-700">remove</button>
|
|
215
|
+
</div>
|
|
216
|
+
))}
|
|
217
|
+
</div>
|
|
218
|
+
)}
|
|
219
|
+
|
|
220
|
+
<button onClick={saveDraft} disabled={!draft.name.trim() || draft.sections.length === 0}
|
|
221
|
+
className="w-full rounded-xl bg-emerald-600 px-4 py-2.5 text-sm font-bold text-white hover:bg-emerald-700 disabled:opacity-40">
|
|
222
|
+
Save custom template
|
|
223
|
+
</button>
|
|
224
|
+
</section>
|
|
225
|
+
|
|
226
|
+
<section className="rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm">
|
|
227
|
+
<h2 className="mb-3 text-sm font-bold text-zinc-900">Saved custom templates ({customTemplates.length})</h2>
|
|
228
|
+
{customTemplates.length === 0 ? (
|
|
229
|
+
<div className="text-sm text-zinc-400 py-8 text-center">No custom templates yet. Build one on the left — it persists in localStorage and appears in the active-template selector.</div>
|
|
230
|
+
) : (
|
|
231
|
+
<div className="space-y-2">
|
|
232
|
+
{customTemplates.map(t => (
|
|
233
|
+
<div key={t.id} className="rounded-xl border border-zinc-200 p-3">
|
|
234
|
+
<div className="flex items-center justify-between">
|
|
235
|
+
<div>
|
|
236
|
+
<div className="text-sm font-bold text-zinc-900">{t.name}</div>
|
|
237
|
+
<div className="text-xs text-indigo-700">{t.tagline} · {t.sections.length} sections</div>
|
|
238
|
+
</div>
|
|
239
|
+
<div className="flex gap-2">
|
|
240
|
+
<button onClick={() => { setPreview(t.id); setTab("masters"); }} className="rounded bg-zinc-100 px-2 py-1 text-[10px] font-bold text-zinc-700 hover:bg-zinc-200">Preview</button>
|
|
241
|
+
<button onClick={() => deleteTemplate(t.id)} className="rounded bg-rose-50 px-2 py-1 text-[10px] font-bold text-rose-700 hover:bg-rose-100">Delete</button>
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
))}
|
|
246
|
+
</div>
|
|
247
|
+
)}
|
|
248
|
+
</section>
|
|
249
|
+
</div>
|
|
250
|
+
)}
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function TemplateDetail({ t, styleMode }: { t: OmegaTemplate; styleMode: string }) {
|
|
257
|
+
const [showPrompt, setShowPrompt] = useState(false);
|
|
258
|
+
return (
|
|
259
|
+
<div className="rounded-2xl border border-zinc-200 bg-white p-5 shadow-sm">
|
|
260
|
+
<div className="flex items-center justify-between">
|
|
261
|
+
<div>
|
|
262
|
+
<h2 className="text-lg font-bold text-zinc-900">{t.name}</h2>
|
|
263
|
+
<p className="text-sm text-indigo-700">{t.tagline}</p>
|
|
264
|
+
</div>
|
|
265
|
+
{t.custom && <span className="rounded-full bg-violet-100 px-2 py-0.5 text-[10px] font-bold text-violet-800">CUSTOM</span>}
|
|
266
|
+
</div>
|
|
267
|
+
<p className="mt-1 text-xs text-zinc-500">Replaces: {t.replaces}</p>
|
|
268
|
+
|
|
269
|
+
<div className="mt-4 space-y-2">
|
|
270
|
+
{t.sections.map(s => (
|
|
271
|
+
<div key={s.id} className="rounded-xl border border-zinc-100 bg-zinc-50 p-3">
|
|
272
|
+
<div className="flex items-center justify-between">
|
|
273
|
+
<span className="text-sm font-bold text-zinc-900"><span className="font-mono text-indigo-700">{s.id}</span> {s.title}</span>
|
|
274
|
+
{s.pages && <span className="text-[10px] text-zinc-400">{s.pages}</span>}
|
|
275
|
+
</div>
|
|
276
|
+
<p className="mt-1 text-xs text-zinc-600">{s.hint}</p>
|
|
277
|
+
</div>
|
|
278
|
+
))}
|
|
279
|
+
</div>
|
|
280
|
+
|
|
281
|
+
{t.styleHooks.length > 0 && (
|
|
282
|
+
<div className="mt-4">
|
|
283
|
+
<div className="text-[10px] font-bold uppercase tracking-wider text-zinc-400 mb-1">Style modulation hooks</div>
|
|
284
|
+
<div className="flex flex-wrap gap-1">
|
|
285
|
+
{t.styleHooks.map(h => <span key={h} className="rounded-full bg-zinc-100 px-2 py-0.5 text-[11px] text-zinc-700">{h}</span>)}
|
|
286
|
+
</div>
|
|
287
|
+
</div>
|
|
288
|
+
)}
|
|
289
|
+
|
|
290
|
+
<button onClick={() => setShowPrompt(!showPrompt)} className="mt-4 text-xs font-bold text-indigo-600 hover:text-indigo-800">
|
|
291
|
+
{showPrompt ? "Hide" : "Show"} injected synthesis prompt
|
|
292
|
+
</button>
|
|
293
|
+
{showPrompt && (
|
|
294
|
+
<pre className="mt-2 max-h-64 overflow-auto whitespace-pre-wrap rounded-xl border border-zinc-200 bg-zinc-950 p-3 font-mono text-[11px] leading-relaxed text-emerald-100">
|
|
295
|
+
{buildTemplatePrompt(t, styleMode)}
|
|
296
|
+
</pre>
|
|
297
|
+
)}
|
|
298
|
+
</div>
|
|
299
|
+
);
|
|
300
|
+
}
|