Revert "All the features"

This commit is contained in:
Spicy Marinara
2025-12-05 22:43:56 +01:00
committed by GitHub
parent 275179fa7f
commit bfb63a34cd
35 changed files with 1389 additions and 5894 deletions
+47 -249
View File
@@ -9,9 +9,11 @@ import {
extensionSettings,
lastGeneratedData,
committedTrackerData,
setExtensionSettings,
updateExtensionSettings,
setLastGeneratedData,
setCommittedTrackerData
setCommittedTrackerData,
FEATURE_FLAGS
} from './state.js';
import { migrateInventory } from '../utils/migration.js';
import { validateStoredInventory, cleanItemString } from '../utils/security.js';
@@ -76,14 +78,19 @@ export function loadSettings() {
}
updateExtensionSettings(savedSettings);
// console.log('[RPG Companion] Settings loaded:', extensionSettings);
} else {
// console.log('[RPG Companion] No saved settings found, using defaults');
}
// Migrate inventory from v1 (string) to v2 (object) format if needed
const migrationResult = migrateInventory(extensionSettings.userStats.inventory);
if (migrationResult.migrated) {
console.log(`[RPG Companion] Inventory migrated from ${migrationResult.source} to v2 format`);
extensionSettings.userStats.inventory = migrationResult.inventory;
saveSettings(); // Persist migrated inventory
// Migrate inventory if feature flag enabled
if (FEATURE_FLAGS.useNewInventory) {
const migrationResult = migrateInventory(extensionSettings.userStats.inventory);
if (migrationResult.migrated) {
console.log(`[RPG Companion] Inventory migrated from ${migrationResult.source} to v2 format`);
extensionSettings.userStats.inventory = migrationResult.inventory;
saveSettings(); // Persist migrated inventory
}
}
// Migrate to trackerConfig if it doesn't exist
@@ -92,16 +99,6 @@ export function loadSettings() {
migrateToTrackerConfig();
saveSettings(); // Persist migration
}
// Migrate to new stats/skills format with descriptions
if (migrateStatsAndSkillsFormat()) {
saveSettings(); // Persist migration
}
// Migrate quests from legacy format to structured format
if (migrateQuestsFormat()) {
saveSettings(); // Persist migration
}
} catch (error) {
console.error('[RPG Companion] Error loading settings:', error);
console.error('[RPG Companion] Error details:', error.message, error.stack);
@@ -143,13 +140,6 @@ export function saveChatData() {
quests: extensionSettings.quests,
lastGeneratedData: lastGeneratedData,
committedTrackerData: committedTrackerData,
// Structured data (JSON format)
inventoryV3: extensionSettings.inventoryV3,
skillsV2: extensionSettings.skillsV2,
skillAbilityLinks: extensionSettings.skillAbilityLinks,
infoBoxData: extensionSettings.infoBoxData,
charactersData: extensionSettings.charactersData,
questsV2: extensionSettings.questsV2,
timestamp: Date.now()
};
@@ -184,6 +174,8 @@ export function updateMessageSwipeData() {
infoBox: lastGeneratedData.infoBox,
characterThoughts: lastGeneratedData.characterThoughts
};
// console.log('[RPG Companion] Updated message swipe data after user edit');
break;
}
}
@@ -195,7 +187,7 @@ export function updateMessageSwipeData() {
*/
export function loadChatData() {
if (!chat_metadata || !chat_metadata.rpg_companion) {
// Reset to defaults if no data exists (new chat)
// Reset to defaults if no data exists
updateExtensionSettings({
userStats: {
health: 100,
@@ -211,29 +203,11 @@ export function loadChatData() {
onPerson: "None",
stored: {},
assets: "None"
},
skills: "None" // Legacy single-string skills (for Status section)
}
},
quests: {
main: "None",
optional: []
},
// Reset structured data fields
inventoryV3: {
onPerson: [],
stored: {},
assets: [],
simplified: []
},
skillsV2: {},
skillsData: {},
skillAbilityLinks: {},
skills: { list: [], categories: {} },
charactersData: [],
infoBoxData: null,
questsV2: {
main: null,
optional: []
}
});
setLastGeneratedData({
@@ -273,59 +247,18 @@ export function loadChatData() {
};
}
// Restore last generated data (sanitize null values in infoBox)
// Restore last generated data
if (savedData.lastGeneratedData) {
const sanitizedData = { ...savedData.lastGeneratedData };
if (sanitizedData.infoBox && typeof sanitizedData.infoBox === 'string') {
// Remove lines that contain "null" values
sanitizedData.infoBox = sanitizedData.infoBox
.split('\n')
.filter(line => !line.match(/:\s*null\s*$/i) && !line.match(/:\s*undefined\s*$/i))
.join('\n');
}
setLastGeneratedData(sanitizedData);
setLastGeneratedData({ ...savedData.lastGeneratedData });
}
// Restore committed tracker data (sanitize null values in infoBox)
// Restore committed tracker data
if (savedData.committedTrackerData) {
const sanitizedData = { ...savedData.committedTrackerData };
if (sanitizedData.infoBox && typeof sanitizedData.infoBox === 'string') {
// Remove lines that contain "null" values
sanitizedData.infoBox = sanitizedData.infoBox
.split('\n')
.filter(line => !line.match(/:\s*null\s*$/i) && !line.match(/:\s*undefined\s*$/i))
.join('\n');
}
setCommittedTrackerData(sanitizedData);
setCommittedTrackerData({ ...savedData.committedTrackerData });
}
// Restore structured data (JSON format)
if (savedData.inventoryV3) {
extensionSettings.inventoryV3 = savedData.inventoryV3;
}
if (savedData.skillsV2) {
extensionSettings.skillsV2 = savedData.skillsV2;
}
if (savedData.skillAbilityLinks) {
extensionSettings.skillAbilityLinks = savedData.skillAbilityLinks;
}
if (savedData.infoBoxData) {
extensionSettings.infoBoxData = savedData.infoBoxData;
}
if (savedData.charactersData) {
extensionSettings.charactersData = savedData.charactersData;
}
if (savedData.questsV2) {
extensionSettings.questsV2 = savedData.questsV2;
}
// Migrate quests from legacy format to structured format if needed
if (migrateQuestsFormat()) {
saveChatData(); // Persist migrated quests to chat metadata
}
// Migrate inventory from v1 (string) to v2 (object) format if needed
if (extensionSettings.userStats.inventory) {
// Migrate inventory in chat data if feature flag enabled
if (FEATURE_FLAGS.useNewInventory && extensionSettings.userStats.inventory) {
const migrationResult = migrateInventory(extensionSettings.userStats.inventory);
if (migrationResult.migrated) {
console.log(`[RPG Companion] Chat inventory migrated from ${migrationResult.source} to v2 format`);
@@ -334,12 +267,16 @@ export function loadChatData() {
}
}
// Validate inventory structure (Bug #3 fix)
validateInventoryStructure(extensionSettings.userStats.inventory, 'chat');
// console.log('[RPG Companion] Loaded chat data:', savedData);
}
/**
* Validates and repairs inventory structure to prevent corruption.
* Ensures all v2 fields exist and are the correct type.
* Fixes Bug #3: Location disappears when switching tabs
*
* @param {Object} inventory - Inventory object to validate
* @param {string} source - Source of load ('settings' or 'chat') for logging
@@ -382,6 +319,7 @@ function validateInventoryStructure(inventory, source) {
}
}
// Validate stored field (CRITICAL for Bug #3)
if (!inventory.stored || typeof inventory.stored !== 'object' || Array.isArray(inventory.stored)) {
console.error(`[RPG Companion] Corrupted stored inventory from ${source}, resetting to empty object`);
inventory.stored = {};
@@ -432,15 +370,13 @@ function migrateToTrackerConfig() {
userStats: {
customStats: [],
showRPGAttributes: true,
alwaysSendAttributes: false,
allowAIUpdateAttributes: true,
rpgAttributes: [
{ id: 'str', name: 'STR', description: '', enabled: true },
{ id: 'dex', name: 'DEX', description: '', enabled: true },
{ id: 'con', name: 'CON', description: '', enabled: true },
{ id: 'int', name: 'INT', description: '', enabled: true },
{ id: 'wis', name: 'WIS', description: '', enabled: true },
{ id: 'cha', name: 'CHA', description: '', enabled: true }
{ id: 'str', name: 'STR', enabled: true },
{ id: 'dex', name: 'DEX', enabled: true },
{ id: 'con', name: 'CON', enabled: true },
{ id: 'int', name: 'INT', enabled: true },
{ id: 'wis', name: 'WIS', enabled: true },
{ id: 'cha', name: 'CHA', enabled: true }
],
statusSection: {
enabled: true,
@@ -503,12 +439,12 @@ function migrateToTrackerConfig() {
if (extensionSettings.trackerConfig.userStats.showRPGAttributes !== undefined) {
const shouldShow = extensionSettings.trackerConfig.userStats.showRPGAttributes;
extensionSettings.trackerConfig.userStats.rpgAttributes = [
{ id: 'str', name: 'STR', description: '', enabled: shouldShow },
{ id: 'dex', name: 'DEX', description: '', enabled: shouldShow },
{ id: 'con', name: 'CON', description: '', enabled: shouldShow },
{ id: 'int', name: 'INT', description: '', enabled: shouldShow },
{ id: 'wis', name: 'WIS', description: '', enabled: shouldShow },
{ id: 'cha', name: 'CHA', description: '', enabled: shouldShow }
{ id: 'str', name: 'STR', enabled: shouldShow },
{ id: 'dex', name: 'DEX', enabled: shouldShow },
{ id: 'con', name: 'CON', enabled: shouldShow },
{ id: 'int', name: 'INT', enabled: shouldShow },
{ id: 'wis', name: 'WIS', enabled: shouldShow },
{ id: 'cha', name: 'CHA', enabled: shouldShow }
];
delete extensionSettings.trackerConfig.userStats.showRPGAttributes;
console.log('[RPG Companion] Migrated showRPGAttributes to rpgAttributes array');
@@ -517,12 +453,12 @@ function migrateToTrackerConfig() {
// Ensure rpgAttributes exists even if no migration was needed
if (!extensionSettings.trackerConfig.userStats.rpgAttributes) {
extensionSettings.trackerConfig.userStats.rpgAttributes = [
{ id: 'str', name: 'STR', description: '', enabled: true },
{ id: 'dex', name: 'DEX', description: '', enabled: true },
{ id: 'con', name: 'CON', description: '', enabled: true },
{ id: 'int', name: 'INT', description: '', enabled: true },
{ id: 'wis', name: 'WIS', description: '', enabled: true },
{ id: 'cha', name: 'CHA', description: '', enabled: true }
{ id: 'str', name: 'STR', enabled: true },
{ id: 'dex', name: 'DEX', enabled: true },
{ id: 'con', name: 'CON', enabled: true },
{ id: 'int', name: 'INT', enabled: true },
{ id: 'wis', name: 'WIS', enabled: true },
{ id: 'cha', name: 'CHA', enabled: true }
];
}
@@ -605,141 +541,3 @@ function migrateToTrackerConfig() {
}
}
}
/**
* Migrates stats and skills to new format with description fields.
* - customStats: adds description field
* - rpgAttributes: adds description field
* - skillsSection.customFields: converts from string array to object array
* @returns {boolean} true if any migration was performed
*/
function migrateStatsAndSkillsFormat() {
let migrated = false;
if (!extensionSettings.trackerConfig?.userStats) {
return false;
}
const userStats = extensionSettings.trackerConfig.userStats;
// Migrate customStats - add description if missing
if (userStats.customStats) {
for (const stat of userStats.customStats) {
if (stat && typeof stat === 'object' && stat.description === undefined) {
stat.description = '';
migrated = true;
}
}
}
// Migrate rpgAttributes - add description if missing
if (userStats.rpgAttributes) {
for (const attr of userStats.rpgAttributes) {
if (attr && typeof attr === 'object' && attr.description === undefined) {
attr.description = '';
migrated = true;
}
}
}
// Migrate skillsSection.customFields - convert string array to object array
if (userStats.skillsSection?.customFields) {
const oldFields = userStats.skillsSection.customFields;
const hasOldFormat = oldFields.some(f => typeof f === 'string');
if (hasOldFormat) {
console.log('[RPG Companion] Migrating skill categories to new format');
userStats.skillsSection.customFields = oldFields.map((field, index) => {
if (typeof field === 'string') {
return {
id: 'skill_' + Date.now() + '_' + index,
name: field,
description: '',
enabled: true
};
}
// Already an object, ensure it has all fields
return {
id: field.id || 'skill_' + Date.now() + '_' + index,
name: field.name || 'Skill',
description: field.description || '',
enabled: field.enabled !== false
};
});
migrated = true;
}
}
// Migrate character stats - add description if missing
if (extensionSettings.trackerConfig?.presentCharacters?.characterStats?.customStats) {
for (const stat of extensionSettings.trackerConfig.presentCharacters.characterStats.customStats) {
if (stat && typeof stat === 'object' && stat.description === undefined) {
stat.description = '';
migrated = true;
}
}
}
if (migrated) {
console.log('[RPG Companion] Stats/skills format migration complete');
}
return migrated;
}
/**
* Migrates quests from legacy format to structured format (questsV2).
* Legacy format: quests.main (string), quests.optional (string array)
* New format: questsV2.main ({name, description}), questsV2.optional (array of {name, description})
* @returns {boolean} true if any migration was performed
*/
function migrateQuestsFormat() {
let migrated = false;
// Initialize questsV2 if it doesn't exist
if (!extensionSettings.questsV2) {
extensionSettings.questsV2 = {
main: null,
optional: []
};
}
// Migrate main quest if it exists in legacy format but not in new format
// Check if legacy format has data AND new format is empty/null
if (extensionSettings.quests?.main &&
extensionSettings.quests.main !== 'None' &&
extensionSettings.quests.main !== '' &&
(!extensionSettings.questsV2.main || !extensionSettings.questsV2.main.name)) {
extensionSettings.questsV2.main = {
name: extensionSettings.quests.main,
description: extensionSettings.quests?.mainDescription || ''
};
migrated = true;
console.log('[RPG Companion] Migrated main quest to structured format:', extensionSettings.quests.main);
}
// Migrate optional quests if they exist in legacy format but not in new format
// Check if legacy format has data AND new format is empty
if (extensionSettings.quests?.optional &&
Array.isArray(extensionSettings.quests.optional) &&
extensionSettings.quests.optional.length > 0 &&
(!extensionSettings.questsV2.optional || extensionSettings.questsV2.optional.length === 0)) {
const descriptions = extensionSettings.quests?.optionalDescriptions || [];
extensionSettings.questsV2.optional = extensionSettings.quests.optional
.filter(title => title && title !== 'None' && title !== '')
.map((title, i) => ({
name: title,
description: descriptions[i] || ''
}));
if (extensionSettings.questsV2.optional.length > 0) {
migrated = true;
console.log('[RPG Companion] Migrated optional quests to structured format:', extensionSettings.questsV2.optional.length, 'quests');
}
}
if (migrated) {
console.log('[RPG Companion] Quests format migration complete');
}
return migrated;
}