claude-devkit-cli 1.0.0 → 1.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-devkit-cli",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "CLI toolkit for spec-first development with Claude Code — hooks, commands, guards, and test runners",
5
5
  "bin": {
6
6
  "claude-devkit": "./bin/devkit.js",
@@ -29,6 +29,7 @@
29
29
  ],
30
30
  "scripts": {
31
31
  "prepublishOnly": "rm -rf templates && cp -r ../kit templates",
32
+ "postpublish": "rm -rf templates",
32
33
  "dev": "node bin/devkit.js"
33
34
  },
34
35
  "license": "MIT",
@@ -90,10 +90,12 @@ export async function initCommand(path, opts) {
90
90
  const manifest = createManifest(pkg.version, null, components);
91
91
  let copied = 0;
92
92
  let skipped = 0;
93
+ let identical = 0;
93
94
 
94
95
  for (const file of files) {
95
96
  const result = await installFile(file, targetDir, { force: opts.force });
96
97
  if (result === 'copied') copied++;
98
+ else if (result === 'identical') identical++;
97
99
  else skipped++;
98
100
 
99
101
  // Record in manifest
@@ -162,11 +164,14 @@ export async function initCommand(path, opts) {
162
164
  console.log(' .claude/CLAUDE.md — Project rules (review and customize)');
163
165
  console.log(' .claude/settings.json — Hook configuration');
164
166
  console.log(' .claude/hooks/ — 6 guards (file, path, glob, comment, sensitive, self-review)');
165
- console.log(' .claude/commands/ — /plan, /test, /fix, /review, /commit, /challenge');
167
+ console.log(' .claude/commands/ — /plan, /challenge, /test, /fix, /review, /commit');
166
168
  console.log(' scripts/build-test.sh — Universal test runner');
167
169
  console.log(' docs/WORKFLOW.md — Workflow reference');
168
170
  log.blank();
169
- console.log(` ${copied} files copied, ${skipped} skipped`);
171
+ const parts = [`${copied} copied`];
172
+ if (identical > 0) parts.push(`${identical} identical`);
173
+ if (skipped > 0) parts.push(`${skipped} conflicted (use --force to overwrite)`);
174
+ console.log(` ${parts.join(', ')}`);
170
175
  log.blank();
171
176
  console.log('Next steps:');
172
177
  console.log(' 1. Review .claude/CLAUDE.md — ensure project info is correct');
@@ -21,11 +21,11 @@ export const COMPONENTS = {
21
21
  ],
22
22
  commands: [
23
23
  '.claude/commands/plan.md',
24
+ '.claude/commands/challenge.md',
24
25
  '.claude/commands/test.md',
25
26
  '.claude/commands/fix.md',
26
27
  '.claude/commands/review.md',
27
28
  '.claude/commands/commit.md',
28
- '.claude/commands/challenge.md',
29
29
  ],
30
30
  config: [
31
31
  '.claude/settings.json',
@@ -91,14 +91,24 @@ export function getAllFiles() {
91
91
 
92
92
  /**
93
93
  * Copy a single file from templates to target.
94
- * @returns {string} 'copied' | 'skipped'
94
+ * @returns {string} 'copied' | 'skipped' | 'identical'
95
95
  */
96
96
  export async function installFile(relativePath, targetDir, { force = false } = {}) {
97
97
  const src = join(getTemplateDir(), relativePath);
98
98
  const dst = join(targetDir, relativePath);
99
99
 
100
100
  if (existsSync(dst) && !force) {
101
- log.skip(`${relativePath} (exists, use --force to overwrite)`);
101
+ // Compare content to distinguish: identical, customized, or from another source
102
+ try {
103
+ const { hashFile } = await import('./hasher.js');
104
+ const srcHash = await hashFile(src);
105
+ const dstHash = await hashFile(dst);
106
+ if (srcHash === dstHash) {
107
+ log.same(`${relativePath} (identical)`);
108
+ return 'identical';
109
+ }
110
+ } catch { /* hash failed, treat as conflict */ }
111
+ log.warn(`${relativePath} (exists with different content — use --force to overwrite)`);
102
112
  return 'skipped';
103
113
  }
104
114
 
@@ -13,11 +13,10 @@ Every change follows this cycle: **SPEC → TEST PLAN → CODE + TESTS → BUILD
13
13
 
14
14
  | Trigger | Commands | Details |
15
15
  |---------|----------|---------|
16
- | New feature | `/plan` → code in chunks → `/test` each chunk | Start with spec or description |
17
- | Update feature | Update spec first → `/plan` (update plan) → code → `/test` | Spec changes before code changes |
16
+ | New feature | `/plan` → `/challenge` (optional) → code in chunks → `/test` each chunk | Start with spec or description |
17
+ | Update feature | Update spec first → `/plan` → code → `/test` | Spec changes before code changes |
18
18
  | Bug fix | `/fix "description"` | Test-first: write failing test → fix → green |
19
19
  | Remove feature | Mark spec as removed → delete code + tests → build pass | Run full suite after removal |
20
- | Stress-test plan | `/challenge` | Adversarial review before coding (optional) |
21
20
  | Pre-merge check | `/review` | Diff-based quality gate |
22
21
  | Commit changes | `/commit` | Secret scan + conventional commit |
23
22