diff --git a/.claude/commands/issue/new.md b/.claude/commands/issue/new.md
index 51c02059..2af2d118 100644
--- a/.claude/commands/issue/new.md
+++ b/.claude/commands/issue/new.md
@@ -320,4 +320,4 @@ function parseMarkdownBody(body) {
## Related Commands
- `/issue:plan` - Plan solution for issue
-- `/issue:manage` - Interactive issue management
+
diff --git a/.claude/commands/issue/plan.md b/.claude/commands/issue/plan.md
index ad557f80..1b79bd6b 100644
--- a/.claude/commands/issue/plan.md
+++ b/.claude/commands/issue/plan.md
@@ -304,6 +304,12 @@ Next: \`/issue:queue\` → \`/issue:execute\`
| User cancels selection | Skip issue, continue with others |
| File conflicts | Agent detects and suggests resolution order |
+## Bash Compatibility
+
+**Avoid**: `$(cmd)`, `$var`, `for` loops — will be escaped incorrectly
+
+**Use**: Simple commands + `&&` chains, quote comma params `"pending,registered"`
+
## Quality Checklist
Before completing, verify:
@@ -319,6 +325,5 @@ Before completing, verify:
## Related Commands
- `/issue:queue` - Form execution queue from bound solutions
-- `/issue:execute` - Execute queue with codex
- `ccw issue list` - List all issues
- `ccw issue status` - View issue and solution details
diff --git a/.claude/commands/issue/queue.md b/.claude/commands/issue/queue.md
index 5a56b1e2..9679c342 100644
--- a/.claude/commands/issue/queue.md
+++ b/.claude/commands/issue/queue.md
@@ -385,7 +385,6 @@ Before completing, verify:
## Related Commands
-- `/issue:plan` - Plan issues and bind solutions
- `/issue:execute` - Execute queue with codex
- `ccw issue queue list` - View current queue
- `ccw issue update --from-queue [queue-id]` - Sync issue statuses from queue
diff --git a/ccw/src/templates/dashboard-js/views/codexlens-manager.js b/ccw/src/templates/dashboard-js/views/codexlens-manager.js
index 8fbf33ae..56c65d2d 100644
--- a/ccw/src/templates/dashboard-js/views/codexlens-manager.js
+++ b/ccw/src/templates/dashboard-js/views/codexlens-manager.js
@@ -666,7 +666,7 @@ var ENV_VAR_GROUPS = {
labelKey: 'codexlens.envGroup.embedding',
icon: 'box',
vars: {
- 'CODEXLENS_EMBEDDING_BACKEND': { label: 'Backend', type: 'select', options: ['fastembed', 'litellm'], default: 'fastembed', settingsPath: 'embedding.backend' },
+ 'CODEXLENS_EMBEDDING_BACKEND': { label: 'Backend', type: 'select', options: ['local', 'api'], default: 'local', settingsPath: 'embedding.backend' },
'CODEXLENS_EMBEDDING_MODEL': {
label: 'Model',
type: 'model-select',
@@ -694,7 +694,7 @@ var ENV_VAR_GROUPS = {
icon: 'arrow-up-down',
vars: {
'CODEXLENS_RERANKER_ENABLED': { label: 'Enabled', type: 'select', options: ['true', 'false'], default: 'true', settingsPath: 'reranker.enabled' },
- 'CODEXLENS_RERANKER_BACKEND': { label: 'Backend', type: 'select', options: ['fastembed', 'onnx', 'api', 'litellm'], default: 'fastembed', settingsPath: 'reranker.backend' },
+ 'CODEXLENS_RERANKER_BACKEND': { label: 'Backend', type: 'select', options: ['local', 'api'], default: 'local', settingsPath: 'reranker.backend' },
'CODEXLENS_RERANKER_MODEL': {
label: 'Model',
type: 'model-select',
@@ -786,9 +786,11 @@ async function loadEnvVariables() {
var localEmbeddingModels = [];
if (localModelsResponse && localModelsResponse.ok) {
var localData = await localModelsResponse.json();
- if (localData.success && localData.models) {
- // Filter to only downloaded models
- localEmbeddingModels = localData.models.filter(function(m) { return m.downloaded; });
+ // CLI returns { success: true, result: { models: [...] } }
+ if (localData.success) {
+ var models = localData.models || (localData.result && localData.result.models) || [];
+ // Filter to only installed models (CLI uses 'installed' not 'downloaded')
+ localEmbeddingModels = models.filter(function(m) { return m.installed; });
}
}
@@ -796,12 +798,28 @@ async function loadEnvVariables() {
var localRerankerModels = [];
if (localRerankerModelsResponse && localRerankerModelsResponse.ok) {
var localRerankerData = await localRerankerModelsResponse.json();
- if (localRerankerData.success && localRerankerData.models) {
- // Filter to only downloaded models
- localRerankerModels = localRerankerData.models.filter(function(m) { return m.downloaded; });
+ // CLI returns { success: true, result: { models: [...] } }
+ if (localRerankerData.success) {
+ var models = localRerankerData.models || (localRerankerData.result && localRerankerData.result.models) || [];
+ // Filter to only installed models
+ localRerankerModels = models.filter(function(m) { return m.installed; });
}
}
+ // Cache model data for dynamic backend switching
+ var embeddingVars = ENV_VAR_GROUPS.embedding.vars;
+ var rerankerVars = ENV_VAR_GROUPS.reranker.vars;
+ cachedEmbeddingModels = {
+ local: localEmbeddingModels,
+ api: configuredEmbeddingModels,
+ apiModels: embeddingVars['CODEXLENS_EMBEDDING_MODEL'] ? embeddingVars['CODEXLENS_EMBEDDING_MODEL'].apiModels || [] : []
+ };
+ cachedRerankerModels = {
+ local: localRerankerModels,
+ api: configuredRerankerModels,
+ apiModels: rerankerVars['CODEXLENS_RERANKER_MODEL'] ? rerankerVars['CODEXLENS_RERANKER_MODEL'].apiModels || [] : []
+ };
+
var env = result.env || {};
var settings = result.settings || {}; // Current settings from settings.json
var html = '
';
@@ -851,9 +869,14 @@ async function loadEnvVariables() {
var value = env[key] || settings[key] || config.default || '';
if (config.type === 'select') {
+ // Add onchange handler for backend selects to update model options dynamically
+ var onchangeHandler = '';
+ if (key === 'CODEXLENS_EMBEDDING_BACKEND' || key === 'CODEXLENS_RERANKER_BACKEND') {
+ onchangeHandler = ' onchange="updateModelOptionsOnBackendChange(\'' + key + '\', this.value)"';
+ }
html += '
' +
'' +
- '