@devshop/crew 0.6.0 → 0.7.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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [0.7.0](https://github.com/devshop-software/crew/compare/v0.6.0...v0.7.0) (2026-04-30)
2
+
3
+
4
+ ### Features
5
+
6
+ * surface what crew update actually did ([51894c5](https://github.com/devshop-software/crew/commit/51894c5ed8a3f5f5fbb7746c0c77ab83ffd0d70d))
7
+
1
8
  # [0.6.0](https://github.com/devshop-software/crew/compare/v0.5.0...v0.6.0) (2026-04-30)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devshop/crew",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Project-agnostic Claude Code skills for spec → implement → qa → review → ship",
5
5
  "bin": {
6
6
  "crew": "scripts/cli.js"
@@ -31,6 +31,7 @@ module.exports = async function update(flags) {
31
31
  return 1;
32
32
  }
33
33
 
34
+ const manifestVersionBefore = manifest.package_version;
34
35
  const diff = diffSkills(PKG_SKILLS, skillsDir, manifest);
35
36
  let bakBase = null;
36
37
  let refused = false;
@@ -38,19 +39,30 @@ module.exports = async function update(flags) {
38
39
  const now = new Date().toISOString();
39
40
  const interactive = process.stdin.isTTY || process.env.CREW_FAKE_TTY === '1';
40
41
  const stamp = (name, hash) => { manifest.skills[name] = { version: PKG_VERSION, hash, installed_at: now }; };
42
+ const stats = { added: 0, updated: 0, keptEdited: 0, droppedFromPackage: 0, unchanged: 0 };
41
43
 
42
44
  for (const s of diff) {
45
+ // Skill in manifest+disk but no longer in the package — keep it but tell the user.
46
+ if (!s.inPkg && s.inDisk && s.mfHash) {
47
+ log.warn(`kept (no longer in package): ${s.name}`);
48
+ stats.droppedFromPackage++;
49
+ continue;
50
+ }
43
51
  if (!s.inPkg) continue;
44
52
  try {
45
53
  if (s.state === 'missing') {
46
54
  if (flags.dryRun) log.dryRun('copy', s.name);
47
55
  else { copyFolder(path.join(PKG_SKILLS, s.name), path.join(skillsDir, s.name)); log.action('copy', s.name); }
48
56
  stamp(s.name, s.pkgHash);
57
+ stats.added++;
49
58
  } else if (s.state === 'managed-unchanged') {
50
59
  if (s.diskHash !== s.pkgHash) {
51
60
  if (flags.dryRun) log.dryRun('replace', s.name);
52
61
  else { copyFolder(path.join(PKG_SKILLS, s.name), path.join(skillsDir, s.name)); log.action('replace', s.name); }
53
62
  stamp(s.name, s.pkgHash);
63
+ stats.updated++;
64
+ } else {
65
+ stats.unchanged++;
54
66
  }
55
67
  } else if (s.state === 'managed-edited') {
56
68
  let action;
@@ -66,6 +78,7 @@ module.exports = async function update(flags) {
66
78
  if (action === 'keep') {
67
79
  if (flags.dryRun) log.dryRun('keep', s.name);
68
80
  else log.action('keep', s.name);
81
+ stats.keptEdited++;
69
82
  continue;
70
83
  }
71
84
  if (action === 'backup') {
@@ -76,6 +89,7 @@ module.exports = async function update(flags) {
76
89
  if (flags.dryRun) log.dryRun('replace', s.name);
77
90
  else { copyFolder(path.join(PKG_SKILLS, s.name), path.join(skillsDir, s.name)); log.action('replace', s.name); }
78
91
  stamp(s.name, s.pkgHash);
92
+ stats.updated++;
79
93
  }
80
94
  // foreign: leave (don't touch)
81
95
  } catch (e) {
@@ -94,6 +108,24 @@ module.exports = async function update(flags) {
94
108
  catch (e) { log.error(`Failed writing manifest: ${e.message}`); return 3; }
95
109
  }
96
110
 
111
+ // Summary
112
+ log.plain('');
113
+ if (manifestVersionBefore && manifestVersionBefore !== PKG_VERSION) {
114
+ log.plain(`${PACKAGE_NAME}: ${manifestVersionBefore} → ${PKG_VERSION}`);
115
+ } else {
116
+ log.plain(`${PACKAGE_NAME}: ${PKG_VERSION}`);
117
+ }
118
+ const parts = [];
119
+ if (stats.added) parts.push(`${stats.added} added`);
120
+ if (stats.updated) parts.push(`${stats.updated} updated`);
121
+ if (stats.keptEdited) parts.push(`${stats.keptEdited} edited (kept)`);
122
+ if (stats.droppedFromPackage) parts.push(`${stats.droppedFromPackage} no longer in package`);
123
+ if (stats.unchanged) parts.push(`${stats.unchanged} unchanged`);
124
+ log.plain(parts.length ? parts.join(', ') + '.' : 'nothing to do.');
125
+ if (stats.droppedFromPackage) {
126
+ log.plain(`Run \`crew uninstall && crew init\` to drop skills the package no longer ships.`);
127
+ }
128
+
97
129
  if (ioError) return 3;
98
130
  if (refused) return 1;
99
131
  return 0;