Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
237 changes: 122 additions & 115 deletions .kilo/kilo.json
Original file line number Diff line number Diff line change
@@ -1,121 +1,125 @@
{
"$schema": "https://app.kilo.ai/config.json",
"instructions": [".kilo/rules/*.md", "AGENTS.md"],
"skills": { "paths": [".kilo/skills", ".claude/skills"] },
"permission": {
"*": "allow",
"read": { "*.env": "deny", "*.lock": "deny", "*": "allow" },
"edit": { "*.lock": "deny", "*": "allow" },
"sudo *": "deny",
"rm -rf /": "deny",
"rm -rf /*": "deny",
"rm -rf ~": "deny",
"rm -rf ~/*": "deny",
":(){:|:&};:": "deny",
"doom_loop": "deny"
},
"provider": {
"openai": {
"options": { "apiKey": "{env:OPENAI_API_KEY}" }
},
"anthropic": {
"$schema": "https://app.kilo.ai/config.json",
"instructions": [".kilo/rules/*.md", "AGENTS.md"],
"skills": { "paths": [".kilo/skills", ".claude/skills"] },
"permission": {
"*": "allow",
"read": { "*.env": "deny", "*.lock": "deny", "*": "allow" },
"edit": { "*.lock": "deny", "*": "allow" },
"sudo *": "deny",
"rm -rf /": "deny",
"rm -rf /*": "deny",
"rm -rf ~": "deny",
"rm -rf ~/*": "deny",
":(){:|:&};:": "deny",
"doom_loop": "deny"
},
"provider": {
"openai": {
"options": { "apiKey": "{env:OPENAI_API_KEY}" }
},
"anthropic": {
"options": { "apiKey": "{env:ANTHROPIC_API_KEY}" }
}
},
"disabled_providers": ["openai", "google", "anthropic"],
"plugin": [
"opencode-ignore@1.1.0",
}
},
"disabled_providers": ["openai", "google", "anthropic"],
"plugin": [
"opencode-ignore@1.1.0",
"@bastiangx/opencode-unmoji",
"@gotgenes/opencode-agent-identity@3.0.1",
"@nick-vi/opencode-type-inject@1.1.2",
"@gotgenes/opencode-agent-identity@3.0.1",
"@nick-vi/opencode-type-inject@1.1.2",
"@openspoon/subtask2@0.3.9",
"@tarquinen/opencode-dcp@3.1.9",
"openslimedit@1.0.4",
"@tarquinen/opencode-dcp@3.1.9",
"openslimedit@1.0.4",
"opencode-agent-memory@0.2.0",
"superpowers@git+https://github.com/obra/superpowers.git"
],
"formatter": {
"biome": {
"command": ["npx", "-y", "@biomejs/biome", "check", "--write", "--format-with-errors=true", "$FILE"],
"extensions": [".json", ".jsonc", ".js", ".ts"]
},
"ruff": {
"command": ["ruff", "format", "$FILE"],
"extensions": [".py", ".pyi",".pyc"]
}
},
"watcher": {
"ignore": ["node_modules/**", "dist/**", ".git/**", ".venv/**", "__pycache__/**", ".ruff_cache/**"]
},
"mcp": {
"ref-tools": {
"type": "remote",
"url": "https://api.ref.tools/mcp",
"enabled": true
},
"github": {
"type": "remote",
"url": "https://api.githubcopilot.com/mcp/",
"enabled": true
},
"exa": {
"type": "remote",
"url": "https://mcp.exa.ai/mcp?tools=web_search_exa,web_search_advanced_exa,get_code_context_exa,crawling_exa",
"enabled": true,
"headers": { "x-api-key": "{env:EXA_API_KEY}" }
},
"serena": {
"type": "local",
"command": [
"uvx", "--from",
"git+https://github.com/oraios/serena",
"serena", "start-mcp-server",
"--context", "ide", "--project-from-cwd"
],
"enabled": true
},
"octocode": {
"type": "local",
"command": ["npx", "-y", "octocode-mcp@latest"],
"enabled": true
},
],
"formatter": {
"biome": {
"command": ["npx", "-y", "@biomejs/biome", "check", "--write", "--format-with-errors=true", "$FILE"],
"extensions": [".json", ".jsonc", ".js", ".ts"]
},
"ruff": {
"command": ["ruff", "format", "$FILE"],
"extensions": [".py", ".pyi", ".pyc"]
}
},
"watcher": {
"ignore": ["node_modules/**", "dist/**", ".git/**", ".venv/**", "__pycache__/**", ".ruff_cache/**"]
},
"mcp": {
"ref-tools": {
"type": "remote",
"url": "https://api.ref.tools/mcp",
"enabled": true
},
"github": {
"type": "remote",
"url": "https://api.githubcopilot.com/mcp/",
"enabled": true
},
"exa": {
"type": "remote",
"url": "https://mcp.exa.ai/mcp?tools=web_search_exa,web_search_advanced_exa,get_code_context_exa,crawling_exa",
"enabled": true,
"headers": { "x-api-key": "{env:EXA_API_KEY}" }
},
"serena": {
"type": "local",
"command": [
"uvx",
"--from",
"git+https://github.com/oraios/serena",
"serena",
"start-mcp-server",
"--context",
"ide",
"--project-from-cwd"
],
"enabled": true
},
"octocode": {
"type": "local",
"command": ["npx", "-y", "octocode-mcp@latest"],
"enabled": true
},
"morph-mcp": {
"type": "local",
"command": ["npx", "-y", "@morphllm/morphmcp"],
"environment": { "MORPH_API_KEY": "{env:MORPH_API_KEY}" },
"enabled": true
}
},
"lsp": {
"basedpyright": {
"command": ["basedpyright-langserver", "--stdio"],
"extensions": [".py", ".pyw", ".pyi"]
},
"bash": {
"command": ["bash-language-server", "start"],
"extensions": [".sh", ".bash", ".zsh"]
},
"vtsls": {
},
"lsp": {
"basedpyright": {
"command": ["basedpyright-langserver", "--stdio"],
"extensions": [".py", ".pyw", ".pyi"]
},
"bash": {
"command": ["bash-language-server", "start"],
"extensions": [".sh", ".bash", ".zsh"]
},
"vtsls": {
"command": ["vtsls", "--stdio"],
"extensions": [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".mts", ".cts"],
"initialization": { "preferences": { "importModuleSpecifierPreference": "relative" } }
},
},
"rust": {
"command": ["rust-analyzer"],
"extensions": [".rs"]
},
"yaml-ls": {
"command": ["yaml-language-server", "--stdio"],
"extensions": [".yaml", ".yml"]
},
"json-ls": {
"command": ["vscode-json-language-server", "--stdio"],
"extensions": [".json", ".jsonc"]
},
"tombi": {
"command": ["tombi", "lsp"],
"extensions": [".toml"]
},
"yaml-ls": {
"command": ["yaml-language-server", "--stdio"],
"extensions": [".yaml", ".yml"]
},
"json-ls": {
"command": ["vscode-json-language-server", "--stdio"],
"extensions": [".json", ".jsonc"]
},
"tombi": {
"command": ["tombi", "lsp"],
"extensions": [".toml"]
},
"dockerfile-ls": {
"command": ["docker-langserver", "--stdio"],
"extensions": [".dockerfile"]
Expand All @@ -128,20 +132,23 @@
"command": ["vscode-css-language-server", "--stdio"],
"extensions": [".css", ".scss", ".less"]
},
"powershell": {
"command": [
"pwsh", "-NoLogo", "-NoProfile", "-Command",
"$module = Get-Module -ListAvailable PowerShellEditorServices | Sort-Object Version -Descending | Select-Object -First 1; if (-not $module) { throw 'PowerShellEditorServices is not installed. Run: Install-Module -Name PowerShellEditorServices -Scope CurrentUser' }; Import-Module $module.Path; Start-EditorServices -HostName 'Claude Code' -HostProfileId 'ClaudeCode' -HostVersion '1.0.0' -Stdio -BundledModulesPath (Split-Path $module.Path) -LogPath '/dev/null' -LogLevel 'None' -EnableConsoleRepl"
],
"extensions": [".ps1", ".psm1", ".psd1"]
}
},
"compaction": { "auto": true, "prune": true },
"experimental": {
"continue_loop_on_deny": false,
"codebase_search": true,
"mcp_timeout": 30000,
"openTelemetry": false,
"batch_tool": true
}
"powershell": {
"command": [
"pwsh",
"-NoLogo",
"-NoProfile",
"-Command",
"$module = Get-Module -ListAvailable PowerShellEditorServices | Sort-Object Version -Descending | Select-Object -First 1; if (-not $module) { throw 'PowerShellEditorServices is not installed. Run: Install-Module -Name PowerShellEditorServices -Scope CurrentUser' }; Import-Module $module.Path; Start-EditorServices -HostName 'Claude Code' -HostProfileId 'ClaudeCode' -HostVersion '1.0.0' -Stdio -BundledModulesPath (Split-Path $module.Path) -LogPath '/dev/null' -LogLevel 'None' -EnableConsoleRepl"
],
"extensions": [".ps1", ".psm1", ".psd1"]
}
},
"compaction": { "auto": true, "prune": true },
"experimental": {
"continue_loop_on_deny": false,
"codebase_search": true,
"mcp_timeout": 30000,
"openTelemetry": false,
"batch_tool": true
}
}
20 changes: 14 additions & 6 deletions userscripts/todo/LLM/Claude_Complete_Enhancement.user.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ IMPROVEMENTS OVER ORIGINALS:
}
};

