claude-code-workflow 6.3.27 → 6.3.29
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/CLAUDE.md +7 -1
- package/.claude/agents/action-planning-agent.md +1 -0
- package/.claude/agents/cli-discuss-agent.md +391 -0
- package/.claude/agents/cli-execution-agent.md +2 -0
- package/.claude/agents/cli-explore-agent.md +2 -1
- package/.claude/agents/cli-lite-planning-agent.md +1 -0
- package/.claude/agents/cli-planning-agent.md +1 -0
- package/.claude/agents/code-developer.md +1 -0
- package/.claude/agents/conceptual-planning-agent.md +2 -0
- package/.claude/agents/context-search-agent.md +1 -0
- package/.claude/agents/debug-explore-agent.md +2 -0
- package/.claude/agents/doc-generator.md +1 -0
- package/.claude/agents/issue-plan-agent.md +2 -1
- package/.claude/agents/issue-queue-agent.md +2 -1
- package/.claude/agents/memory-bridge.md +2 -0
- package/.claude/agents/test-context-search-agent.md +2 -0
- package/.claude/agents/test-fix-agent.md +1 -0
- package/.claude/agents/ui-design-agent.md +2 -0
- package/.claude/agents/universal-executor.md +1 -0
- package/.claude/commands/issue/execute.md +269 -176
- package/.claude/commands/workflow/debug.md +6 -0
- package/.claude/commands/workflow/execute.md +4 -0
- package/.claude/commands/workflow/lite-execute.md +4 -0
- package/.claude/commands/workflow/lite-lite-lite.md +433 -0
- package/.claude/commands/workflow/multi-cli-plan.md +510 -0
- package/.claude/commands/workflow/review-fix.md +4 -0
- package/.claude/commands/workflow/test-cycle-execute.md +4 -0
- package/.claude/skills/ccw/SKILL.md +262 -372
- package/.claude/skills/ccw/command.json +547 -0
- package/.claude/skills/ccw-help/SKILL.md +46 -107
- package/.claude/skills/ccw-help/command.json +511 -0
- package/.claude/skills/skill-tuning/SKILL.md +303 -0
- package/.claude/skills/skill-tuning/phases/actions/action-abort.md +164 -0
- package/.claude/skills/skill-tuning/phases/actions/action-analyze-requirements.md +406 -0
- package/.claude/skills/skill-tuning/phases/actions/action-apply-fix.md +206 -0
- package/.claude/skills/skill-tuning/phases/actions/action-complete.md +195 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-agent.md +317 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-context.md +243 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-dataflow.md +318 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-docs.md +299 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-memory.md +269 -0
- package/.claude/skills/skill-tuning/phases/actions/action-diagnose-token-consumption.md +200 -0
- package/.claude/skills/skill-tuning/phases/actions/action-gemini-analysis.md +322 -0
- package/.claude/skills/skill-tuning/phases/actions/action-generate-report.md +228 -0
- package/.claude/skills/skill-tuning/phases/actions/action-init.md +149 -0
- package/.claude/skills/skill-tuning/phases/actions/action-propose-fixes.md +317 -0
- package/.claude/skills/skill-tuning/phases/actions/action-verify.md +222 -0
- package/.claude/skills/skill-tuning/phases/orchestrator.md +377 -0
- package/.claude/skills/skill-tuning/phases/state-schema.md +378 -0
- package/.claude/skills/skill-tuning/specs/category-mappings.json +284 -0
- package/.claude/skills/skill-tuning/specs/dimension-mapping.md +212 -0
- package/.claude/skills/skill-tuning/specs/problem-taxonomy.md +318 -0
- package/.claude/skills/skill-tuning/specs/quality-gates.md +263 -0
- package/.claude/skills/skill-tuning/specs/skill-authoring-principles.md +189 -0
- package/.claude/skills/skill-tuning/specs/tuning-strategies.md +1537 -0
- package/.claude/skills/skill-tuning/templates/diagnosis-report.md +153 -0
- package/.claude/skills/skill-tuning/templates/fix-proposal.md +204 -0
- package/.claude/workflows/cli-templates/schemas/multi-cli-discussion-schema.json +421 -0
- package/.claude/workflows/cli-tools-usage.md +0 -41
- package/.codex/prompts/issue-execute.md +72 -12
- package/README.md +3 -0
- package/ccw/dist/core/data-aggregator.d.ts +2 -0
- package/ccw/dist/core/data-aggregator.d.ts.map +1 -1
- package/ccw/dist/core/data-aggregator.js +5 -2
- package/ccw/dist/core/data-aggregator.js.map +1 -1
- package/ccw/dist/core/lite-scanner.d.ts +2 -1
- package/ccw/dist/core/lite-scanner.d.ts.map +1 -1
- package/ccw/dist/core/lite-scanner.js +348 -6
- package/ccw/dist/core/lite-scanner.js.map +1 -1
- package/ccw/dist/core/routes/session-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/session-routes.js +166 -48
- package/ccw/dist/core/routes/session-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 +87 -0
- package/ccw/dist/core/routes/system-routes.js.map +1 -1
- package/ccw/dist/core/server.js +2 -2
- package/ccw/dist/core/server.js.map +1 -1
- package/ccw/dist/tools/memory-update-queue.d.ts.map +1 -1
- package/ccw/dist/tools/memory-update-queue.js +5 -11
- package/ccw/dist/tools/memory-update-queue.js.map +1 -1
- package/ccw/scripts/IMPLEMENTATION-SUMMARY.md +226 -0
- package/ccw/scripts/QUICK-REFERENCE.md +135 -0
- package/ccw/scripts/README-memory-embedder.md +157 -0
- package/ccw/scripts/__pycache__/memory_embedder.cpython-313.pyc +0 -0
- package/ccw/scripts/__pycache__/test_memory_embedder.cpython-313-pytest-8.4.2.pyc +0 -0
- package/ccw/scripts/memory-embedder-example.ts +184 -0
- package/ccw/scripts/memory_embedder.py +428 -0
- package/ccw/scripts/test_memory_embedder.py +245 -0
- package/ccw/src/core/data-aggregator.ts +7 -2
- package/ccw/src/core/lite-scanner.ts +495 -6
- package/ccw/src/core/routes/session-routes.ts +201 -48
- package/ccw/src/core/routes/system-routes.ts +102 -0
- package/ccw/src/core/server.ts +2 -2
- package/ccw/src/templates/dashboard-css/01-base.css +8 -0
- package/ccw/src/templates/dashboard-css/02-session.css +81 -0
- package/ccw/src/templates/dashboard-css/03-tasks.css +5 -0
- package/ccw/src/templates/dashboard-css/04-lite-tasks.css +3071 -0
- package/ccw/src/templates/dashboard-css/21-cli-toolmgmt.css +157 -0
- package/ccw/src/templates/dashboard-css/32-issue-manager.css +23 -0
- package/ccw/src/templates/dashboard-js/components/cli-stream-viewer.js +38 -4
- package/ccw/src/templates/dashboard-js/components/hook-manager.js +68 -34
- package/ccw/src/templates/dashboard-js/components/navigation.js +24 -4
- package/ccw/src/templates/dashboard-js/i18n.js +278 -4
- package/ccw/src/templates/dashboard-js/views/api-settings.js +32 -0
- package/ccw/src/templates/dashboard-js/views/claude-manager.js +44 -3
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +303 -31
- package/ccw/src/templates/dashboard-js/views/history.js +44 -6
- package/ccw/src/templates/dashboard-js/views/home.js +1 -0
- package/ccw/src/templates/dashboard-js/views/issue-manager.js +54 -7
- package/ccw/src/templates/dashboard-js/views/lite-tasks.js +2621 -4
- package/ccw/src/templates/dashboard.html +5 -0
- package/ccw/src/tools/memory-update-queue.js +5 -11
- package/package.json +2 -1
- package/.claude/skills/ccw/index/command-capabilities.json +0 -127
- package/.claude/skills/ccw/index/intent-rules.json +0 -136
- package/.claude/skills/ccw/index/workflow-chains.json +0 -451
- package/.claude/skills/ccw/phases/actions/bugfix.md +0 -218
- package/.claude/skills/ccw/phases/actions/coupled.md +0 -194
- package/.claude/skills/ccw/phases/actions/docs.md +0 -93
- package/.claude/skills/ccw/phases/actions/full.md +0 -154
- package/.claude/skills/ccw/phases/actions/issue.md +0 -201
- package/.claude/skills/ccw/phases/actions/rapid.md +0 -104
- package/.claude/skills/ccw/phases/actions/review-fix.md +0 -84
- package/.claude/skills/ccw/phases/actions/tdd.md +0 -66
- package/.claude/skills/ccw/phases/actions/ui.md +0 -79
- package/.claude/skills/ccw/phases/orchestrator.md +0 -435
- package/.claude/skills/ccw/specs/intent-classification.md +0 -336
- package/.claude/skills/ccw-help/index/all-agents.json +0 -82
- package/.claude/skills/ccw-help/index/all-commands.json +0 -882
- package/.claude/skills/ccw-help/index/by-category.json +0 -914
- package/.claude/skills/ccw-help/index/by-use-case.json +0 -896
- package/.claude/skills/ccw-help/index/command-relationships.json +0 -160
- package/.claude/skills/ccw-help/index/essential-commands.json +0 -112
|
@@ -661,3 +661,160 @@
|
|
|
661
661
|
color: hsl(var(--success));
|
|
662
662
|
}
|
|
663
663
|
|
|
664
|
+
/* ========================================
|
|
665
|
+
* File Browser Modal
|
|
666
|
+
* ======================================== */
|
|
667
|
+
|
|
668
|
+
.file-browser-modal {
|
|
669
|
+
width: 600px;
|
|
670
|
+
max-width: 90vw;
|
|
671
|
+
max-height: 80vh;
|
|
672
|
+
display: flex;
|
|
673
|
+
flex-direction: column;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
.file-browser-toolbar {
|
|
677
|
+
display: flex;
|
|
678
|
+
align-items: center;
|
|
679
|
+
gap: 0.5rem;
|
|
680
|
+
padding: 0.5rem;
|
|
681
|
+
background: hsl(var(--muted) / 0.3);
|
|
682
|
+
border-radius: 0.375rem;
|
|
683
|
+
margin-bottom: 0.75rem;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
.file-browser-toolbar .btn-sm {
|
|
687
|
+
flex-shrink: 0;
|
|
688
|
+
padding: 0.375rem;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
.file-browser-path {
|
|
692
|
+
flex: 1;
|
|
693
|
+
padding: 0.375rem 0.5rem;
|
|
694
|
+
font-family: monospace;
|
|
695
|
+
font-size: 0.75rem;
|
|
696
|
+
background: hsl(var(--background));
|
|
697
|
+
border: 1px solid hsl(var(--border));
|
|
698
|
+
border-radius: 0.25rem;
|
|
699
|
+
color: hsl(var(--foreground));
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
.file-browser-path:focus {
|
|
703
|
+
outline: none;
|
|
704
|
+
border-color: hsl(var(--primary));
|
|
705
|
+
box-shadow: 0 0 0 2px hsl(var(--primary) / 0.2);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
.file-browser-drives {
|
|
709
|
+
display: flex;
|
|
710
|
+
gap: 0.25rem;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
.btn-xs {
|
|
714
|
+
padding: 0.25rem 0.5rem;
|
|
715
|
+
font-size: 0.6875rem;
|
|
716
|
+
border-radius: 0.25rem;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.drive-btn {
|
|
720
|
+
font-family: monospace;
|
|
721
|
+
font-weight: 600;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
.file-browser-hidden-toggle {
|
|
725
|
+
display: flex;
|
|
726
|
+
align-items: center;
|
|
727
|
+
gap: 0.375rem;
|
|
728
|
+
font-size: 0.75rem;
|
|
729
|
+
color: hsl(var(--muted-foreground));
|
|
730
|
+
cursor: pointer;
|
|
731
|
+
white-space: nowrap;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
.file-browser-hidden-toggle input {
|
|
735
|
+
cursor: pointer;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.file-browser-list {
|
|
739
|
+
flex: 1;
|
|
740
|
+
min-height: 300px;
|
|
741
|
+
max-height: 400px;
|
|
742
|
+
overflow-y: auto;
|
|
743
|
+
border: 1px solid hsl(var(--border));
|
|
744
|
+
border-radius: 0.375rem;
|
|
745
|
+
background: hsl(var(--background));
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
.file-browser-loading,
|
|
749
|
+
.file-browser-empty {
|
|
750
|
+
display: flex;
|
|
751
|
+
align-items: center;
|
|
752
|
+
justify-content: center;
|
|
753
|
+
height: 100%;
|
|
754
|
+
min-height: 200px;
|
|
755
|
+
color: hsl(var(--muted-foreground));
|
|
756
|
+
font-size: 0.875rem;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
.file-browser-error {
|
|
760
|
+
display: flex;
|
|
761
|
+
flex-direction: column;
|
|
762
|
+
align-items: center;
|
|
763
|
+
justify-content: center;
|
|
764
|
+
height: 100%;
|
|
765
|
+
min-height: 200px;
|
|
766
|
+
font-size: 0.875rem;
|
|
767
|
+
text-align: center;
|
|
768
|
+
padding: 1rem;
|
|
769
|
+
gap: 0.5rem;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
.file-browser-error p {
|
|
773
|
+
margin: 0;
|
|
774
|
+
color: hsl(var(--destructive));
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
.file-browser-hint {
|
|
778
|
+
color: hsl(var(--muted-foreground));
|
|
779
|
+
font-size: 0.8rem;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
.file-browser-item {
|
|
783
|
+
display: flex;
|
|
784
|
+
align-items: center;
|
|
785
|
+
gap: 0.5rem;
|
|
786
|
+
padding: 0.5rem 0.75rem;
|
|
787
|
+
cursor: pointer;
|
|
788
|
+
border-bottom: 1px solid hsl(var(--border) / 0.5);
|
|
789
|
+
transition: background-color 0.15s;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
.file-browser-item:last-child {
|
|
793
|
+
border-bottom: none;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
.file-browser-item:hover {
|
|
797
|
+
background: hsl(var(--muted) / 0.5);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
.file-browser-item.selected {
|
|
801
|
+
background: hsl(var(--primary) / 0.15);
|
|
802
|
+
border-color: hsl(var(--primary) / 0.3);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
.file-browser-item.is-directory {
|
|
806
|
+
color: hsl(var(--primary));
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
.file-browser-item.is-file {
|
|
810
|
+
color: hsl(var(--foreground));
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
.file-browser-item-name {
|
|
814
|
+
flex: 1;
|
|
815
|
+
font-size: 0.8125rem;
|
|
816
|
+
overflow: hidden;
|
|
817
|
+
text-overflow: ellipsis;
|
|
818
|
+
white-space: nowrap;
|
|
819
|
+
}
|
|
820
|
+
|
|
@@ -128,6 +128,29 @@
|
|
|
128
128
|
box-shadow: 0 4px 12px hsl(var(--foreground) / 0.08);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
/* Archived Issue Card */
|
|
132
|
+
.issue-card.archived {
|
|
133
|
+
opacity: 0.85;
|
|
134
|
+
background: hsl(var(--muted) / 0.3);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.issue-card.archived:hover {
|
|
138
|
+
opacity: 1;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.issue-archived-badge {
|
|
142
|
+
display: inline-flex;
|
|
143
|
+
align-items: center;
|
|
144
|
+
padding: 0.125rem 0.375rem;
|
|
145
|
+
background: hsl(var(--muted));
|
|
146
|
+
color: hsl(var(--muted-foreground));
|
|
147
|
+
font-size: 0.625rem;
|
|
148
|
+
font-weight: 500;
|
|
149
|
+
border-radius: 0.25rem;
|
|
150
|
+
text-transform: uppercase;
|
|
151
|
+
letter-spacing: 0.025em;
|
|
152
|
+
}
|
|
153
|
+
|
|
131
154
|
.issue-card-header {
|
|
132
155
|
display: flex;
|
|
133
156
|
align-items: flex-start;
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
* Real-time streaming output viewer for CLI executions
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
// ===== Lifecycle Management =====
|
|
7
|
+
let cliStreamViewerDestroy = null;
|
|
8
|
+
let streamKeyboardHandler = null;
|
|
9
|
+
let streamScrollHandler = null; // Track scroll listener
|
|
10
|
+
let streamStatusTimers = []; // Track status update timers
|
|
11
|
+
|
|
6
12
|
// ===== State Management =====
|
|
7
13
|
let cliStreamExecutions = {}; // { executionId: { tool, mode, output, status, startTime, endTime } }
|
|
8
14
|
let activeStreamTab = null;
|
|
@@ -91,7 +97,7 @@ async function syncActiveExecutions() {
|
|
|
91
97
|
// ===== Initialization =====
|
|
92
98
|
function initCliStreamViewer() {
|
|
93
99
|
// Initialize keyboard shortcuts
|
|
94
|
-
|
|
100
|
+
streamKeyboardHandler = function(e) {
|
|
95
101
|
if (e.key === 'Escape' && isCliStreamViewerOpen) {
|
|
96
102
|
if (searchFilter) {
|
|
97
103
|
clearSearch();
|
|
@@ -108,12 +114,14 @@ function initCliStreamViewer() {
|
|
|
108
114
|
searchInput.select();
|
|
109
115
|
}
|
|
110
116
|
}
|
|
111
|
-
}
|
|
117
|
+
};
|
|
118
|
+
document.addEventListener('keydown', streamKeyboardHandler);
|
|
112
119
|
|
|
113
120
|
// Initialize scroll detection for auto-scroll
|
|
114
121
|
const content = document.getElementById('cliStreamContent');
|
|
115
122
|
if (content) {
|
|
116
|
-
|
|
123
|
+
streamScrollHandler = handleStreamContentScroll;
|
|
124
|
+
content.addEventListener('scroll', streamScrollHandler);
|
|
117
125
|
}
|
|
118
126
|
|
|
119
127
|
// Sync active executions from server (recover state for mid-execution joins)
|
|
@@ -592,11 +600,12 @@ function renderStreamStatus(executionId) {
|
|
|
592
600
|
|
|
593
601
|
// Update duration periodically for running executions
|
|
594
602
|
if (exec.status === 'running') {
|
|
595
|
-
setTimeout(() => {
|
|
603
|
+
const timerId = setTimeout(() => {
|
|
596
604
|
if (activeStreamTab === executionId && cliStreamExecutions[executionId]?.status === 'running') {
|
|
597
605
|
renderStreamStatus(executionId);
|
|
598
606
|
}
|
|
599
607
|
}, 1000);
|
|
608
|
+
streamStatusTimers.push(timerId);
|
|
600
609
|
}
|
|
601
610
|
}
|
|
602
611
|
|
|
@@ -760,6 +769,31 @@ if (document.readyState === 'loading') {
|
|
|
760
769
|
initCliStreamViewer();
|
|
761
770
|
}
|
|
762
771
|
|
|
772
|
+
// ===== Lifecycle Functions =====
|
|
773
|
+
function destroyCliStreamViewer() {
|
|
774
|
+
// Remove keyboard event listener if exists
|
|
775
|
+
if (streamKeyboardHandler) {
|
|
776
|
+
document.removeEventListener('keydown', streamKeyboardHandler);
|
|
777
|
+
streamKeyboardHandler = null;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// Remove scroll event listener if exists
|
|
781
|
+
if (streamScrollHandler) {
|
|
782
|
+
const content = document.getElementById('cliStreamContent');
|
|
783
|
+
if (content) {
|
|
784
|
+
content.removeEventListener('scroll', streamScrollHandler);
|
|
785
|
+
}
|
|
786
|
+
streamScrollHandler = null;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
// Clear all pending status update timers
|
|
790
|
+
streamStatusTimers.forEach(timerId => clearTimeout(timerId));
|
|
791
|
+
streamStatusTimers = [];
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// Export lifecycle functions
|
|
795
|
+
window.destroyCliStreamViewer = destroyCliStreamViewer;
|
|
796
|
+
|
|
763
797
|
// ===== Global Exposure =====
|
|
764
798
|
window.toggleCliStreamViewer = toggleCliStreamViewer;
|
|
765
799
|
window.handleCliStreamStarted = handleCliStreamStarted;
|
|
@@ -52,12 +52,13 @@ const HOOK_TEMPLATES = {
|
|
|
52
52
|
'memory-update-queue': {
|
|
53
53
|
event: 'Stop',
|
|
54
54
|
matcher: '',
|
|
55
|
-
command: '
|
|
56
|
-
args: ['-
|
|
55
|
+
command: 'node',
|
|
56
|
+
args: ['-e', "require('child_process').spawnSync(process.platform==='win32'?'cmd':'ccw',process.platform==='win32'?['/c','ccw','tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'gemini'})]:['tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'gemini'})],{stdio:'inherit'})"],
|
|
57
57
|
description: 'Queue CLAUDE.md update when session ends (batched by threshold/timeout)',
|
|
58
58
|
category: 'memory',
|
|
59
59
|
configurable: true,
|
|
60
60
|
config: {
|
|
61
|
+
tool: { type: 'select', default: 'gemini', options: ['gemini', 'qwen', 'codex', 'opencode'], label: 'CLI Tool' },
|
|
61
62
|
threshold: { type: 'number', default: 5, min: 1, max: 20, label: 'Threshold (paths)', step: 1 },
|
|
62
63
|
timeout: { type: 'number', default: 300, min: 60, max: 1800, label: 'Timeout (seconds)', step: 60 }
|
|
63
64
|
}
|
|
@@ -66,8 +67,8 @@ const HOOK_TEMPLATES = {
|
|
|
66
67
|
'skill-context-keyword': {
|
|
67
68
|
event: 'UserPromptSubmit',
|
|
68
69
|
matcher: '',
|
|
69
|
-
command: '
|
|
70
|
-
args: ['-
|
|
70
|
+
command: 'node',
|
|
71
|
+
args: ['-e', "const p=JSON.parse(process.env.HOOK_INPUT||'{}');require('child_process').spawnSync('ccw',['tool','exec','skill_context_loader',JSON.stringify({prompt:p.user_prompt||''})],{stdio:'inherit'})"],
|
|
71
72
|
description: 'Load SKILL context based on keyword matching in user prompt',
|
|
72
73
|
category: 'skill',
|
|
73
74
|
configurable: true,
|
|
@@ -79,8 +80,8 @@ const HOOK_TEMPLATES = {
|
|
|
79
80
|
'skill-context-auto': {
|
|
80
81
|
event: 'UserPromptSubmit',
|
|
81
82
|
matcher: '',
|
|
82
|
-
command: '
|
|
83
|
-
args: ['-
|
|
83
|
+
command: 'node',
|
|
84
|
+
args: ['-e', "const p=JSON.parse(process.env.HOOK_INPUT||'{}');require('child_process').spawnSync('ccw',['tool','exec','skill_context_loader',JSON.stringify({mode:'auto',prompt:p.user_prompt||''})],{stdio:'inherit'})"],
|
|
84
85
|
description: 'Auto-detect and load SKILL based on skill name in prompt',
|
|
85
86
|
category: 'skill',
|
|
86
87
|
configurable: false
|
|
@@ -195,6 +196,7 @@ const WIZARD_TEMPLATES = {
|
|
|
195
196
|
}
|
|
196
197
|
],
|
|
197
198
|
configFields: [
|
|
199
|
+
{ key: 'tool', type: 'select', label: 'CLI Tool', default: 'gemini', options: ['gemini', 'qwen', 'codex', 'opencode'], description: 'CLI tool for CLAUDE.md generation' },
|
|
198
200
|
{ key: 'threshold', type: 'number', label: 'Threshold (paths)', default: 5, min: 1, max: 20, step: 1, description: 'Number of paths to trigger batch update' },
|
|
199
201
|
{ key: 'timeout', type: 'number', label: 'Timeout (seconds)', default: 300, min: 60, max: 1800, step: 60, description: 'Auto-flush queue after this time' }
|
|
200
202
|
]
|
|
@@ -359,48 +361,73 @@ async function loadAvailableSkills() {
|
|
|
359
361
|
* Convert internal hook format to Claude Code format
|
|
360
362
|
* Internal: { command, args, matcher, timeout }
|
|
361
363
|
* Claude Code: { matcher, hooks: [{ type: "command", command: "...", timeout }] }
|
|
364
|
+
*
|
|
365
|
+
* IMPORTANT: For bash -c commands, use single quotes to wrap the script argument
|
|
366
|
+
* to avoid complex escaping issues with jq commands inside.
|
|
367
|
+
* See: https://github.com/catlog22/Claude-Code-Workflow/issues/73
|
|
362
368
|
*/
|
|
363
369
|
function convertToClaudeCodeFormat(hookData) {
|
|
364
370
|
// If already in correct format, return as-is
|
|
365
371
|
if (hookData.hooks && Array.isArray(hookData.hooks)) {
|
|
366
372
|
return hookData;
|
|
367
373
|
}
|
|
368
|
-
|
|
374
|
+
|
|
369
375
|
// Build command string from command + args
|
|
370
376
|
let commandStr = hookData.command || '';
|
|
371
377
|
if (hookData.args && Array.isArray(hookData.args)) {
|
|
372
|
-
//
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
378
|
+
// Special handling for bash -c commands: use single quotes for the script
|
|
379
|
+
// This avoids complex escaping issues with jq and other shell commands
|
|
380
|
+
if (commandStr === 'bash' && hookData.args.length >= 2 && hookData.args[0] === '-c') {
|
|
381
|
+
// Use single quotes for bash -c script argument
|
|
382
|
+
// Single quotes prevent shell expansion, so internal double quotes work naturally
|
|
383
|
+
const script = hookData.args[1];
|
|
384
|
+
// Escape single quotes within the script: ' -> '\''
|
|
385
|
+
const escapedScript = script.replace(/'/g, "'\\''");
|
|
386
|
+
commandStr = `bash -c '${escapedScript}'`;
|
|
387
|
+
// Handle any additional args after the script
|
|
388
|
+
if (hookData.args.length > 2) {
|
|
389
|
+
const additionalArgs = hookData.args.slice(2).map(arg => {
|
|
390
|
+
if (arg.includes(' ') && !arg.startsWith('"') && !arg.startsWith("'")) {
|
|
391
|
+
return `"${arg.replace(/"/g, '\\"')}"`;
|
|
392
|
+
}
|
|
393
|
+
return arg;
|
|
394
|
+
});
|
|
395
|
+
commandStr += ' ' + additionalArgs.join(' ');
|
|
376
396
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
397
|
+
} else {
|
|
398
|
+
// Default handling for other commands
|
|
399
|
+
const quotedArgs = hookData.args.map(arg => {
|
|
400
|
+
if (arg.includes(' ') && !arg.startsWith('"') && !arg.startsWith("'")) {
|
|
401
|
+
return `"${arg.replace(/"/g, '\\"')}"`;
|
|
402
|
+
}
|
|
403
|
+
return arg;
|
|
404
|
+
});
|
|
405
|
+
commandStr = `${commandStr} ${quotedArgs.join(' ')}`.trim();
|
|
406
|
+
}
|
|
380
407
|
}
|
|
381
|
-
|
|
408
|
+
|
|
382
409
|
const converted = {
|
|
383
410
|
hooks: [{
|
|
384
411
|
type: 'command',
|
|
385
412
|
command: commandStr
|
|
386
413
|
}]
|
|
387
414
|
};
|
|
388
|
-
|
|
415
|
+
|
|
389
416
|
// Add matcher if present (not needed for UserPromptSubmit, Stop, etc.)
|
|
390
417
|
if (hookData.matcher) {
|
|
391
418
|
converted.matcher = hookData.matcher;
|
|
392
419
|
}
|
|
393
|
-
|
|
420
|
+
|
|
394
421
|
// Add timeout if present (in seconds for Claude Code)
|
|
395
422
|
if (hookData.timeout) {
|
|
396
423
|
converted.hooks[0].timeout = Math.ceil(hookData.timeout / 1000);
|
|
397
424
|
}
|
|
398
|
-
|
|
425
|
+
|
|
399
426
|
// Preserve replaceIndex for updates
|
|
400
427
|
if (hookData.replaceIndex !== undefined) {
|
|
401
428
|
converted.replaceIndex = hookData.replaceIndex;
|
|
402
429
|
}
|
|
403
|
-
|
|
430
|
+
|
|
404
431
|
return converted;
|
|
405
432
|
}
|
|
406
433
|
|
|
@@ -723,6 +750,7 @@ function renderWizardModalContent() {
|
|
|
723
750
|
// Helper to get translated field labels
|
|
724
751
|
const getFieldLabel = (fieldKey) => {
|
|
725
752
|
const labels = {
|
|
753
|
+
'tool': t('hook.wizard.cliTool') || 'CLI Tool',
|
|
726
754
|
'threshold': t('hook.wizard.thresholdPaths') || 'Threshold (paths)',
|
|
727
755
|
'timeout': t('hook.wizard.timeoutSeconds') || 'Timeout (seconds)'
|
|
728
756
|
};
|
|
@@ -731,6 +759,7 @@ function renderWizardModalContent() {
|
|
|
731
759
|
|
|
732
760
|
const getFieldDesc = (fieldKey) => {
|
|
733
761
|
const descs = {
|
|
762
|
+
'tool': t('hook.wizard.cliToolDesc') || 'CLI tool for CLAUDE.md generation',
|
|
734
763
|
'threshold': t('hook.wizard.thresholdPathsDesc') || 'Number of paths to trigger batch update',
|
|
735
764
|
'timeout': t('hook.wizard.timeoutSecondsDesc') || 'Auto-flush queue after this time'
|
|
736
765
|
};
|
|
@@ -1096,20 +1125,19 @@ function generateWizardCommand() {
|
|
|
1096
1125
|
keywords: c.keywords.split(',').map(k => k.trim()).filter(k => k)
|
|
1097
1126
|
}));
|
|
1098
1127
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1128
|
+
// Use node + spawnSync for cross-platform JSON handling
|
|
1129
|
+
const paramsObj = { configs: configJson, prompt: '${p.user_prompt}' };
|
|
1130
|
+
return `node -e "const p=JSON.parse(process.env.HOOK_INPUT||'{}');require('child_process').spawnSync('ccw',['tool','exec','skill_context_loader',JSON.stringify(${JSON.stringify(paramsObj).replace('${p.user_prompt}', "'+p.user_prompt+'")})],{stdio:'inherit'})"`;
|
|
1101
1131
|
} else {
|
|
1102
|
-
// auto mode
|
|
1103
|
-
const
|
|
1104
|
-
return `ccw tool exec skill_context_loader '${params}'`;
|
|
1132
|
+
// auto mode - use node + spawnSync
|
|
1133
|
+
return `node -e "const p=JSON.parse(process.env.HOOK_INPUT||'{}');require('child_process').spawnSync('ccw',['tool','exec','skill_context_loader',JSON.stringify({mode:'auto',prompt:p.user_prompt||''})],{stdio:'inherit'})"`;
|
|
1105
1134
|
}
|
|
1106
1135
|
}
|
|
1107
1136
|
|
|
1108
1137
|
// Handle memory-update wizard (default)
|
|
1109
|
-
//
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
return `ccw tool exec memory_queue ${params}`;
|
|
1138
|
+
// Use node + spawnSync for cross-platform JSON handling
|
|
1139
|
+
const selectedTool = wizardConfig.tool || 'gemini';
|
|
1140
|
+
return `node -e "require('child_process').spawnSync(process.platform==='win32'?'cmd':'ccw',process.platform==='win32'?['/c','ccw','tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'${selectedTool}'})]:['tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'${selectedTool}'})],{stdio:'inherit'})"`;
|
|
1113
1141
|
}
|
|
1114
1142
|
|
|
1115
1143
|
async function submitHookWizard() {
|
|
@@ -1192,13 +1220,18 @@ async function submitHookWizard() {
|
|
|
1192
1220
|
const baseTemplate = HOOK_TEMPLATES[selectedOption.templateId];
|
|
1193
1221
|
if (!baseTemplate) return;
|
|
1194
1222
|
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
args: ['-c', command]
|
|
1223
|
+
// Build hook data with configured values
|
|
1224
|
+
let hookData = {
|
|
1225
|
+
command: baseTemplate.command,
|
|
1226
|
+
args: [...baseTemplate.args]
|
|
1200
1227
|
};
|
|
1201
1228
|
|
|
1229
|
+
// For memory-update wizard, use configured tool in args (cross-platform)
|
|
1230
|
+
if (wizard.id === 'memory-update') {
|
|
1231
|
+
const selectedTool = wizardConfig.tool || 'gemini';
|
|
1232
|
+
hookData.args = ['-e', `require('child_process').spawnSync(process.platform==='win32'?'cmd':'ccw',process.platform==='win32'?['/c','ccw','tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'${selectedTool}'})]:['tool','exec','memory_queue',JSON.stringify({action:'add',path:process.env.CLAUDE_PROJECT_DIR,tool:'${selectedTool}'})],{stdio:'inherit'})`];
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1202
1235
|
if (baseTemplate.matcher) {
|
|
1203
1236
|
hookData.matcher = baseTemplate.matcher;
|
|
1204
1237
|
}
|
|
@@ -1207,6 +1240,7 @@ async function submitHookWizard() {
|
|
|
1207
1240
|
|
|
1208
1241
|
// For memory-update wizard, also configure queue settings
|
|
1209
1242
|
if (wizard.id === 'memory-update') {
|
|
1243
|
+
const selectedTool = wizardConfig.tool || 'gemini';
|
|
1210
1244
|
const threshold = wizardConfig.threshold || 5;
|
|
1211
1245
|
const timeout = wizardConfig.timeout || 300;
|
|
1212
1246
|
try {
|
|
@@ -1217,7 +1251,7 @@ async function submitHookWizard() {
|
|
|
1217
1251
|
body: JSON.stringify({ tool: 'memory_queue', params: configParams })
|
|
1218
1252
|
});
|
|
1219
1253
|
if (response.ok) {
|
|
1220
|
-
showRefreshToast(`Queue configured: threshold=${threshold}, timeout=${timeout}s`, 'success');
|
|
1254
|
+
showRefreshToast(`Queue configured: tool=${selectedTool}, threshold=${threshold}, timeout=${timeout}s`, 'success');
|
|
1221
1255
|
}
|
|
1222
1256
|
} catch (e) {
|
|
1223
1257
|
console.warn('Failed to configure memory queue:', e);
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// Navigation and Routing
|
|
2
2
|
// Manages navigation events, active state, content title updates, search, and path selector
|
|
3
3
|
|
|
4
|
+
// View lifecycle management
|
|
5
|
+
var currentViewDestroy = null;
|
|
6
|
+
|
|
4
7
|
// Path Selector
|
|
5
8
|
function initPathSelector() {
|
|
6
9
|
const btn = document.getElementById('pathButton');
|
|
@@ -54,6 +57,11 @@ function initPathSelector() {
|
|
|
54
57
|
|
|
55
58
|
// Cleanup function for view transitions
|
|
56
59
|
function cleanupPreviousView() {
|
|
60
|
+
// Call current view's destroy function if exists
|
|
61
|
+
if (currentViewDestroy) {
|
|
62
|
+
currentViewDestroy();
|
|
63
|
+
currentViewDestroy = null;
|
|
64
|
+
}
|
|
57
65
|
// Cleanup graph explorer
|
|
58
66
|
if (currentView === 'graph-explorer' && typeof window.cleanupGraphExplorer === 'function') {
|
|
59
67
|
window.cleanupGraphExplorer();
|
|
@@ -121,6 +129,10 @@ function initNavigation() {
|
|
|
121
129
|
renderCliManager();
|
|
122
130
|
} else if (currentView === 'cli-history') {
|
|
123
131
|
renderCliHistoryView();
|
|
132
|
+
// Register destroy function for cli-history view
|
|
133
|
+
if (typeof window.destroyCliHistoryView === 'function') {
|
|
134
|
+
currentViewDestroy = window.destroyCliHistoryView;
|
|
135
|
+
}
|
|
124
136
|
} else if (currentView === 'hook-manager') {
|
|
125
137
|
renderHookManager();
|
|
126
138
|
} else if (currentView === 'memory') {
|
|
@@ -133,6 +145,10 @@ function initNavigation() {
|
|
|
133
145
|
renderRulesManager();
|
|
134
146
|
} else if (currentView === 'claude-manager') {
|
|
135
147
|
renderClaudeManager();
|
|
148
|
+
// Register destroy function for claude-manager view
|
|
149
|
+
if (typeof window.initClaudeManager === 'function') {
|
|
150
|
+
window.initClaudeManager();
|
|
151
|
+
}
|
|
136
152
|
} else if (currentView === 'graph-explorer') {
|
|
137
153
|
renderGraphExplorer();
|
|
138
154
|
} else if (currentView === 'help') {
|
|
@@ -216,8 +232,10 @@ function updateContentTitle() {
|
|
|
216
232
|
} else if (currentView === 'issue-discovery') {
|
|
217
233
|
titleEl.textContent = t('title.issueDiscovery');
|
|
218
234
|
} else if (currentView === 'liteTasks') {
|
|
219
|
-
const names = { 'lite-plan': t('title.litePlanSessions'), 'lite-fix': t('title.liteFixSessions') };
|
|
235
|
+
const names = { 'lite-plan': t('title.litePlanSessions'), 'lite-fix': t('title.liteFixSessions'), 'multi-cli-plan': t('title.multiCliPlanSessions') || 'Multi-CLI Plan Sessions' };
|
|
220
236
|
titleEl.textContent = names[currentLiteType] || t('title.liteTasks');
|
|
237
|
+
} else if (currentView === 'multiCliDetail') {
|
|
238
|
+
titleEl.textContent = t('title.multiCliDetail') || 'Multi-CLI Discussion Detail';
|
|
221
239
|
} else if (currentView === 'sessionDetail') {
|
|
222
240
|
titleEl.textContent = t('title.sessionDetail');
|
|
223
241
|
} else if (currentView === 'liteTaskDetail') {
|
|
@@ -319,12 +337,14 @@ function updateSidebarCounts(data) {
|
|
|
319
337
|
if (archivedCount) archivedCount.textContent = data.archivedSessions?.length || 0;
|
|
320
338
|
if (allCount) allCount.textContent = (data.activeSessions?.length || 0) + (data.archivedSessions?.length || 0);
|
|
321
339
|
|
|
322
|
-
// Update lite task counts
|
|
323
|
-
const litePlanCount = document.
|
|
324
|
-
const liteFixCount = document.
|
|
340
|
+
// Update lite task counts (using ID selectors to match dashboard.html structure)
|
|
341
|
+
const litePlanCount = document.getElementById('badgeLitePlan');
|
|
342
|
+
const liteFixCount = document.getElementById('badgeLiteFix');
|
|
343
|
+
const multiCliPlanCount = document.getElementById('badgeMultiCliPlan');
|
|
325
344
|
|
|
326
345
|
if (litePlanCount) litePlanCount.textContent = data.liteTasks?.litePlan?.length || 0;
|
|
327
346
|
if (liteFixCount) liteFixCount.textContent = data.liteTasks?.liteFix?.length || 0;
|
|
347
|
+
if (multiCliPlanCount) multiCliPlanCount.textContent = data.liteTasks?.multiCliPlan?.length || 0;
|
|
328
348
|
}
|
|
329
349
|
|
|
330
350
|
// ========== Navigation Badge Aggregation ==========
|