clawdex-mobile 1.1.2 → 1.2.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.
Files changed (3) hide show
  1. package/README.md +4 -0
  2. package/bin/clawdex.js +148 -10
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -207,6 +207,10 @@ Published CLI equivalent:
207
207
  - `npm install -g clawdex-mobile@latest` — install/upgrade the published CLI
208
208
  - `clawdex init` — full interactive onboarding + auto-start
209
209
  - `clawdex stop` — stop running Expo + bridge for this project
210
+ - `clawdex upgrade` / `clawdex update` — upgrade global CLI package to latest
211
+ - `clawdex upgrade --version 1.1.2` — upgrade to a specific published version
212
+ - `clawdex upgrade --restart` — stop services, upgrade, then restart via `clawdex init`
213
+ - `clawdex version` — print installed CLI version
210
214
  - `clawdex init --no-start` — onboarding without launching bridge/expo
211
215
  - `clawdex init --platform ios` — auto-start with iOS target
212
216
 
package/bin/clawdex.js CHANGED
@@ -4,6 +4,7 @@
4
4
  const { spawnSync } = require("node:child_process");
5
5
  const fs = require("node:fs");
6
6
  const path = require("node:path");
7
+ const os = require("node:os");
7
8
 
8
9
  function printUsage() {
9
10
  console.log(`Usage: clawdex <command> [options]
@@ -17,30 +18,59 @@ Commands:
17
18
  stop
18
19
  Stop bridge + Expo services for this project.
19
20
 
21
+ upgrade [--version <latest|x.y.z>] [--restart]
22
+ update [--version <latest|x.y.z>] [--restart]
23
+ Upgrade clawdex-mobile globally.
24
+ --restart stops running services first, upgrades, then runs 'clawdex init'.
25
+
26
+ version
27
+ Print current CLI package version.
28
+
20
29
  help
21
30
  Show this help.
22
31
  `);
23
32
  }
24
33
 
