claude-code-workflow 6.3.43 → 6.3.44

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.
Files changed (77) hide show
  1. package/.claude/agents/tdd-developer.md +530 -0
  2. package/.claude/commands/issue/discover-by-prompt.md +5 -1
  3. package/.claude/commands/issue/discover.md +472 -468
  4. package/.claude/commands/issue/execute.md +580 -581
  5. package/.claude/commands/issue/new.md +417 -413
  6. package/.claude/commands/issue/plan.md +5 -1
  7. package/.claude/commands/issue/queue.md +445 -441
  8. package/.claude/commands/task/breakdown.md +207 -203
  9. package/.claude/commands/task/replan.md +440 -436
  10. package/.claude/commands/workflow/action-plan-verify.md +485 -447
  11. package/.claude/commands/workflow/brainstorm/artifacts.md +457 -453
  12. package/.claude/commands/workflow/brainstorm/auto-parallel.md +5 -1
  13. package/.claude/commands/workflow/brainstorm/synthesis.md +402 -398
  14. package/.claude/commands/workflow/clean.md +67 -35
  15. package/.claude/commands/workflow/debug-with-file.md +670 -666
  16. package/.claude/commands/workflow/debug.md +331 -327
  17. package/.claude/commands/workflow/develop-with-file.md +5 -1
  18. package/.claude/commands/workflow/execute.md +546 -498
  19. package/.claude/commands/workflow/lite-execute.md +44 -26
  20. package/.claude/commands/workflow/lite-fix.md +780 -730
  21. package/.claude/commands/workflow/lite-lite-lite.md +5 -1
  22. package/.claude/commands/workflow/lite-plan.md +87 -39
  23. package/.claude/commands/workflow/multi-cli-plan.md +572 -568
  24. package/.claude/commands/workflow/plan-verify.md +527 -0
  25. package/.claude/commands/workflow/plan.md +555 -551
  26. package/.claude/commands/workflow/replan.md +572 -515
  27. package/.claude/commands/workflow/review-fix.md +608 -610
  28. package/.claude/commands/workflow/session/complete.md +37 -14
  29. package/.claude/commands/workflow/session/solidify.md +303 -299
  30. package/.claude/commands/workflow/tdd-plan.md +630 -597
  31. package/.claude/commands/workflow/tdd-verify.md +391 -206
  32. package/.claude/commands/workflow/tools/conflict-resolution.md +24 -12
  33. package/.claude/commands/workflow/tools/task-generate-agent.md +583 -563
  34. package/.claude/commands/workflow/tools/task-generate-tdd.md +749 -517
  35. package/.claude/commands/workflow/ui-design/animation-extract.md +1154 -1150
  36. package/.claude/commands/workflow/ui-design/layout-extract.md +792 -788
  37. package/.claude/commands/workflow/ui-design/style-extract.md +777 -773
  38. package/.claude/skills/ccw/command.json +4 -4
  39. package/.claude/skills/ccw-coordinator/README.md +45 -0
  40. package/.claude/skills/ccw-coordinator/SKILL.md +320 -0
  41. package/.claude/skills/ccw-coordinator/phases/actions/action-abort.md +9 -0
  42. package/.claude/skills/ccw-coordinator/phases/actions/action-command-build.md +40 -0
  43. package/.claude/skills/ccw-coordinator/phases/actions/action-command-execute.md +124 -0
  44. package/.claude/skills/ccw-coordinator/phases/actions/action-command-selection.md +48 -0
  45. package/.claude/skills/ccw-coordinator/phases/actions/action-complete.md +25 -0
  46. package/.claude/skills/ccw-coordinator/phases/actions/action-init.md +26 -0
  47. package/.claude/skills/ccw-coordinator/phases/orchestrator.md +59 -0
  48. package/.claude/skills/ccw-coordinator/phases/state-schema.md +66 -0
  49. package/.claude/skills/ccw-coordinator/skill-config.json +66 -0
  50. package/.claude/skills/ccw-coordinator/specs/command-library.md +169 -0
  51. package/.claude/skills/ccw-coordinator/specs/specs.md +362 -0
  52. package/.claude/skills/ccw-coordinator/tools/README.md +95 -0
  53. package/.claude/skills/ccw-coordinator/tools/chain-validate.cjs +320 -0
  54. package/.claude/skills/ccw-coordinator/tools/command-registry.cjs +255 -0
  55. package/.claude/skills/ccw-help/command.json +5 -5
  56. package/.claude/skills/ccw-help/scripts/analyze_commands.py +337 -337
  57. package/.claude/workflows/cli-templates/prompts/workflow-impl-plan-template.txt +1 -1
  58. package/ccw/dist/commands/issue.d.ts +4 -0
  59. package/ccw/dist/commands/issue.d.ts.map +1 -1
  60. package/ccw/dist/commands/issue.js +73 -6
  61. package/ccw/dist/commands/issue.js.map +1 -1
  62. package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
  63. package/ccw/dist/core/routes/cli-routes.js +32 -28
  64. package/ccw/dist/core/routes/cli-routes.js.map +1 -1
  65. package/ccw/dist/tools/claude-cli-tools.d.ts +10 -0
  66. package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -1
  67. package/ccw/dist/tools/claude-cli-tools.js +45 -0
  68. package/ccw/dist/tools/claude-cli-tools.js.map +1 -1
  69. package/ccw/dist/tools/codex-lens.d.ts.map +1 -1
  70. package/ccw/dist/tools/codex-lens.js +38 -11
  71. package/ccw/dist/tools/codex-lens.js.map +1 -1
  72. package/ccw/src/commands/issue.ts +84 -6
  73. package/ccw/src/core/routes/cli-routes.ts +30 -25
  74. package/ccw/src/templates/dashboard-js/views/help.js +1 -1
  75. package/ccw/src/tools/claude-cli-tools.ts +50 -0
  76. package/ccw/src/tools/codex-lens.ts +40 -11
  77. package/package.json +1 -1