// eslint-disable-next-line no-unused-vars
function _saveConfig() {
GM_setValue("warning_threshold", CONFIG.thresholds.warning);
GM_setValue("danger_threshold", CONFIG.thresholds.danger);
Expand Down Expand Up @@ -1562,6 +1561,15 @@ IMPROVEMENTS OVER ORIGINALS:
document.getElementById("cts-refresh")?.addEventListener("click", () => TokenSaverModule.refresh());
document.getElementById("cts-clear")?.addEventListener("click", () => TokenSaverModule.clear());

// Settings checkboxes
panel.querySelectorAll(".feature-checkbox").forEach((checkbox) => {
checkbox.addEventListener("change", (e) => {
const feature = e.target.dataset.feature;
CONFIG.features[feature] = e.target.checked;
_saveConfig();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist feature toggles using read-compatible keys

Calling _saveConfig() here makes the settings UI appear to save, but on reload most toggles revert because _saveConfig writes feature_${key} (e.g. feature_tokenSaver, feature_codeCollapser, feature_usageMonitor) while initialization reads snake_case keys (feature_token_saver, feature_code_collapser, feature_usage_monitor). This means the newly wired change handler only persists theme/fork correctly and silently drops the other feature choices after refresh.

Useful? React with 👍 / 👎.

});
});
Comment on lines +1565 to +1571
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using e.target can be less robust than referencing the scoped checkbox element directly. Additionally, to ensure defensive programming and prevent potential runtime errors or prototype pollution, we should validate that the feature key exists in CONFIG.features before updating it.

Suggested change
panel.querySelectorAll(".feature-checkbox").forEach((checkbox) => {
checkbox.addEventListener("change", (e) => {
const feature = e.target.dataset.feature;
CONFIG.features[feature] = e.target.checked;
_saveConfig();
});
});
panel.querySelectorAll(".feature-checkbox").forEach((checkbox) => {
checkbox.addEventListener("change", () => {
const feature = checkbox.dataset.feature;
if (feature && Object.prototype.hasOwnProperty.call(CONFIG.features, feature)) {
CONFIG.features[feature] = checkbox.checked;
_saveConfig();
}
});
});

Comment on lines +1564 to +1571

// Draggable header
const header = panel.querySelector(".panel-header");
this.makeDraggable(panel, "ui_position", null, header);
Expand Down Expand Up @@ -1617,11 +1625,11 @@ IMPROVEMENTS OVER ORIGINALS:
<div class="cts-section">
<div class="cts-section-title">⚙️ Feature Toggles</div>
<div class="cts-help">
<label><input type="checkbox" ${CONFIG.features.theme ? "checked" : ""}> Dark oceanic theme</label><br>
<label><input type="checkbox" ${CONFIG.features.tokenSaver ? "checked" : ""}> Token Saver</label><br>
<label><input type="checkbox" ${CONFIG.features.codeCollapser ? "checked" : ""}> Code Collapser</label><br>
<label><input type="checkbox" ${CONFIG.features.usageMonitor ? "checked" : ""}> Usage Monitor</label><br>
<label><input type="checkbox" ${CONFIG.features.fork ? "checked" : ""}> Fork Conversation</label><br>
<label><input type="checkbox" class="feature-checkbox" data-feature="theme" ${CONFIG.features.theme ? "checked" : ""}> Dark oceanic theme</label><br>
<label><input type="checkbox" class="feature-checkbox" data-feature="tokenSaver" ${CONFIG.features.tokenSaver ? "checked" : ""}> Token Saver</label><br>
<label><input type="checkbox" class="feature-checkbox" data-feature="codeCollapser" ${CONFIG.features.codeCollapser ? "checked" : ""}> Code Collapser</label><br>
<label><input type="checkbox" class="feature-checkbox" data-feature="usageMonitor" ${CONFIG.features.usageMonitor ? "checked" : ""}> Usage Monitor</label><br>
<label><input type="checkbox" class="feature-checkbox" data-feature="fork" ${CONFIG.features.fork ? "checked" : ""}> Fork Conversation</label><br>
<br>
<small style="color:#909090;">Refresh page to apply changes</small>
</div>
Expand Down