motif-design 0.2.0 → 0.2.2

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/bin/install.js CHANGED
@@ -362,8 +362,9 @@ function writeManifest(mapping, copyResult, flags) {
362
362
 
363
363
  const cwd = process.cwd();
364
364
  const pkgDir = path.dirname(__dirname);
365
+ const pkgJson = JSON.parse(fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf8'));
365
366
  const manifest = {
366
- version: '0.1.0',
367
+ version: pkgJson.version,
367
368
  runtime: 'claude-code',
368
369
  installedAt: new Date().toISOString(),
369
370
  files: {},
@@ -700,6 +701,10 @@ if (flags.uninstall) {
700
701
  const runtime = detectRuntime(flags);
701
702
  const mapping = resolveMapping(runtime);
702
703
 
704
+ // Read current package version
705
+ const pkgDir = path.dirname(__dirname);
706
+ const currentVersion = JSON.parse(fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf8')).version;
707
+
703
708
  // Load existing manifest for upgrade tracking (re-install detection)
704
709
  const manifestPath = path.join(process.cwd(), '.motif-manifest.json');
705
710
  let existingManifest = null;
@@ -712,6 +717,22 @@ if (fs.existsSync(manifestPath)) {
712
717
  }
713
718
  }
714
719
 
720
+ // Detect install type: fresh install vs upgrade vs re-install
721
+ if (existingManifest) {
722
+ const prevVersion = existingManifest.version;
723
+ if (prevVersion !== currentVersion) {
724
+ console.log('');
725
+ console.log(styleText('cyan', `Upgrading Motif: ${prevVersion} → ${currentVersion}`));
726
+ console.log('Modified files will be backed up to .motif-backup/');
727
+ } else {
728
+ console.log('');
729
+ console.log(styleText('cyan', `Re-installing Motif v${currentVersion}`));
730
+ }
731
+ } else {
732
+ console.log('');
733
+ console.log(styleText('cyan', `Installing Motif v${currentVersion}`));
734
+ }
735
+
715
736
  const copyResult = copyFiles(mapping, existingManifest, flags);
716
737
  const injectResult = injectConfig(mapping, flags);
717
738
  injectHookSettings(mapping, flags);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "motif-design",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Domain-intelligent design system for AI coding assistants",
5
5
  "bin": {
6
6
  "motif": "bin/install.js"
@@ -17,8 +17,9 @@ description: Show all Motif commands
17
17
  | `/motif:evolve` | Update design system based on learnings |
18
18
  | `/motif:quick [desc]` | Ad-hoc task with design system consistency |
19
19
 
20
- ## Navigation
21
- | `/motif:progress` | Current status + next steps |
20
+ ## Navigation & Maintenance
21
+ | `/motif:progress` | Current status + next steps + version check |
22
+ | `/motif:update` | Check for and apply Motif updates |
22
23
  | `/motif:help` | This reference |
23
24
 
24
25
  ## Typical flow
@@ -1,6 +1,27 @@
1
1
  ---
2
2
  description: Show current Motif project status and next steps
3
+ allowed-tools: Read, Bash(node:*)
3
4
  ---
5
+
6
+ # /motif:progress — Project Status
7
+
8
+ ## Step 1: Version check
9
+
10
+ Run:
11
+ ```bash
12
+ node .claude/get-motif/scripts/check-version.js
13
+ ```
14
+
15
+ Parse the JSON output. If `updateAvailable` is true, display at the top:
16
+
17
+ ```
18
+ ⬆ Motif update available: [installed] → [latest]. Run /motif:update to upgrade.
19
+ ```
20
+
21
+ If the check fails or latest is unknown, just show the installed version silently.
22
+
23
+ ## Step 2: Project status
24
+
4
25
  Read `.planning/design/STATE.md` and display:
5
26
  1. Current phase
6
27
  2. Screen status table
@@ -9,3 +30,10 @@ Read `.planning/design/STATE.md` and display:
9
30
  5. Recommended next command
10
31
 
11
32
  If STATE.md doesn't exist: "No project initialized. Run /motif:init."
33
+
34
+ ## Step 3: Footer
35
+
36
+ Always show at the bottom:
37
+ ```
38
+ Motif v[installed] | /motif:help for commands
39
+ ```
@@ -0,0 +1,67 @@
1
+ ---
2
+ description: Check for and apply Motif updates
3
+ allowed-tools: Read, Bash(node:*), Bash(npx:*)
4
+ ---
5
+
6
+ # /motif:update — Update Motif
7
+
8
+ You are the Motif updater. Check for new versions and apply updates.
9
+
10
+ ## Step 1: Check current version
11
+
12
+ Run:
13
+ ```bash
14
+ node .claude/get-motif/scripts/check-version.js
15
+ ```
16
+
17
+ Parse the JSON output.
18
+
19
+ ## Step 2: Report status
20
+
21
+ **If `updateAvailable` is true:**
22
+
23
+ Display:
24
+ ```
25
+ Motif update available: [installed] → [latest]
26
+
27
+ Updating now...
28
+ ```
29
+
30
+ Then run:
31
+ ```bash
32
+ npx motif-design@latest
33
+ ```
34
+
35
+ After it completes, display:
36
+ ```
37
+ Motif updated to [latest]. Your modified files were backed up to .motif-backup/.
38
+ ```
39
+
40
+ **If `updateAvailable` is false and `latest` is not `"unknown"`:**
41
+
42
+ Display:
43
+ ```
44
+ Motif v[installed] is up to date.
45
+ ```
46
+
47
+ **If `latest` is `"unknown"` (network error):**
48
+
49
+ Display:
50
+ ```
51
+ Motif v[installed] installed. Could not check for updates (offline or npm registry unavailable).
52
+
53
+ To update manually: npx motif-design@latest
54
+ ```
55
+
56
+ ## Step 3: Show what changed (if updated)
57
+
58
+ After a successful update, read the new `.motif-manifest.json` and compare with the previous version. Show:
59
+ - New version number
60
+ - Number of files updated
61
+ - Reminder to review any files in `.motif-backup/` if the user had customizations
62
+
63
+ ## Rules
64
+
65
+ 1. **Never force-install.** Always run without `--force` so user modifications get backed up.
66
+ 2. **Be transparent.** Show what version is installed and what's available before acting.
67
+ 3. **Handle offline gracefully.** Users may not have network access.
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Checks if a newer version of motif-design is available on npm.
6
+ * Outputs JSON: { "installed": "0.2.0", "latest": "0.3.0", "updateAvailable": true }
7
+ * Exits 0 on success, 1 on error (prints error JSON).
8
+ */
9
+
10
+ const fs = require('node:fs');
11
+ const path = require('node:path');
12
+ const https = require('node:https');
13
+
14
+ function getInstalledVersion() {
15
+ const manifestPath = path.join(process.cwd(), '.motif-manifest.json');
16
+ if (!fs.existsSync(manifestPath)) return null;
17
+
18
+ try {
19
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
20
+ return manifest.version || null;
21
+ } catch {
22
+ return null;
23
+ }
24
+ }
25
+
26
+ function fetchLatestVersion() {
27
+ return new Promise((resolve, reject) => {
28
+ const req = https.get('https://registry.npmjs.org/motif-design/latest', {
29
+ headers: { 'Accept': 'application/json' },
30
+ timeout: 5000,
31
+ }, (res) => {
32
+ let data = '';
33
+ res.on('data', chunk => { data += chunk; });
34
+ res.on('end', () => {
35
+ try {
36
+ const pkg = JSON.parse(data);
37
+ resolve(pkg.version || null);
38
+ } catch {
39
+ reject(new Error('Failed to parse npm registry response'));
40
+ }
41
+ });
42
+ });
43
+
44
+ req.on('error', reject);
45
+ req.on('timeout', () => {
46
+ req.destroy();
47
+ reject(new Error('npm registry request timed out'));
48
+ });
49
+ });
50
+ }
51
+
52
+ function compareVersions(a, b) {
53
+ const pa = a.split('.').map(Number);
54
+ const pb = b.split('.').map(Number);
55
+ for (let i = 0; i < 3; i++) {
56
+ if ((pa[i] || 0) < (pb[i] || 0)) return -1;
57
+ if ((pa[i] || 0) > (pb[i] || 0)) return 1;
58
+ }
59
+ return 0;
60
+ }
61
+
62
+ async function main() {
63
+ const installed = getInstalledVersion();
64
+
65
+ if (!installed) {
66
+ console.log(JSON.stringify({ error: 'No Motif installation found' }));
67
+ process.exit(1);
68
+ }
69
+
70
+ try {
71
+ const latest = await fetchLatestVersion();
72
+ const updateAvailable = latest ? compareVersions(installed, latest) < 0 : false;
73
+
74
+ console.log(JSON.stringify({
75
+ installed,
76
+ latest: latest || 'unknown',
77
+ updateAvailable,
78
+ }));
79
+ } catch (err) {
80
+ // Network failure is non-fatal — report installed version
81
+ console.log(JSON.stringify({
82
+ installed,
83
+ latest: 'unknown',
84
+ updateAvailable: false,
85
+ warning: err.message,
86
+ }));
87
+ }
88
+ }
89
+
90
+ main();