worclaude 1.2.4 → 1.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worclaude",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "CLI tool that scaffolds a comprehensive Claude Code workflow into any project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +1,8 @@
1
1
  import path from 'node:path';
2
- import { readWorkflowMeta, workflowMetaExists } from '../core/config.js';
2
+ import { readWorkflowMeta, workflowMetaExists, getPackageVersion } from '../core/config.js';
3
3
  import { hashFile } from '../utils/hash.js';
4
4
  import { fileExists, readFile, listFilesRecursive } from '../utils/file.js';
5
+ import { getLatestNpmVersion } from '../utils/npm.js';
5
6
  import { TECH_STACKS } from '../data/agents.js';
6
7
  import * as display from '../utils/display.js';
7
8
 
@@ -28,9 +29,17 @@ export async function statusCommand() {
28
29
  display.sectionHeader('WORCLAUDE STATUS');
29
30
 
30
31
  // Version
31
- display.barLine(
32
- `${'Version'.padEnd(11)}${display.green(`v${meta.version}`)} ${display.dimColor('(up to date)')}`
33
- );
32
+ const cliVersion = await getPackageVersion();
33
+ const latestVersion = getLatestNpmVersion();
34
+
35
+ let versionSuffix = '';
36
+ if (latestVersion && latestVersion !== cliVersion) {
37
+ versionSuffix = ` ${display.yellow(`(update available: v${latestVersion})`)}`;
38
+ } else if (latestVersion) {
39
+ versionSuffix = ` ${display.dimColor('(up to date)')}`;
40
+ }
41
+
42
+ display.barLine(`${'Version'.padEnd(11)}${display.green(`v${meta.version}`)}${versionSuffix}`);
34
43
 
35
44
  // Project info
36
45
  const projectTypes = meta.projectTypes || [];
@@ -1,4 +1,5 @@
1
1
  import path from 'node:path';
2
+ import { execSync } from 'node:child_process';
2
3
  import inquirer from 'inquirer';
3
4
  import ora from 'ora';
4
5
  import {
@@ -13,12 +14,57 @@ import { buildSettingsJson, mergeSettingsPermissionsAndHooks } from '../core/mer
13
14
  import { readTemplate } from '../core/scaffolder.js';
14
15
  import { hashFile } from '../utils/hash.js';
15
16
  import { writeFile, fileExists, listFilesRecursive } from '../utils/file.js';
17
+ import { getLatestNpmVersion } from '../utils/npm.js';
16
18
  import * as display from '../utils/display.js';
17
19
 
20
+ function selfUpdate(latestVersion) {
21
+ const spinner = ora(`Updating worclaude to v${latestVersion}...`).start();
22
+ try {
23
+ execSync('npm install -g worclaude@latest', { encoding: 'utf-8', stdio: 'pipe' });
24
+ spinner.succeed(`worclaude updated to v${latestVersion}.`);
25
+ return true;
26
+ } catch (err) {
27
+ spinner.fail('Self-update failed.');
28
+ display.error(err.message);
29
+ display.info('Try manually: npm install -g worclaude@latest');
30
+ return false;
31
+ }
32
+ }
33
+
18
34
  export async function upgradeCommand() {
19
35
  const projectRoot = process.cwd();
20
36
 
21
- // 1. Check prerequisite
37
+ // 1. Check for CLI self-update from npm
38
+ const cliVersion = await getPackageVersion();
39
+ const latestVersion = await getLatestNpmVersion();
40
+
41
+ if (latestVersion && latestVersion !== cliVersion) {
42
+ display.newline();
43
+ display.info(
44
+ `New worclaude version available: ${display.dimColor(`v${cliVersion}`)} → ${display.green(`v${latestVersion}`)}`
45
+ );
46
+ const { doUpdate } = await inquirer.prompt([
47
+ {
48
+ type: 'list',
49
+ name: 'doUpdate',
50
+ message: 'Update worclaude CLI?',
51
+ choices: [
52
+ { name: 'Yes, update and continue', value: true },
53
+ { name: 'No, continue with current version', value: false },
54
+ ],
55
+ },
56
+ ]);
57
+
58
+ if (doUpdate) {
59
+ const updated = await selfUpdate(latestVersion);
60
+ if (updated) {
61
+ display.info('Re-run `worclaude upgrade` to apply the new workflow files.');
62
+ return;
63
+ }
64
+ }
65
+ }
66
+
67
+ // 2. Check prerequisite
22
68
  if (!(await workflowMetaExists(projectRoot))) {
23
69
  display.error('No workflow installation found.');
24
70
  display.info('Run `worclaude init` to set up the workflow first.');
@@ -32,7 +78,7 @@ export async function upgradeCommand() {
32
78
  return;
33
79
  }
34
80
 
35
- // 2. Version comparison
81
+ // 3. Version comparison
36
82
  const currentVersion = await getPackageVersion();
37
83
  const installedVersion = meta.version;
38
84
 
@@ -41,10 +87,10 @@ export async function upgradeCommand() {
41
87
  return;
42
88
  }
43
89
 
44
- // 3. Categorize files
90
+ // 4. Categorize files
45
91
  const categories = await categorizeFiles(projectRoot, meta);
46
92
 
47
- // 4. Preview
93
+ // 5. Preview
48
94
  display.sectionHeader(`WORCLAUDE UPGRADE (v${installedVersion} → v${currentVersion})`);
49
95
  display.newline();
50
96
 
@@ -105,7 +151,7 @@ export async function upgradeCommand() {
105
151
  display.newline();
106
152
  }
107
153
 
108
- // 5. Confirm
154
+ // 6. Confirm
109
155
  const { proceed } = await inquirer.prompt([
110
156
  {
111
157
  type: 'list',
@@ -123,7 +169,7 @@ export async function upgradeCommand() {
123
169
  return;
124
170
  }
125
171
 
126
- // 6. Execute
172
+ // 7. Execute
127
173
  const spinner = ora('Upgrading...').start();
128
174
 
129
175
  try {
@@ -180,7 +226,7 @@ export async function upgradeCommand() {
180
226
 
181
227
  spinner.succeed(`Upgrade complete! (${installedVersion} → ${currentVersion})`);
182
228
 
183
- // 7. Display report
229
+ // 8. Display report
184
230
  display.newline();
185
231
  if (categories.autoUpdate.length > 0) {
186
232
  display.barLine(`Updated: ${categories.autoUpdate.length} files`);
@@ -1,11 +1,16 @@
1
1
  import path from 'node:path';
2
+ import { readFileSync } from 'node:fs';
2
3
  import { fileURLToPath } from 'node:url';
3
4
  import { readFile, writeFile, fileExists } from '../utils/file.js';
4
5
 
5
6
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const pkgPath = path.resolve(__dirname, '..', '..', 'package.json');
8
+
9
+ export function getPackageVersionSync() {
10
+ return JSON.parse(readFileSync(pkgPath, 'utf-8')).version;
11
+ }
6
12
 
7
13
  export async function getPackageVersion() {
8
- const pkgPath = path.resolve(__dirname, '..', '..', 'package.json');
9
14
  const content = await readFile(pkgPath);
10
15
  return JSON.parse(content).version;
11
16
  }
package/src/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { Command } from 'commander';
4
+ import { getPackageVersionSync } from './core/config.js';
4
5
  import { initCommand } from './commands/init.js';
5
6
  import { upgradeCommand } from './commands/upgrade.js';
6
7
  import { statusCommand } from './commands/status.js';
@@ -12,7 +13,7 @@ const program = new Command();
12
13
 
13
14
  program
14
15
  .name('worclaude')
15
- .version('1.0.0')
16
+ .version(getPackageVersionSync())
16
17
  .description('Scaffold a comprehensive Claude Code workflow into any project');
17
18
 
18
19
  program.showSuggestionAfterError(true);
@@ -0,0 +1,16 @@
1
+ import { execSync } from 'node:child_process';
2
+
3
+ /**
4
+ * Fetch the latest published version of worclaude from the npm registry.
5
+ * Returns null if offline or if the command fails.
6
+ */
7
+ export function getLatestNpmVersion() {
8
+ try {
9
+ return execSync('npm view worclaude version', {
10
+ encoding: 'utf-8',
11
+ timeout: 5000,
12
+ }).trim();
13
+ } catch {
14
+ return null;
15
+ }
16
+ }