worclaude 1.0.0

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 (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +278 -0
  3. package/package.json +62 -0
  4. package/src/commands/backup.js +55 -0
  5. package/src/commands/diff.js +76 -0
  6. package/src/commands/init.js +628 -0
  7. package/src/commands/restore.js +95 -0
  8. package/src/commands/status.js +141 -0
  9. package/src/commands/upgrade.js +208 -0
  10. package/src/core/backup.js +94 -0
  11. package/src/core/config.js +54 -0
  12. package/src/core/detector.js +43 -0
  13. package/src/core/file-categorizer.js +177 -0
  14. package/src/core/merger.js +413 -0
  15. package/src/core/scaffolder.js +60 -0
  16. package/src/data/agents.js +164 -0
  17. package/src/index.js +51 -0
  18. package/src/prompts/agent-selection.js +99 -0
  19. package/src/prompts/claude-md-merge.js +153 -0
  20. package/src/prompts/conflict-resolution.js +24 -0
  21. package/src/prompts/project-type.js +75 -0
  22. package/src/prompts/tech-stack.js +35 -0
  23. package/src/utils/display.js +41 -0
  24. package/src/utils/file.js +70 -0
  25. package/src/utils/hash.js +13 -0
  26. package/src/utils/time.js +22 -0
  27. package/templates/agents/optional/backend/api-designer.md +61 -0
  28. package/templates/agents/optional/backend/auth-auditor.md +63 -0
  29. package/templates/agents/optional/backend/database-analyst.md +61 -0
  30. package/templates/agents/optional/data/data-pipeline-reviewer.md +68 -0
  31. package/templates/agents/optional/data/ml-experiment-tracker.md +67 -0
  32. package/templates/agents/optional/data/prompt-engineer.md +75 -0
  33. package/templates/agents/optional/devops/ci-fixer.md +64 -0
  34. package/templates/agents/optional/devops/dependency-manager.md +55 -0
  35. package/templates/agents/optional/devops/deploy-validator.md +68 -0
  36. package/templates/agents/optional/devops/docker-helper.md +63 -0
  37. package/templates/agents/optional/docs/changelog-generator.md +69 -0
  38. package/templates/agents/optional/docs/doc-writer.md +60 -0
  39. package/templates/agents/optional/frontend/style-enforcer.md +47 -0
  40. package/templates/agents/optional/frontend/ui-reviewer.md +51 -0
  41. package/templates/agents/optional/quality/bug-fixer.md +54 -0
  42. package/templates/agents/optional/quality/performance-auditor.md +65 -0
  43. package/templates/agents/optional/quality/refactorer.md +61 -0
  44. package/templates/agents/optional/quality/security-reviewer.md +74 -0
  45. package/templates/agents/universal/build-validator.md +15 -0
  46. package/templates/agents/universal/code-simplifier.md +17 -0
  47. package/templates/agents/universal/plan-reviewer.md +20 -0
  48. package/templates/agents/universal/test-writer.md +17 -0
  49. package/templates/agents/universal/verify-app.md +16 -0
  50. package/templates/claude-md.md +40 -0
  51. package/templates/commands/commit-push-pr.md +9 -0
  52. package/templates/commands/compact-safe.md +8 -0
  53. package/templates/commands/end.md +9 -0
  54. package/templates/commands/review-plan.md +10 -0
  55. package/templates/commands/setup.md +112 -0
  56. package/templates/commands/start.md +3 -0
  57. package/templates/commands/status.md +6 -0
  58. package/templates/commands/techdebt.md +9 -0
  59. package/templates/commands/update-claude-md.md +9 -0
  60. package/templates/commands/verify.md +8 -0
  61. package/templates/mcp-json.json +3 -0
  62. package/templates/progress-md.md +21 -0
  63. package/templates/settings/base.json +64 -0
  64. package/templates/settings/docker.json +9 -0
  65. package/templates/settings/go.json +10 -0
  66. package/templates/settings/node.json +17 -0
  67. package/templates/settings/python.json +16 -0
  68. package/templates/settings/rust.json +11 -0
  69. package/templates/skills/templates/backend-conventions.md +57 -0
  70. package/templates/skills/templates/frontend-design-system.md +48 -0
  71. package/templates/skills/templates/project-patterns.md +48 -0
  72. package/templates/skills/universal/claude-md-maintenance.md +110 -0
  73. package/templates/skills/universal/context-management.md +71 -0
  74. package/templates/skills/universal/git-conventions.md +95 -0
  75. package/templates/skills/universal/planning-with-files.md +114 -0
  76. package/templates/skills/universal/prompt-engineering.md +97 -0
  77. package/templates/skills/universal/review-and-handoff.md +106 -0
  78. package/templates/skills/universal/subagent-usage.md +108 -0
  79. package/templates/skills/universal/testing.md +116 -0
  80. package/templates/skills/universal/verification.md +120 -0
  81. package/templates/spec-md-backend.md +85 -0
  82. package/templates/spec-md-cli.md +79 -0
  83. package/templates/spec-md-data.md +74 -0
  84. package/templates/spec-md-devops.md +87 -0
  85. package/templates/spec-md-frontend.md +81 -0
  86. package/templates/spec-md-fullstack.md +81 -0
  87. package/templates/spec-md-library.md +87 -0
  88. package/templates/spec-md.md +22 -0
  89. package/templates/workflow-meta.json +10 -0
@@ -0,0 +1,164 @@
1
+ export const UNIVERSAL_AGENTS = [
2
+ 'plan-reviewer',
3
+ 'code-simplifier',
4
+ 'test-writer',
5
+ 'build-validator',
6
+ 'verify-app',
7
+ ];
8
+
9
+ export const AGENT_CATALOG = {
10
+ 'ui-reviewer': { model: 'sonnet', isolation: 'none', category: 'frontend', description: 'Reviews UI for consistency and accessibility' },
11
+ 'style-enforcer': { model: 'haiku', isolation: 'none', category: 'frontend', description: 'Ensures design system compliance' },
12
+ 'api-designer': { model: 'opus', isolation: 'none', category: 'backend', description: 'Reviews API design for RESTful conventions' },
13
+ 'database-analyst': { model: 'sonnet', isolation: 'none', category: 'backend', description: 'Reviews database schemas and queries' },
14
+ 'auth-auditor': { model: 'opus', isolation: 'none', category: 'backend', description: 'Audits authentication and authorization' },
15
+ 'security-reviewer': { model: 'opus', isolation: 'none', category: 'quality', description: 'Reviews code for security vulnerabilities' },
16
+ 'performance-auditor': { model: 'sonnet', isolation: 'none', category: 'quality', description: 'Analyzes code for performance issues' },
17
+ 'bug-fixer': { model: 'sonnet', isolation: 'worktree', category: 'quality', description: 'Diagnoses and fixes bugs' },
18
+ 'refactorer': { model: 'sonnet', isolation: 'worktree', category: 'quality', description: 'Refactors code to improve maintainability' },
19
+ 'dependency-manager': { model: 'haiku', isolation: 'none', category: 'devops', description: 'Reviews dependency health and updates' },
20
+ 'ci-fixer': { model: 'sonnet', isolation: 'worktree', category: 'devops', description: 'Diagnoses and fixes CI/CD failures' },
21
+ 'docker-helper': { model: 'sonnet', isolation: 'none', category: 'devops', description: 'Reviews Docker configs for best practices' },
22
+ 'deploy-validator': { model: 'sonnet', isolation: 'none', category: 'devops', description: 'Validates deployment readiness' },
23
+ 'doc-writer': { model: 'sonnet', isolation: 'worktree', category: 'docs', description: 'Writes and updates documentation' },
24
+ 'changelog-generator': { model: 'haiku', isolation: 'none', category: 'docs', description: 'Generates changelog from commits' },
25
+ 'data-pipeline-reviewer': { model: 'sonnet', isolation: 'none', category: 'data', description: 'Reviews data pipeline correctness' },
26
+ 'ml-experiment-tracker': { model: 'sonnet', isolation: 'none', category: 'data', description: 'Reviews ML experiment reproducibility' },
27
+ 'prompt-engineer': { model: 'opus', isolation: 'none', category: 'data', description: 'Reviews and improves LLM prompts' },
28
+ };
29
+
30
+ export const CATEGORY_RECOMMENDATIONS = {
31
+ 'Full-stack web application': ['ui-reviewer', 'api-designer', 'database-analyst', 'security-reviewer', 'bug-fixer', 'doc-writer'],
32
+ 'Backend / API': ['api-designer', 'database-analyst', 'security-reviewer', 'auth-auditor', 'bug-fixer', 'performance-auditor'],
33
+ 'Frontend / UI': ['ui-reviewer', 'style-enforcer', 'performance-auditor', 'bug-fixer'],
34
+ 'CLI tool': ['bug-fixer', 'doc-writer', 'dependency-manager'],
35
+ 'Data / ML / AI': ['data-pipeline-reviewer', 'ml-experiment-tracker', 'prompt-engineer', 'database-analyst'],
36
+ 'Library / Package': ['doc-writer', 'dependency-manager', 'performance-auditor', 'refactorer', 'changelog-generator'],
37
+ 'DevOps / Infrastructure': ['ci-fixer', 'docker-helper', 'deploy-validator', 'dependency-manager'],
38
+ };
39
+
40
+ export const COMMAND_FILES = [
41
+ 'start',
42
+ 'end',
43
+ 'commit-push-pr',
44
+ 'review-plan',
45
+ 'techdebt',
46
+ 'verify',
47
+ 'compact-safe',
48
+ 'status',
49
+ 'update-claude-md',
50
+ 'setup',
51
+ ];
52
+
53
+ export const UNIVERSAL_SKILLS = [
54
+ 'context-management',
55
+ 'git-conventions',
56
+ 'planning-with-files',
57
+ 'review-and-handoff',
58
+ 'prompt-engineering',
59
+ 'verification',
60
+ 'testing',
61
+ 'claude-md-maintenance',
62
+ 'subagent-usage',
63
+ ];
64
+
65
+ export const TEMPLATE_SKILLS = [
66
+ 'backend-conventions',
67
+ 'frontend-design-system',
68
+ 'project-patterns',
69
+ ];
70
+
71
+ export const PROJECT_TYPES = [
72
+ 'Full-stack web application',
73
+ 'Backend / API',
74
+ 'Frontend / UI',
75
+ 'CLI tool',
76
+ 'Data / ML / AI',
77
+ 'Library / Package',
78
+ 'DevOps / Infrastructure',
79
+ ];
80
+
81
+ export const TECH_STACKS = [
82
+ { name: 'Python', value: 'python' },
83
+ { name: 'Node.js / TypeScript', value: 'node' },
84
+ { name: 'Rust', value: 'rust' },
85
+ { name: 'Go', value: 'go' },
86
+ { name: 'Other / None', value: 'other' },
87
+ ];
88
+
89
+ export const FORMATTER_COMMANDS = {
90
+ python: 'ruff format . || true',
91
+ node: 'npx prettier --write . || true',
92
+ rust: 'cargo fmt || true',
93
+ go: 'gofmt -w . || true',
94
+ };
95
+
96
+ export const PROJECT_TYPE_DESCRIPTIONS = {
97
+ 'Full-stack web application': 'Frontend + backend in one repo',
98
+ 'Backend / API': 'Server, REST/GraphQL, no frontend',
99
+ 'Frontend / UI': 'Client-side app, no backend',
100
+ 'CLI tool': 'Command-line application',
101
+ 'Data / ML / AI': 'Data pipelines, ML models, LLM apps',
102
+ 'Library / Package': 'Reusable module published to npm/PyPI',
103
+ 'DevOps / Infrastructure': 'Infrastructure, CI/CD, deployment',
104
+ };
105
+
106
+ export const AGENT_CATEGORIES = {
107
+ Backend: {
108
+ agents: ['api-designer', 'database-analyst', 'auth-auditor'],
109
+ description: 'api-designer, database-analyst, auth-auditor',
110
+ },
111
+ Frontend: {
112
+ agents: ['ui-reviewer', 'style-enforcer'],
113
+ description: 'ui-reviewer, style-enforcer',
114
+ },
115
+ DevOps: {
116
+ agents: ['ci-fixer', 'docker-helper', 'deploy-validator', 'dependency-manager'],
117
+ description: 'ci-fixer, docker-helper, deploy-validator, dependency-manager',
118
+ },
119
+ Quality: {
120
+ agents: ['bug-fixer', 'security-reviewer', 'performance-auditor', 'refactorer'],
121
+ description: 'bug-fixer, security-reviewer, performance-auditor, refactorer',
122
+ },
123
+ Documentation: {
124
+ agents: ['doc-writer', 'changelog-generator'],
125
+ description: 'doc-writer, changelog-generator',
126
+ },
127
+ 'Data / AI': {
128
+ agents: ['data-pipeline-reviewer', 'ml-experiment-tracker', 'prompt-engineer'],
129
+ description: 'data-pipeline-reviewer, ml-experiment-tracker, prompt-engineer',
130
+ },
131
+ };
132
+
133
+ export const PROJECT_TYPE_TO_CATEGORIES = {
134
+ 'Full-stack web application': ['Backend', 'Frontend', 'Quality', 'Documentation'],
135
+ 'Backend / API': ['Backend', 'Quality'],
136
+ 'Frontend / UI': ['Frontend', 'Quality'],
137
+ 'CLI tool': ['Quality', 'Documentation'],
138
+ 'Data / ML / AI': ['Data / AI', 'Backend'],
139
+ 'Library / Package': ['Quality', 'Documentation'],
140
+ 'DevOps / Infrastructure': ['DevOps'],
141
+ };
142
+
143
+ export const SPEC_MD_TEMPLATE_MAP = {
144
+ 'Full-stack web application': 'spec-md-fullstack.md',
145
+ 'Backend / API': 'spec-md-backend.md',
146
+ 'Frontend / UI': 'spec-md-frontend.md',
147
+ 'CLI tool': 'spec-md-cli.md',
148
+ 'Data / ML / AI': 'spec-md-data.md',
149
+ 'Library / Package': 'spec-md-library.md',
150
+ 'DevOps / Infrastructure': 'spec-md-devops.md',
151
+ };
152
+
153
+ export const CONFIRMATION_STEPS = [
154
+ { name: 'Project name and description', value: 'projectInfo' },
155
+ { name: 'Project type', value: 'projectType' },
156
+ { name: 'Tech stack', value: 'techStack' },
157
+ { name: 'Agent selection', value: 'agents' },
158
+ ];
159
+
160
+ export const NOTIFICATION_COMMANDS = {
161
+ linux: "notify-send 'Claude Code' 'Session needs attention' 2>/dev/null || true",
162
+ darwin: `osascript -e 'display notification "Session needs attention" with title "Claude Code"' 2>/dev/null || true`,
163
+ win32: `powershell -command "New-BurntToastNotification -Text 'Claude Code','Session needs attention'" 2>/dev/null || true`,
164
+ };
package/src/index.js ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import { initCommand } from './commands/init.js';
5
+ import { upgradeCommand } from './commands/upgrade.js';
6
+ import { statusCommand } from './commands/status.js';
7
+ import { backupCommand } from './commands/backup.js';
8
+ import { restoreCommand } from './commands/restore.js';
9
+ import { diffCommand } from './commands/diff.js';
10
+
11
+ const program = new Command();
12
+
13
+ program
14
+ .name('worclaude')
15
+ .version('1.0.0')
16
+ .description('Scaffold a comprehensive Claude Code workflow into any project');
17
+
18
+ program.showSuggestionAfterError(true);
19
+ program.showHelpAfterError(true);
20
+
21
+ program
22
+ .command('init')
23
+ .description('Initialize Claude workflow in the current project')
24
+ .action(initCommand);
25
+
26
+ program
27
+ .command('upgrade')
28
+ .description('Update workflow components to the latest version')
29
+ .action(upgradeCommand);
30
+
31
+ program
32
+ .command('status')
33
+ .description('Show current workflow installation status')
34
+ .action(statusCommand);
35
+
36
+ program
37
+ .command('backup')
38
+ .description('Create a backup of current Claude setup')
39
+ .action(backupCommand);
40
+
41
+ program
42
+ .command('restore')
43
+ .description('Restore Claude setup from a backup')
44
+ .action(restoreCommand);
45
+
46
+ program
47
+ .command('diff')
48
+ .description('Compare current setup against installed workflow version')
49
+ .action(diffCommand);
50
+
51
+ program.parse();
@@ -0,0 +1,99 @@
1
+ import inquirer from 'inquirer';
2
+ import {
3
+ UNIVERSAL_AGENTS,
4
+ AGENT_CATALOG,
5
+ AGENT_CATEGORIES,
6
+ PROJECT_TYPE_TO_CATEGORIES,
7
+ } from '../data/agents.js';
8
+ import * as display from '../utils/display.js';
9
+
10
+ export async function promptAgentSelection(projectTypes) {
11
+ // Show universal agents (informational)
12
+ display.newline();
13
+ display.info('Universal agents (always installed):');
14
+ for (const agent of UNIVERSAL_AGENTS) {
15
+ display.success(agent);
16
+ }
17
+ display.newline();
18
+
19
+ // Derive pre-selected categories from project types
20
+ const preSelectedCategories = new Set();
21
+ for (const type of projectTypes) {
22
+ const cats = PROJECT_TYPE_TO_CATEGORIES[type] || [];
23
+ for (const cat of cats) {
24
+ preSelectedCategories.add(cat);
25
+ }
26
+ }
27
+
28
+ // Step 1: Category selection
29
+ const categoryNames = Object.keys(AGENT_CATEGORIES);
30
+ const { selectedCategories } = await inquirer.prompt([
31
+ {
32
+ type: 'checkbox',
33
+ name: 'selectedCategories',
34
+ message: 'Which agent categories do you need? (space to toggle)',
35
+ choices: categoryNames.map((cat) => ({
36
+ name: `${cat} — ${AGENT_CATEGORIES[cat].description}`,
37
+ value: cat,
38
+ checked: preSelectedCategories.has(cat),
39
+ })),
40
+ },
41
+ ]);
42
+
43
+ // Step 2: Fine-tune each selected category
44
+ const selected = [];
45
+
46
+ for (const cat of selectedCategories) {
47
+ const agentNames = AGENT_CATEGORIES[cat].agents;
48
+ const { selectedAgents } = await inquirer.prompt([
49
+ {
50
+ type: 'checkbox',
51
+ name: 'selectedAgents',
52
+ message: `Fine-tune ${cat} agents? (space to toggle, enter to accept defaults)`,
53
+ choices: agentNames.map((name) => ({
54
+ name: `${name} — ${AGENT_CATALOG[name].description}`,
55
+ value: name,
56
+ checked: true,
57
+ })),
58
+ },
59
+ ]);
60
+ selected.push(...selectedAgents);
61
+ }
62
+
63
+ // Step 3: Offer unselected categories
64
+ const unselectedCategories = categoryNames.filter((cat) => !selectedCategories.includes(cat));
65
+
66
+ if (unselectedCategories.length > 0) {
67
+ const { additionalCategories } = await inquirer.prompt([
68
+ {
69
+ type: 'checkbox',
70
+ name: 'additionalCategories',
71
+ message: 'Any other agent categories you\'d like to add? (space to toggle, enter to skip)',
72
+ choices: unselectedCategories.map((cat) => ({
73
+ name: `${cat} — ${AGENT_CATEGORIES[cat].description}`,
74
+ value: cat,
75
+ })),
76
+ },
77
+ ]);
78
+
79
+ for (const cat of additionalCategories) {
80
+ const agentNames = AGENT_CATEGORIES[cat].agents;
81
+ const { selectedAgents } = await inquirer.prompt([
82
+ {
83
+ type: 'checkbox',
84
+ name: 'selectedAgents',
85
+ message: `Fine-tune ${cat} agents? (space to toggle, enter to accept defaults)`,
86
+ choices: agentNames.map((name) => ({
87
+ name: `${name} — ${AGENT_CATALOG[name].description}`,
88
+ value: name,
89
+ checked: true,
90
+ })),
91
+ },
92
+ ]);
93
+ selected.push(...selectedAgents);
94
+ }
95
+ }
96
+
97
+ // Deduplicate
98
+ return [...new Set(selected)];
99
+ }
@@ -0,0 +1,153 @@
1
+ import inquirer from 'inquirer';
2
+ import * as display from '../utils/display.js';
3
+
4
+ const SECTION_DETECTORS = [
5
+ {
6
+ name: 'Key Files',
7
+ heading: '## Key Files',
8
+ test: (c) => /PROGRESS\.md/i.test(c) || /Key Files/i.test(c),
9
+ },
10
+ {
11
+ name: 'Session Protocol',
12
+ heading: '## Session Protocol',
13
+ test: (c) =>
14
+ /Session Protocol/i.test(c) || (/\*\*Start:\*\*/i.test(c) && /\*\*End:\*\*/i.test(c)),
15
+ },
16
+ {
17
+ name: 'Critical Rules',
18
+ heading: '## Critical Rules',
19
+ test: (c) => /Critical Rules/i.test(c) || /## Rules/i.test(c),
20
+ },
21
+ {
22
+ name: 'Skills pointer',
23
+ heading: '## Skills',
24
+ test: (c) => /\.claude\/skills\//i.test(c) || /Skills.*read on demand/i.test(c),
25
+ },
26
+ {
27
+ name: 'Gotchas section',
28
+ heading: '## Gotchas',
29
+ test: (c) => /Gotchas/i.test(c),
30
+ },
31
+ ];
32
+
33
+ export function detectMissingSections(existingContent) {
34
+ return SECTION_DETECTORS.filter((s) => !s.test(existingContent)).map((s) => s.name);
35
+ }
36
+
37
+ function extractSection(content, heading) {
38
+ const lines = content.split(/\r?\n/);
39
+ const startIdx = lines.findIndex((l) => l.startsWith(heading));
40
+ if (startIdx === -1) return null;
41
+
42
+ // Find the next ## heading after this one
43
+ let endIdx = lines.length;
44
+ for (let i = startIdx + 1; i < lines.length; i++) {
45
+ if (/^## /.test(lines[i])) {
46
+ endIdx = i;
47
+ break;
48
+ }
49
+ }
50
+
51
+ return lines.slice(startIdx, endIdx).join('\n').trimEnd();
52
+ }
53
+
54
+ export function generateWorkflowSuggestions(existingContent, renderedTemplate) {
55
+ const missing = detectMissingSections(existingContent);
56
+
57
+ const lines = [
58
+ '# Worclaude — Suggested CLAUDE.md Additions',
59
+ '',
60
+ 'The following sections are recommended based on the Claude Code',
61
+ 'workflow system. Review and merge what\'s useful into your CLAUDE.md.',
62
+ '',
63
+ ];
64
+
65
+ for (const sectionName of missing) {
66
+ const detector = SECTION_DETECTORS.find((s) => s.name === sectionName);
67
+ if (!detector) continue;
68
+
69
+ const sectionContent = extractSection(renderedTemplate, detector.heading);
70
+ if (!sectionContent) continue;
71
+
72
+ lines.push(`## Suggested: ${sectionName}`);
73
+ lines.push('```');
74
+ lines.push(sectionContent);
75
+ lines.push('```');
76
+ lines.push('');
77
+ }
78
+
79
+ if (missing.length === 0) {
80
+ lines.push('Your CLAUDE.md already has all recommended sections. No suggestions needed.');
81
+ }
82
+
83
+ return lines.join('\n');
84
+ }
85
+
86
+ export async function promptClaudeMdMerge(existingContent, missingSections) {
87
+ const lineCount = existingContent.split(/\r?\n/).length;
88
+
89
+ display.newline();
90
+ display.info(`Your CLAUDE.md (${lineCount} lines) was detected.`);
91
+
92
+ if (missingSections.length === 0) {
93
+ display.success('Your CLAUDE.md already has all recommended sections!');
94
+ return 'keep';
95
+ }
96
+
97
+ display.newline();
98
+ display.info('The workflow recommends these additions:');
99
+ for (const section of missingSections) {
100
+ display.success(`[+] ${section}`);
101
+ }
102
+
103
+ const { choice } = await inquirer.prompt([
104
+ {
105
+ type: 'list',
106
+ name: 'choice',
107
+ message: 'How would you like to handle CLAUDE.md?',
108
+ choices: [
109
+ { name: 'Keep mine, save suggestions to CLAUDE.md.workflow-suggestions', value: 'keep' },
110
+ { name: 'Merge interactively section by section', value: 'merge-sections' },
111
+ ],
112
+ },
113
+ ]);
114
+
115
+ return choice;
116
+ }
117
+
118
+ export async function interactiveSectionMerge(existingContent, renderedTemplate, missingSections) {
119
+ let updatedContent = existingContent;
120
+
121
+ for (const sectionName of missingSections) {
122
+ const detector = SECTION_DETECTORS.find((s) => s.name === sectionName);
123
+ if (!detector) continue;
124
+
125
+ const sectionContent = extractSection(renderedTemplate, detector.heading);
126
+ if (!sectionContent) continue;
127
+
128
+ display.newline();
129
+ display.info(`Section: ${sectionName}`);
130
+ display.dim(sectionContent.split(/\r?\n/).slice(0, 5).join('\n'));
131
+ if (sectionContent.split(/\r?\n/).length > 5) {
132
+ display.dim(' ...');
133
+ }
134
+
135
+ const { addSection } = await inquirer.prompt([
136
+ {
137
+ type: 'list',
138
+ name: 'addSection',
139
+ message: `Add "${sectionName}" to your CLAUDE.md?`,
140
+ choices: [
141
+ { name: 'Yes', value: true },
142
+ { name: 'No', value: false },
143
+ ],
144
+ },
145
+ ]);
146
+
147
+ if (addSection) {
148
+ updatedContent = updatedContent.trimEnd() + '\n\n' + sectionContent + '\n';
149
+ }
150
+ }
151
+
152
+ return updatedContent;
153
+ }
@@ -0,0 +1,24 @@
1
+ import inquirer from 'inquirer';
2
+ import * as display from '../utils/display.js';
3
+
4
+ export async function promptHookConflict(hookCategory, existingHook, workflowHook) {
5
+ display.newline();
6
+ display.warn(`Hook conflict: ${hookCategory} matcher "${existingHook.matcher}"`);
7
+ display.dim(` Existing: ${existingHook.hooks[0].command}`);
8
+ display.dim(` Workflow: ${workflowHook.hooks[0].command}`);
9
+
10
+ const { resolution } = await inquirer.prompt([
11
+ {
12
+ type: 'list',
13
+ name: 'resolution',
14
+ message: 'How would you like to resolve this?',
15
+ choices: [
16
+ { name: 'Keep existing hook', value: 'keep' },
17
+ { name: 'Replace with workflow hook', value: 'replace' },
18
+ { name: 'Chain both (existing && workflow)', value: 'chain' },
19
+ ],
20
+ },
21
+ ]);
22
+
23
+ return resolution;
24
+ }
@@ -0,0 +1,75 @@
1
+ import inquirer from 'inquirer';
2
+ import { PROJECT_TYPES, PROJECT_TYPE_DESCRIPTIONS, CATEGORY_RECOMMENDATIONS } from '../data/agents.js';
3
+ import * as display from '../utils/display.js';
4
+
5
+ export async function promptProjectType() {
6
+ const { projectTypes } = await inquirer.prompt([
7
+ {
8
+ type: 'checkbox',
9
+ name: 'projectTypes',
10
+ message:
11
+ 'What type of project is this? (space to toggle, enter to confirm)\n ℹ Not sure? Pick what\'s closest. You can add/remove agents later.',
12
+ choices: PROJECT_TYPES.map((t) => ({
13
+ name: `${t} — ${PROJECT_TYPE_DESCRIPTIONS[t]}`,
14
+ value: t,
15
+ })),
16
+ validate(answer) {
17
+ if (answer.length === 0) {
18
+ return 'Please select at least one project type.';
19
+ }
20
+ return true;
21
+ },
22
+ },
23
+ ]);
24
+
25
+ // Smart redundancy detection — confirm prompt if overlap detected
26
+ if (projectTypes.includes('Full-stack web application')) {
27
+ const overlaps = [];
28
+ if (projectTypes.includes('Backend / API')) overlaps.push('Backend / API');
29
+ if (projectTypes.includes('Frontend / UI')) overlaps.push('Frontend / UI');
30
+ if (overlaps.length > 0) {
31
+ display.newline();
32
+ display.warn('"Full-stack web" already includes backend and frontend.');
33
+ display.dim('You may not need both.');
34
+ const { continueAnyway } = await inquirer.prompt([
35
+ {
36
+ type: 'list',
37
+ name: 'continueAnyway',
38
+ message: 'Continue anyway?',
39
+ choices: [
40
+ { name: 'Yes', value: true },
41
+ { name: 'No', value: false },
42
+ ],
43
+ },
44
+ ]);
45
+ if (!continueAnyway) {
46
+ return promptProjectType();
47
+ }
48
+ }
49
+ }
50
+
51
+ // Check for overlapping agent recommendations
52
+ if (projectTypes.length > 1) {
53
+ const agentSets = projectTypes.map((t) => new Set(CATEGORY_RECOMMENDATIONS[t] || []));
54
+ const allAgents = new Set();
55
+ const overlapping = new Set();
56
+
57
+ for (const agentSet of agentSets) {
58
+ for (const agent of agentSet) {
59
+ if (allAgents.has(agent)) {
60
+ overlapping.add(agent);
61
+ }
62
+ allAgents.add(agent);
63
+ }
64
+ }
65
+
66
+ if (overlapping.size > 0) {
67
+ display.info(
68
+ `Some agents are recommended by multiple project types: ${[...overlapping].join(', ')}`
69
+ );
70
+ display.dim('They will only be installed once.');
71
+ }
72
+ }
73
+
74
+ return projectTypes;
75
+ }
@@ -0,0 +1,35 @@
1
+ import inquirer from 'inquirer';
2
+ import { TECH_STACKS } from '../data/agents.js';
3
+
4
+ export async function promptTechStack(_projectTypes) {
5
+ const { languages } = await inquirer.prompt([
6
+ {
7
+ type: 'checkbox',
8
+ name: 'languages',
9
+ message:
10
+ 'Primary language(s) / runtime: (space to toggle, enter to confirm)\n ℹ This sets tool permissions and formatters. Update anytime via settings.json.',
11
+ choices: TECH_STACKS,
12
+ validate(answer) {
13
+ if (answer.length === 0) {
14
+ return 'Please select at least one language or "Other / None".';
15
+ }
16
+ return true;
17
+ },
18
+ },
19
+ ]);
20
+
21
+ const { useDocker } = await inquirer.prompt([
22
+ {
23
+ type: 'list',
24
+ name: 'useDocker',
25
+ message: 'Do you use Docker currently?',
26
+ choices: [
27
+ { name: 'Yes', value: true },
28
+ { name: 'No', value: false },
29
+ ],
30
+ suffix: '\n ℹ If you add Docker later, run `worclaude upgrade`.',
31
+ },
32
+ ]);
33
+
34
+ return { languages, useDocker };
35
+ }
@@ -0,0 +1,41 @@
1
+ import chalk from 'chalk';
2
+
3
+ export function header(text) {
4
+ console.log();
5
+ console.log(chalk.bold(text));
6
+ console.log(chalk.dim('─'.repeat(text.length)));
7
+ }
8
+
9
+ export function success(text) {
10
+ console.log(chalk.green(' ✓ ') + text);
11
+ }
12
+
13
+ export function error(text) {
14
+ console.log(chalk.red(' ✗ ') + text);
15
+ }
16
+
17
+ export function info(text) {
18
+ console.log(chalk.blue(' ℹ ') + text);
19
+ }
20
+
21
+ export function warn(text) {
22
+ console.log(chalk.yellow(' ⚠ ') + text);
23
+ }
24
+
25
+ export function dim(text) {
26
+ console.log(chalk.dim(' ' + text));
27
+ }
28
+
29
+ export function newline() {
30
+ console.log();
31
+ }
32
+
33
+ export function reviewBox(lines) {
34
+ console.log();
35
+ console.log(chalk.dim(' ─── Review Your Selections ───'));
36
+ console.log();
37
+ for (const line of lines) {
38
+ console.log(' ' + line);
39
+ }
40
+ console.log();
41
+ }