claude-code-workflow 6.3.4 → 6.3.6

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 (111) hide show
  1. package/.claude/agents/issue-plan-agent.md +859 -0
  2. package/.claude/agents/issue-queue-agent.md +702 -0
  3. package/.claude/commands/issue/execute.md +453 -0
  4. package/.claude/commands/issue/manage.md +865 -0
  5. package/.claude/commands/issue/new.md +484 -0
  6. package/.claude/commands/issue/plan.md +421 -0
  7. package/.claude/commands/issue/queue.md +354 -0
  8. package/.claude/commands/{clean.md → workflow/clean.md} +5 -5
  9. package/.claude/commands/workflow/docs/analyze.md +1467 -0
  10. package/.claude/commands/workflow/docs/copyright.md +1265 -0
  11. package/.claude/commands/workflow/execute.md +0 -1
  12. package/.claude/commands/workflow/tools/conflict-resolution.md +76 -240
  13. package/.claude/commands/workflow/tools/context-gather.md +0 -2
  14. package/.claude/commands/workflow/tools/task-generate-agent.md +81 -8
  15. package/.claude/commands/workflow/tools/task-generate-tdd.md +0 -9
  16. package/.claude/commands/workflow/tools/test-context-gather.md +2 -3
  17. package/.claude/commands/workflow/tools/test-task-generate.md +0 -2
  18. package/.claude/skills/_shared/mermaid-utils.md +584 -0
  19. package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +0 -2
  20. package/.claude/skills/command-guide/reference/commands/workflow/execute.md +1 -1
  21. package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +1 -2
  22. package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +1 -8
  23. package/.claude/skills/command-guide/reference/commands/workflow/tools/test-context-gather.md +1 -4
  24. package/.claude/skills/command-guide/reference/commands/workflow/tools/test-task-generate.md +0 -2
  25. package/.claude/skills/copyright-docs/SKILL.md +132 -0
  26. package/.claude/skills/copyright-docs/phases/01-metadata-collection.md +78 -0
  27. package/.claude/skills/copyright-docs/phases/01.5-project-exploration.md +150 -0
  28. package/.claude/skills/copyright-docs/phases/02-deep-analysis.md +664 -0
  29. package/.claude/skills/copyright-docs/phases/02.5-consolidation.md +192 -0
  30. package/.claude/skills/copyright-docs/phases/04-document-assembly.md +261 -0
  31. package/.claude/skills/copyright-docs/phases/05-compliance-refinement.md +192 -0
  32. package/.claude/skills/copyright-docs/specs/cpcc-requirements.md +121 -0
  33. package/.claude/skills/copyright-docs/templates/agent-base.md +200 -0
  34. package/.claude/skills/project-analyze/SKILL.md +162 -0
  35. package/.claude/skills/project-analyze/phases/01-requirements-discovery.md +79 -0
  36. package/.claude/skills/project-analyze/phases/02-project-exploration.md +176 -0
  37. package/.claude/skills/project-analyze/phases/03-deep-analysis.md +854 -0
  38. package/.claude/skills/project-analyze/phases/03.5-consolidation.md +233 -0
  39. package/.claude/skills/project-analyze/phases/04-report-generation.md +217 -0
  40. package/.claude/skills/project-analyze/phases/05-iterative-refinement.md +124 -0
  41. package/.claude/skills/project-analyze/specs/quality-standards.md +115 -0
  42. package/.claude/skills/project-analyze/specs/writing-style.md +152 -0
  43. package/.claude/workflows/cli-templates/schemas/conflict-resolution-schema.json +79 -65
  44. package/.claude/workflows/cli-templates/schemas/issue-task-jsonl-schema.json +136 -0
  45. package/.claude/workflows/cli-templates/schemas/issues-jsonl-schema.json +74 -0
  46. package/.claude/workflows/cli-templates/schemas/queue-schema.json +136 -0
  47. package/.claude/workflows/cli-templates/schemas/registry-schema.json +94 -0
  48. package/.claude/workflows/cli-templates/schemas/solution-schema.json +120 -0
  49. package/.claude/workflows/cli-templates/schemas/solutions-jsonl-schema.json +125 -0
  50. package/.codex/prompts/issue-execute.md +266 -0
  51. package/README.md +11 -1
  52. package/ccw/dist/cli.d.ts.map +1 -1
  53. package/ccw/dist/cli.js +25 -0
  54. package/ccw/dist/cli.js.map +1 -1
  55. package/ccw/dist/commands/cli.d.ts.map +1 -1
  56. package/ccw/dist/commands/cli.js +46 -8
  57. package/ccw/dist/commands/cli.js.map +1 -1
  58. package/ccw/dist/commands/issue.d.ts +21 -0
  59. package/ccw/dist/commands/issue.d.ts.map +1 -0
  60. package/ccw/dist/commands/issue.js +895 -0
  61. package/ccw/dist/commands/issue.js.map +1 -0
  62. package/ccw/dist/core/dashboard-generator-patch.js +1 -0
  63. package/ccw/dist/core/dashboard-generator-patch.js.map +1 -1
  64. package/ccw/dist/core/routes/cli-routes.js +2 -2
  65. package/ccw/dist/core/routes/cli-routes.js.map +1 -1
  66. package/ccw/dist/core/routes/issue-routes.d.ts +34 -0
  67. package/ccw/dist/core/routes/issue-routes.d.ts.map +1 -0
  68. package/ccw/dist/core/routes/issue-routes.js +487 -0
  69. package/ccw/dist/core/routes/issue-routes.js.map +1 -0
  70. package/ccw/dist/core/server.d.ts.map +1 -1
  71. package/ccw/dist/core/server.js +17 -2
  72. package/ccw/dist/core/server.js.map +1 -1
  73. package/ccw/dist/tools/claude-cli-tools.d.ts +7 -3
  74. package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -1
  75. package/ccw/dist/tools/claude-cli-tools.js +31 -17
  76. package/ccw/dist/tools/claude-cli-tools.js.map +1 -1
  77. package/ccw/dist/tools/smart-search.d.ts +25 -0
  78. package/ccw/dist/tools/smart-search.d.ts.map +1 -1
  79. package/ccw/dist/tools/smart-search.js +121 -17
  80. package/ccw/dist/tools/smart-search.js.map +1 -1
  81. package/ccw/src/cli.ts +26 -0
  82. package/ccw/src/commands/cli.ts +49 -7
  83. package/ccw/src/commands/issue.ts +1184 -0
  84. package/ccw/src/core/dashboard-generator-patch.ts +1 -0
  85. package/ccw/src/core/routes/cli-routes.ts +3 -3
  86. package/ccw/src/core/routes/issue-routes.ts +559 -0
  87. package/ccw/src/core/server.ts +17 -2
  88. package/ccw/src/templates/dashboard-css/32-issue-manager.css +2544 -0
  89. package/ccw/src/templates/dashboard-css/33-cli-stream-viewer.css +467 -0
  90. package/ccw/src/templates/dashboard-js/components/cli-history.js +40 -13
  91. package/ccw/src/templates/dashboard-js/components/cli-status.js +26 -2
  92. package/ccw/src/templates/dashboard-js/components/cli-stream-viewer.js +461 -0
  93. package/ccw/src/templates/dashboard-js/components/navigation.js +8 -0
  94. package/ccw/src/templates/dashboard-js/components/notifications.js +16 -0
  95. package/ccw/src/templates/dashboard-js/i18n.js +290 -2
  96. package/ccw/src/templates/dashboard-js/views/cli-manager.js +5 -0
  97. package/ccw/src/templates/dashboard-js/views/history.js +19 -4
  98. package/ccw/src/templates/dashboard-js/views/hook-manager.js +11 -5
  99. package/ccw/src/templates/dashboard-js/views/issue-manager.js +1546 -0
  100. package/ccw/src/templates/dashboard.html +55 -0
  101. package/ccw/src/tools/claude-cli-tools.ts +37 -20
  102. package/ccw/src/tools/smart-search.ts +157 -16
  103. package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
  104. package/codex-lens/src/codexlens/config.py +5 -0
  105. package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
  106. package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
  107. package/codex-lens/src/codexlens/search/hybrid_search.py +144 -11
  108. package/codex-lens/src/codexlens/search/ranking.py +267 -1
  109. package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-313.pyc +0 -0
  110. package/codex-lens/src/codexlens/semantic/chunker.py +55 -10
  111. package/package.json +2 -2