25
- function runScript(scriptName, args = []) {
26
- const scriptPath = path.resolve(__dirname, "..", "scripts", scriptName);
27
- if (!fs.existsSync(scriptPath)) {
28
- console.error(`error: script not found at ${scriptPath}`);
29
- process.exit(1);
30
- }
31
-
32
- const child = spawnSync(scriptPath, args, {
34
+ function runCommand(command, args = [], options = {}) {
35
+ const child = spawnSync(command, args, {
33
36
  stdio: "inherit",
34
37
  env: process.env,
35
38
  cwd: process.cwd(),
39
+ ...options,
36
40
  });
37
41
 
38
42
  if (child.error) {
39
- console.error(`error: failed to run ${scriptName}: ${child.error.message}`);
43
+ return {
44
+ ok: false,
45
+ status: child.status ?? 1,
46
+ error: child.error,
47
+ };
48
+ }
49
+
50
+ return {
51
+ ok: (child.status ?? 1) === 0,
52
+ status: child.status ?? 1,
53
+ error: null,
54
+ };
55
+ }
56
+
57
+ function runScript(scriptName, args = [], { exitOnComplete = true } = {}) {
58
+ const scriptPath = path.resolve(__dirname, "..", "scripts", scriptName);
59
+ if (!fs.existsSync(scriptPath)) {
60
+ console.error(`error: script not found at ${scriptPath}`);
40
61
  process.exit(1);
41
62
  }
42
63
 
43
- process.exit(child.status ?? 1);
64
+ const result = runCommand(scriptPath, args);
65
+ if (!result.ok && result.error) {
66
+ console.error(`error: failed to run ${scriptName}: ${result.error.message}`);
67
+ }
68
+
69
+ if (exitOnComplete) {
70
+ process.exit(result.status);
71
+ }
72
+
73
+ return result;
44
74
  }
45
75
 
46
76
  function runInit(args) {
@@ -51,6 +81,106 @@ function runStop(args) {
51
81
  runScript("stop-services.sh", args);
52
82
  }
53
83
 
84
+ function getCliVersion() {
85
+ const packageJsonPath = path.resolve(__dirname, "..", "package.json");
86
+ try {
87
+ const parsed = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
88
+ return parsed.version || "unknown";
89
+ } catch {
90
+ return "unknown";
91
+ }
92
+ }
93
+
94
+ function parseUpgradeArgs(args) {
95
+ let targetVersion = "latest";
96
+ let restart = false;
97
+ let noStop = false;
98
+
99
+ for (let i = 0; i < args.length; i += 1) {
100
+ const value = args[i];
101
+ if (value === "--version") {
102
+ const candidate = args[i + 1];
103
+ if (!candidate || candidate.startsWith("-")) {
104
+ throw new Error("--version requires a value (for example: latest, 1.1.2)");
105
+ }
106
+ targetVersion = candidate;
107
+ i += 1;
108
+ continue;
109
+ }
110
+
111
+ if (value === "--restart") {
112
+ restart = true;
113
+ continue;
114
+ }
115
+
116
+ if (value === "--no-stop") {
117
+ noStop = true;
118
+ continue;
119
+ }
120
+
121
+ if (value === "--help" || value === "-h") {
122
+ printUsage();
123
+ process.exit(0);
124
+ }
125
+
126
+ throw new Error(`unknown option '${value}'`);
127
+ }
128
+
129
+ return { targetVersion, restart, noStop };
130
+ }
131
+
132
+ function runUpgrade(args) {
133
+ let options;
134
+ try {
135
+ options = parseUpgradeArgs(args);
136
+ } catch (error) {
137
+ console.error(`error: ${error.message}`);
138
+ process.exit(1);
139
+ }
140
+
141
+ const previousVersion = getCliVersion();
142
+ const packageSpecifier =
143
+ options.targetVersion === "latest"
144
+ ? "clawdex-mobile@latest"
145
+ : `clawdex-mobile@${options.targetVersion}`;
146
+
147
+ console.log(`Current clawdex-mobile version: ${previousVersion}`);
148
+ if (!options.noStop) {
149
+ console.log("Stopping running bridge/Expo services before upgrade...");
150
+ const stopResult = runScript("stop-services.sh", [], { exitOnComplete: false });
151
+ if (!stopResult.ok) {
152
+ console.error("error: failed to stop services before upgrade.");
153
+ process.exit(stopResult.status);
154
+ }
155
+ }
156
+
157
+ console.log(`Upgrading via npm: ${packageSpecifier}`);
158
+ const installResult = runCommand("npm", ["install", "-g", packageSpecifier]);
159
+ if (!installResult.ok) {
160
+ const platformHint =
161
+ os.platform() === "win32"
162
+ ? "Run terminal as Administrator and retry."
163
+ : "If this is a permissions error, retry with sudo or fix npm global prefix.";
164
+ console.error(`error: upgrade failed. ${platformHint}`);
165
+ process.exit(installResult.status);
166
+ }
167
+
168
+ console.log("Upgrade completed.");
169
+ if (options.restart) {
170
+ console.log("Restarting with updated setup: clawdex init");
171
+ const restartResult = runCommand("clawdex", ["init"]);
172
+ process.exit(restartResult.status);
173
+ }
174
+
175
+ console.log("Run 'clawdex init' to start services with the updated version.");
176
+ process.exit(0);
177
+ }
178
+
179
+ function runVersion() {
180
+ console.log(getCliVersion());
181
+ process.exit(0);
182
+ }
183
+
54
184
  const argv = process.argv.slice(2);
55
185
  const command = argv[0];
56
186
 
@@ -67,6 +197,14 @@ if (command === "stop") {
67
197
  runStop(argv.slice(1));
68
198
  }
69
199
 
200
+ if (command === "upgrade" || command === "update") {
201
+ runUpgrade(argv.slice(1));
202
+ }
203
+
204
+ if (command === "version" || command === "--version" || command === "-v") {
205
+ runVersion();
206
+ }
207
+
70
208
  console.error(`error: unknown command '${command}'`);
71
209
  printUsage();
72
210
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawdex-mobile",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },