claude-dev-env 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.
- package/LICENSE +21 -0
- package/README.md +219 -0
- package/agents/agent-writer.md +157 -0
- package/agents/clasp-deployment-orchestrator.md +609 -0
- package/agents/clean-coder.md +295 -0
- package/agents/code-quality-agent.md +40 -0
- package/agents/code-standards-agent.md +93 -0
- package/agents/config-centralizer.md +686 -0
- package/agents/config-extraction-agent.md +225 -0
- package/agents/doc-orchestrator.md +47 -0
- package/agents/docs-agent.md +112 -0
- package/agents/docx-agent.md +211 -0
- package/agents/git-commit-crafter.md +100 -0
- package/agents/magic-value-eliminator-agent.md +72 -0
- package/agents/mandatory-agent-workflow-agent.md +88 -0
- package/agents/parallel-workflow-coordinator.md +779 -0
- package/agents/pdf-agent.md +302 -0
- package/agents/plan-executor.md +226 -0
- package/agents/pr-description-writer.md +87 -0
- package/agents/project-context-loader.md +238 -0
- package/agents/project-docs-analyzer.md +54 -0
- package/agents/project-structure-organizer-agent.md +72 -0
- package/agents/readability-review-agent.md +76 -0
- package/agents/refactoring-specialist.md +69 -0
- package/agents/right-sized-engineer.md +129 -0
- package/agents/session-continuity-manager.md +53 -0
- package/agents/skill-to-agent-converter.md +371 -0
- package/agents/skill-writer-agent.md +470 -0
- package/agents/stub-detector-agent.md +140 -0
- package/agents/tdd-test-writer.md +62 -0
- package/agents/test-data-builder.md +68 -0
- package/agents/tooling-builder.md +78 -0
- package/agents/user-docs-writer.md +67 -0
- package/agents/validation-expert.md +71 -0
- package/agents/workflow-visual-documenter.md +82 -0
- package/agents/xlsx-agent.md +169 -0
- package/bin/install.mjs +256 -0
- package/commands/commit.md +28 -0
- package/commands/docupdate.md +322 -0
- package/commands/implement.md +102 -0
- package/commands/initialize.md +91 -0
- package/commands/plan.md +63 -0
- package/commands/pr-comments.md +47 -0
- package/commands/readability-review.md +20 -0
- package/commands/review-plan.md +7 -0
- package/commands/right-size.md +15 -0
- package/commands/stubcheck.md +89 -0
- package/commands/sum.md +30 -0
- package/docs/CODE_RULES.md +186 -0
- package/docs/DJANGO_PATTERNS.md +80 -0
- package/docs/REACT_PATTERNS.md +185 -0
- package/docs/TEST_QUALITY.md +104 -0
- package/hooks/advisory/migration-safety-advisor.py +49 -0
- package/hooks/advisory/refactor-guard.py +205 -0
- package/hooks/blocking/block-main-commit.py +168 -0
- package/hooks/blocking/code-rules-enforcer.py +549 -0
- package/hooks/blocking/destructive-command-blocker.py +107 -0
- package/hooks/blocking/docker-settings-guard.py +44 -0
- package/hooks/blocking/hedging-language-blocker.py +130 -0
- package/hooks/blocking/parallel-task-blocker.py +69 -0
- package/hooks/blocking/pr-description-enforcer.py +87 -0
- package/hooks/blocking/pyautogui-scroll-blocker.py +74 -0
- package/hooks/blocking/sensitive-file-protector.py +70 -0
- package/hooks/blocking/tdd-enforcer.py +62 -0
- package/hooks/blocking/test-preflight-check.py +343 -0
- package/hooks/blocking/write-existing-file-blocker.py +63 -0
- package/hooks/git-hooks/post-commit.py +103 -0
- package/hooks/github-action/test_workflow.py +33 -0
- package/hooks/hooks.json +246 -0
- package/hooks/lifecycle/config-change-guard.py +84 -0
- package/hooks/lifecycle/session-end-cleanup.py +59 -0
- package/hooks/notification/attention-needed-notify.py +63 -0
- package/hooks/notification/claude-notification-handler.py +59 -0
- package/hooks/notification/notification_utils.py +206 -0
- package/hooks/rewrite-plugin-paths.py +116 -0
- package/hooks/session/bulk-edit-reminder.py +30 -0
- package/hooks/session/code-rules-reminder.py +97 -0
- package/hooks/session/compact-context-reinject.py +39 -0
- package/hooks/session/hook-structure-context.py +140 -0
- package/hooks/session/plugin-data-dir-cleanup.py +39 -0
- package/hooks/validation/code-style-validator.py +145 -0
- package/hooks/validation/e2e-test-validator.py +142 -0
- package/hooks/validation/hook-format-validator.py +66 -0
- package/hooks/validation/mypy_validator.py +180 -0
- package/hooks/validators/README.md +125 -0
- package/hooks/validators/VALIDATION_REPORT.md +287 -0
- package/hooks/validators/__init__.py +19 -0
- package/hooks/validators/abbreviation_checks.py +82 -0
- package/hooks/validators/code_quality_checks.py +133 -0
- package/hooks/validators/comment_checks.py +188 -0
- package/hooks/validators/file_structure_checks.py +182 -0
- package/hooks/validators/git_checks.py +107 -0
- package/hooks/validators/health_check.py +214 -0
- package/hooks/validators/magic_value_checks.py +81 -0
- package/hooks/validators/mypy_integration.py +52 -0
- package/hooks/validators/output_formatter.py +266 -0
- package/hooks/validators/pr_reference_checks.py +72 -0
- package/hooks/validators/python_antipattern_checks.py +110 -0
- package/hooks/validators/python_style_checks.py +364 -0
- package/hooks/validators/react_checks.py +90 -0
- package/hooks/validators/ruff_integration.py +80 -0
- package/hooks/validators/run_all_validators.py +772 -0
- package/hooks/validators/security_checks.py +135 -0
- package/hooks/validators/test_abbreviation_checks.py +76 -0
- package/hooks/validators/test_bad.tsx +7 -0
- package/hooks/validators/test_code_quality_checks.py +129 -0
- package/hooks/validators/test_file_structure_checks.py +307 -0
- package/hooks/validators/test_files/01_basic_component.tsx +10 -0
- package/hooks/validators/test_files/02_component_without_react.tsx +10 -0
- package/hooks/validators/test_files/03_pure_component.tsx +10 -0
- package/hooks/validators/test_files/04_pure_component_import.tsx +10 -0
- package/hooks/validators/test_files/05_typescript_generics.tsx +14 -0
- package/hooks/validators/test_files/06_typescript_two_generics.tsx +18 -0
- package/hooks/validators/test_files/07_multiline_declaration.tsx +11 -0
- package/hooks/validators/test_files/08_error_boundary_valid.tsx +14 -0
- package/hooks/validators/test_files/09_error_boundary_with_other_class.tsx +20 -0
- package/hooks/validators/test_files/10_inheritance_chain.tsx +16 -0
- package/hooks/validators/test_files/11_ts_file.ts +10 -0
- package/hooks/validators/test_files/12_non_react_class.tsx +14 -0
- package/hooks/validators/test_files/13_functional_component.tsx +8 -0
- package/hooks/validators/test_files/14_indented_class.tsx +13 -0
- package/hooks/validators/test_files/15_getDerivedStateFromError.tsx +14 -0
- package/hooks/validators/test_files/16_mixed_components.tsx +20 -0
- package/hooks/validators/test_files/EXECUTIVE_SUMMARY.md +175 -0
- package/hooks/validators/test_files/TEST_RESULTS_TABLE.txt +60 -0
- package/hooks/validators/test_files/VALIDATION_REPORT.md +201 -0
- package/hooks/validators/test_files/async_views.py +23 -0
- package/hooks/validators/test_files/async_with_imports.py +14 -0
- package/hooks/validators/test_files/bad_inline_imports.py +37 -0
- package/hooks/validators/test_files/management/commands/cmd_01_no_debug_check.py +10 -0
- package/hooks/validators/test_files/management/commands/cmd_02_proper_debug_check.py +14 -0
- package/hooks/validators/test_files/management/commands/cmd_03_debug_check_with_return.py +14 -0
- package/hooks/validators/test_files/management/commands/cmd_04_imported_DEBUG.py +14 -0
- package/hooks/validators/test_files/management/commands/cmd_05_debug_check_in_helper.py +16 -0
- package/hooks/validators/test_files/management/commands/cmd_06_debug_check_late.py +22 -0
- package/hooks/validators/test_files/management/commands/cmd_07_positive_debug_check.py +15 -0
- package/hooks/validators/test_files/management/commands/cmd_08_debug_with_and.py +14 -0
- package/hooks/validators/test_files/not_management_command.py +10 -0
- package/hooks/validators/test_files/skip_decorators/test_01_simple_skip.py +8 -0
- package/hooks/validators/test_files/skip_decorators/test_02_pytest_skipif.py +8 -0
- package/hooks/validators/test_files/skip_decorators/test_03_unittest_skipIf.py +8 -0
- package/hooks/validators/test_files/skip_decorators/test_04_skip_with_parens.py +8 -0
- package/hooks/validators/test_files/skip_decorators/test_05_xfail.py +7 -0
- package/hooks/validators/test_files/skip_decorators/test_06_custom_skip.py +11 -0
- package/hooks/validators/test_files/skip_decorators/test_07_capital_Skip.py +8 -0
- package/hooks/validators/test_files/skip_decorators/test_08_skipUnless.py +7 -0
- package/hooks/validators/test_files/skip_decorators/test_09_pytest_mark_skip_simple.py +7 -0
- package/hooks/validators/test_files/test_async_functions.py +45 -0
- package/hooks/validators/test_files/test_purecomponent/PureComponentExample.tsx +7 -0
- package/hooks/validators/test_files/test_purecomponent/ReactPureComponentExample.tsx +7 -0
- package/hooks/validators/test_git_checks.py +295 -0
- package/hooks/validators/test_good.tsx +5 -0
- package/hooks/validators/test_health_check.py +57 -0
- package/hooks/validators/test_magic_value_checks.py +63 -0
- package/hooks/validators/test_mypy_integration.py +27 -0
- package/hooks/validators/test_output_formatter.py +150 -0
- package/hooks/validators/test_pr_reference_checks.py +41 -0
- package/hooks/validators/test_python_antipattern_checks.py +113 -0
- package/hooks/validators/test_python_style_checks.py +439 -0
- package/hooks/validators/test_react_checks.py +213 -0
- package/hooks/validators/test_results.txt +25 -0
- package/hooks/validators/test_ruff_integration.py +27 -0
- package/hooks/validators/test_run_all_validators.py +228 -0
- package/hooks/validators/test_run_all_validators_integration.py +48 -0
- package/hooks/validators/test_safety_checks.py +243 -0
- package/hooks/validators/test_security_checks.py +105 -0
- package/hooks/validators/test_test_safety_checks.py +321 -0
- package/hooks/validators/test_todo_checks.py +39 -0
- package/hooks/validators/test_type_safety_checks.py +85 -0
- package/hooks/validators/test_useless_test_checks.py +55 -0
- package/hooks/validators/test_validator_base.py +26 -0
- package/hooks/validators/test_verify_paths.py +34 -0
- package/hooks/validators/todo_checks.py +59 -0
- package/hooks/validators/type_safety_checks.py +101 -0
- package/hooks/validators/useless_test_checks.py +92 -0
- package/hooks/validators/validator_base.py +19 -0
- package/hooks/validators/verify_paths.py +57 -0
- package/hooks/workflow/auto-formatter.py +114 -0
- package/hooks/workflow/investigation-tracker-reset.py +46 -0
- package/package.json +30 -0
- package/rules/agent-spawn-protocol.md +47 -0
- package/rules/cleanup-temp-files.md +27 -0
- package/rules/code-reviews.md +11 -0
- package/rules/code-standards.md +43 -0
- package/rules/conservative-action.md +20 -0
- package/rules/context7.md +12 -0
- package/rules/explore-thoroughly.md +27 -0
- package/rules/git-workflow.md +42 -0
- package/rules/parallel-tools.md +23 -0
- package/rules/research-mode.md +23 -0
- package/rules/right-sized-engineering.md +28 -0
- package/rules/tdd.md +7 -0
- package/rules/testing.md +12 -0
- package/skills/agent-prompt/SKILL.md +102 -0
- package/skills/anthropic-plan/SKILL.md +107 -0
- package/skills/everything-search/SKILL.md +144 -0
- package/skills/ingest/SKILL.md +40 -0
- package/skills/npm-creator/SKILL.md +183 -0
- package/skills/pr-review-responder/EXAMPLES.md +590 -0
- package/skills/pr-review-responder/PRINCIPLES.md +539 -0
- package/skills/pr-review-responder/README.md +209 -0
- package/skills/pr-review-responder/SKILL.md +202 -0
- package/skills/pr-review-responder/TESTING.md +407 -0
- package/skills/pr-review-responder/scripts/respond_to_reviews.py +376 -0
- package/skills/pr-review-responder/update_skill.py +297 -0
- package/skills/prompt-generator/REFERENCE.md +150 -0
- package/skills/prompt-generator/SKILL.md +154 -0
- package/skills/readability-review/SKILL.md +127 -0
- package/skills/recall/SKILL.md +27 -0
- package/skills/remember/SKILL.md +63 -0
- package/skills/rule-audit/SKILL.md +307 -0
- package/skills/rule-creator/SKILL.md +150 -0
- package/skills/skill-writer/REFERENCE.md +246 -0
- package/skills/skill-writer/SKILL.md +270 -0
- package/skills/tdd-team/SKILL.md +128 -0
package/bin/install.mjs
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, statSync, copyFileSync, unlinkSync, rmSync } from 'node:fs';
|
|
4
|
+
import { join, dirname, resolve, relative } from 'node:path';
|
|
5
|
+
import { homedir } from 'node:os';
|
|
6
|
+
import { execSync } from 'node:child_process';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
|
|
9
|
+
const CLAUDE_HOME = join(homedir(), '.claude');
|
|
10
|
+
const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
11
|
+
const MANIFEST_FILE = join(CLAUDE_HOME, '.claude-dev-env-manifest.json');
|
|
12
|
+
const PACKAGE_NAME = 'claude-dev-env';
|
|
13
|
+
|
|
14
|
+
const CONTENT_DIRECTORIES = ['rules', 'docs', 'commands', 'agents'];
|
|
15
|
+
|
|
16
|
+
function detectPython() {
|
|
17
|
+
const candidates = [
|
|
18
|
+
{ command: 'python3', versionFlag: '--version' },
|
|
19
|
+
{ command: 'python', versionFlag: '--version' },
|
|
20
|
+
{ command: 'py -3', versionFlag: '--version' },
|
|
21
|
+
];
|
|
22
|
+
for (const { command, versionFlag } of candidates) {
|
|
23
|
+
try {
|
|
24
|
+
const version = execSync(`${command} ${versionFlag}`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
25
|
+
if (version.includes('Python 3.')) {
|
|
26
|
+
return command;
|
|
27
|
+
}
|
|
28
|
+
} catch { /* try next */ }
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function collectFiles(directory) {
|
|
34
|
+
const collected = [];
|
|
35
|
+
if (!existsSync(directory)) return collected;
|
|
36
|
+
const entries = readdirSync(directory, { withFileTypes: true });
|
|
37
|
+
for (const entry of entries) {
|
|
38
|
+
const entryPath = join(directory, entry.name);
|
|
39
|
+
if (entry.isDirectory()) {
|
|
40
|
+
collected.push(...collectFiles(entryPath));
|
|
41
|
+
} else {
|
|
42
|
+
collected.push(entryPath);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return collected;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function copyTree(sourceBase, destBase) {
|
|
49
|
+
const files = collectFiles(sourceBase);
|
|
50
|
+
const stats = { created: 0, updated: 0, paths: [] };
|
|
51
|
+
for (const sourceFile of files) {
|
|
52
|
+
const relativePath = relative(sourceBase, sourceFile);
|
|
53
|
+
const destFile = join(destBase, relativePath);
|
|
54
|
+
mkdirSync(dirname(destFile), { recursive: true });
|
|
55
|
+
const existed = existsSync(destFile);
|
|
56
|
+
copyFileSync(sourceFile, destFile);
|
|
57
|
+
stats.paths.push(destFile);
|
|
58
|
+
if (existed) {
|
|
59
|
+
stats.updated++;
|
|
60
|
+
console.log(` \u21bb ${join(relative(CLAUDE_HOME, destBase), relativePath)} (updated)`);
|
|
61
|
+
} else {
|
|
62
|
+
stats.created++;
|
|
63
|
+
console.log(` \u2713 ${join(relative(CLAUDE_HOME, destBase), relativePath)} (new)`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return stats;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function mergeHooks(pythonCommand) {
|
|
70
|
+
const hooksJsonPath = join(PACKAGE_ROOT, 'hooks', 'hooks.json');
|
|
71
|
+
if (!existsSync(hooksJsonPath)) return 0;
|
|
72
|
+
const hooksConfig = JSON.parse(readFileSync(hooksJsonPath, 'utf8'));
|
|
73
|
+
const settingsPath = join(CLAUDE_HOME, 'settings.json');
|
|
74
|
+
let settings = {};
|
|
75
|
+
if (existsSync(settingsPath)) {
|
|
76
|
+
const raw = readFileSync(settingsPath, 'utf8').trim();
|
|
77
|
+
if (raw) {
|
|
78
|
+
try { settings = JSON.parse(raw); }
|
|
79
|
+
catch { console.error(' ERROR: settings.json is malformed JSON. Fix it and rerun.'); process.exit(1); }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (!settings.hooks) settings.hooks = {};
|
|
83
|
+
const installedHooksDir = join(CLAUDE_HOME, 'hooks');
|
|
84
|
+
let groupCount = 0;
|
|
85
|
+
for (const [eventType, matcherGroups] of Object.entries(hooksConfig.hooks)) {
|
|
86
|
+
if (!settings.hooks[eventType]) settings.hooks[eventType] = [];
|
|
87
|
+
for (const sourceGroup of matcherGroups) {
|
|
88
|
+
const rewrittenHooks = sourceGroup.hooks.map(hook => {
|
|
89
|
+
let command = hook.command;
|
|
90
|
+
command = command.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, installedHooksDir.replace(/\\/g, '/'));
|
|
91
|
+
command = command.replace(/^python3\b/, pythonCommand);
|
|
92
|
+
return { ...hook, command };
|
|
93
|
+
});
|
|
94
|
+
const existingIndex = settings.hooks[eventType].findIndex(
|
|
95
|
+
group => group.matcher === sourceGroup.matcher
|
|
96
|
+
);
|
|
97
|
+
if (existingIndex >= 0) {
|
|
98
|
+
const existing = settings.hooks[eventType][existingIndex];
|
|
99
|
+
const userHooks = existing.hooks.filter(
|
|
100
|
+
hook => !hook.command.includes(installedHooksDir.replace(/\\/g, '/'))
|
|
101
|
+
);
|
|
102
|
+
settings.hooks[eventType][existingIndex] = {
|
|
103
|
+
...existing,
|
|
104
|
+
hooks: [...userHooks, ...rewrittenHooks],
|
|
105
|
+
};
|
|
106
|
+
} else {
|
|
107
|
+
settings.hooks[eventType].push({ matcher: sourceGroup.matcher, hooks: rewrittenHooks });
|
|
108
|
+
}
|
|
109
|
+
groupCount++;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 4) + '\n');
|
|
113
|
+
return groupCount;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function writeManifest(installedFiles) {
|
|
117
|
+
const manifest = { package: PACKAGE_NAME, version: '1.0.0', installedAt: new Date().toISOString(), files: installedFiles };
|
|
118
|
+
writeFileSync(MANIFEST_FILE, JSON.stringify(manifest, null, 2) + '\n');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function install() {
|
|
122
|
+
console.log(`\nInstalling ${PACKAGE_NAME}...\n`);
|
|
123
|
+
const pythonCommand = detectPython();
|
|
124
|
+
if (!pythonCommand) {
|
|
125
|
+
console.error('ERROR: Python 3 not found. Install Python 3.8+ and ensure python3, python, or py is on PATH.');
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
console.log(` Python: ${pythonCommand}`);
|
|
129
|
+
mkdirSync(CLAUDE_HOME, { recursive: true });
|
|
130
|
+
const allInstalledFiles = [];
|
|
131
|
+
const summary = {};
|
|
132
|
+
for (const directory of CONTENT_DIRECTORIES) {
|
|
133
|
+
const sourceDir = join(PACKAGE_ROOT, directory);
|
|
134
|
+
if (!existsSync(sourceDir)) continue;
|
|
135
|
+
const destDir = join(CLAUDE_HOME, directory);
|
|
136
|
+
const stats = copyTree(sourceDir, destDir);
|
|
137
|
+
summary[directory] = stats;
|
|
138
|
+
allInstalledFiles.push(...stats.paths);
|
|
139
|
+
}
|
|
140
|
+
const skillsSource = join(PACKAGE_ROOT, 'skills');
|
|
141
|
+
if (existsSync(skillsSource)) {
|
|
142
|
+
const skillDirs = readdirSync(skillsSource, { withFileTypes: true }).filter(entry => entry.isDirectory());
|
|
143
|
+
let skillsCreated = 0;
|
|
144
|
+
let skillsUpdated = 0;
|
|
145
|
+
const skillPaths = [];
|
|
146
|
+
for (const skillDir of skillDirs) {
|
|
147
|
+
const stats = copyTree(join(skillsSource, skillDir.name), join(CLAUDE_HOME, 'skills', skillDir.name));
|
|
148
|
+
skillsCreated += stats.created;
|
|
149
|
+
skillsUpdated += stats.updated;
|
|
150
|
+
skillPaths.push(...stats.paths);
|
|
151
|
+
}
|
|
152
|
+
summary.skills = { created: skillsCreated, updated: skillsUpdated, paths: skillPaths };
|
|
153
|
+
allInstalledFiles.push(...skillPaths);
|
|
154
|
+
}
|
|
155
|
+
const hooksSource = join(PACKAGE_ROOT, 'hooks');
|
|
156
|
+
if (existsSync(hooksSource)) {
|
|
157
|
+
const hooksDestination = join(CLAUDE_HOME, 'hooks');
|
|
158
|
+
const filesToCopy = collectFiles(hooksSource).filter(file => !file.endsWith('hooks.json'));
|
|
159
|
+
let hooksCreated = 0;
|
|
160
|
+
let hooksUpdated = 0;
|
|
161
|
+
for (const sourceFile of filesToCopy) {
|
|
162
|
+
const relativePath = relative(hooksSource, sourceFile);
|
|
163
|
+
const destFile = join(hooksDestination, relativePath);
|
|
164
|
+
mkdirSync(dirname(destFile), { recursive: true });
|
|
165
|
+
const existed = existsSync(destFile);
|
|
166
|
+
copyFileSync(sourceFile, destFile);
|
|
167
|
+
allInstalledFiles.push(destFile);
|
|
168
|
+
if (existed) { hooksUpdated++; } else { hooksCreated++; }
|
|
169
|
+
}
|
|
170
|
+
summary.hookFiles = { created: hooksCreated, updated: hooksUpdated };
|
|
171
|
+
console.log(` Hook files: ${hooksCreated} new, ${hooksUpdated} updated`);
|
|
172
|
+
const groupCount = mergeHooks(pythonCommand);
|
|
173
|
+
summary.hookGroups = groupCount;
|
|
174
|
+
console.log(` Hook groups: ${groupCount} merged into settings.json`);
|
|
175
|
+
}
|
|
176
|
+
writeManifest(allInstalledFiles);
|
|
177
|
+
console.log(`\nInstalled ${PACKAGE_NAME}:`);
|
|
178
|
+
for (const directory of CONTENT_DIRECTORIES) {
|
|
179
|
+
if (summary[directory]) {
|
|
180
|
+
const { created, updated } = summary[directory];
|
|
181
|
+
console.log(` ${directory}: ${created + updated} files (${created} new, ${updated} updated)`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (summary.skills) {
|
|
185
|
+
const { created, updated } = summary.skills;
|
|
186
|
+
console.log(` skills: ${created + updated} files (${created} new, ${updated} updated)`);
|
|
187
|
+
}
|
|
188
|
+
if (summary.hookFiles) {
|
|
189
|
+
console.log(` hooks: ${summary.hookFiles.created + summary.hookFiles.updated} files, ${summary.hookGroups} groups in settings.json`);
|
|
190
|
+
}
|
|
191
|
+
console.log(` python: ${pythonCommand}\n`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function uninstall() {
|
|
195
|
+
console.log(`\nUninstalling ${PACKAGE_NAME}...\n`);
|
|
196
|
+
if (!existsSync(MANIFEST_FILE)) {
|
|
197
|
+
console.error('No installation manifest found. Nothing to uninstall.');
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
const manifest = JSON.parse(readFileSync(MANIFEST_FILE, 'utf8'));
|
|
201
|
+
let removed = 0;
|
|
202
|
+
for (const filePath of manifest.files) {
|
|
203
|
+
if (existsSync(filePath)) {
|
|
204
|
+
unlinkSync(filePath);
|
|
205
|
+
console.log(` \u2717 ${relative(CLAUDE_HOME, filePath)} (removed)`);
|
|
206
|
+
removed++;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const settingsPath = join(CLAUDE_HOME, 'settings.json');
|
|
210
|
+
if (existsSync(settingsPath)) {
|
|
211
|
+
const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
|
|
212
|
+
if (settings.hooks) {
|
|
213
|
+
const installedHooksDir = join(CLAUDE_HOME, 'hooks').replace(/\\/g, '/');
|
|
214
|
+
for (const [eventType, matcherGroups] of Object.entries(settings.hooks)) {
|
|
215
|
+
settings.hooks[eventType] = matcherGroups
|
|
216
|
+
.map(group => ({
|
|
217
|
+
...group,
|
|
218
|
+
hooks: group.hooks.filter(hook => !hook.command.includes(installedHooksDir)),
|
|
219
|
+
}))
|
|
220
|
+
.filter(group => group.hooks.length > 0);
|
|
221
|
+
if (settings.hooks[eventType].length === 0) delete settings.hooks[eventType];
|
|
222
|
+
}
|
|
223
|
+
if (Object.keys(settings.hooks).length === 0) delete settings.hooks;
|
|
224
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 4) + '\n');
|
|
225
|
+
console.log(' Hook entries removed from settings.json');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
unlinkSync(MANIFEST_FILE);
|
|
229
|
+
for (const directory of [...CONTENT_DIRECTORIES, 'skills', 'hooks']) {
|
|
230
|
+
const dirPath = join(CLAUDE_HOME, directory);
|
|
231
|
+
try {
|
|
232
|
+
if (existsSync(dirPath) && readdirSync(dirPath).length === 0) {
|
|
233
|
+
rmSync(dirPath, { recursive: true });
|
|
234
|
+
}
|
|
235
|
+
} catch { /* leave non-empty dirs */ }
|
|
236
|
+
}
|
|
237
|
+
console.log(`\nRemoved ${removed} files.\n`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function printHelp() {
|
|
241
|
+
console.log(`
|
|
242
|
+
${PACKAGE_NAME} - Claude Code development standards installer
|
|
243
|
+
|
|
244
|
+
Usage:
|
|
245
|
+
npx ${PACKAGE_NAME} Install rules, hooks, agents, commands, skills
|
|
246
|
+
npx ${PACKAGE_NAME} --uninstall Remove installed files and hooks
|
|
247
|
+
npx ${PACKAGE_NAME} --help Show this help
|
|
248
|
+
|
|
249
|
+
Install location: ~/.claude/
|
|
250
|
+
`);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const args = process.argv.slice(2);
|
|
254
|
+
if (args.includes('--help') || args.includes('-h')) printHelp();
|
|
255
|
+
else if (args.includes('--uninstall')) uninstall();
|
|
256
|
+
else install();
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Commit and push changes to GitHub (use instead of git commit)
|
|
3
|
+
allowed-tools: Bash, Read, Glob, Grep
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Step 1: Analyze Changes
|
|
7
|
+
|
|
8
|
+
Run these in parallel:
|
|
9
|
+
- `git status` (never use -uall flag)
|
|
10
|
+
- `git diff` and `git diff --staged` to see all changes
|
|
11
|
+
- `git log --oneline -5` to match the repo's commit message style
|
|
12
|
+
|
|
13
|
+
If there are no changes to commit, tell the user and stop.
|
|
14
|
+
|
|
15
|
+
## Step 2: Commit
|
|
16
|
+
|
|
17
|
+
- Stage relevant files by name (not `git add -A` or `git add .`)
|
|
18
|
+
- Do NOT stage files that look like secrets (.env, credentials, etc.)
|
|
19
|
+
- Create a single commit with a conventional commit message (feat:, fix:, chore:, etc.)
|
|
20
|
+
- Focus the message on "why" not "what"
|
|
21
|
+
- End the commit message with: `Co-Authored-By: Claude <noreply@anthropic.com>`
|
|
22
|
+
- Use a HEREDOC for the commit message
|
|
23
|
+
|
|
24
|
+
## Step 3: Push to GitHub
|
|
25
|
+
|
|
26
|
+
- Run `git push` to push the commit to the remote
|
|
27
|
+
- If the branch has no upstream, use `git push -u origin <branch-name>`
|
|
28
|
+
- Report the result to the user (success or any errors)
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scan and update all documentation (.md files, skills, agents) for the current project
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
You are being invoked as the **docupdate** command to comprehensively audit and update documentation for the current project.
|
|
6
|
+
|
|
7
|
+
## Core Philosophy
|
|
8
|
+
|
|
9
|
+
**Documentation must match implementation.** After completing work, documentation often becomes stale. This command:
|
|
10
|
+
1. Uses an **Explore agent** to FIND all documentation that might need updates
|
|
11
|
+
2. You (the orchestrator) analyze the findings and decide what actually needs updating
|
|
12
|
+
3. Creates/updates project-specific skills when appropriate
|
|
13
|
+
4. NEVER modifies global skills/agents unless the change is truly universal
|
|
14
|
+
|
|
15
|
+
## MANDATORY: Two-Phase Architecture
|
|
16
|
+
|
|
17
|
+
### Phase 1: Discovery (Explore Agent)
|
|
18
|
+
|
|
19
|
+
**IMMEDIATELY** launch an Explore agent with this prompt:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
Task tool with subagent_type="Explore":
|
|
23
|
+
|
|
24
|
+
"Documentation Discovery for /docupdate command
|
|
25
|
+
|
|
26
|
+
Find ALL documentation files in this project. For EACH file found, report:
|
|
27
|
+
1. **Location**: Full file path
|
|
28
|
+
2. **Filename**: Just the filename
|
|
29
|
+
3. **Category**: One of [README, Skill, Agent, Command, API Doc, Guide, Changelog, Session State, Config Doc, Other]
|
|
30
|
+
4. **Summary**: 1-2 sentence description of what the doc covers
|
|
31
|
+
|
|
32
|
+
## Search Locations
|
|
33
|
+
|
|
34
|
+
**Project .claude/ directory:**
|
|
35
|
+
- .claude/skills/**/*.md
|
|
36
|
+
- .claude/agents/**/*.md
|
|
37
|
+
- .claude/commands/**/*.md
|
|
38
|
+
- .claude/SESSION_STATE.md
|
|
39
|
+
- .claude/*.md
|
|
40
|
+
|
|
41
|
+
**Project root and subdirectories:**
|
|
42
|
+
- README.md, CHANGELOG.md, CLAUDE.md
|
|
43
|
+
- docs/**/*.md
|
|
44
|
+
- **/*.md (any other markdown)
|
|
45
|
+
|
|
46
|
+
**Scripts/modules with their own docs:**
|
|
47
|
+
- scripts/**/README.md
|
|
48
|
+
- scripts/**/docs/*.md
|
|
49
|
+
|
|
50
|
+
## Also Identify
|
|
51
|
+
|
|
52
|
+
1. **Recent code changes** - What files were modified recently (git log/diff if available, or file timestamps)
|
|
53
|
+
2. **Key source files** - Main implementation files that docs should reference
|
|
54
|
+
3. **Potential gaps** - Areas with code but no documentation
|
|
55
|
+
|
|
56
|
+
## Output Format
|
|
57
|
+
|
|
58
|
+
Return a structured report:
|
|
59
|
+
|
|
60
|
+
### Documentation Inventory
|
|
61
|
+
|
|
62
|
+
| # | Location | Filename | Category | Summary |
|
|
63
|
+
|---|----------|----------|----------|---------|
|
|
64
|
+
| 1 | path/to/file.md | file.md | Category | Brief summary |
|
|
65
|
+
| 2 | ... | ... | ... | ... |
|
|
66
|
+
|
|
67
|
+
### Recent Changes (if git available)
|
|
68
|
+
- List of recently modified files that might affect docs
|
|
69
|
+
|
|
70
|
+
### Key Source Files
|
|
71
|
+
- Main implementation files the docs should reference
|
|
72
|
+
|
|
73
|
+
### Potential Documentation Gaps
|
|
74
|
+
- Code without corresponding documentation
|
|
75
|
+
|
|
76
|
+
Be thorough - check ALL subdirectories. Do not skip any .md files."
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Phase 2: Orchestration (You)
|
|
80
|
+
|
|
81
|
+
After the Explore agent returns its inventory, YOU:
|
|
82
|
+
|
|
83
|
+
1. **Triage** the inventory by priority (see below)
|
|
84
|
+
2. **Read each doc** that might be affected by recent changes
|
|
85
|
+
3. **Compare against source** - Does the doc match current implementation?
|
|
86
|
+
4. **Decide what to update** using the decision tree
|
|
87
|
+
5. **Make updates** to stale documentation
|
|
88
|
+
6. **Generate summary report**
|
|
89
|
+
|
|
90
|
+
## Decision Tree: Global vs Project-Specific
|
|
91
|
+
|
|
92
|
+
**CREATE PROJECT-SPECIFIC skill/doc when:**
|
|
93
|
+
- The work was specific to THIS project (e.g., scheduled-report for automation)
|
|
94
|
+
- The patterns only apply to this codebase
|
|
95
|
+
- The configuration/credentials are project-specific
|
|
96
|
+
- The workflow integrates with project-specific systems
|
|
97
|
+
|
|
98
|
+
**UPDATE GLOBAL skill/doc when:**
|
|
99
|
+
- The change is a universal best practice
|
|
100
|
+
- The pattern applies to ALL projects (e.g., git workflow, code standards)
|
|
101
|
+
- The fix corrects an error in the global documentation
|
|
102
|
+
|
|
103
|
+
**When in doubt, create project-specific.** It's easier to promote to global later than to untangle project-specific details from global docs.
|
|
104
|
+
|
|
105
|
+
## Phase 2 Detailed Workflow
|
|
106
|
+
|
|
107
|
+
### Step 1: Triage the Inventory
|
|
108
|
+
|
|
109
|
+
From the Explore agent's report, categorize docs:
|
|
110
|
+
|
|
111
|
+
| Priority | Category | Action |
|
|
112
|
+
|----------|----------|--------|
|
|
113
|
+
| HIGH | Skills, Agents, READMEs in changed areas | Read and compare to source |
|
|
114
|
+
| MEDIUM | General docs in project | Skim for staleness |
|
|
115
|
+
| LOW | Unchanged areas, global docs | Note but don't modify |
|
|
116
|
+
|
|
117
|
+
### Step 2: Read and Compare
|
|
118
|
+
|
|
119
|
+
For HIGH priority docs:
|
|
120
|
+
1. Read the documentation file
|
|
121
|
+
2. Read the source code it documents
|
|
122
|
+
3. Identify discrepancies:
|
|
123
|
+
- Outdated function names
|
|
124
|
+
- Missing new features
|
|
125
|
+
- Incorrect paths or configurations
|
|
126
|
+
- Stale examples
|
|
127
|
+
|
|
128
|
+
### Step 3: Update Stale Documentation
|
|
129
|
+
|
|
130
|
+
**Priority order:**
|
|
131
|
+
1. `.claude/skills/` - Project skills (most impactful)
|
|
132
|
+
2. `.claude/CLAUDE.md` - Project instructions
|
|
133
|
+
3. `scripts/*/README.md` - Module READMEs
|
|
134
|
+
4. `README.md` - Project overview
|
|
135
|
+
5. `.claude/agents/` - Project agents
|
|
136
|
+
6. `docs/*.md` - Other guides
|
|
137
|
+
|
|
138
|
+
**MANDATORY: Skills must match code.** For each project skill:
|
|
139
|
+
1. Identify the source files the skill documents
|
|
140
|
+
2. Read both skill AND source files
|
|
141
|
+
3. Update skill if source has changed (paths, functions, data sources, workflows)
|
|
142
|
+
|
|
143
|
+
### Step 4: Archive Obsolete Documentation
|
|
144
|
+
|
|
145
|
+
Identify and archive documentation that is:
|
|
146
|
+
- **Completed plans** - Implementation plans that have been fully executed
|
|
147
|
+
- **Superseded docs** - Old versions replaced by newer documentation
|
|
148
|
+
- **Stale analysis** - Analysis docs for decisions already made
|
|
149
|
+
|
|
150
|
+
**Archive strategy:**
|
|
151
|
+
```
|
|
152
|
+
docs/plans/2025-01-*.md -> docs/archive/2025-01-completed-plans/
|
|
153
|
+
docs/plans/2025-11-*.md -> docs/archive/2025-11-completed-plans/
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Archiving rules:**
|
|
157
|
+
1. Keep active/current plan (most recent, still in progress)
|
|
158
|
+
2. Move completed plans to `docs/archive/YYYY-MM-completed-plans/`
|
|
159
|
+
3. Move stray docs to appropriate folders (e.g., `docs/guides/`)
|
|
160
|
+
4. Create archive README if folder has 3+ files
|
|
161
|
+
|
|
162
|
+
**Do NOT archive:**
|
|
163
|
+
- Active SESSION_STATE.md
|
|
164
|
+
- Current README.md
|
|
165
|
+
- Skills/Agents (they evolve, not archive)
|
|
166
|
+
- Recent plans still being implemented
|
|
167
|
+
|
|
168
|
+
### Step 5: Create New Skills When Needed
|
|
169
|
+
|
|
170
|
+
If recent work introduced a significant workflow without documentation:
|
|
171
|
+
|
|
172
|
+
**Create skill in:** `.claude/skills/<skill-name>/SKILL.md`
|
|
173
|
+
|
|
174
|
+
```yaml
|
|
175
|
+
---
|
|
176
|
+
name: skill-name
|
|
177
|
+
description: What this does and when to use it. Use when [trigger phrases].
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
# Skill Name
|
|
181
|
+
|
|
182
|
+
Brief overview.
|
|
183
|
+
|
|
184
|
+
## When to Use This Skill
|
|
185
|
+
- Trigger condition 1
|
|
186
|
+
- Trigger condition 2
|
|
187
|
+
|
|
188
|
+
## Quick Start
|
|
189
|
+
Minimal example to get started.
|
|
190
|
+
|
|
191
|
+
## Instructions
|
|
192
|
+
1. Step one
|
|
193
|
+
2. Step two
|
|
194
|
+
|
|
195
|
+
## Configuration
|
|
196
|
+
Key settings and where they live.
|
|
197
|
+
|
|
198
|
+
## Troubleshooting
|
|
199
|
+
Common issues and fixes.
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Output Requirements
|
|
203
|
+
|
|
204
|
+
After completing both phases, provide:
|
|
205
|
+
|
|
206
|
+
### 1. Discovery Summary (from Explore agent)
|
|
207
|
+
```markdown
|
|
208
|
+
## Discovery Summary
|
|
209
|
+
|
|
210
|
+
**Files Found:** X documentation files
|
|
211
|
+
**Categories:** X Skills, X Agents, X READMEs, X Other
|
|
212
|
+
|
|
213
|
+
### Documentation Inventory
|
|
214
|
+
[Include the table from Explore agent]
|
|
215
|
+
|
|
216
|
+
### Recent Changes Detected
|
|
217
|
+
[List from Explore agent]
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### 2. Analysis Results (your decisions)
|
|
221
|
+
```markdown
|
|
222
|
+
## Analysis Results
|
|
223
|
+
|
|
224
|
+
### Needs Update (HIGH priority)
|
|
225
|
+
| File | Reason |
|
|
226
|
+
|------|--------|
|
|
227
|
+
| path/file.md | [specific reason] |
|
|
228
|
+
|
|
229
|
+
### Current (No changes needed)
|
|
230
|
+
- file.md - Still accurate
|
|
231
|
+
- file2.md - Matches implementation
|
|
232
|
+
|
|
233
|
+
### Out of Scope (Global/Unrelated)
|
|
234
|
+
- ~/.claude/skills/X - Not affected by project work
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 3. Changes Made
|
|
238
|
+
```markdown
|
|
239
|
+
## Documentation Update Summary
|
|
240
|
+
|
|
241
|
+
### Updated
|
|
242
|
+
- `path/to/file.md` - [what changed]
|
|
243
|
+
|
|
244
|
+
### Created
|
|
245
|
+
- `path/to/new.md` - [why created]
|
|
246
|
+
|
|
247
|
+
### Archived
|
|
248
|
+
- `docs/plans/2025-01-*.md` -> `docs/archive/2025-01-completed-plans/` - [completed implementation]
|
|
249
|
+
|
|
250
|
+
### Skipped
|
|
251
|
+
- `path/file.md` - [why skipped]
|
|
252
|
+
|
|
253
|
+
### Global Resources (NOT Modified)
|
|
254
|
+
- `~/.claude/skills/X` - [why not touched]
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### 4. Recommendations
|
|
258
|
+
```markdown
|
|
259
|
+
## Recommendations
|
|
260
|
+
|
|
261
|
+
### Manual Review Needed
|
|
262
|
+
- [docs that need human attention]
|
|
263
|
+
|
|
264
|
+
### Future Documentation
|
|
265
|
+
- [suggested new docs to create]
|
|
266
|
+
|
|
267
|
+
### Next /docupdate
|
|
268
|
+
- Run after [specific trigger]
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Skill-Source Mapping
|
|
272
|
+
|
|
273
|
+
For each skill, identify its source files. Common patterns:
|
|
274
|
+
|
|
275
|
+
| Skill Pattern | Source Files to Check |
|
|
276
|
+
|--------------|----------------------|
|
|
277
|
+
| periodic-reports | generator.py, batch_run*.py |
|
|
278
|
+
| *-automation | automation/*.py, scripts/*.py |
|
|
279
|
+
| *-workflow | Main orchestration scripts |
|
|
280
|
+
|
|
281
|
+
**When source changes, skill MUST be updated:**
|
|
282
|
+
- Data sources (CSV -> SQLite, API changes)
|
|
283
|
+
- File paths and locations
|
|
284
|
+
- Function signatures and workflows
|
|
285
|
+
- Configuration and credentials
|
|
286
|
+
- New features or removed functionality
|
|
287
|
+
|
|
288
|
+
## Important Guidelines
|
|
289
|
+
|
|
290
|
+
1. **Always launch Explore agent first** - Don't skip discovery phase
|
|
291
|
+
2. **Project-first mindset:** Default to project-specific documentation
|
|
292
|
+
3. **Don't over-update:** Only change what's actually stale
|
|
293
|
+
4. **Be specific:** Include actual file names, discrepancies found
|
|
294
|
+
5. **Preserve history:** Add to docs, don't delete useful content
|
|
295
|
+
6. **Test triggers:** Ensure skill descriptions will activate correctly
|
|
296
|
+
|
|
297
|
+
## Error Handling
|
|
298
|
+
|
|
299
|
+
- If no .claude directory exists, create it
|
|
300
|
+
- If no git repo, work with file modification dates
|
|
301
|
+
- If Explore agent finds no docs, report "No documentation found - consider creating README.md"
|
|
302
|
+
- If unsure about a change, flag for manual review instead of guessing
|
|
303
|
+
|
|
304
|
+
## Example Execution
|
|
305
|
+
|
|
306
|
+
```
|
|
307
|
+
User: /docupdate
|
|
308
|
+
|
|
309
|
+
Claude:
|
|
310
|
+
1. Launches Explore agent for documentation discovery
|
|
311
|
+
2. Receives inventory: 15 docs found, 3 skills, 1 agent, 2 READMEs
|
|
312
|
+
3. Identifies Code.gs was heavily modified recently
|
|
313
|
+
4. Triages: SKILL.md and README.md are HIGH priority
|
|
314
|
+
5. Reads SKILL.md, finds it references old function names
|
|
315
|
+
6. Updates SKILL.md with:
|
|
316
|
+
- New architecture section
|
|
317
|
+
- Updated function references
|
|
318
|
+
- New troubleshooting items
|
|
319
|
+
7. Reads README.md, finds it's current
|
|
320
|
+
8. Generates summary report
|
|
321
|
+
9. Notes global skills weren't affected
|
|
322
|
+
```
|