@@ -0,0 +1,484 @@
1
+ ---
2
+ name: new
3
+ description: Create structured issue from GitHub URL or text description, extracting key elements into issues.jsonl
4
+ argument-hint: "<github-url | text-description> [--priority 1-5] [--labels label1,label2]"
5
+ allowed-tools: TodoWrite(*), Bash(*), Read(*), Write(*), WebFetch(*), AskUserQuestion(*)
6
+ ---
7
+
8
+ # Issue New Command (/issue:new)
9
+
10
+ ## Overview
11
+
12
+ Creates a new structured issue from either:
13
+ 1. **GitHub Issue URL** - Fetches and parses issue content via `gh` CLI
14
+ 2. **Text Description** - Parses natural language into structured fields
15
+
16
+ Outputs a well-formed issue entry to `.workflow/issues/issues.jsonl`.
17
+
18
+ ## Issue Structure (Closed-Loop)
19
+
20
+ ```typescript
21
+ interface Issue {
22
+ id: string; // GH-123 or ISS-YYYYMMDD-HHMMSS
23
+ title: string; // Issue title (clear, concise)
24
+ status: 'registered'; // Initial status
25
+ priority: number; // 1 (critical) to 5 (low)
26
+ context: string; // Problem description
27
+ source: 'github' | 'text'; // Input source type
28
+ source_url?: string; // GitHub URL if applicable
29
+ labels?: string[]; // Categorization labels
30
+
31
+ // Structured extraction
32
+ problem_statement: string; // What is the problem?
33
+ expected_behavior?: string; // What should happen?
34
+ actual_behavior?: string; // What actually happens?
35
+ affected_components?: string[];// Files/modules affected
36
+ reproduction_steps?: string[]; // Steps to reproduce
37
+
38
+ // Closed-loop requirements (guide plan generation)
39
+ lifecycle_requirements: {
40
+ test_strategy: 'unit' | 'integration' | 'e2e' | 'manual' | 'auto';
41
+ regression_scope: 'affected' | 'related' | 'full'; // Which tests to run
42
+ acceptance_type: 'automated' | 'manual' | 'both'; // How to verify
43
+ commit_strategy: 'per-task' | 'squash' | 'atomic'; // Commit granularity
44
+ };
45
+
46
+ // Metadata
47
+ bound_solution_id: null;
48
+ solution_count: 0;
49
+ created_at: string;
50
+ updated_at: string;
51
+ }
52
+ ```
53
+
54
+ ## Task Lifecycle (Each Task is Closed-Loop)
55
+
56
+ When `/issue:plan` generates tasks, each task MUST include:
57
+
58
+ ```typescript
59
+ interface SolutionTask {
60
+ id: string;
61
+ title: string;
62
+ scope: string;
63
+ action: string;
64
+
65
+ // Phase 1: Implementation
66
+ implementation: string[]; // Step-by-step implementation
67
+ modification_points: { file: string; target: string; change: string }[];
68
+
69
+ // Phase 2: Testing
70
+ test: {
71
+ unit?: string[]; // Unit test requirements
72
+ integration?: string[]; // Integration test requirements
73
+ commands?: string[]; // Test commands to run
74
+ coverage_target?: number; // Minimum coverage %
75
+ };
76
+
77
+ // Phase 3: Regression
78
+ regression: string[]; // Regression check commands/points
79
+
80
+ // Phase 4: Acceptance
81
+ acceptance: {
82
+ criteria: string[]; // Testable acceptance criteria
83
+ verification: string[]; // How to verify each criterion
84
+ manual_checks?: string[]; // Manual verification if needed
85
+ };
86
+
87
+ // Phase 5: Commit
88
+ commit: {
89
+ type: 'feat' | 'fix' | 'refactor' | 'test' | 'docs' | 'chore';
90
+ scope: string; // e.g., "auth", "api"
91
+ message_template: string; // Commit message template
92
+ breaking?: boolean;
93
+ };
94
+
95
+ depends_on: string[];
96
+ executor: 'codex' | 'gemini' | 'agent' | 'auto';
97
+ }
98
+ ```
99
+
100
+ ## Usage
101
+
102
+ ```bash
103
+ # From GitHub URL
104
+ /issue:new https://github.com/owner/repo/issues/123
105
+
106
+ # From text description
107
+ /issue:new "Login fails when password contains special characters. Expected: successful login. Actual: 500 error. Affects src/auth/*"
108
+
109
+ # With options
110
+ /issue:new <url-or-text> --priority 2 --labels "bug,auth"
111
+ ```
112
+
113
+ ## Implementation
114
+
115
+ ### Phase 1: Input Detection
116
+
117
+ ```javascript
118
+ const input = userInput.trim();
119
+ const flags = parseFlags(userInput); // --priority, --labels
120
+
121
+ // Detect input type
122
+ const isGitHubUrl = input.match(/github\.com\/[\w-]+\/[\w-]+\/issues\/\d+/);
123
+ const isGitHubShort = input.match(/^#(\d+)$/); // #123 format
124
+
125
+ let issueData = {};
126
+
127
+ if (isGitHubUrl || isGitHubShort) {
128
+ // GitHub issue - fetch via gh CLI
129
+ issueData = await fetchGitHubIssue(input);
130
+ } else {
131
+ // Text description - parse structure
132
+ issueData = await parseTextDescription(input);
133
+ }
134
+ ```
135
+
136
+ ### Phase 2: GitHub Issue Fetching
137
+
138
+ ```javascript
139
+ async function fetchGitHubIssue(urlOrNumber) {
140
+ let issueRef;
141
+
142
+ if (urlOrNumber.startsWith('http')) {
143
+ // Extract owner/repo/number from URL
144
+ const match = urlOrNumber.match(/github\.com\/([\w-]+)\/([\w-]+)\/issues\/(\d+)/);
145
+ if (!match) throw new Error('Invalid GitHub URL');
146
+ issueRef = `${match[1]}/${match[2]}#${match[3]}`;
147
+ } else {
148
+ // #123 format - use current repo
149
+ issueRef = urlOrNumber.replace('#', '');
150
+ }
151
+
152
+ // Fetch via gh CLI
153
+ const result = Bash(`gh issue view ${issueRef} --json number,title,body,labels,state,url`);
154
+ const ghIssue = JSON.parse(result);
155
+
156
+ // Parse body for structure
157
+ const parsed = parseIssueBody(ghIssue.body);
158
+
159
+ return {
160
+ id: `GH-${ghIssue.number}`,
161
+ title: ghIssue.title,
162
+ source: 'github',
163
+ source_url: ghIssue.url,
164
+ labels: ghIssue.labels.map(l => l.name),
165
+ context: ghIssue.body,
166
+ ...parsed
167
+ };
168
+ }
169
+
170
+ function parseIssueBody(body) {
171
+ // Extract structured sections from markdown body
172
+ const sections = {};
173
+
174
+ // Problem/Description
175
+ const problemMatch = body.match(/##?\s*(problem|description|issue)[:\s]*([\s\S]*?)(?=##|$)/i);
176
+ if (problemMatch) sections.problem_statement = problemMatch[2].trim();
177
+
178
+ // Expected behavior
179
+ const expectedMatch = body.match(/##?\s*(expected|should)[:\s]*([\s\S]*?)(?=##|$)/i);
180
+ if (expectedMatch) sections.expected_behavior = expectedMatch[2].trim();
181
+
182
+ // Actual behavior
183
+ const actualMatch = body.match(/##?\s*(actual|current)[:\s]*([\s\S]*?)(?=##|$)/i);
184
+ if (actualMatch) sections.actual_behavior = actualMatch[2].trim();
185
+
186
+ // Steps to reproduce
187
+ const stepsMatch = body.match(/##?\s*(steps|reproduce)[:\s]*([\s\S]*?)(?=##|$)/i);
188
+ if (stepsMatch) {
189
+ const stepsText = stepsMatch[2].trim();
190
+ sections.reproduction_steps = stepsText
191
+ .split('\n')
192
+ .filter(line => line.match(/^\s*[\d\-\*]/))
193
+ .map(line => line.replace(/^\s*[\d\.\-\*]\s*/, '').trim());
194
+ }
195
+
196
+ // Affected components (from file references)
197
+ const fileMatches = body.match(/`[^`]*\.(ts|js|tsx|jsx|py|go|rs)[^`]*`/g);
198
+ if (fileMatches) {
199
+ sections.affected_components = [...new Set(fileMatches.map(f => f.replace(/`/g, '')))];
200
+ }
201
+
202
+ // Fallback: use entire body as problem statement
203
+ if (!sections.problem_statement) {
204
+ sections.problem_statement = body.substring(0, 500);
205
+ }
206
+
207
+ return sections;
208
+ }
209
+ ```
210
+
211
+ ### Phase 3: Text Description Parsing
212
+
213
+ ```javascript
214
+ async function parseTextDescription(text) {
215
+ // Generate unique ID
216
+ const id = `ISS-${new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14)}`;
217
+
218
+ // Extract structured elements using patterns
219
+ const result = {
220
+ id,
221
+ source: 'text',
222
+ title: '',
223
+ problem_statement: '',
224
+ expected_behavior: null,
225
+ actual_behavior: null,
226
+ affected_components: [],
227
+ reproduction_steps: []
228
+ };
229
+
230
+ // Pattern: "Title. Description. Expected: X. Actual: Y. Affects: files"
231
+ const sentences = text.split(/\.(?=\s|$)/);
232
+
233
+ // First sentence as title
234
+ result.title = sentences[0]?.trim() || 'Untitled Issue';
235
+
236
+ // Look for keywords
237
+ for (const sentence of sentences) {
238
+ const s = sentence.trim();
239
+
240
+ if (s.match(/^expected:?\s*/i)) {
241
+ result.expected_behavior = s.replace(/^expected:?\s*/i, '');
242
+ } else if (s.match(/^actual:?\s*/i)) {
243
+ result.actual_behavior = s.replace(/^actual:?\s*/i, '');
244
+ } else if (s.match(/^affects?:?\s*/i)) {
245
+ const components = s.replace(/^affects?:?\s*/i, '').split(/[,\s]+/);
246
+ result.affected_components = components.filter(c => c.includes('/') || c.includes('.'));
247
+ } else if (s.match(/^steps?:?\s*/i)) {
248
+ result.reproduction_steps = s.replace(/^steps?:?\s*/i, '').split(/[,;]/);
249
+ } else if (!result.problem_statement && s.length > 10) {
250
+ result.problem_statement = s;
251
+ }
252
+ }
253
+
254
+ // Fallback problem statement
255
+ if (!result.problem_statement) {
256
+ result.problem_statement = text.substring(0, 300);
257
+ }
258
+
259
+ return result;
260
+ }
261
+ ```
262
+
263
+ ### Phase 4: Lifecycle Configuration
264
+
265
+ ```javascript
266
+ // Ask for lifecycle requirements (or use smart defaults)
267
+ const lifecycleAnswer = AskUserQuestion({
268
+ questions: [
269
+ {
270
+ question: 'Test strategy for this issue?',
271
+ header: 'Test',
272
+ multiSelect: false,
273
+ options: [
274
+ { label: 'auto', description: 'Auto-detect based on affected files (Recommended)' },
275
+ { label: 'unit', description: 'Unit tests only' },
276
+ { label: 'integration', description: 'Integration tests' },
277
+ { label: 'e2e', description: 'End-to-end tests' },
278
+ { label: 'manual', description: 'Manual testing only' }
279
+ ]
280
+ },
281
+ {
282
+ question: 'Regression scope?',
283
+ header: 'Regression',
284
+ multiSelect: false,
285
+ options: [
286
+ { label: 'affected', description: 'Only affected module tests (Recommended)' },
287
+ { label: 'related', description: 'Affected + dependent modules' },
288
+ { label: 'full', description: 'Full test suite' }
289
+ ]
290
+ },
291
+ {
292
+ question: 'Commit strategy?',
293
+ header: 'Commit',
294
+ multiSelect: false,
295
+ options: [
296
+ { label: 'per-task', description: 'One commit per task (Recommended)' },
297
+ { label: 'atomic', description: 'Single commit for entire issue' },
298
+ { label: 'squash', description: 'Squash at the end' }
299
+ ]
300
+ }
301
+ ]
302
+ });
303
+
304
+ const lifecycle = {
305
+ test_strategy: lifecycleAnswer.test || 'auto',
306
+ regression_scope: lifecycleAnswer.regression || 'affected',
307
+ acceptance_type: 'automated',
308
+ commit_strategy: lifecycleAnswer.commit || 'per-task'
309
+ };
310
+
311
+ issueData.lifecycle_requirements = lifecycle;
312
+ ```
313
+
314
+ ### Phase 5: User Confirmation
315
+
316
+ ```javascript
317
+ // Show parsed data and ask for confirmation
318
+ console.log(`
319
+ ## Parsed Issue
320
+
321
+ **ID**: ${issueData.id}
322
+ **Title**: ${issueData.title}
323
+ **Source**: ${issueData.source}${issueData.source_url ? ` (${issueData.source_url})` : ''}
324
+
325
+ ### Problem Statement
326
+ ${issueData.problem_statement}
327
+
328
+ ${issueData.expected_behavior ? `### Expected Behavior\n${issueData.expected_behavior}\n` : ''}
329
+ ${issueData.actual_behavior ? `### Actual Behavior\n${issueData.actual_behavior}\n` : ''}
330
+ ${issueData.affected_components?.length ? `### Affected Components\n${issueData.affected_components.map(c => `- ${c}`).join('\n')}\n` : ''}
331
+ ${issueData.reproduction_steps?.length ? `### Reproduction Steps\n${issueData.reproduction_steps.map((s, i) => `${i+1}. ${s}`).join('\n')}\n` : ''}
332
+
333
+ ### Lifecycle Configuration
334
+ - **Test Strategy**: ${lifecycle.test_strategy}
335
+ - **Regression Scope**: ${lifecycle.regression_scope}
336
+ - **Commit Strategy**: ${lifecycle.commit_strategy}
337
+ `);
338
+
339
+ // Ask user to confirm or edit
340
+ const answer = AskUserQuestion({
341
+ questions: [{
342
+ question: 'Create this issue?',
343
+ header: 'Confirm',
344
+ multiSelect: false,
345
+ options: [
346
+ { label: 'Create', description: 'Save issue to issues.jsonl' },
347
+ { label: 'Edit Title', description: 'Modify the issue title' },
348
+ { label: 'Edit Priority', description: 'Change priority (1-5)' },
349
+ { label: 'Cancel', description: 'Discard and exit' }
350
+ ]
351
+ }]
352
+ });
353
+
354
+ if (answer.includes('Cancel')) {
355
+ console.log('Issue creation cancelled.');
356
+ return;
357
+ }
358
+
359
+ if (answer.includes('Edit Title')) {
360
+ const titleAnswer = AskUserQuestion({
361
+ questions: [{
362
+ question: 'Enter new title:',
363
+ header: 'Title',
364
+ multiSelect: false,
365
+ options: [
366
+ { label: issueData.title.substring(0, 40), description: 'Keep current' }
367
+ ]
368
+ }]
369
+ });
370
+ // Handle custom input via "Other"
371
+ if (titleAnswer.customText) {
372
+ issueData.title = titleAnswer.customText;
373
+ }
374
+ }
375
+ ```
376
+
377
+ ### Phase 6: Write to JSONL
378
+
379
+ ```javascript
380
+ // Construct final issue object
381
+ const priority = flags.priority ? parseInt(flags.priority) : 3;
382
+ const labels = flags.labels ? flags.labels.split(',').map(l => l.trim()) : [];
383
+
384
+ const newIssue = {
385
+ id: issueData.id,
386
+ title: issueData.title,
387
+ status: 'registered',
388
+ priority,
389
+ context: issueData.problem_statement,
390
+ source: issueData.source,
391
+ source_url: issueData.source_url || null,
392
+ labels: [...(issueData.labels || []), ...labels],
393
+
394
+ // Structured fields
395
+ problem_statement: issueData.problem_statement,
396
+ expected_behavior: issueData.expected_behavior || null,
397
+ actual_behavior: issueData.actual_behavior || null,
398
+ affected_components: issueData.affected_components || [],
399
+ reproduction_steps: issueData.reproduction_steps || [],
400
+
401
+ // Closed-loop lifecycle requirements
402
+ lifecycle_requirements: issueData.lifecycle_requirements || {
403
+ test_strategy: 'auto',
404
+ regression_scope: 'affected',
405
+ acceptance_type: 'automated',
406
+ commit_strategy: 'per-task'
407
+ },
408
+
409
+ // Metadata
410
+ bound_solution_id: null,
411
+ solution_count: 0,
412
+ created_at: new Date().toISOString(),
413
+ updated_at: new Date().toISOString()
414
+ };
415
+
416
+ // Ensure directory exists
417
+ Bash('mkdir -p .workflow/issues');
418
+
419
+ // Append to issues.jsonl
420
+ const issuesPath = '.workflow/issues/issues.jsonl';
421
+ Bash(`echo '${JSON.stringify(newIssue)}' >> "${issuesPath}"`);
422
+
423
+ console.log(`
424
+ ## Issue Created
425
+
426
+ **ID**: ${newIssue.id}
427
+ **Title**: ${newIssue.title}
428
+ **Priority**: ${newIssue.priority}
429
+ **Labels**: ${newIssue.labels.join(', ') || 'none'}
430
+ **Source**: ${newIssue.source}
431
+
432
+ ### Next Steps
433
+ 1. Plan solution: \`/issue:plan ${newIssue.id}\`
434
+ 2. View details: \`ccw issue status ${newIssue.id}\`
435
+ 3. Manage issues: \`/issue:manage\`
436
+ `);
437
+ ```
438
+
439
+ ## Examples
440
+
441
+ ### GitHub Issue
442
+
443
+ ```bash
444
+ /issue:new https://github.com/myorg/myrepo/issues/42 --priority 2
445
+
446
+ # Output:
447
+ ## Issue Created
448
+ **ID**: GH-42
449
+ **Title**: Fix memory leak in WebSocket handler
450
+ **Priority**: 2
451
+ **Labels**: bug, performance
452
+ **Source**: github (https://github.com/myorg/myrepo/issues/42)
453
+ ```
454
+
455
+ ### Text Description
456
+
457
+ ```bash
458
+ /issue:new "API rate limiting not working. Expected: 429 after 100 requests. Actual: No limit. Affects src/middleware/rate-limit.ts"
459
+
460
+ # Output:
461
+ ## Issue Created
462
+ **ID**: ISS-20251227-142530
463
+ **Title**: API rate limiting not working
464
+ **Priority**: 3
465
+ **Labels**: none
466
+ **Source**: text
467
+ ```
468
+
469
+ ## Error Handling
470
+
471
+ | Error | Resolution |
472
+ |-------|------------|
473
+ | Invalid GitHub URL | Show format hint, ask for correction |
474
+ | gh CLI not available | Fall back to WebFetch for public issues |
475
+ | Empty description | Prompt user for required fields |
476
+ | Duplicate issue ID | Auto-increment or suggest merge |
477
+ | Parse failure | Show raw input, ask for manual structuring |
478
+
479
+ ## Related Commands
480
+
481
+ - `/issue:plan` - Plan solution for issue
482
+ - `/issue:manage` - Interactive issue management
483
+ - `ccw issue list` - List all issues
484
+ - `ccw issue status <id>` - View issue details