claude-code-workflow 6.3.37 → 6.3.39
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/.claude/commands/workflow/lite-execute.md +2 -0
- package/.codex/agents/action-planning-agent.md +885 -0
- package/.codex/agents/ccw-loop-b-complete.md +227 -0
- package/.codex/agents/ccw-loop-b-debug.md +172 -0
- package/.codex/agents/ccw-loop-b-develop.md +147 -0
- package/.codex/agents/ccw-loop-b-init.md +82 -0
- package/.codex/agents/ccw-loop-b-validate.md +204 -0
- package/.codex/agents/ccw-loop-executor.md +260 -0
- package/.codex/agents/cli-discuss-agent.md +391 -0
- package/.codex/agents/cli-execution-agent.md +333 -0
- package/.codex/agents/cli-explore-agent.md +186 -0
- package/.codex/agents/cli-lite-planning-agent.md +736 -0
- package/.codex/agents/cli-planning-agent.md +562 -0
- package/.codex/agents/code-developer.md +408 -0
- package/.codex/agents/conceptual-planning-agent.md +321 -0
- package/.codex/agents/context-search-agent.md +585 -0
- package/.codex/agents/debug-explore-agent.md +436 -0
- package/.codex/agents/doc-generator.md +334 -0
- package/.codex/agents/issue-plan-agent.md +417 -0
- package/.codex/agents/issue-queue-agent.md +311 -0
- package/.codex/agents/memory-bridge.md +96 -0
- package/.codex/agents/test-context-search-agent.md +402 -0
- package/.codex/agents/test-fix-agent.md +359 -0
- package/.codex/agents/ui-design-agent.md +595 -0
- package/.codex/agents/universal-executor.md +135 -0
- package/.codex/prompts/clean.md +409 -0
- package/.codex/prompts/issue-discover-by-prompt.md +364 -0
- package/.codex/prompts/issue-discover.md +261 -0
- package/.codex/prompts/issue-execute.md +10 -0
- package/.codex/prompts/issue-new.md +285 -0
- package/.codex/prompts/issue-plan.md +161 -63
- package/.codex/prompts/issue-queue.md +298 -288
- package/.codex/prompts/lite-execute.md +627 -133
- package/.codex/prompts/lite-fix.md +670 -0
- package/.codex/prompts/lite-plan-a.md +337 -0
- package/.codex/prompts/lite-plan-b.md +485 -0
- package/.codex/prompts/{lite-plan.md → lite-plan-c.md} +601 -469
- package/.codex/skills/ccw-loop/README.md +171 -0
- package/.codex/skills/ccw-loop/SKILL.md +349 -0
- package/.codex/skills/ccw-loop/phases/actions/action-complete.md +269 -0
- package/.codex/skills/ccw-loop/phases/actions/action-debug.md +286 -0
- package/.codex/skills/ccw-loop/phases/actions/action-develop.md +183 -0
- package/.codex/skills/ccw-loop/phases/actions/action-init.md +164 -0
- package/.codex/skills/ccw-loop/phases/actions/action-menu.md +205 -0
- package/.codex/skills/ccw-loop/phases/actions/action-validate.md +250 -0
- package/.codex/skills/ccw-loop/phases/orchestrator.md +416 -0
- package/.codex/skills/ccw-loop/phases/state-schema.md +388 -0
- package/.codex/skills/ccw-loop/specs/action-catalog.md +182 -0
- package/.codex/skills/ccw-loop-b/README.md +301 -0
- package/.codex/skills/ccw-loop-b/SKILL.md +322 -0
- package/.codex/skills/ccw-loop-b/phases/orchestrator.md +257 -0
- package/.codex/skills/ccw-loop-b/phases/state-schema.md +181 -0
- package/.codex/skills/ccw-loop-b/specs/action-catalog.md +383 -0
- package/.codex/skills/parallel-dev-cycle/README.md +382 -0
- package/.codex/skills/parallel-dev-cycle/SKILL.md +512 -0
- package/.codex/skills/parallel-dev-cycle/phases/agents/code-developer.md +242 -0
- package/.codex/skills/parallel-dev-cycle/phases/agents/exploration-planner.md +285 -0
- package/.codex/skills/parallel-dev-cycle/phases/agents/requirements-analyst.md +285 -0
- package/.codex/skills/parallel-dev-cycle/phases/agents/validation-archivist.md +381 -0
- package/.codex/skills/parallel-dev-cycle/phases/orchestrator.md +696 -0
- package/.codex/skills/parallel-dev-cycle/phases/state-schema.md +436 -0
- package/.codex/skills/parallel-dev-cycle/specs/communication-optimization.md +423 -0
- package/.codex/skills/parallel-dev-cycle/specs/coordination-protocol.md +391 -0
- package/.codex/skills/parallel-dev-cycle/specs/versioning-strategy.md +330 -0
- package/ccw/dist/cli.d.ts.map +1 -1
- package/ccw/dist/cli.js +4 -0
- package/ccw/dist/cli.js.map +1 -1
- package/ccw/dist/commands/install.d.ts.map +1 -1
- package/ccw/dist/commands/install.js +39 -8
- package/ccw/dist/commands/install.js.map +1 -1
- package/ccw/dist/commands/issue.d.ts +3 -0
- package/ccw/dist/commands/issue.d.ts.map +1 -1
- package/ccw/dist/commands/issue.js +107 -0
- package/ccw/dist/commands/issue.js.map +1 -1
- package/ccw/dist/commands/upgrade.js +1 -1
- package/ccw/dist/commands/upgrade.js.map +1 -1
- package/ccw/dist/config/litellm-api-config-manager.d.ts.map +1 -1
- package/ccw/dist/config/litellm-api-config-manager.js +3 -2
- package/ccw/dist/config/litellm-api-config-manager.js.map +1 -1
- package/ccw/dist/core/memory-embedder-bridge.d.ts.map +1 -1
- package/ccw/dist/core/memory-embedder-bridge.js +2 -5
- package/ccw/dist/core/memory-embedder-bridge.js.map +1 -1
- package/ccw/dist/core/routes/cli-routes.js.map +1 -1
- package/ccw/dist/core/routes/codexlens/config-handlers.d.ts.map +1 -1
- package/ccw/dist/core/routes/codexlens/config-handlers.js +7 -6
- package/ccw/dist/core/routes/codexlens/config-handlers.js.map +1 -1
- package/ccw/dist/core/routes/codexlens/semantic-handlers.d.ts.map +1 -1
- package/ccw/dist/core/routes/codexlens/semantic-handlers.js +2 -2
- package/ccw/dist/core/routes/codexlens/semantic-handlers.js.map +1 -1
- package/ccw/dist/core/routes/graph-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/graph-routes.js +17 -2
- package/ccw/dist/core/routes/graph-routes.js.map +1 -1
- package/ccw/dist/core/routes/issue-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/issue-routes.js +280 -33
- package/ccw/dist/core/routes/issue-routes.js.map +1 -1
- package/ccw/dist/core/routes/loop-v2-routes.d.ts +9 -0
- package/ccw/dist/core/routes/loop-v2-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/loop-v2-routes.js +56 -4
- package/ccw/dist/core/routes/loop-v2-routes.js.map +1 -1
- package/ccw/dist/core/routes/system-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/system-routes.js +3 -2
- package/ccw/dist/core/routes/system-routes.js.map +1 -1
- package/ccw/dist/core/server.d.ts.map +1 -1
- package/ccw/dist/core/server.js +5 -3
- package/ccw/dist/core/server.js.map +1 -1
- package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -1
- package/ccw/dist/tools/claude-cli-tools.js +4 -3
- package/ccw/dist/tools/claude-cli-tools.js.map +1 -1
- package/ccw/dist/tools/cli-config-manager.d.ts +1 -0
- package/ccw/dist/tools/cli-config-manager.d.ts.map +1 -1
- package/ccw/dist/tools/cli-config-manager.js +2 -1
- package/ccw/dist/tools/cli-config-manager.js.map +1 -1
- package/ccw/dist/tools/codex-lens-lsp.d.ts.map +1 -1
- package/ccw/dist/tools/codex-lens-lsp.js +2 -5
- package/ccw/dist/tools/codex-lens-lsp.js.map +1 -1
- package/ccw/dist/tools/codex-lens.d.ts.map +1 -1
- package/ccw/dist/tools/codex-lens.js +22 -32
- package/ccw/dist/tools/codex-lens.js.map +1 -1
- package/ccw/dist/tools/litellm-client.d.ts +6 -0
- package/ccw/dist/tools/litellm-client.d.ts.map +1 -1
- package/ccw/dist/tools/litellm-client.js +15 -2
- package/ccw/dist/tools/litellm-client.js.map +1 -1
- package/ccw/dist/tools/loop-task-manager.d.ts +13 -2
- package/ccw/dist/tools/loop-task-manager.d.ts.map +1 -1
- package/ccw/dist/tools/loop-task-manager.js.map +1 -1
- package/ccw/dist/tools/native-session-discovery.d.ts.map +1 -1
- package/ccw/dist/tools/native-session-discovery.js +35 -7
- package/ccw/dist/tools/native-session-discovery.js.map +1 -1
- package/ccw/dist/utils/codexlens-path.d.ts +36 -0
- package/ccw/dist/utils/codexlens-path.d.ts.map +1 -0
- package/ccw/dist/utils/codexlens-path.js +56 -0
- package/ccw/dist/utils/codexlens-path.js.map +1 -0
- package/ccw/dist/utils/uv-manager.d.ts.map +1 -1
- package/ccw/dist/utils/uv-manager.js +3 -2
- package/ccw/dist/utils/uv-manager.js.map +1 -1
- package/ccw/src/cli.ts +4 -0
- package/ccw/src/commands/install.ts +51 -8
- package/ccw/src/commands/issue.ts +119 -0
- package/ccw/src/commands/upgrade.ts +1 -1
- package/ccw/src/config/litellm-api-config-manager.ts +3 -2
- package/ccw/src/core/memory-embedder-bridge.ts +2 -6
- package/ccw/src/core/routes/cli-routes.ts +1 -1
- package/ccw/src/core/routes/codexlens/config-handlers.ts +7 -6
- package/ccw/src/core/routes/codexlens/semantic-handlers.ts +2 -2
- package/ccw/src/core/routes/graph-routes.ts +18 -2
- package/ccw/src/core/routes/issue-routes.ts +308 -33
- package/ccw/src/core/routes/loop-v2-routes.ts +64 -6
- package/ccw/src/core/routes/system-routes.ts +3 -2
- package/ccw/src/core/server.ts +6 -3
- package/ccw/src/templates/dashboard-css/02-session.css +2 -0
- package/ccw/src/templates/dashboard-css/04-lite-tasks.css +103 -1
- package/ccw/src/templates/dashboard-css/32-issue-manager.css +32 -0
- package/ccw/src/templates/dashboard-js/components/cli-history.js +48 -48
- package/ccw/src/templates/dashboard-js/components/navigation.js +6 -0
- package/ccw/src/templates/dashboard-js/components/notifications.js +6 -0
- package/ccw/src/templates/dashboard-js/components/version-check.js +38 -0
- package/ccw/src/templates/dashboard-js/i18n.js +126 -0
- package/ccw/src/templates/dashboard-js/state.js +2 -0
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +1 -1
- package/ccw/src/templates/dashboard-js/views/issue-manager.js +183 -1
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +55 -11
- package/ccw/src/templates/dashboard-js/views/loop-monitor.js +112 -11
- package/ccw/src/templates/dashboard.html +48 -2
- package/ccw/src/tools/claude-cli-tools.ts +4 -3
- package/ccw/src/tools/cli-config-manager.ts +3 -1
- package/ccw/src/tools/codex-lens-lsp.ts +2 -5
- package/ccw/src/tools/codex-lens.ts +27 -38
- package/ccw/src/tools/litellm-client.ts +16 -2
- package/ccw/src/tools/loop-task-manager.ts +13 -2
- package/ccw/src/tools/native-session-discovery.ts +38 -7
- package/ccw/src/utils/codexlens-path.ts +60 -0
- package/ccw/src/utils/uv-manager.ts +3 -2
- package/package.json +1 -1
|
@@ -289,6 +289,65 @@ const i18n = {
|
|
|
289
289
|
'cli.fileBrowserApiError': 'Server restart required to enable file browser',
|
|
290
290
|
'cli.fileBrowserManualHint': 'Type the full path above and click Select (e.g., C:\\Users\\name\\.gemini)',
|
|
291
291
|
|
|
292
|
+
// CLI History & Execution
|
|
293
|
+
'cli.executionHistory': 'Execution History',
|
|
294
|
+
'cli.conversationDetail': 'Conversation Detail',
|
|
295
|
+
'cli.nativeSessionDetail': 'Native Session Detail',
|
|
296
|
+
'cli.viewFullConversation': 'View Full Process Conversation',
|
|
297
|
+
'cli.perTurnView': 'Per-Turn View',
|
|
298
|
+
'cli.concatenatedView': 'Concatenated View',
|
|
299
|
+
'cli.userPrompt': 'User Prompt',
|
|
300
|
+
'cli.assistantResponse': 'Assistant Response',
|
|
301
|
+
'cli.user': 'User',
|
|
302
|
+
'cli.assistant': 'Assistant',
|
|
303
|
+
'cli.latest': 'Latest',
|
|
304
|
+
'cli.turn': 'Turn',
|
|
305
|
+
'cli.thinkingProcess': 'Thinking Process',
|
|
306
|
+
'cli.thoughts': 'thoughts',
|
|
307
|
+
'cli.toolCalls': 'Tool Calls',
|
|
308
|
+
'cli.totalTokens': 'Total Tokens',
|
|
309
|
+
'cli.input': 'Input',
|
|
310
|
+
'cli.output': 'Output',
|
|
311
|
+
'cli.cached': 'Cached',
|
|
312
|
+
'cli.concatenatedPrompt': 'Concatenated Prompt (sent to CLI)',
|
|
313
|
+
'cli.sessionId': 'Session ID',
|
|
314
|
+
|
|
315
|
+
// CLI History Actions & Buttons
|
|
316
|
+
'cli.refresh': 'Refresh',
|
|
317
|
+
'cli.copyId': 'Copy ID',
|
|
318
|
+
'cli.copyFullPrompt': 'Copy Full Prompt',
|
|
319
|
+
'cli.delete': 'Delete',
|
|
320
|
+
'cli.exportJson': 'Export JSON',
|
|
321
|
+
'cli.copyFilePath': 'Copy File Path',
|
|
322
|
+
'cli.copySessionId': 'Copy Session ID',
|
|
323
|
+
'cli.viewNativeSession': 'View Native Session',
|
|
324
|
+
'cli.viewDetails': 'View Details',
|
|
325
|
+
'cli.searchHistory': 'Search history...',
|
|
326
|
+
'cli.allTools': 'All Tools',
|
|
327
|
+
'cli.noExecutions': 'No executions yet',
|
|
328
|
+
'cli.noMatchingResults': 'No matching results',
|
|
329
|
+
|
|
330
|
+
// CLI History Messages
|
|
331
|
+
'cli.conversationNotFound': 'Conversation not found',
|
|
332
|
+
'cli.nativeSessionNotFound': 'Native session not found',
|
|
333
|
+
'cli.historyRefreshed': 'History refreshed',
|
|
334
|
+
'cli.executionDeleted': 'Execution deleted',
|
|
335
|
+
'cli.deleteFailed': 'Delete failed',
|
|
336
|
+
'cli.idCopied': 'ID copied',
|
|
337
|
+
'cli.promptCopied': 'Prompt copied to clipboard',
|
|
338
|
+
'cli.fullPromptCopied': 'Full prompt copied to clipboard',
|
|
339
|
+
'cli.sessionIdCopied': 'Session ID copied',
|
|
340
|
+
'cli.filePathCopied': 'File path copied',
|
|
341
|
+
'cli.pathNotAvailable': 'Path not available',
|
|
342
|
+
'cli.noSessionData': 'No session data',
|
|
343
|
+
'cli.sessionExported': 'Session exported',
|
|
344
|
+
'cli.failedToCopy': 'Failed to copy',
|
|
345
|
+
'cli.executionNotFound': 'Execution not found',
|
|
346
|
+
|
|
347
|
+
// CLI History Confirm Dialog
|
|
348
|
+
'cli.confirmDelete': 'Delete this execution record? This action cannot be undone.',
|
|
349
|
+
'cli.nativeSessionBadge': 'Native session',
|
|
350
|
+
|
|
292
351
|
// CodexLens Configuration
|
|
293
352
|
'codexlens.config': 'CodexLens Configuration',
|
|
294
353
|
'codexlens.configDesc': 'Manage code indexing, semantic search, and embedding models',
|
|
@@ -2202,6 +2261,10 @@ const i18n = {
|
|
|
2202
2261
|
'loop.kanban.noBoardData': 'No tasks to display',
|
|
2203
2262
|
'loop.listView': 'List View',
|
|
2204
2263
|
'loop.addTask': 'Add Task',
|
|
2264
|
+
'loop.add': 'Add',
|
|
2265
|
+
'loop.save': 'Save',
|
|
2266
|
+
'loop.cancel': 'Cancel',
|
|
2267
|
+
'loop.loadToolsError': 'Failed to load available tools. Please try again.',
|
|
2205
2268
|
|
|
2206
2269
|
// Navigation & Grouping
|
|
2207
2270
|
'loop.nav.groupBy': 'Group By',
|
|
@@ -2871,6 +2934,65 @@ const i18n = {
|
|
|
2871
2934
|
'cli.fileBrowserApiError': '需要重启服务器以启用文件浏览器',
|
|
2872
2935
|
'cli.fileBrowserManualHint': '请在上方输入完整路径后点击选择(如 C:\\Users\\用户名\\.gemini)',
|
|
2873
2936
|
|
|
2937
|
+
// CLI 历史与执行
|
|
2938
|
+
'cli.executionHistory': '执行历史',
|
|
2939
|
+
'cli.conversationDetail': '对话详情',
|
|
2940
|
+
'cli.nativeSessionDetail': '原生会话详情',
|
|
2941
|
+
'cli.viewFullConversation': '查看完整过程对话',
|
|
2942
|
+
'cli.perTurnView': '按轮次查看',
|
|
2943
|
+
'cli.concatenatedView': '合并视图',
|
|
2944
|
+
'cli.userPrompt': '用户提示词',
|
|
2945
|
+
'cli.assistantResponse': '助手回复',
|
|
2946
|
+
'cli.user': '用户',
|
|
2947
|
+
'cli.assistant': '助手',
|
|
2948
|
+
'cli.latest': '最新',
|
|
2949
|
+
'cli.turn': '轮次',
|
|
2950
|
+
'cli.thinkingProcess': '思考过程',
|
|
2951
|
+
'cli.thoughts': '个思考',
|
|
2952
|
+
'cli.toolCalls': '工具调用',
|
|
2953
|
+
'cli.totalTokens': '总令牌数',
|
|
2954
|
+
'cli.input': '输入',
|
|
2955
|
+
'cli.output': '输出',
|
|
2956
|
+
'cli.cached': '已缓存',
|
|
2957
|
+
'cli.concatenatedPrompt': '合并提示词(发送至 CLI)',
|
|
2958
|
+
'cli.sessionId': '会话 ID',
|
|
2959
|
+
|
|
2960
|
+
// CLI 历史操作与按钮
|
|
2961
|
+
'cli.refresh': '刷新',
|
|
2962
|
+
'cli.copyId': '复制 ID',
|
|
2963
|
+
'cli.copyFullPrompt': '复制完整提示词',
|
|
2964
|
+
'cli.delete': '删除',
|
|
2965
|
+
'cli.exportJson': '导出 JSON',
|
|
2966
|
+
'cli.copyFilePath': '复制文件路径',
|
|
2967
|
+
'cli.copySessionId': '复制会话 ID',
|
|
2968
|
+
'cli.viewNativeSession': '查看原生会话',
|
|
2969
|
+
'cli.viewDetails': '查看详情',
|
|
2970
|
+
'cli.searchHistory': '搜索历史...',
|
|
2971
|
+
'cli.allTools': '所有工具',
|
|
2972
|
+
'cli.noExecutions': '暂无执行记录',
|
|
2973
|
+
'cli.noMatchingResults': '无匹配结果',
|
|
2974
|
+
|
|
2975
|
+
// CLI 历史消息
|
|
2976
|
+
'cli.conversationNotFound': '未找到对话',
|
|
2977
|
+
'cli.nativeSessionNotFound': '未找到原生会话',
|
|
2978
|
+
'cli.historyRefreshed': '历史已刷新',
|
|
2979
|
+
'cli.executionDeleted': '执行记录已删除',
|
|
2980
|
+
'cli.deleteFailed': '删除失败',
|
|
2981
|
+
'cli.idCopied': 'ID 已复制',
|
|
2982
|
+
'cli.promptCopied': '提示词已复制到剪贴板',
|
|
2983
|
+
'cli.fullPromptCopied': '完整提示词已复制到剪贴板',
|
|
2984
|
+
'cli.sessionIdCopied': '会话 ID 已复制',
|
|
2985
|
+
'cli.filePathCopied': '文件路径已复制',
|
|
2986
|
+
'cli.pathNotAvailable': '路径不可用',
|
|
2987
|
+
'cli.noSessionData': '无会话数据',
|
|
2988
|
+
'cli.sessionExported': '会话已导出',
|
|
2989
|
+
'cli.failedToCopy': '复制失败',
|
|
2990
|
+
'cli.executionNotFound': '未找到执行记录',
|
|
2991
|
+
|
|
2992
|
+
// CLI 历史确认对话框
|
|
2993
|
+
'cli.confirmDelete': '删除此执行记录?此操作无法撤销。',
|
|
2994
|
+
'cli.nativeSessionBadge': '原生会话',
|
|
2995
|
+
|
|
2874
2996
|
// CodexLens 配置
|
|
2875
2997
|
'codexlens.config': 'CodexLens 配置',
|
|
2876
2998
|
'codexlens.configDesc': '管理代码索引、语义搜索和嵌入模型',
|
|
@@ -4796,6 +4918,10 @@ const i18n = {
|
|
|
4796
4918
|
'loop.kanban.noBoardData': '没有要显示的任务',
|
|
4797
4919
|
'loop.listView': '列表视图',
|
|
4798
4920
|
'loop.addTask': '添加任务',
|
|
4921
|
+
'loop.add': '添加',
|
|
4922
|
+
'loop.save': '保存',
|
|
4923
|
+
'loop.cancel': '取消',
|
|
4924
|
+
'loop.loadToolsError': '加载可用工具失败,请重试。',
|
|
4799
4925
|
|
|
4800
4926
|
// Navigation & Grouping
|
|
4801
4927
|
'loop.nav.groupBy': '分组',
|
|
@@ -36,10 +36,12 @@ const sessionDataStore = {};
|
|
|
36
36
|
// Store lite task session data for detail page access
|
|
37
37
|
// Key: session key, Value: lite session data object
|
|
38
38
|
const liteTaskDataStore = {};
|
|
39
|
+
window.liteTaskDataStore = liteTaskDataStore;
|
|
39
40
|
|
|
40
41
|
// Store task JSON data in a global map instead of inline script tags
|
|
41
42
|
// Key: unique task ID, Value: raw task JSON data
|
|
42
43
|
const taskJsonStore = {};
|
|
44
|
+
window.taskJsonStore = taskJsonStore;
|
|
43
45
|
|
|
44
46
|
// ========== Global Notification Queue ==========
|
|
45
47
|
// Notification queue visible from any view (persisted to localStorage)
|
|
@@ -570,7 +570,7 @@ var fileBrowserState = {
|
|
|
570
570
|
|
|
571
571
|
function showFileBrowserModal(onSelect) {
|
|
572
572
|
fileBrowserState.onSelect = onSelect;
|
|
573
|
-
fileBrowserState.showHidden =
|
|
573
|
+
fileBrowserState.showHidden = true;
|
|
574
574
|
|
|
575
575
|
// Create modal overlay
|
|
576
576
|
var overlay = document.createElement('div');
|
|
@@ -185,6 +185,14 @@ function renderIssueView() {
|
|
|
185
185
|
</div>
|
|
186
186
|
|
|
187
187
|
<div class="flex items-center gap-3">
|
|
188
|
+
<!-- Pull from GitHub Button -->
|
|
189
|
+
<button class="issue-pull-btn" onclick="showPullIssuesModal()" title="Pull issues from GitHub repository">
|
|
190
|
+
<svg class="w-4 h-4 mr-1.5" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
191
|
+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v 3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
|
192
|
+
</svg>
|
|
193
|
+
<span>Pull from GitHub</span>
|
|
194
|
+
</button>
|
|
195
|
+
|
|
188
196
|
<!-- Create Button -->
|
|
189
197
|
<button class="issue-create-btn" onclick="showCreateIssueModal()">
|
|
190
198
|
<i data-lucide="plus" class="w-4 h-4"></i>
|
|
@@ -281,6 +289,59 @@ function renderIssueView() {
|
|
|
281
289
|
</div>
|
|
282
290
|
</div>
|
|
283
291
|
</div>
|
|
292
|
+
|
|
293
|
+
<!-- Pull Issues Modal -->
|
|
294
|
+
<div id="pullIssuesModal" class="issue-modal hidden">
|
|
295
|
+
<div class="issue-modal-backdrop" onclick="hidePullIssuesModal()"></div>
|
|
296
|
+
<div class="issue-modal-content">
|
|
297
|
+
<div class="issue-modal-header">
|
|
298
|
+
<h3>
|
|
299
|
+
<svg class="w-5 h-5 inline mr-2 -mt-1" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
300
|
+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
|
301
|
+
</svg>
|
|
302
|
+
Pull Issues from GitHub
|
|
303
|
+
</h3>
|
|
304
|
+
<button class="btn-icon" onclick="hidePullIssuesModal()">
|
|
305
|
+
<i data-lucide="x" class="w-5 h-5"></i>
|
|
306
|
+
</button>
|
|
307
|
+
</div>
|
|
308
|
+
<div class="issue-modal-body">
|
|
309
|
+
<div class="form-group">
|
|
310
|
+
<label>Issue State</label>
|
|
311
|
+
<select id="pullIssueState">
|
|
312
|
+
<option value="open" selected>Open</option>
|
|
313
|
+
<option value="closed">Closed</option>
|
|
314
|
+
<option value="all">All</option>
|
|
315
|
+
</select>
|
|
316
|
+
</div>
|
|
317
|
+
<div class="form-group">
|
|
318
|
+
<label>Maximum Issues</label>
|
|
319
|
+
<input type="number" id="pullIssueLimit" value="20" min="1" max="100" />
|
|
320
|
+
</div>
|
|
321
|
+
<div class="form-group">
|
|
322
|
+
<label>Labels (optional)</label>
|
|
323
|
+
<input type="text" id="pullIssueLabels" placeholder="bug, enhancement (comma-separated)" />
|
|
324
|
+
</div>
|
|
325
|
+
<div class="form-group">
|
|
326
|
+
<label class="checkbox-label">
|
|
327
|
+
<input type="checkbox" id="pullDownloadImages" checked />
|
|
328
|
+
<span>Download images to local</span>
|
|
329
|
+
</label>
|
|
330
|
+
<p class="form-hint text-xs text-muted-foreground mt-1">Images will be saved to .workflow/issues/images/ and links updated in issue context</p>
|
|
331
|
+
</div>
|
|
332
|
+
<div id="pullIssueResult" class="pull-result hidden mt-4 p-3 rounded-md bg-muted"></div>
|
|
333
|
+
</div>
|
|
334
|
+
<div class="issue-modal-footer">
|
|
335
|
+
<button class="btn-secondary" onclick="hidePullIssuesModal()">Cancel</button>
|
|
336
|
+
<button class="btn-primary" id="pullIssuesBtn" onclick="pullGitHubIssues()">
|
|
337
|
+
<svg class="w-4 h-4 mr-1 inline" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
338
|
+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
|
339
|
+
</svg>
|
|
340
|
+
Pull Issues
|
|
341
|
+
</button>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
</div>
|
|
284
345
|
</div>
|
|
285
346
|
`;
|
|
286
347
|
|
|
@@ -650,7 +711,7 @@ function renderQueueCard(queue, isActive) {
|
|
|
650
711
|
<span class="queue-card-id font-mono">${safeQueueId}</span>
|
|
651
712
|
<div class="queue-card-badges">
|
|
652
713
|
${isActive ? '<span class="queue-active-badge">Active</span>' : ''}
|
|
653
|
-
|
|
714
|
+
${!isActive || queue.status !== 'active' ? `<span class="queue-status-badge ${statusClass}">${queue.status || 'unknown'}</span>` : ''}
|
|
654
715
|
</div>
|
|
655
716
|
</div>
|
|
656
717
|
|
|
@@ -2627,6 +2688,127 @@ function hideCreateIssueModal() {
|
|
|
2627
2688
|
}
|
|
2628
2689
|
}
|
|
2629
2690
|
|
|
2691
|
+
// ========== Pull Issues Modal ==========
|
|
2692
|
+
function showPullIssuesModal() {
|
|
2693
|
+
const modal = document.getElementById('pullIssuesModal');
|
|
2694
|
+
if (modal) {
|
|
2695
|
+
modal.classList.remove('hidden');
|
|
2696
|
+
// Reset result area
|
|
2697
|
+
const resultDiv = document.getElementById('pullIssueResult');
|
|
2698
|
+
if (resultDiv) {
|
|
2699
|
+
resultDiv.classList.add('hidden');
|
|
2700
|
+
resultDiv.innerHTML = '';
|
|
2701
|
+
}
|
|
2702
|
+
lucide.createIcons();
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
function hidePullIssuesModal() {
|
|
2707
|
+
const modal = document.getElementById('pullIssuesModal');
|
|
2708
|
+
if (modal) {
|
|
2709
|
+
modal.classList.add('hidden');
|
|
2710
|
+
// Clear form
|
|
2711
|
+
const stateSelect = document.getElementById('pullIssueState');
|
|
2712
|
+
const limitInput = document.getElementById('pullIssueLimit');
|
|
2713
|
+
const labelsInput = document.getElementById('pullIssueLabels');
|
|
2714
|
+
const downloadImagesCheck = document.getElementById('pullDownloadImages');
|
|
2715
|
+
if (stateSelect) stateSelect.value = 'open';
|
|
2716
|
+
if (limitInput) limitInput.value = '20';
|
|
2717
|
+
if (labelsInput) labelsInput.value = '';
|
|
2718
|
+
if (downloadImagesCheck) downloadImagesCheck.checked = true;
|
|
2719
|
+
}
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2722
|
+
async function pullGitHubIssues() {
|
|
2723
|
+
const stateSelect = document.getElementById('pullIssueState');
|
|
2724
|
+
const limitInput = document.getElementById('pullIssueLimit');
|
|
2725
|
+
const labelsInput = document.getElementById('pullIssueLabels');
|
|
2726
|
+
const downloadImagesCheck = document.getElementById('pullDownloadImages');
|
|
2727
|
+
const resultDiv = document.getElementById('pullIssueResult');
|
|
2728
|
+
const pullBtn = document.getElementById('pullIssuesBtn');
|
|
2729
|
+
|
|
2730
|
+
const state = stateSelect?.value || 'open';
|
|
2731
|
+
const limit = parseInt(limitInput?.value || '20');
|
|
2732
|
+
const labels = labelsInput?.value?.trim();
|
|
2733
|
+
const downloadImages = downloadImagesCheck?.checked || false;
|
|
2734
|
+
|
|
2735
|
+
// Disable button and show loading
|
|
2736
|
+
if (pullBtn) {
|
|
2737
|
+
pullBtn.disabled = true;
|
|
2738
|
+
pullBtn.innerHTML = '<i data-lucide="loader-2" class="w-4 h-4 mr-1 animate-spin"></i>' + (t('common.loading') || 'Loading...');
|
|
2739
|
+
lucide.createIcons();
|
|
2740
|
+
}
|
|
2741
|
+
|
|
2742
|
+
try {
|
|
2743
|
+
const params = new URLSearchParams({
|
|
2744
|
+
path: projectPath,
|
|
2745
|
+
state: state,
|
|
2746
|
+
limit: limit.toString(),
|
|
2747
|
+
downloadImages: downloadImages.toString()
|
|
2748
|
+
});
|
|
2749
|
+
if (labels) params.set('labels', labels);
|
|
2750
|
+
|
|
2751
|
+
const response = await fetch('/api/issues/pull?' + params.toString(), {
|
|
2752
|
+
method: 'POST'
|
|
2753
|
+
});
|
|
2754
|
+
|
|
2755
|
+
const result = await response.json();
|
|
2756
|
+
|
|
2757
|
+
if (!response.ok || result.error) {
|
|
2758
|
+
showNotification(result.error || 'Failed to pull issues', 'error');
|
|
2759
|
+
if (resultDiv) {
|
|
2760
|
+
resultDiv.classList.remove('hidden');
|
|
2761
|
+
resultDiv.innerHTML = `<p class="text-destructive">${result.error || 'Failed to pull issues'}</p>`;
|
|
2762
|
+
}
|
|
2763
|
+
return;
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2766
|
+
// Show results
|
|
2767
|
+
if (resultDiv) {
|
|
2768
|
+
resultDiv.classList.remove('hidden');
|
|
2769
|
+
resultDiv.innerHTML = `
|
|
2770
|
+
<div class="flex items-start gap-2">
|
|
2771
|
+
<i data-lucide="check-circle" class="w-5 h-5 text-success mt-0.5"></i>
|
|
2772
|
+
<div class="flex-1">
|
|
2773
|
+
<p class="font-medium mb-2">${t('issues.pullSuccess') || 'GitHub Issues Pulled Successfully'}</p>
|
|
2774
|
+
<div class="text-sm text-muted-foreground space-y-1">
|
|
2775
|
+
<p>✓ Imported: <strong>${result.imported || 0}</strong> new issues</p>
|
|
2776
|
+
<p>✓ Updated: <strong>${result.updated || 0}</strong> existing issues</p>
|
|
2777
|
+
<p>✓ Skipped: <strong>${result.skipped || 0}</strong> unchanged issues</p>
|
|
2778
|
+
${result.images_downloaded > 0 ? `<p>✓ Downloaded: <strong>${result.images_downloaded}</strong> images</p>` : ''}
|
|
2779
|
+
</div>
|
|
2780
|
+
</div>
|
|
2781
|
+
</div>
|
|
2782
|
+
`;
|
|
2783
|
+
lucide.createIcons();
|
|
2784
|
+
}
|
|
2785
|
+
|
|
2786
|
+
showNotification(`Pulled ${result.imported + result.updated} issues from GitHub`, 'success');
|
|
2787
|
+
|
|
2788
|
+
// Reload data after 1 second
|
|
2789
|
+
setTimeout(async () => {
|
|
2790
|
+
await loadIssueData();
|
|
2791
|
+
renderIssueView();
|
|
2792
|
+
hidePullIssuesModal();
|
|
2793
|
+
}, 1500);
|
|
2794
|
+
|
|
2795
|
+
} catch (err) {
|
|
2796
|
+
console.error('Failed to pull issues:', err);
|
|
2797
|
+
showNotification('Failed to pull issues', 'error');
|
|
2798
|
+
if (resultDiv) {
|
|
2799
|
+
resultDiv.classList.remove('hidden');
|
|
2800
|
+
resultDiv.innerHTML = `<p class="text-destructive">${err.message || 'Unknown error occurred'}</p>`;
|
|
2801
|
+
}
|
|
2802
|
+
} finally {
|
|
2803
|
+
// Re-enable button
|
|
2804
|
+
if (pullBtn) {
|
|
2805
|
+
pullBtn.disabled = false;
|
|
2806
|
+
pullBtn.innerHTML = '<i data-lucide="download" class="w-4 h-4 mr-1"></i>' + (t('issues.pull') || 'Pull');
|
|
2807
|
+
lucide.createIcons();
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
|
|
2630
2812
|
async function createIssue() {
|
|
2631
2813
|
const idInput = document.getElementById('newIssueId');
|
|
2632
2814
|
const titleInput = document.getElementById('newIssueTitle');
|
|
@@ -418,7 +418,7 @@ function showMultiCliDetailPage(sessionKey) {
|
|
|
418
418
|
</div>
|
|
419
419
|
|
|
420
420
|
<!-- Tab Content -->
|
|
421
|
-
<div class="detail-tab-content" id="multiCliDetailTabContent">
|
|
421
|
+
<div class="detail-tab-content active" id="multiCliDetailTabContent">
|
|
422
422
|
${renderMultiCliTasksTab(session)}
|
|
423
423
|
</div>
|
|
424
424
|
</div>
|
|
@@ -653,12 +653,17 @@ function switchMultiCliDetailTab(tabName) {
|
|
|
653
653
|
break;
|
|
654
654
|
case 'context':
|
|
655
655
|
loadAndRenderMultiCliContextTab(session, contentArea);
|
|
656
|
+
contentArea.classList.add('active');
|
|
656
657
|
return; // Early return as this is async
|
|
657
658
|
case 'summary':
|
|
658
659
|
loadAndRenderMultiCliSummaryTab(session, contentArea);
|
|
660
|
+
contentArea.classList.add('active');
|
|
659
661
|
return; // Early return as this is async
|
|
660
662
|
}
|
|
661
663
|
|
|
664
|
+
// Add active class to show content
|
|
665
|
+
contentArea.classList.add('active');
|
|
666
|
+
|
|
662
667
|
// Re-initialize after tab switch
|
|
663
668
|
setTimeout(() => {
|
|
664
669
|
if (typeof lucide !== 'undefined') lucide.createIcons();
|
|
@@ -1097,13 +1102,52 @@ function renderMultiCliSummaryContent(summary, session) {
|
|
|
1097
1102
|
<span class="section-label"><i data-lucide="lightbulb" class="w-4 h-4 inline mr-1"></i> ${t('multiCli.summary.solutions')} (${synthesis.solutions.length})</span>
|
|
1098
1103
|
</div>
|
|
1099
1104
|
<div class="collapsible-content collapsed">
|
|
1100
|
-
${synthesis.solutions.map((sol, idx) =>
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1105
|
+
${synthesis.solutions.map((sol, idx) => {
|
|
1106
|
+
const name = getI18nText(sol.name) || sol.title || sol.id || `${t('multiCli.summary.solution')} ${idx + 1}`;
|
|
1107
|
+
const summary = getI18nText(sol.summary) || '';
|
|
1108
|
+
const feasibility = sol.feasibility?.score || sol.feasibility || 0;
|
|
1109
|
+
const effort = sol.effort || '';
|
|
1110
|
+
const risk = sol.risk || '';
|
|
1111
|
+
const pros = sol.pros || [];
|
|
1112
|
+
const cons = sol.cons || [];
|
|
1113
|
+
|
|
1114
|
+
return `
|
|
1115
|
+
<div class="solution-card">
|
|
1116
|
+
<div class="solution-header">
|
|
1117
|
+
<div class="solution-title-row">
|
|
1118
|
+
<span class="solution-num">#${idx + 1}</span>
|
|
1119
|
+
<span class="solution-name">${escapeHtml(name)}</span>
|
|
1120
|
+
</div>
|
|
1121
|
+
<div class="solution-badges">
|
|
1122
|
+
${feasibility ? `<span class="badge feasibility">${Math.round(feasibility * 100)}%</span>` : ''}
|
|
1123
|
+
${effort ? `<span class="badge effort ${escapeHtml(effort)}">${escapeHtml(effort)}</span>` : ''}
|
|
1124
|
+
${risk ? `<span class="badge risk ${escapeHtml(risk)}">${escapeHtml(risk)}</span>` : ''}
|
|
1125
|
+
</div>
|
|
1126
|
+
</div>
|
|
1127
|
+
${summary ? `
|
|
1128
|
+
<div class="solution-summary">
|
|
1129
|
+
<p>${escapeHtml(summary)}</p>
|
|
1130
|
+
</div>
|
|
1131
|
+
` : ''}
|
|
1132
|
+
${pros.length > 0 ? `
|
|
1133
|
+
<div class="solution-details">
|
|
1134
|
+
<h5 class="details-label">✓ ${t('multiCli.summary.pros') || 'Pros'}:</h5>
|
|
1135
|
+
<ul class="details-list">
|
|
1136
|
+
${pros.map(p => `<li>${escapeHtml(getI18nText(p) || p)}</li>`).join('')}
|
|
1137
|
+
</ul>
|
|
1138
|
+
</div>
|
|
1139
|
+
` : ''}
|
|
1140
|
+
${cons.length > 0 ? `
|
|
1141
|
+
<div class="solution-details">
|
|
1142
|
+
<h5 class="details-label">✗ ${t('multiCli.summary.cons') || 'Cons'}:</h5>
|
|
1143
|
+
<ul class="details-list">
|
|
1144
|
+
${cons.map(c => `<li>${escapeHtml(getI18nText(c) || c)}</li>`).join('')}
|
|
1145
|
+
</ul>
|
|
1146
|
+
</div>
|
|
1147
|
+
` : ''}
|
|
1148
|
+
</div>
|
|
1149
|
+
`;
|
|
1150
|
+
}).join('')}
|
|
1107
1151
|
</div>
|
|
1108
1152
|
</div>
|
|
1109
1153
|
`);
|
|
@@ -2722,12 +2766,12 @@ function showLiteTaskDetailPage(sessionKey) {
|
|
|
2722
2766
|
<div class="detail-header">
|
|
2723
2767
|
<button class="btn-back" onclick="goBackToLiteTasks()">
|
|
2724
2768
|
<span class="back-icon">←</span>
|
|
2725
|
-
<span
|
|
2769
|
+
<span>${session.type === 'lite-plan' ? t('lite.backToList', { type: 'Plan' }) : session.type === 'lite-fix' ? t('lite.backToList', { type: 'Fix' }) : t('multiCli.backToList')}</span>
|
|
2726
2770
|
</button>
|
|
2727
2771
|
<div class="detail-title-row">
|
|
2728
|
-
<h2 class="detail-session-id">${session.type === 'lite-plan' ? '<i data-lucide="file-edit" class="w-5 h-5 inline mr-2"></i>' : '<i data-lucide="wrench" class="w-5 h-5 inline mr-2"></i>'} ${escapeHtml(session.id)}</h2>
|
|
2772
|
+
<h2 class="detail-session-id">${session.type === 'lite-plan' ? '<i data-lucide="file-edit" class="w-5 h-5 inline mr-2"></i>' : session.type === 'lite-fix' ? '<i data-lucide="wrench" class="w-5 h-5 inline mr-2"></i>' : '<i data-lucide="speech-icon" class="w-5 h-5 inline mr-2"></i>'} ${escapeHtml(session.id)}</h2>
|
|
2729
2773
|
<div class="detail-badges">
|
|
2730
|
-
<span class="session-type-badge ${session.type}">${session.type}</span>
|
|
2774
|
+
<span class="session-type-badge ${session.type}">${session.type === 'multi-cli-plan' ? 'MULTI-CLI' : session.type}</span>
|
|
2731
2775
|
</div>
|
|
2732
2776
|
</div>
|
|
2733
2777
|
</div>
|
|
@@ -1012,15 +1012,24 @@ async function saveTaskOrder(loopId, newOrder) {
|
|
|
1012
1012
|
|
|
1013
1013
|
/**
|
|
1014
1014
|
* Show add task modal
|
|
1015
|
+
* Loads enabled tools before displaying modal to prevent race conditions
|
|
1015
1016
|
*/
|
|
1016
1017
|
async function showAddTaskModal(loopId) {
|
|
1017
|
-
//
|
|
1018
|
-
const
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1018
|
+
// Find and disable the "Add Task" button to prevent multiple clicks during loading
|
|
1019
|
+
const addTaskButton = event?.target;
|
|
1020
|
+
if (addTaskButton) {
|
|
1021
|
+
addTaskButton.disabled = true;
|
|
1022
|
+
const originalText = addTaskButton.innerHTML;
|
|
1023
|
+
addTaskButton.innerHTML = '<i class="spinner"></i> ' + (t('common.loading') || 'Loading...');
|
|
1024
|
+
|
|
1025
|
+
try {
|
|
1026
|
+
// Get enabled tools (this ensures tools are loaded before modal opens)
|
|
1027
|
+
const enabledTools = await getEnabledTools();
|
|
1028
|
+
|
|
1029
|
+
// Build tool options HTML
|
|
1030
|
+
const toolOptions = enabledTools.map(tool =>
|
|
1031
|
+
`<option value="${tool}">${tool.charAt(0).toUpperCase() + tool.slice(1)}</option>`
|
|
1032
|
+
).join('');
|
|
1024
1033
|
|
|
1025
1034
|
const modal = document.createElement('div');
|
|
1026
1035
|
modal.id = 'addTaskModal';
|
|
@@ -1075,11 +1084,103 @@ async function showAddTaskModal(loopId) {
|
|
|
1075
1084
|
</div>
|
|
1076
1085
|
`;
|
|
1077
1086
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1087
|
+
document.body.appendChild(modal);
|
|
1088
|
+
if (typeof lucide !== 'undefined') lucide.createIcons();
|
|
1080
1089
|
|
|
1081
|
-
|
|
1082
|
-
|
|
1090
|
+
// Focus on description field
|
|
1091
|
+
setTimeout(() => document.getElementById('taskDescription').focus(), 100);
|
|
1092
|
+
|
|
1093
|
+
} catch (err) {
|
|
1094
|
+
console.error('Failed to show add task modal:', err);
|
|
1095
|
+
alert(t('loop.loadToolsError') || 'Failed to load available tools. Please try again.');
|
|
1096
|
+
} finally {
|
|
1097
|
+
// Restore button state
|
|
1098
|
+
if (addTaskButton) {
|
|
1099
|
+
addTaskButton.disabled = false;
|
|
1100
|
+
addTaskButton.innerHTML = originalText;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
} else {
|
|
1104
|
+
// Fallback if event is not available (shouldn't happen normally)
|
|
1105
|
+
const enabledTools = await getEnabledTools();
|
|
1106
|
+
const toolOptions = enabledTools.map(tool =>
|
|
1107
|
+
`<option value="${tool}">${tool.charAt(0).toUpperCase() + tool.slice(1)}</option>`
|
|
1108
|
+
).join('');
|
|
1109
|
+
|
|
1110
|
+
const modal = document.createElement('div');
|
|
1111
|
+
modal.id = 'addTaskModal';
|
|
1112
|
+
modal.className = 'modal-overlay';
|
|
1113
|
+
modal.innerHTML = `
|
|
1114
|
+
<div class="modal-content">
|
|
1115
|
+
<div class="modal-header">
|
|
1116
|
+
<h3><i data-lucide="plus-circle" class="w-5 h-5"></i> ${t('loop.addTask') || 'Add Task'}</h3>
|
|
1117
|
+
<button class="modal-close" onclick="closeTaskModal()">
|
|
1118
|
+
<i data-lucide="x" class="w-5 h-5"></i>
|
|
1119
|
+
</button>
|
|
1120
|
+
</div>
|
|
1121
|
+
<div class="modal-body">
|
|
1122
|
+
<form id="addTaskForm" onsubmit="handleAddTask(event, '${loopId}')">
|
|
1123
|
+
<div id="addTaskError" class="alert alert-error" style="display: none;"></div>
|
|
1124
|
+
|
|
1125
|
+
<!-- Description -->
|
|
1126
|
+
<div class="form-group">
|
|
1127
|
+
<label for="taskDescription">${t('loop.taskDescription') || 'Task Description'} <span class="required">*</span></label>
|
|
1128
|
+
<textarea id="taskDescription" name="description" rows="3" required
|
|
1129
|
+
placeholder="${t('loop.taskDescriptionPlaceholder') || 'Describe what this task should do...'}"
|
|
1130
|
+
class="form-control"></textarea>
|
|
1131
|
+
</div>
|
|
1132
|
+
|
|
1133
|
+
<!-- Tool -->
|
|
1134
|
+
<div class="form-group">
|
|
1135
|
+
<label for="taskTool">${t('loop.tool') || 'Tool'}</label>
|
|
1136
|
+
<select id="taskTool" name="tool" class="form-control">
|
|
1137
|
+
${toolOptions}
|
|
1138
|
+
</select>
|
|
1139
|
+
</div>
|
|
1140
|
+
|
|
1141
|
+
<!-- Mode -->
|
|
1142
|
+
<div class="form-group">
|
|
1143
|
+
<label for="taskMode">${t('loop.mode') || 'Mode'}</label>
|
|
1144
|
+
<select id="taskMode" name="mode" class="form-control">
|
|
1145
|
+
<option value="analysis">${t('loop.modeAnalysis') || 'Analysis'}</option>
|
|
1146
|
+
<option value="write">${t('loop.modeWrite') || 'Write'}</option>
|
|
1147
|
+
<option value="review">${t('loop.modeReview') || 'Review'}</option>
|
|
1148
|
+
</select>
|
|
1149
|
+
</div>
|
|
1150
|
+
|
|
1151
|
+
<!-- Prompt Template -->
|
|
1152
|
+
<div class="form-group">
|
|
1153
|
+
<label for="taskPrompt">${t('loop.promptTemplate') || 'Prompt Template'} <span class="required">*</span></label>
|
|
1154
|
+
<textarea id="taskPrompt" name="prompt_template" rows="5" required
|
|
1155
|
+
placeholder="${t('loop.promptPlaceholder') || 'Enter the prompt to execute...'}"
|
|
1156
|
+
class="form-control"></textarea>
|
|
1157
|
+
<small class="form-help">${t('loop.promptHelp') || 'Variables: {iteration}, {output_prev}'}</small>
|
|
1158
|
+
</div>
|
|
1159
|
+
|
|
1160
|
+
<!-- Error Handling -->
|
|
1161
|
+
<div class="form-group">
|
|
1162
|
+
<label for="taskOnError">${t('loop.onError') || 'On Error'}</label>
|
|
1163
|
+
<select id="taskOnError" name="on_error" class="form-control">
|
|
1164
|
+
<option value="continue">${t('loop.errorContinue') || 'Continue'}</option>
|
|
1165
|
+
<option value="pause">${t('loop.errorPause') || 'Pause'}</option>
|
|
1166
|
+
<option value="fail_fast">${t('loop.errorFailFast') || 'Fail Fast'}</option>
|
|
1167
|
+
</select>
|
|
1168
|
+
</div>
|
|
1169
|
+
|
|
1170
|
+
<!-- Form Actions -->
|
|
1171
|
+
<div class="modal-footer">
|
|
1172
|
+
<button type="button" class="btn btn-secondary" onclick="closeTaskModal()">${t('loop.cancel') || 'Cancel'}</button>
|
|
1173
|
+
<button type="submit" class="btn btn-primary">${t('loop.add') || 'Add'}</button>
|
|
1174
|
+
</div>
|
|
1175
|
+
</form>
|
|
1176
|
+
</div>
|
|
1177
|
+
</div>
|
|
1178
|
+
`;
|
|
1179
|
+
|
|
1180
|
+
document.body.appendChild(modal);
|
|
1181
|
+
if (typeof lucide !== 'undefined') lucide.createIcons();
|
|
1182
|
+
setTimeout(() => document.getElementById('taskDescription').focus(), 100);
|
|
1183
|
+
}
|
|
1083
1184
|
}
|
|
1084
1185
|
|
|
1085
1186
|
/**
|