principles-disciple 1.13.0 → 1.14.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/ui/src/styles.css CHANGED
@@ -1702,3 +1702,319 @@ pre {
1702
1702
  grid-template-columns: 1fr !important;
1703
1703
  }
1704
1704
  }
1705
+
1706
+ /* ==========================================================================
1707
+ Thinking Models Page — New styles for v1.10 polish pass
1708
+ ========================================================================== */
1709
+
1710
+ /* Typography utility classes */
1711
+ .text-xs { font-size: var(--text-xs, 0.65rem); }
1712
+ .text-sm { font-size: var(--text-sm, 0.7rem); }
1713
+ .text-base { font-size: var(--text-base, 0.75rem); }
1714
+ .text-lg { font-size: var(--text-lg, 0.8rem); }
1715
+ .text-xl { font-size: var(--text-xl, 0.85rem); }
1716
+ .text-semibold { font-weight: 600; }
1717
+ .text-error { color: var(--error); }
1718
+
1719
+ /* Section title (replaces inline fontWeight + fontSize on h3/h4) */
1720
+ .section-title {
1721
+ font-size: var(--text-xl, 0.85rem);
1722
+ font-weight: 600;
1723
+ color: var(--text-primary);
1724
+ margin-bottom: var(--space-2);
1725
+ }
1726
+
1727
+ /* Search + Sort + Filter controls */
1728
+ .sort-button {
1729
+ display: flex;
1730
+ align-items: center;
1731
+ gap: var(--space-1);
1732
+ padding: 6px 10px;
1733
+ border: 1px solid var(--border);
1734
+ border-radius: 6px;
1735
+ background: var(--bg-panel, var(--bg-elevated));
1736
+ color: var(--text-secondary);
1737
+ cursor: pointer;
1738
+ font-size: var(--text-base);
1739
+ transition: all var(--duration-fast) var(--ease-out);
1740
+ }
1741
+
1742
+ .sort-button:hover {
1743
+ border-color: var(--border-hover);
1744
+ color: var(--text-primary);
1745
+ }
1746
+
1747
+ .filter-button {
1748
+ padding: 3px 8px;
1749
+ border: 1px solid var(--border);
1750
+ border-radius: 4px;
1751
+ background: transparent;
1752
+ color: var(--text-secondary);
1753
+ cursor: pointer;
1754
+ font-size: var(--text-sm);
1755
+ transition: all var(--duration-fast) var(--ease-out);
1756
+ }
1757
+
1758
+ .filter-button:hover {
1759
+ border-color: var(--border-hover);
1760
+ }
1761
+
1762
+ .filter-button.active {
1763
+ border-color: var(--accent);
1764
+ background: rgba(91, 139, 160, 0.15);
1765
+ color: var(--accent);
1766
+ }
1767
+
1768
+ /* Compare button bar */
1769
+ .compare-bar {
1770
+ display: flex;
1771
+ justify-content: space-between;
1772
+ align-items: center;
1773
+ padding: var(--space-2) var(--space-3);
1774
+ margin-bottom: var(--space-2);
1775
+ background: rgba(91, 139, 160, 0.08);
1776
+ border-radius: 6px;
1777
+ border: 1px solid var(--border);
1778
+ }
1779
+
1780
+ .compare-button {
1781
+ display: flex;
1782
+ align-items: center;
1783
+ gap: var(--space-1);
1784
+ padding: 4px 12px;
1785
+ border: none;
1786
+ border-radius: 4px;
1787
+ background: var(--accent);
1788
+ color: #fff;
1789
+ cursor: pointer;
1790
+ font-size: var(--text-base);
1791
+ font-weight: 600;
1792
+ transition: background var(--duration-fast) var(--ease-out);
1793
+ }
1794
+
1795
+ .compare-button:hover {
1796
+ background: var(--accent-hover);
1797
+ }
1798
+
1799
+ /* Model list button (replaces inline style button) */
1800
+ .model-list-button {
1801
+ flex: 1;
1802
+ display: flex;
1803
+ justify-content: space-between;
1804
+ align-items: center;
1805
+ background: none;
1806
+ border: none;
1807
+ cursor: pointer;
1808
+ padding: 0;
1809
+ color: inherit;
1810
+ text-align: left;
1811
+ }
1812
+
1813
+ .hits-count {
1814
+ font-weight: 600;
1815
+ font-size: var(--text-xl, 0.85rem);
1816
+ }
1817
+
1818
+ .scenario-ellipsis {
1819
+ overflow: hidden;
1820
+ text-overflow: ellipsis;
1821
+ white-space: nowrap;
1822
+ max-width: 180px;
1823
+ display: block;
1824
+ }
1825
+
1826
+ /* Code blocks for trigger / anti-pattern */
1827
+ .code-block {
1828
+ font-size: var(--text-base);
1829
+ white-space: pre-wrap;
1830
+ word-break: break-word;
1831
+ padding: var(--space-2) var(--space-3);
1832
+ border-radius: 6px;
1833
+ display: block;
1834
+ line-height: 1.5;
1835
+ font-family: var(--font-mono);
1836
+ }
1837
+
1838
+ .code-block-trigger {
1839
+ background: var(--bg-sunken);
1840
+ }
1841
+
1842
+ .code-block-antipattern {
1843
+ background: rgba(220, 53, 69, 0.08);
1844
+ color: var(--error);
1845
+ }
1846
+
1847
+ /* Event context helpers */
1848
+ .event-context-tool {
1849
+ font-size: var(--text-sm);
1850
+ color: var(--text-secondary);
1851
+ display: flex;
1852
+ align-items: center;
1853
+ gap: var(--space-1);
1854
+ }
1855
+
1856
+ .event-context-pain {
1857
+ font-size: var(--text-sm);
1858
+ color: var(--error);
1859
+ display: flex;
1860
+ align-items: center;
1861
+ gap: var(--space-1);
1862
+ }
1863
+
1864
+ .event-context-principle {
1865
+ font-size: var(--text-sm);
1866
+ color: var(--info);
1867
+ display: flex;
1868
+ align-items: center;
1869
+ gap: var(--space-1);
1870
+ }
1871
+
1872
+ .matched-pattern {
1873
+ font-size: var(--text-xs);
1874
+ color: var(--text-secondary);
1875
+ background: var(--bg-sunken);
1876
+ padding: 2px 6px;
1877
+ border-radius: 3px;
1878
+ font-family: var(--font-mono);
1879
+ }
1880
+
1881
+ .event-trigger-excerpt {
1882
+ font-size: var(--text-sm);
1883
+ white-space: pre-wrap;
1884
+ word-break: break-word;
1885
+ }
1886
+
1887
+ /* Heatmap table */
1888
+ .heatmap-table {
1889
+ border-collapse: collapse;
1890
+ width: 100%;
1891
+ }
1892
+
1893
+ .heatmap-header {
1894
+ text-align: center;
1895
+ padding: 4px 6px;
1896
+ border-bottom: 1px solid var(--border);
1897
+ color: var(--text-secondary);
1898
+ }
1899
+
1900
+ .heatmap-scenario {
1901
+ font-size: var(--text-xs);
1902
+ writing-mode: vertical-lr;
1903
+ transform: rotate(180deg);
1904
+ height: 80px;
1905
+ }
1906
+
1907
+ .heatmap-sticky {
1908
+ position: sticky;
1909
+ left: 0;
1910
+ background: var(--bg-panel, var(--bg-elevated));
1911
+ z-index: 1;
1912
+ text-align: left;
1913
+ padding: 6px 8px;
1914
+ font-size: var(--text-base);
1915
+ font-weight: 600;
1916
+ min-width: 100px;
1917
+ }
1918
+
1919
+ .heatmap-model {
1920
+ font-weight: 500;
1921
+ font-size: var(--text-base);
1922
+ padding: 4px 8px;
1923
+ border-top: 1px solid var(--border);
1924
+ }
1925
+
1926
+ .heatmap-cell {
1927
+ text-align: center;
1928
+ padding: 4px 6px;
1929
+ font-size: var(--text-sm);
1930
+ border-top: 1px solid var(--border);
1931
+ color: var(--text-primary);
1932
+ }
1933
+
1934
+ /* Loader spin animation (reuses existing .spinner keyframes) */
1935
+ .spin {
1936
+ animation: spin 0.8s linear infinite;
1937
+ }
1938
+
1939
+ /* Loading placeholder for empty model definitions grid */
1940
+ .loading-placeholder {
1941
+ display: flex;
1942
+ flex-direction: column;
1943
+ align-items: center;
1944
+ justify-content: center;
1945
+ padding: var(--space-6);
1946
+ color: var(--text-secondary);
1947
+ gap: var(--space-2);
1948
+ }
1949
+
1950
+ /* Text alignment utility */
1951
+ .text-center { text-align: center; }
1952
+
1953
+ /* Stage badge (EvolutionPage) */
1954
+ .stage-badge {
1955
+ display: inline-flex;
1956
+ align-items: center;
1957
+ gap: var(--space-1);
1958
+ padding: var(--space-2) var(--space-4);
1959
+ border-radius: var(--radius-lg);
1960
+ font-size: var(--text-lg, 0.8rem);
1961
+ font-weight: 600;
1962
+ background: var(--accent);
1963
+ color: #fff;
1964
+ border: 2px solid var(--accent);
1965
+ }
1966
+
1967
+ .stage-badge svg {
1968
+ width: 16px;
1969
+ height: 16px;
1970
+ }
1971
+
1972
+ /* Sample pre blocks (SamplesPage) */
1973
+ .sample-pre {
1974
+ white-space: pre-wrap;
1975
+ word-break: break-word;
1976
+ background: var(--bg-sunken);
1977
+ padding: var(--space-3);
1978
+ border-radius: var(--radius-md);
1979
+ font-family: var(--font-mono);
1980
+ font-size: var(--text-sm);
1981
+ overflow-x: auto;
1982
+ max-width: 100%;
1983
+ }
1984
+
1985
+ /* GFI big number (FeedbackPage) */
1986
+ .gfi-big-number {
1987
+ font-size: 3rem;
1988
+ font-weight: 700;
1989
+ line-height: 1;
1990
+ }
1991
+
1992
+ /* Progress bar (shared component pattern) */
1993
+ .progress-bar {
1994
+ width: 100%;
1995
+ height: 8px;
1996
+ background: var(--bg-sunken);
1997
+ border-radius: 4px;
1998
+ overflow: hidden;
1999
+ margin-top: var(--space-2);
2000
+ }
2001
+
2002
+ .progress-bar-fill {
2003
+ height: 100%;
2004
+ border-radius: 4px;
2005
+ transition: width 0.3s ease;
2006
+ }
2007
+
2008
+ /* GateMonitor trust/EP big numbers */
2009
+ .stat-big-number {
2010
+ font-size: 1.5rem;
2011
+ font-weight: 700;
2012
+ line-height: 1;
2013
+ }
2014
+
2015
+ /* EvolutionPage icon alignment */
2016
+ .panel h3 svg {
2017
+ vertical-align: middle;
2018
+ margin-right: var(--space-1);
2019
+ }
2020
+
@@ -1,195 +0,0 @@
1
- /**
2
- * Principle Tree Migration — Migrates trainingStore to tree.principles
3
- *
4
- * This migration handles the Phase 11 gap: existing principles in trainingStore
5
- * were never written to tree.principles, blocking the Rule/Implementation layer.
6
- *
7
- * Usage:
8
- * - Called automatically by migratePrincipleTree() during plugin initialization
9
- * - Or run manually: node scripts/migrate-principle-tree.mjs <workspace-dir>
10
- */
11
-
12
- import * as fs from 'fs';
13
- import * as path from 'path';
14
- import {
15
- loadLedger,
16
- createPrinciple,
17
- type LedgerPrinciple,
18
- } from './principle-tree-ledger.js';
19
- import type { LegacyPrincipleTrainingState } from './principle-tree-ledger.js';
20
- import { SystemLogger } from './system-logger.js';
21
-
22
- export interface PrincipleTreeMigrationResult {
23
- migratedCount: number;
24
- skippedCount: number;
25
- errorCount: number;
26
- details: Array<{
27
- principleId: string;
28
- status: 'migrated' | 'skipped' | 'error';
29
- reason?: string;
30
- }>;
31
- }
32
-
33
- /**
34
- * Check if migration is needed by comparing trainingStore and tree.principles
35
- */
36
- export function needsMigration(stateDir: string): boolean {
37
- const ledger = loadLedger(stateDir);
38
- const trainingStoreCount = Object.keys(ledger.trainingStore).length;
39
- const treePrinciplesCount = Object.keys(ledger.tree.principles).length;
40
-
41
- // Migration needed if trainingStore has more principles than tree.principles
42
- return trainingStoreCount > treePrinciplesCount;
43
- }
44
-
45
- /**
46
- * Create a minimal LedgerPrinciple from LegacyPrincipleTrainingState
47
- */
48
- function trainingStateToTreePrinciple(
49
- principleId: string,
50
- state: LegacyPrincipleTrainingState,
51
- now: string
52
- ): LedgerPrinciple {
53
- return {
54
- id: principleId,
55
- version: 1,
56
- text: `Principle ${principleId}`, // Minimal text, will be enriched from PRINCIPLES.md if available
57
- triggerPattern: '', // Unknown from legacy data
58
- action: '', // Unknown from legacy data
59
- status: mapInternalizationStatusToPrincipleStatus(state.internalizationStatus),
60
- priority: 'P1', // Default priority
61
- scope: 'general',
62
- evaluability: state.evaluability,
63
- valueScore: 0,
64
- adherenceRate: state.complianceRate * 100, // Convert 0-1 to 0-100
65
- painPreventedCount: 0,
66
- derivedFromPainIds: [],
67
- ruleIds: [],
68
- conflictsWithPrincipleIds: [],
69
- createdAt: now,
70
- updatedAt: now,
71
- };
72
- }
73
-
74
- /**
75
- * Map internalization status to principle status
76
- */
77
- function mapInternalizationStatusToPrincipleStatus(
78
- status: LegacyPrincipleTrainingState['internalizationStatus']
79
- ): 'candidate' | 'active' | 'deprecated' {
80
- switch (status) {
81
- case 'internalized':
82
- case 'deployed_pending_eval':
83
- return 'active';
84
- case 'regressed':
85
- case 'needs_training':
86
- return 'candidate';
87
- case 'prompt_only':
88
- case 'in_training':
89
- return 'candidate';
90
- default:
91
- return 'candidate';
92
- }
93
- }
94
-
95
- /**
96
- * Migrate trainingStore principles to tree.principles
97
- *
98
- * This function is idempotent: it only migrates principles that don't exist
99
- * in tree.principles yet.
100
- */
101
- export function migratePrincipleTree(
102
- stateDir: string,
103
- workspaceDir?: string
104
- ): PrincipleTreeMigrationResult {
105
- const result: PrincipleTreeMigrationResult = {
106
- migratedCount: 0,
107
- skippedCount: 0,
108
- errorCount: 0,
109
- details: [],
110
- };
111
-
112
- try {
113
- const ledger = loadLedger(stateDir);
114
- const now = new Date().toISOString();
115
-
116
- for (const [principleId, state] of Object.entries(ledger.trainingStore)) {
117
- // Skip if already exists in tree.principles
118
- if (ledger.tree.principles[principleId]) {
119
- result.skippedCount++;
120
- result.details.push({
121
- principleId,
122
- status: 'skipped',
123
- reason: 'Already exists in tree.principles',
124
- });
125
- continue;
126
- }
127
-
128
- try {
129
- const treePrinciple = trainingStateToTreePrinciple(principleId, state, now);
130
- createPrinciple(stateDir, treePrinciple);
131
-
132
- result.migratedCount++;
133
- result.details.push({
134
- principleId,
135
- status: 'migrated',
136
- });
137
-
138
- if (workspaceDir) {
139
- SystemLogger.log(
140
- workspaceDir,
141
- 'PRINCIPLE_TREE_MIGRATED',
142
- `Migrated ${principleId} from trainingStore to tree.principles`
143
- );
144
- }
145
- } catch (err) {
146
- result.errorCount++;
147
- result.details.push({
148
- principleId,
149
- status: 'error',
150
- reason: String(err),
151
- });
152
-
153
- if (workspaceDir) {
154
- SystemLogger.log(
155
- workspaceDir,
156
- 'PRINCIPLE_TREE_MIGRATION_ERROR',
157
- `Failed to migrate ${principleId}: ${String(err)}`
158
- );
159
- }
160
- }
161
- }
162
-
163
- if (workspaceDir && result.migratedCount > 0) {
164
- SystemLogger.log(
165
- workspaceDir,
166
- 'PRINCIPLE_TREE_MIGRATION_COMPLETE',
167
- `Migrated ${result.migratedCount} principles to tree.principles (${result.skippedCount} skipped, ${result.errorCount} errors)`
168
- );
169
- }
170
- } catch (err) {
171
- if (workspaceDir) {
172
- SystemLogger.log(
173
- workspaceDir,
174
- 'PRINCIPLE_TREE_MIGRATION_FAILED',
175
- `Migration failed: ${String(err)}`
176
- );
177
- }
178
- }
179
-
180
- return result;
181
- }
182
-
183
- /**
184
- * Run migration if needed (called during plugin initialization)
185
- */
186
- export function runMigrationIfNeeded(
187
- stateDir: string,
188
- workspaceDir?: string
189
- ): PrincipleTreeMigrationResult | null {
190
- if (!needsMigration(stateDir)) {
191
- return null;
192
- }
193
-
194
- return migratePrincipleTree(stateDir, workspaceDir);
195
- }