@@ -1,413 +1,417 @@
1
- ---
2
- name: new
3
- description: Create structured issue from GitHub URL or text description
4
- argument-hint: "<github-url | text-description> [--priority 1-5]"
5
- allowed-tools: TodoWrite(*), Bash(*), Read(*), AskUserQuestion(*), mcp__ace-tool__search_context(*)
6
- ---
7
-
8
- # Issue New Command (/issue:new)
9
-
10
- ## Core Principle
11
-
12
- **Requirement Clarity Detection** Ask only when needed
13
-
14
- ```
15
- Clear Input (GitHub URL, structured text) → Direct creation
16
- Unclear Input (vague description) Minimal clarifying questions
17
- ```
18
-
19
- ## Issue Structure
20
-
21
- ```typescript
22
- interface Issue {
23
- id: string; // GH-123 or ISS-YYYYMMDD-HHMMSS
24
- title: string;
25
- status: 'registered' | 'planned' | 'queued' | 'in_progress' | 'completed' | 'failed';
26
- priority: number; // 1 (critical) to 5 (low)
27
- context: string; // Problem description (single source of truth)
28
- source: 'github' | 'text' | 'discovery';
29
- source_url?: string;
30
- labels?: string[];
31
-
32
- // GitHub binding (for non-GitHub sources that publish to GitHub)
33
- github_url?: string; // https://github.com/owner/repo/issues/123
34
- github_number?: number; // 123
35
-
36
- // Optional structured fields
37
- expected_behavior?: string;
38
- actual_behavior?: string;
39
- affected_components?: string[];
40
-
41
- // Feedback history (failures + human clarifications)
42
- feedback?: {
43
- type: 'failure' | 'clarification' | 'rejection';
44
- stage: string; // new/plan/execute
45
- content: string;
46
- created_at: string;
47
- }[];
48
-
49
- // Solution binding
50
- bound_solution_id: string | null;
51
-
52
- // Timestamps
53
- created_at: string;
54
- updated_at: string;
55
- }
56
- ```
57
-
58
- ## Quick Reference
59
-
60
- ```bash
61
- # Clear inputs - direct creation
62
- /issue:new https://github.com/owner/repo/issues/123
63
- /issue:new "Login fails with special chars. Expected: success. Actual: 500 error"
64
-
65
- # Vague input - will ask clarifying questions
66
- /issue:new "something wrong with auth"
67
- ```
68
-
69
- ## Implementation
70
-
71
- ### Phase 1: Input Analysis & Clarity Detection
72
-
73
- ```javascript
74
- const input = userInput.trim();
75
- const flags = parseFlags(userInput); // --priority
76
-
77
- // Detect input type and clarity
78
- const isGitHubUrl = input.match(/github\.com\/[\w-]+\/[\w-]+\/issues\/\d+/);
79
- const isGitHubShort = input.match(/^#(\d+)$/);
80
- const hasStructure = input.match(/(expected|actual|affects|steps):/i);
81
-
82
- // Clarity score: 0-3
83
- let clarityScore = 0;
84
- if (isGitHubUrl || isGitHubShort) clarityScore = 3; // GitHub = fully clear
85
- else if (hasStructure) clarityScore = 2; // Structured text = clear
86
- else if (input.length > 50) clarityScore = 1; // Long text = somewhat clear
87
- else clarityScore = 0; // Vague
88
-
89
- let issueData = {};
90
- ```
91
-
92
- ### Phase 2: Data Extraction (GitHub or Text)
93
-
94
- ```javascript
95
- if (isGitHubUrl || isGitHubShort) {
96
- // GitHub - fetch via gh CLI
97
- const result = Bash(`gh issue view ${extractIssueRef(input)} --json number,title,body,labels,url`);
98
- const gh = JSON.parse(result);
99
- issueData = {
100
- id: `GH-${gh.number}`,
101
- title: gh.title,
102
- source: 'github',
103
- source_url: gh.url,
104
- labels: gh.labels.map(l => l.name),
105
- context: gh.body?.substring(0, 500) || gh.title,
106
- ...parseMarkdownBody(gh.body)
107
- };
108
- } else {
109
- // Text description
110
- issueData = {
111
- id: `ISS-${new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14)}`,
112
- source: 'text',
113
- ...parseTextDescription(input)
114
- };
115
- }
116
- ```
117
-
118
- ### Phase 3: Lightweight Context Hint (Conditional)
119
-
120
- ```javascript
121
- // ACE search ONLY for medium clarity (1-2) AND missing components
122
- // Skip for: GitHub (has context), vague (needs clarification first)
123
- // Note: Deep exploration happens in /issue:plan, this is just a quick hint
124
-
125
- if (clarityScore >= 1 && clarityScore <= 2 && !issueData.affected_components?.length) {
126
- const keywords = extractKeywords(issueData.context);
127
-
128
- if (keywords.length >= 2) {
129
- try {
130
- const aceResult = mcp__ace-tool__search_context({
131
- project_root_path: process.cwd(),
132
- query: keywords.slice(0, 3).join(' ')
133
- });
134
- issueData.affected_components = aceResult.files?.slice(0, 3) || [];
135
- } catch {
136
- // ACE failure is non-blocking
137
- }
138
- }
139
- }
140
- ```
141
-
142
- ### Phase 4: Conditional Clarification (Only if Unclear)
143
-
144
- ```javascript
145
- // ONLY ask questions if clarity is low - simple open-ended prompt
146
- if (clarityScore < 2 && (!issueData.context || issueData.context.length < 20)) {
147
- const answer = AskUserQuestion({
148
- questions: [{
149
- question: 'Please describe the issue in more detail:',
150
- header: 'Clarify',
151
- multiSelect: false,
152
- options: [
153
- { label: 'Provide details', description: 'Describe what, where, and expected behavior' }
154
- ]
155
- }]
156
- });
157
-
158
- // Use custom text input (via "Other")
159
- if (answer.customText) {
160
- issueData.context = answer.customText;
161
- issueData.title = answer.customText.split(/[.\n]/)[0].substring(0, 60);
162
- issueData.feedback = [{
163
- type: 'clarification',
164
- stage: 'new',
165
- content: answer.customText,
166
- created_at: new Date().toISOString()
167
- }];
168
- }
169
- }
170
- ```
171
-
172
- ### Phase 5: GitHub Publishing Decision (Non-GitHub Sources)
173
-
174
- ```javascript
175
- // For non-GitHub sources, ask if user wants to publish to GitHub
176
- let publishToGitHub = false;
177
-
178
- if (issueData.source !== 'github') {
179
- const publishAnswer = AskUserQuestion({
180
- questions: [{
181
- question: 'Would you like to publish this issue to GitHub?',
182
- header: 'Publish',
183
- multiSelect: false,
184
- options: [
185
- { label: 'Yes, publish to GitHub', description: 'Create issue on GitHub and link it' },
186
- { label: 'No, keep local only', description: 'Store as local issue without GitHub sync' }
187
- ]
188
- }]
189
- });
190
-
191
- publishToGitHub = publishAnswer.answers?.['Publish']?.includes('Yes');
192
- }
193
- ```
194
-
195
- ### Phase 6: Create Issue
196
-
197
- **Summary Display:**
198
- - Show ID, title, source, affected files (if any)
199
-
200
- **Confirmation** (only for vague inputs, clarityScore < 2):
201
- - Use `AskUserQuestion` to confirm before creation
202
-
203
- **Issue Creation** (via CLI endpoint):
204
- ```bash
205
- # Option 1: Pipe input (recommended for complex JSON - avoids shell escaping)
206
- echo '{"title":"...", "context":"...", "priority":3}' | ccw issue create
207
-
208
- # Option 2: Heredoc (for multi-line JSON)
209
- ccw issue create << 'EOF'
210
- {"title":"...", "context":"含\"引号\"的内容", "priority":3}
211
- EOF
212
-
213
- # Option 3: --data parameter (simple cases only)
214
- ccw issue create --data '{"title":"...", "priority":3}'
215
- ```
216
-
217
- **CLI Endpoint Features:**
218
- | Feature | Description |
219
- |---------|-------------|
220
- | Auto-increment ID | `ISS-YYYYMMDD-NNN` (e.g., `ISS-20251229-001`) |
221
- | Trailing newline | Proper JSONL format, no corruption |
222
- | JSON output | Returns created issue with all fields |
223
-
224
- **Example:**
225
- ```bash
226
- # Create issue via pipe (recommended)
227
- echo '{"title": "Login fails with special chars", "context": "500 error when password contains quotes", "priority": 2}' | ccw issue create
228
-
229
- # Or with heredoc for complex JSON
230
- ccw issue create << 'EOF'
231
- {
232
- "title": "Login fails with special chars",
233
- "context": "500 error when password contains \"quotes\"",
234
- "priority": 2,
235
- "source": "text",
236
- "expected_behavior": "Login succeeds",
237
- "actual_behavior": "500 Internal Server Error"
238
- }
239
- EOF
240
-
241
- # Output (JSON)
242
- {
243
- "id": "ISS-20251229-001",
244
- "title": "Login fails with special chars",
245
- "status": "registered",
246
- ...
247
- }
248
- ```
249
-
250
- **GitHub Publishing** (if user opted in):
251
- ```javascript
252
- // Step 1: Create local issue FIRST
253
- const localIssue = createLocalIssue(issueData); // ccw issue create
254
-
255
- // Step 2: Publish to GitHub if requested
256
- if (publishToGitHub) {
257
- const ghResult = Bash(`gh issue create --title "${issueData.title}" --body "${issueData.context}"`);
258
- // Parse GitHub URL from output
259
- const ghUrl = ghResult.match(/https:\/\/github\.com\/[\w-]+\/[\w-]+\/issues\/\d+/)?.[0];
260
- const ghNumber = parseInt(ghUrl?.match(/\/issues\/(\d+)/)?.[1]);
261
-
262
- if (ghNumber) {
263
- // Step 3: Update local issue with GitHub binding
264
- Bash(`ccw issue update ${localIssue.id} --github-url "${ghUrl}" --github-number ${ghNumber}`);
265
- // Or via pipe:
266
- // echo '{"github_url":"${ghUrl}","github_number":${ghNumber}}' | ccw issue update ${localIssue.id}
267
- }
268
- }
269
- ```
270
-
271
- **Workflow:**
272
- ```
273
- 1. Create local issue (ISS-YYYYMMDD-NNN) → stored in .workflow/issues.jsonl
274
- 2. If publishToGitHub:
275
- a. gh issue create → returns GitHub URL
276
- b. Update local issue with github_url + github_number binding
277
- 3. Both local and GitHub issues exist, linked together
278
- ```
279
-
280
- **Example with GitHub Publishing:**
281
- ```bash
282
- # User creates text issue
283
- /issue:new "Login fails with special chars. Expected: success. Actual: 500"
284
-
285
- # System asks: "Would you like to publish this issue to GitHub?"
286
- # User selects: "Yes, publish to GitHub"
287
-
288
- # Output:
289
- # Local issue created: ISS-20251229-001
290
- # Published to GitHub: https://github.com/org/repo/issues/123
291
- # ✓ GitHub binding saved to local issue
292
- # → Next step: /issue:plan ISS-20251229-001
293
-
294
- # Resulting issue JSON:
295
- {
296
- "id": "ISS-20251229-001",
297
- "title": "Login fails with special chars",
298
- "source": "text",
299
- "github_url": "https://github.com/org/repo/issues/123",
300
- "github_number": 123,
301
- ...
302
- }
303
- ```
304
-
305
- **Completion:**
306
- - Display created issue ID
307
- - Show GitHub URL (if published)
308
- - Show next step: `/issue:plan <id>`
309
-
310
- ## Execution Flow
311
-
312
- ```
313
- Phase 1: Input Analysis
314
- └─ Detect clarity score (GitHub URL? Structured text? Keywords?)
315
-
316
- Phase 2: Data Extraction (branched by clarity)
317
- ┌────────────┬─────────────────┬──────────────┐
318
- │ Score 3 │ Score 1-2 │ Score 0 │
319
- │ GitHub │ Text + ACE │ Vague │
320
- ├────────────┼─────────────────┼──────────────┤
321
- │ gh CLI │ Parse struct │ AskQuestion │
322
- parse + quick hint (1 question)
323
- (3 files max) → feedback
324
- └────────────┴─────────────────┴──────────────┘
325
-
326
- Phase 3: GitHub Publishing Decision (non-GitHub only)
327
- ├─ Source = github: Skip (already from GitHub)
328
- └─ Source ≠ github: AskUserQuestion
329
- ├─ Yes → publishToGitHub = true
330
- └─ No → publishToGitHub = false
331
-
332
- Phase 4: Create Issue
333
- ├─ Score 2: Direct creation
334
- └─ Score < 2: Confirm first → Create
335
- └─ If publishToGitHub: gh issue create → link URL
336
-
337
- Note: Deep exploration & lifecycle deferred to /issue:plan
338
- ```
339
-
340
- ## Helper Functions
341
-
342
- ```javascript
343
- function extractKeywords(text) {
344
- const stopWords = new Set(['the', 'a', 'an', 'is', 'are', 'was', 'were', 'not', 'with']);
345
- return text
346
- .toLowerCase()
347
- .split(/\W+/)
348
- .filter(w => w.length > 3 && !stopWords.has(w))
349
- .slice(0, 5);
350
- }
351
-
352
- function parseTextDescription(text) {
353
- const result = { title: '', context: '' };
354
- const sentences = text.split(/\.(?=\s|$)/);
355
-
356
- result.title = sentences[0]?.trim().substring(0, 60) || 'Untitled';
357
- result.context = text.substring(0, 500);
358
-
359
- // Extract structured fields if present
360
- const expected = text.match(/expected:?\s*([^.]+)/i);
361
- const actual = text.match(/actual:?\s*([^.]+)/i);
362
- const affects = text.match(/affects?:?\s*([^.]+)/i);
363
-
364
- if (expected) result.expected_behavior = expected[1].trim();
365
- if (actual) result.actual_behavior = actual[1].trim();
366
- if (affects) {
367
- result.affected_components = affects[1].split(/[,\s]+/).filter(c => c.includes('/') || c.includes('.'));
368
- }
369
-
370
- return result;
371
- }
372
-
373
- function parseMarkdownBody(body) {
374
- if (!body) return {};
375
- const result = {};
376
-
377
- const problem = body.match(/##?\s*(problem|description)[:\s]*([\s\S]*?)(?=##|$)/i);
378
- const expected = body.match(/##?\s*expected[:\s]*([\s\S]*?)(?=##|$)/i);
379
- const actual = body.match(/##?\s*actual[:\s]*([\s\S]*?)(?=##|$)/i);
380
-
381
- if (problem) result.context = problem[2].trim().substring(0, 500);
382
- if (expected) result.expected_behavior = expected[2].trim();
383
- if (actual) result.actual_behavior = actual[2].trim();
384
-
385
- return result;
386
- }
387
- ```
388
-
389
- ## Examples
390
-
391
- ### Clear Input (No Questions)
392
-
393
- ```bash
394
- /issue:new https://github.com/org/repo/issues/42
395
- # Fetches, parses, creates immediately
396
-
397
- /issue:new "Login fails with special chars. Expected: success. Actual: 500"
398
- # → Parses structure, creates immediately
399
- ```
400
-
401
- ### Vague Input (1 Question)
402
-
403
- ```bash
404
- /issue:new "auth broken"
405
- # Asks: "Input unclear. What is the issue about?"
406
- # → User provides details → saved to feedback[]
407
- # → Creates issue
408
- ```
409
-
410
- ## Related Commands
411
-
412
- - `/issue:plan` - Plan solution for issue
413
-
1
+ ---
2
+ name: new
3
+ description: Create structured issue from GitHub URL or text description
4
+ argument-hint: "[-y|--yes] <github-url | text-description> [--priority 1-5]"
5
+ allowed-tools: TodoWrite(*), Bash(*), Read(*), AskUserQuestion(*), mcp__ace-tool__search_context(*)
6
+ ---
7
+
8
+ ## Auto Mode
9
+
10
+ When `--yes` or `-y`: Skip clarification questions, create issue with inferred details.
11
+
12
+ # Issue New Command (/issue:new)
13
+
14
+ ## Core Principle
15
+
16
+ **Requirement Clarity Detection**Ask only when needed
17
+
18
+ ```
19
+ Clear Input (GitHub URL, structured text) → Direct creation
20
+ Unclear Input (vague description) → Minimal clarifying questions
21
+ ```
22
+
23
+ ## Issue Structure
24
+
25
+ ```typescript
26
+ interface Issue {
27
+ id: string; // GH-123 or ISS-YYYYMMDD-HHMMSS
28
+ title: string;
29
+ status: 'registered' | 'planned' | 'queued' | 'in_progress' | 'completed' | 'failed';
30
+ priority: number; // 1 (critical) to 5 (low)
31
+ context: string; // Problem description (single source of truth)
32
+ source: 'github' | 'text' | 'discovery';
33
+ source_url?: string;
34
+ labels?: string[];
35
+
36
+ // GitHub binding (for non-GitHub sources that publish to GitHub)
37
+ github_url?: string; // https://github.com/owner/repo/issues/123
38
+ github_number?: number; // 123
39
+
40
+ // Optional structured fields
41
+ expected_behavior?: string;
42
+ actual_behavior?: string;
43
+ affected_components?: string[];
44
+
45
+ // Feedback history (failures + human clarifications)
46
+ feedback?: {
47
+ type: 'failure' | 'clarification' | 'rejection';
48
+ stage: string; // new/plan/execute
49
+ content: string;
50
+ created_at: string;
51
+ }[];
52
+
53
+ // Solution binding
54
+ bound_solution_id: string | null;
55
+
56
+ // Timestamps
57
+ created_at: string;
58
+ updated_at: string;
59
+ }
60
+ ```
61
+
62
+ ## Quick Reference
63
+
64
+ ```bash
65
+ # Clear inputs - direct creation
66
+ /issue:new https://github.com/owner/repo/issues/123
67
+ /issue:new "Login fails with special chars. Expected: success. Actual: 500 error"
68
+
69
+ # Vague input - will ask clarifying questions
70
+ /issue:new "something wrong with auth"
71
+ ```
72
+
73
+ ## Implementation
74
+
75
+ ### Phase 1: Input Analysis & Clarity Detection
76
+
77
+ ```javascript
78
+ const input = userInput.trim();
79
+ const flags = parseFlags(userInput); // --priority
80
+
81
+ // Detect input type and clarity
82
+ const isGitHubUrl = input.match(/github\.com\/[\w-]+\/[\w-]+\/issues\/\d+/);
83
+ const isGitHubShort = input.match(/^#(\d+)$/);
84
+ const hasStructure = input.match(/(expected|actual|affects|steps):/i);
85
+
86
+ // Clarity score: 0-3
87
+ let clarityScore = 0;
88
+ if (isGitHubUrl || isGitHubShort) clarityScore = 3; // GitHub = fully clear
89
+ else if (hasStructure) clarityScore = 2; // Structured text = clear
90
+ else if (input.length > 50) clarityScore = 1; // Long text = somewhat clear
91
+ else clarityScore = 0; // Vague
92
+
93
+ let issueData = {};
94
+ ```
95
+
96
+ ### Phase 2: Data Extraction (GitHub or Text)
97
+
98
+ ```javascript
99
+ if (isGitHubUrl || isGitHubShort) {
100
+ // GitHub - fetch via gh CLI
101
+ const result = Bash(`gh issue view ${extractIssueRef(input)} --json number,title,body,labels,url`);
102
+ const gh = JSON.parse(result);
103
+ issueData = {
104
+ id: `GH-${gh.number}`,
105
+ title: gh.title,
106
+ source: 'github',
107
+ source_url: gh.url,
108
+ labels: gh.labels.map(l => l.name),
109
+ context: gh.body?.substring(0, 500) || gh.title,
110
+ ...parseMarkdownBody(gh.body)
111
+ };
112
+ } else {
113
+ // Text description
114
+ issueData = {
115
+ id: `ISS-${new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14)}`,
116
+ source: 'text',
117
+ ...parseTextDescription(input)
118
+ };
119
+ }
120
+ ```
121
+
122
+ ### Phase 3: Lightweight Context Hint (Conditional)
123
+
124
+ ```javascript
125
+ // ACE search ONLY for medium clarity (1-2) AND missing components
126
+ // Skip for: GitHub (has context), vague (needs clarification first)
127
+ // Note: Deep exploration happens in /issue:plan, this is just a quick hint
128
+
129
+ if (clarityScore >= 1 && clarityScore <= 2 && !issueData.affected_components?.length) {
130
+ const keywords = extractKeywords(issueData.context);
131
+
132
+ if (keywords.length >= 2) {
133
+ try {
134
+ const aceResult = mcp__ace-tool__search_context({
135
+ project_root_path: process.cwd(),
136
+ query: keywords.slice(0, 3).join(' ')
137
+ });
138
+ issueData.affected_components = aceResult.files?.slice(0, 3) || [];
139
+ } catch {
140
+ // ACE failure is non-blocking
141
+ }
142
+ }
143
+ }
144
+ ```
145
+
146
+ ### Phase 4: Conditional Clarification (Only if Unclear)
147
+
148
+ ```javascript
149
+ // ONLY ask questions if clarity is low - simple open-ended prompt
150
+ if (clarityScore < 2 && (!issueData.context || issueData.context.length < 20)) {
151
+ const answer = AskUserQuestion({
152
+ questions: [{
153
+ question: 'Please describe the issue in more detail:',
154
+ header: 'Clarify',
155
+ multiSelect: false,
156
+ options: [
157
+ { label: 'Provide details', description: 'Describe what, where, and expected behavior' }
158
+ ]
159
+ }]
160
+ });
161
+
162
+ // Use custom text input (via "Other")
163
+ if (answer.customText) {
164
+ issueData.context = answer.customText;
165
+ issueData.title = answer.customText.split(/[.\n]/)[0].substring(0, 60);
166
+ issueData.feedback = [{
167
+ type: 'clarification',
168
+ stage: 'new',
169
+ content: answer.customText,
170
+ created_at: new Date().toISOString()
171
+ }];
172
+ }
173
+ }
174
+ ```
175
+
176
+ ### Phase 5: GitHub Publishing Decision (Non-GitHub Sources)
177
+
178
+ ```javascript
179
+ // For non-GitHub sources, ask if user wants to publish to GitHub
180
+ let publishToGitHub = false;
181
+
182
+ if (issueData.source !== 'github') {
183
+ const publishAnswer = AskUserQuestion({
184
+ questions: [{
185
+ question: 'Would you like to publish this issue to GitHub?',
186
+ header: 'Publish',
187
+ multiSelect: false,
188
+ options: [
189
+ { label: 'Yes, publish to GitHub', description: 'Create issue on GitHub and link it' },
190
+ { label: 'No, keep local only', description: 'Store as local issue without GitHub sync' }
191
+ ]
192
+ }]
193
+ });
194
+
195
+ publishToGitHub = publishAnswer.answers?.['Publish']?.includes('Yes');
196
+ }
197
+ ```
198
+
199
+ ### Phase 6: Create Issue
200
+
201
+ **Summary Display:**
202
+ - Show ID, title, source, affected files (if any)
203
+
204
+ **Confirmation** (only for vague inputs, clarityScore < 2):
205
+ - Use `AskUserQuestion` to confirm before creation
206
+
207
+ **Issue Creation** (via CLI endpoint):
208
+ ```bash
209
+ # Option 1: Pipe input (recommended for complex JSON - avoids shell escaping)
210
+ echo '{"title":"...", "context":"...", "priority":3}' | ccw issue create
211
+
212
+ # Option 2: Heredoc (for multi-line JSON)
213
+ ccw issue create << 'EOF'
214
+ {"title":"...", "context":"含\"引号\"的内容", "priority":3}
215
+ EOF
216
+
217
+ # Option 3: --data parameter (simple cases only)
218
+ ccw issue create --data '{"title":"...", "priority":3}'
219
+ ```
220
+
221
+ **CLI Endpoint Features:**
222
+ | Feature | Description |
223
+ |---------|-------------|
224
+ | Auto-increment ID | `ISS-YYYYMMDD-NNN` (e.g., `ISS-20251229-001`) |
225
+ | Trailing newline | Proper JSONL format, no corruption |
226
+ | JSON output | Returns created issue with all fields |
227
+
228
+ **Example:**
229
+ ```bash
230
+ # Create issue via pipe (recommended)
231
+ echo '{"title": "Login fails with special chars", "context": "500 error when password contains quotes", "priority": 2}' | ccw issue create
232
+
233
+ # Or with heredoc for complex JSON
234
+ ccw issue create << 'EOF'
235
+ {
236
+ "title": "Login fails with special chars",
237
+ "context": "500 error when password contains \"quotes\"",
238
+ "priority": 2,
239
+ "source": "text",
240
+ "expected_behavior": "Login succeeds",
241
+ "actual_behavior": "500 Internal Server Error"
242
+ }
243
+ EOF
244
+
245
+ # Output (JSON)
246
+ {
247
+ "id": "ISS-20251229-001",
248
+ "title": "Login fails with special chars",
249
+ "status": "registered",
250
+ ...
251
+ }
252
+ ```
253
+
254
+ **GitHub Publishing** (if user opted in):
255
+ ```javascript
256
+ // Step 1: Create local issue FIRST
257
+ const localIssue = createLocalIssue(issueData); // ccw issue create
258
+
259
+ // Step 2: Publish to GitHub if requested
260
+ if (publishToGitHub) {
261
+ const ghResult = Bash(`gh issue create --title "${issueData.title}" --body "${issueData.context}"`);
262
+ // Parse GitHub URL from output
263
+ const ghUrl = ghResult.match(/https:\/\/github\.com\/[\w-]+\/[\w-]+\/issues\/\d+/)?.[0];
264
+ const ghNumber = parseInt(ghUrl?.match(/\/issues\/(\d+)/)?.[1]);
265
+
266
+ if (ghNumber) {
267
+ // Step 3: Update local issue with GitHub binding
268
+ Bash(`ccw issue update ${localIssue.id} --github-url "${ghUrl}" --github-number ${ghNumber}`);
269
+ // Or via pipe:
270
+ // echo '{"github_url":"${ghUrl}","github_number":${ghNumber}}' | ccw issue update ${localIssue.id}
271
+ }
272
+ }
273
+ ```
274
+
275
+ **Workflow:**
276
+ ```
277
+ 1. Create local issue (ISS-YYYYMMDD-NNN) stored in .workflow/issues.jsonl
278
+ 2. If publishToGitHub:
279
+ a. gh issue create → returns GitHub URL
280
+ b. Update local issue with github_url + github_number binding
281
+ 3. Both local and GitHub issues exist, linked together
282
+ ```
283
+
284
+ **Example with GitHub Publishing:**
285
+ ```bash
286
+ # User creates text issue
287
+ /issue:new "Login fails with special chars. Expected: success. Actual: 500"
288
+
289
+ # System asks: "Would you like to publish this issue to GitHub?"
290
+ # User selects: "Yes, publish to GitHub"
291
+
292
+ # Output:
293
+ # ✓ Local issue created: ISS-20251229-001
294
+ # Published to GitHub: https://github.com/org/repo/issues/123
295
+ # ✓ GitHub binding saved to local issue
296
+ # → Next step: /issue:plan ISS-20251229-001
297
+
298
+ # Resulting issue JSON:
299
+ {
300
+ "id": "ISS-20251229-001",
301
+ "title": "Login fails with special chars",
302
+ "source": "text",
303
+ "github_url": "https://github.com/org/repo/issues/123",
304
+ "github_number": 123,
305
+ ...
306
+ }
307
+ ```
308
+
309
+ **Completion:**
310
+ - Display created issue ID
311
+ - Show GitHub URL (if published)
312
+ - Show next step: `/issue:plan <id>`
313
+
314
+ ## Execution Flow
315
+
316
+ ```
317
+ Phase 1: Input Analysis
318
+ └─ Detect clarity score (GitHub URL? Structured text? Keywords?)
319
+
320
+ Phase 2: Data Extraction (branched by clarity)
321
+ ┌────────────┬─────────────────┬──────────────┐
322
+ Score 3Score 1-2 │ Score 0
323
+ GitHub Text + ACE Vague
324
+ ├────────────┼─────────────────┼──────────────┤
325
+ │ gh CLI │ Parse struct │ AskQuestion │
326
+ │ → parse │ + quick hint │ (1 question)
327
+ │ │ (3 files max) │ → feedback │
328
+ └────────────┴─────────────────┴──────────────┘
329
+
330
+ Phase 3: GitHub Publishing Decision (non-GitHub only)
331
+ ├─ Source = github: Skip (already from GitHub)
332
+ └─ Source ≠ github: AskUserQuestion
333
+ ├─ Yes publishToGitHub = true
334
+ └─ No → publishToGitHub = false
335
+
336
+ Phase 4: Create Issue
337
+ ├─ Score 2: Direct creation
338
+ └─ Score < 2: Confirm first → Create
339
+ └─ If publishToGitHub: gh issue create → link URL
340
+
341
+ Note: Deep exploration & lifecycle deferred to /issue:plan
342
+ ```
343
+
344
+ ## Helper Functions
345
+
346
+ ```javascript
347
+ function extractKeywords(text) {
348
+ const stopWords = new Set(['the', 'a', 'an', 'is', 'are', 'was', 'were', 'not', 'with']);
349
+ return text
350
+ .toLowerCase()
351
+ .split(/\W+/)
352
+ .filter(w => w.length > 3 && !stopWords.has(w))
353
+ .slice(0, 5);
354
+ }
355
+
356
+ function parseTextDescription(text) {
357
+ const result = { title: '', context: '' };
358
+ const sentences = text.split(/\.(?=\s|$)/);
359
+
360
+ result.title = sentences[0]?.trim().substring(0, 60) || 'Untitled';
361
+ result.context = text.substring(0, 500);
362
+
363
+ // Extract structured fields if present
364
+ const expected = text.match(/expected:?\s*([^.]+)/i);
365
+ const actual = text.match(/actual:?\s*([^.]+)/i);
366
+ const affects = text.match(/affects?:?\s*([^.]+)/i);
367
+
368
+ if (expected) result.expected_behavior = expected[1].trim();
369
+ if (actual) result.actual_behavior = actual[1].trim();
370
+ if (affects) {
371
+ result.affected_components = affects[1].split(/[,\s]+/).filter(c => c.includes('/') || c.includes('.'));
372
+ }
373
+
374
+ return result;
375
+ }
376
+
377
+ function parseMarkdownBody(body) {
378
+ if (!body) return {};
379
+ const result = {};
380
+
381
+ const problem = body.match(/##?\s*(problem|description)[:\s]*([\s\S]*?)(?=##|$)/i);
382
+ const expected = body.match(/##?\s*expected[:\s]*([\s\S]*?)(?=##|$)/i);
383
+ const actual = body.match(/##?\s*actual[:\s]*([\s\S]*?)(?=##|$)/i);
384
+
385
+ if (problem) result.context = problem[2].trim().substring(0, 500);
386
+ if (expected) result.expected_behavior = expected[2].trim();
387
+ if (actual) result.actual_behavior = actual[2].trim();
388
+
389
+ return result;
390
+ }
391
+ ```
392
+
393
+ ## Examples
394
+
395
+ ### Clear Input (No Questions)
396
+
397
+ ```bash
398
+ /issue:new https://github.com/org/repo/issues/42
399
+ # → Fetches, parses, creates immediately
400
+
401
+ /issue:new "Login fails with special chars. Expected: success. Actual: 500"
402
+ # → Parses structure, creates immediately
403
+ ```
404
+
405
+ ### Vague Input (1 Question)
406
+
407
+ ```bash
408
+ /issue:new "auth broken"
409
+ # → Asks: "Input unclear. What is the issue about?"
410
+ # User provides details → saved to feedback[]
411
+ # → Creates issue
412
+ ```
413
+
414
+ ## Related Commands
415
+
416
+ - `/issue:plan` - Plan solution for issue
417
+