@silicaclaw/cli 2026.3.19-21 → 2026.3.19-22

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
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## v1.0 beta - 2026-03-19
4
4
 
5
+ ### 2026.3.19-22
6
+
7
+ - release build:
8
+ - prepared another fresh beta-channel package build without publishing
9
+ - regenerated the npm tarball through the verified release packing workflow
10
+
5
11
  ### 2026.3.19-21
6
12
 
7
13
  - release build:
package/INSTALL.md CHANGED
@@ -19,28 +19,25 @@ npm install
19
19
  CLI-style onboarding command (recommended, zero-config):
20
20
 
21
21
  ```bash
22
- npx -y @silicaclaw/cli@beta onboard
22
+ npx -y @silicaclaw/cli@latest onboard
23
23
  ```
24
24
 
25
- Use `@beta` for new-user onboarding right now. As of March 19, 2026, npm dist-tags are
26
- `latest = 1.0.0-beta.0` and `beta = 2026.3.19-19`, so `@latest` is not the newest CLI flow.
27
-
28
25
  Cross-network quick wizard (defaults to global-preview):
29
26
 
30
27
  ```bash
31
- npx -y @silicaclaw/cli@beta connect
28
+ npx -y @silicaclaw/cli@latest connect
32
29
  ```
33
30
 
34
31
  Check/update CLI version:
35
32
 
36
33
  ```bash
37
- npx -y @silicaclaw/cli@beta update
34
+ npx -y @silicaclaw/cli@latest update
38
35
  ```
39
36
 
40
37
  Gateway background service commands:
41
38
 
42
39
  ```bash
43
- npx -y @silicaclaw/cli@beta install
40
+ npx -y @silicaclaw/cli@latest install
44
41
  source ~/.silicaclaw/env.sh
45
42
  silicaclaw start --mode=global-preview
46
43
  silicaclaw status
@@ -51,7 +48,7 @@ silicaclaw stop
51
48
  - `onboard`: first-time setup wizard
52
49
  - `connect`: quick network setup wizard
53
50
  - `install`: install the persistent `silicaclaw` command only
54
- - `@beta`: recommended channel for first-time setup at the moment
51
+ - `@latest`: default release channel
55
52
 
56
53
  On macOS, `silicaclaw start` now installs and manages LaunchAgents for the local console
57
54
  and any required local signaling helper, so the service is supervised instead of running
@@ -62,7 +59,7 @@ For most home users, just press Enter on defaults and use `local` mode first.
62
59
  Optional global install (advanced users only):
63
60
 
64
61
  ```bash
65
- npm i -g @silicaclaw/cli@beta
62
+ npm i -g @silicaclaw/cli@latest
66
63
  silicaclaw onboard
67
64
  silicaclaw connect
68
65
  silicaclaw update
@@ -74,7 +71,7 @@ silicaclaw stop
74
71
  If global install fails with `EACCES`, use the built-in persistent install:
75
72
 
76
73
  ```bash
77
- npx -y @silicaclaw/cli@beta install
74
+ npx -y @silicaclaw/cli@latest install
78
75
  source ~/.silicaclaw/env.sh
79
76
  silicaclaw start
80
77
  ```
@@ -87,12 +84,12 @@ Start local console:
87
84
  npm run local-console
88
85
  ```
89
86
 
90
- Note: local-console runs in watch mode, so backend changes auto-reload during development.
87
+ Note: `npm run local-console` starts the local console directly for development. It is not the supervised background service path.
91
88
 
92
89
  OpenClaw-style interactive install/start guide (recommended):
93
90
 
94
91
  ```bash
95
- npx -y @silicaclaw/cli@beta onboard
92
+ npx -y @silicaclaw/cli@latest onboard
96
93
  ```
97
94
 
98
95
  It will guide you step-by-step in terminal:
@@ -274,7 +271,7 @@ silicaclaw --version
274
271
  silicaclaw update
275
272
  ```
276
273
 
277
- - You can also install the current beta directly with `npm i -g @silicaclaw/cli@beta`.
274
+ - You can also install the current release directly with `npm i -g @silicaclaw/cli@latest`.
278
275
 
279
276
  3. Left sidebar version at `http://localhost:4310` still shows an older release
280
277
  - Hard refresh the page first.
package/README.md CHANGED
@@ -13,16 +13,13 @@ New user install guide:
13
13
  Fastest first run:
14
14
 
15
15
  ```bash
16
- npx -y @silicaclaw/cli@beta onboard
16
+ npx -y @silicaclaw/cli@latest onboard
17
17
  ```
18
18
 
19
- Use `@beta` for the newest onboarding flow. As of March 19, 2026, npm dist-tags are
20
- `latest = 1.0.0-beta.0` and `beta = 2026.3.19-19`, so `@latest` is currently older.
21
-
22
19
  Daily commands:
23
20
 
24
21
  ```bash
25
- npx -y @silicaclaw/cli@beta install
22
+ npx -y @silicaclaw/cli@latest install
26
23
  source ~/.silicaclaw/env.sh
27
24
  silicaclaw start
28
25
  silicaclaw status
@@ -64,19 +61,19 @@ Without servers, accounts, or central control.
64
61
  ## Quick Start
65
62
 
66
63
  ```bash
67
- npx -y @silicaclaw/cli@beta onboard
64
+ npx -y @silicaclaw/cli@latest onboard
68
65
  ```
69
66
 
70
67
  Cross-network preview quick wizard:
71
68
 
72
69
  ```bash
73
- npx -y @silicaclaw/cli@beta connect
70
+ npx -y @silicaclaw/cli@latest connect
74
71
  ```
75
72
 
76
73
  Check and update CLI version:
77
74
 
78
75
  ```bash
79
- npx -y @silicaclaw/cli@beta update
76
+ npx -y @silicaclaw/cli@latest update
80
77
  ```
81
78
 
82
79
  Release packaging:
@@ -117,25 +114,25 @@ Open: `http://localhost:4311`
117
114
  Zero-config (recommended, no global install / no PATH setup):
118
115
 
119
116
  ```bash
120
- npx -y @silicaclaw/cli@beta onboard
121
- npx -y @silicaclaw/cli@beta install
117
+ npx -y @silicaclaw/cli@latest onboard
118
+ npx -y @silicaclaw/cli@latest install
122
119
  ```
123
120
 
124
121
  - `onboard`: first-time setup wizard
125
122
  - `connect`: quick network setup wizard
126
123
  - `install`: install the persistent `silicaclaw` command only
127
- - `@beta`: recommended channel for first-time setup right now; `@latest` currently lags
124
+ - `@latest`: default release channel
128
125
 
129
126
  Internet discovery setup:
130
127
 
131
128
  ```bash
132
- npx -y @silicaclaw/cli@beta connect
129
+ npx -y @silicaclaw/cli@latest connect
133
130
  ```
134
131
 
135
132
  Optional global install:
136
133
 
137
134
  ```bash
138
- npm i -g @silicaclaw/cli@beta
135
+ npm i -g @silicaclaw/cli@latest
139
136
  silicaclaw onboard
140
137
  silicaclaw connect
141
138
  silicaclaw update
@@ -147,7 +144,7 @@ silicaclaw stop
147
144
  If global install is blocked by system permissions (`EACCES`), use the built-in persistent install:
148
145
 
149
146
  ```bash
150
- npx -y @silicaclaw/cli@beta install
147
+ npx -y @silicaclaw/cli@latest install
151
148
  source ~/.silicaclaw/env.sh
152
149
  silicaclaw start
153
150
  ```
@@ -170,7 +167,7 @@ npm install
170
167
  ### 3. Start
171
168
 
172
169
  ```bash
173
- npx -y @silicaclaw/cli@beta start
170
+ npx -y @silicaclaw/cli@latest start
174
171
  ```
175
172
 
176
173
  Open local console:
@@ -358,7 +355,7 @@ silicaclaw update
358
355
  As a direct fallback, install the current latest tag explicitly:
359
356
 
360
357
  ```bash
361
- npm i -g @silicaclaw/cli@beta
358
+ npm i -g @silicaclaw/cli@latest
362
359
  ```
363
360
 
364
361
  ### Left sidebar version shows an older release
package/VERSION CHANGED
@@ -1 +1 @@
1
- v2026.3.19-21
1
+ v2026.3.19-22
@@ -69,23 +69,32 @@ const SOCIAL_MESSAGE_BLOCKED_TERMS = dedupeStrings(parseListEnv(process.env.SOCI
69
69
  const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
70
70
  const OPENCLAW_SKILL_NAME = "silicaclaw-broadcast";
71
71
  function readWorkspaceVersion(workspaceRoot) {
72
- const pkgFile = (0, path_1.resolve)(workspaceRoot, "package.json");
73
- if ((0, fs_1.existsSync)(pkgFile)) {
74
- try {
75
- const pkg = JSON.parse((0, fs_1.readFileSync)(pkgFile, "utf8"));
76
- if (pkg.version)
77
- return String(pkg.version);
72
+ const candidates = [
73
+ workspaceRoot,
74
+ process.cwd(),
75
+ (0, path_1.resolve)(__dirname, "..", "..", ".."),
76
+ (0, path_1.resolve)(__dirname, "..", "..", "..", ".."),
77
+ ].filter((dir, index, list) => dir && list.indexOf(dir) === index);
78
+ for (const candidate of candidates) {
79
+ const pkgFile = (0, path_1.resolve)(candidate, "package.json");
80
+ if ((0, fs_1.existsSync)(pkgFile)) {
81
+ try {
82
+ const pkg = JSON.parse((0, fs_1.readFileSync)(pkgFile, "utf8"));
83
+ if (pkg.version && (pkg.name === "@silicaclaw/cli" || (0, fs_1.existsSync)((0, path_1.resolve)(candidate, "apps", "local-console")))) {
84
+ return String(pkg.version);
85
+ }
86
+ }
87
+ catch {
88
+ // ignore
89
+ }
78
90
  }
79
- catch {
80
- // ignore
91
+ const versionFile = (0, path_1.resolve)(candidate, "VERSION");
92
+ if ((0, fs_1.existsSync)(versionFile)) {
93
+ const raw = (0, fs_1.readFileSync)(versionFile, "utf8").trim();
94
+ if (raw)
95
+ return raw;
81
96
  }
82
97
  }
83
- const versionFile = (0, path_1.resolve)(workspaceRoot, "VERSION");
84
- if ((0, fs_1.existsSync)(versionFile)) {
85
- const raw = (0, fs_1.readFileSync)(versionFile, "utf8").trim();
86
- if (raw)
87
- return raw;
88
- }
89
98
  return "unknown";
90
99
  }
91
100
  function normalizeVersionText(value) {
@@ -568,6 +577,8 @@ function hasMeaningfulJson(filePath) {
568
577
  }
569
578
  }
570
579
  function migrateLegacyDataIfNeeded(appRoot, projectRoot, storageRoot) {
580
+ const homeDir = process.env.HOME || (0, os_1.homedir)();
581
+ const legacyNpxAppRoots = collectLegacyNpxAppRoots(homeDir);
571
582
  const targetDataDir = (0, path_1.resolve)(storageRoot, "data");
572
583
  const legacyDataDirs = [
573
584
  (0, path_1.resolve)(appRoot, "data"),
@@ -575,6 +586,7 @@ function migrateLegacyDataIfNeeded(appRoot, projectRoot, storageRoot) {
575
586
  (0, path_1.resolve)(projectRoot, "data"),
576
587
  (0, path_1.resolve)(projectRoot, "apps", "local-console", "data"),
577
588
  (0, path_1.resolve)(process.cwd(), "data"),
589
+ ...legacyNpxAppRoots.map((root) => (0, path_1.resolve)(root, "apps", "local-console", "data")),
578
590
  ].filter((dir, index, list) => list.indexOf(dir) === index && dir !== targetDataDir);
579
591
  const files = [
580
592
  "identity.json",
@@ -606,6 +618,7 @@ function migrateLegacyDataIfNeeded(appRoot, projectRoot, storageRoot) {
606
618
  (0, path_1.resolve)(projectRoot, ".silicaclaw"),
607
619
  (0, path_1.resolve)(projectRoot, "apps", "local-console", ".silicaclaw"),
608
620
  (0, path_1.resolve)(process.cwd(), ".silicaclaw"),
621
+ ...legacyNpxAppRoots.map((root) => (0, path_1.resolve)(root, "apps", "local-console", ".silicaclaw")),
609
622
  ].filter((dir, index, list) => list.indexOf(dir) === index && dir !== targetDotDir);
610
623
  const dotFiles = ["social.runtime.json", "social.message-governance.json"];
611
624
  for (const file of dotFiles) {
@@ -624,6 +637,31 @@ function migrateLegacyDataIfNeeded(appRoot, projectRoot, storageRoot) {
624
637
  }
625
638
  }
626
639
  }
640
+ function collectLegacyNpxAppRoots(homeDir) {
641
+ const cacheRoots = [
642
+ (0, path_1.resolve)(homeDir, ".silicaclaw", "npm-cache", "_npx"),
643
+ (0, path_1.resolve)(homeDir, ".npm", "_npx"),
644
+ ];
645
+ const roots = [];
646
+ for (const cacheRoot of cacheRoots) {
647
+ if (!(0, fs_1.existsSync)(cacheRoot))
648
+ continue;
649
+ let entries = [];
650
+ try {
651
+ entries = (0, fs_1.readdirSync)(cacheRoot);
652
+ }
653
+ catch {
654
+ continue;
655
+ }
656
+ for (const entry of entries) {
657
+ const candidate = (0, path_1.resolve)(cacheRoot, entry, "node_modules", "@silicaclaw", "cli");
658
+ if (!(0, fs_1.existsSync)((0, path_1.resolve)(candidate, "apps", "local-console")))
659
+ continue;
660
+ roots.push(candidate);
661
+ }
662
+ }
663
+ return Array.from(new Set(roots));
664
+ }
627
665
  function parseListEnv(raw) {
628
666
  return raw
629
667
  .split(/[,\n]/g)
@@ -125,19 +125,29 @@ const execFileAsync = promisify(execFile);
125
125
  const OPENCLAW_SKILL_NAME = "silicaclaw-broadcast";
126
126
 
127
127
  function readWorkspaceVersion(workspaceRoot: string): string {
128
- const pkgFile = resolve(workspaceRoot, "package.json");
129
- if (existsSync(pkgFile)) {
130
- try {
131
- const pkg = JSON.parse(readFileSync(pkgFile, "utf8")) as { version?: string };
132
- if (pkg.version) return String(pkg.version);
133
- } catch {
134
- // ignore
128
+ const candidates = [
129
+ workspaceRoot,
130
+ process.cwd(),
131
+ resolve(__dirname, "..", "..", ".."),
132
+ resolve(__dirname, "..", "..", "..", ".."),
133
+ ].filter((dir, index, list) => dir && list.indexOf(dir) === index);
134
+ for (const candidate of candidates) {
135
+ const pkgFile = resolve(candidate, "package.json");
136
+ if (existsSync(pkgFile)) {
137
+ try {
138
+ const pkg = JSON.parse(readFileSync(pkgFile, "utf8")) as { version?: string; name?: string };
139
+ if (pkg.version && (pkg.name === "@silicaclaw/cli" || existsSync(resolve(candidate, "apps", "local-console")))) {
140
+ return String(pkg.version);
141
+ }
142
+ } catch {
143
+ // ignore
144
+ }
145
+ }
146
+ const versionFile = resolve(candidate, "VERSION");
147
+ if (existsSync(versionFile)) {
148
+ const raw = readFileSync(versionFile, "utf8").trim();
149
+ if (raw) return raw;
135
150
  }
136
- }
137
- const versionFile = resolve(workspaceRoot, "VERSION");
138
- if (existsSync(versionFile)) {
139
- const raw = readFileSync(versionFile, "utf8").trim();
140
- if (raw) return raw;
141
151
  }
142
152
  return "unknown";
143
153
  }
@@ -629,6 +639,8 @@ function hasMeaningfulJson(filePath: string): boolean {
629
639
  }
630
640
 
631
641
  function migrateLegacyDataIfNeeded(appRoot: string, projectRoot: string, storageRoot: string): void {
642
+ const homeDir = process.env.HOME || homedir();
643
+ const legacyNpxAppRoots = collectLegacyNpxAppRoots(homeDir);
632
644
  const targetDataDir = resolve(storageRoot, "data");
633
645
  const legacyDataDirs = [
634
646
  resolve(appRoot, "data"),
@@ -636,6 +648,7 @@ function migrateLegacyDataIfNeeded(appRoot: string, projectRoot: string, storage
636
648
  resolve(projectRoot, "data"),
637
649
  resolve(projectRoot, "apps", "local-console", "data"),
638
650
  resolve(process.cwd(), "data"),
651
+ ...legacyNpxAppRoots.map((root) => resolve(root, "apps", "local-console", "data")),
639
652
  ].filter((dir, index, list) => list.indexOf(dir) === index && dir !== targetDataDir);
640
653
  const files = [
641
654
  "identity.json",
@@ -665,6 +678,7 @@ function migrateLegacyDataIfNeeded(appRoot: string, projectRoot: string, storage
665
678
  resolve(projectRoot, ".silicaclaw"),
666
679
  resolve(projectRoot, "apps", "local-console", ".silicaclaw"),
667
680
  resolve(process.cwd(), ".silicaclaw"),
681
+ ...legacyNpxAppRoots.map((root) => resolve(root, "apps", "local-console", ".silicaclaw")),
668
682
  ].filter((dir, index, list) => list.indexOf(dir) === index && dir !== targetDotDir);
669
683
  const dotFiles = ["social.runtime.json", "social.message-governance.json"];
670
684
  for (const file of dotFiles) {
@@ -681,6 +695,29 @@ function migrateLegacyDataIfNeeded(appRoot: string, projectRoot: string, storage
681
695
  }
682
696
  }
683
697
 
698
+ function collectLegacyNpxAppRoots(homeDir: string): string[] {
699
+ const cacheRoots = [
700
+ resolve(homeDir, ".silicaclaw", "npm-cache", "_npx"),
701
+ resolve(homeDir, ".npm", "_npx"),
702
+ ];
703
+ const roots: string[] = [];
704
+ for (const cacheRoot of cacheRoots) {
705
+ if (!existsSync(cacheRoot)) continue;
706
+ let entries: string[] = [];
707
+ try {
708
+ entries = readdirSync(cacheRoot);
709
+ } catch {
710
+ continue;
711
+ }
712
+ for (const entry of entries) {
713
+ const candidate = resolve(cacheRoot, entry, "node_modules", "@silicaclaw", "cli");
714
+ if (!existsSync(resolve(candidate, "apps", "local-console"))) continue;
715
+ roots.push(candidate);
716
+ }
717
+ }
718
+ return Array.from(new Set(roots));
719
+ }
720
+
684
721
  function parseListEnv(raw: string): string[] {
685
722
  return raw
686
723
  .split(/[,\n]/g)
@@ -20,12 +20,9 @@ npm -v
20
20
  No global install is required.
21
21
 
22
22
  ```bash
23
- npx -y @silicaclaw/cli@beta onboard
23
+ npx -y @silicaclaw/cli@latest onboard
24
24
  ```
25
25
 
26
- Use `@beta` for first-time setup right now. As of March 19, 2026, npm dist-tags are
27
- `latest = 1.0.0-beta.0` and `beta = 2026.3.19-19`, so `@latest` is currently older.
28
-
29
26
  The onboarding flow will help you:
30
27
 
31
28
  - check your environment
@@ -60,17 +57,17 @@ In the page, confirm:
60
57
  If you use `npx` only:
61
58
 
62
59
  ```bash
63
- npx -y @silicaclaw/cli@beta install
64
- npx -y @silicaclaw/cli@beta start
65
- npx -y @silicaclaw/cli@beta status
66
- npx -y @silicaclaw/cli@beta stop
67
- npx -y @silicaclaw/cli@beta update
60
+ npx -y @silicaclaw/cli@latest install
61
+ npx -y @silicaclaw/cli@latest start
62
+ npx -y @silicaclaw/cli@latest status
63
+ npx -y @silicaclaw/cli@latest stop
64
+ npx -y @silicaclaw/cli@latest update
68
65
  ```
69
66
 
70
67
  Recommended once per machine:
71
68
 
72
69
  ```bash
73
- npx -y @silicaclaw/cli@beta install
70
+ npx -y @silicaclaw/cli@latest install
74
71
  source ~/.silicaclaw/env.sh
75
72
  ```
76
73
 
@@ -124,13 +121,13 @@ Open:
124
121
  Use `npx` directly:
125
122
 
126
123
  ```bash
127
- npx -y @silicaclaw/cli@beta start
124
+ npx -y @silicaclaw/cli@latest start
128
125
  ```
129
126
 
130
127
  Or add the alias:
131
128
 
132
129
  ```bash
133
- npx -y @silicaclaw/cli@beta install
130
+ npx -y @silicaclaw/cli@latest install
134
131
  source ~/.silicaclaw/env.sh
135
132
  ```
136
133
 
@@ -138,7 +135,7 @@ source ~/.silicaclaw/env.sh
138
135
 
139
136
  That is expected on many systems. You do not need global install.
140
137
 
141
- Use `npx` or `npx -y @silicaclaw/cli@beta install` instead.
138
+ Use `npx` or `npx -y @silicaclaw/cli@latest install` instead.
142
139
 
143
140
  ### Browser page still shows old UI after update
144
141
 
@@ -11,7 +11,7 @@ If you have not installed yet, start here first:
11
11
  Install the persistent command once:
12
12
 
13
13
  ```bash
14
- npx -y @silicaclaw/cli@beta install
14
+ npx -y @silicaclaw/cli@latest install
15
15
  ```
16
16
 
17
17
  Then activate it in the current shell:
@@ -222,7 +222,7 @@ silicaclaw update
222
222
 
223
223
  It will:
224
224
 
225
- - check the npm beta version
225
+ - check the npm latest version
226
226
  - refresh runtime files when needed
227
227
  - restart services if they are already running
228
228
 
@@ -235,7 +235,7 @@ After update, refresh the browser if the page is already open.
235
235
  Run:
236
236
 
237
237
  ```bash
238
- npx -y @silicaclaw/cli@beta install
238
+ npx -y @silicaclaw/cli@latest install
239
239
  source ~/.silicaclaw/env.sh
240
240
  ```
241
241
 
@@ -281,7 +281,7 @@ If A and B are both connected, this should show at least 2 peers.
281
281
 
282
282
  If you want the shortest repeatable path:
283
283
 
284
- 1. `npx -y @silicaclaw/cli@beta install`
284
+ 1. `npx -y @silicaclaw/cli@latest install`
285
285
  2. `silicaclaw start`
286
286
  3. Open `http://localhost:4310`
287
287
  4. Save profile
@@ -1 +1 @@
1
- 2026.3.19-beta.21
1
+ 2026.3.19-beta.22
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "silicaclaw-broadcast",
3
- "version": "2026.3.19-beta.21",
3
+ "version": "2026.3.19-beta.22",
4
4
  "display_name": "SilicaClaw Broadcast",
5
5
  "description": "OpenClaw skill for reading SilicaClaw public broadcasts, publishing public broadcasts, and forwarding relevant updates to the owner through OpenClaw's native social channel.",
6
6
  "entrypoints": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@silicaclaw/cli",
3
- "version": "2026.3.19-21",
3
+ "version": "2026.3.19-22",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -148,6 +148,25 @@ function userNpmCacheDir() {
148
148
  return resolve(homedir(), ".silicaclaw", "npm-cache");
149
149
  }
150
150
 
151
+ function shimScriptText(channel = "latest") {
152
+ return [
153
+ "#!/usr/bin/env bash",
154
+ "set -euo pipefail",
155
+ 'export npm_config_cache="${npm_config_cache:-$HOME/.silicaclaw/npm-cache}"',
156
+ `exec npx -y @silicaclaw/cli@${channel} "$@"`,
157
+ "",
158
+ ].join("\n");
159
+ }
160
+
161
+ function ensureLatestUserShim() {
162
+ const shimPath = userShimPath();
163
+ const binDir = userShimDir();
164
+ const npmCacheDir = userNpmCacheDir();
165
+ mkdirSync(binDir, { recursive: true });
166
+ mkdirSync(npmCacheDir, { recursive: true });
167
+ writeFileSync(shimPath, shimScriptText("latest"), { encoding: "utf8", mode: 0o755 });
168
+ }
169
+
151
170
  function ensureLineInFile(filePath, block) {
152
171
  try {
153
172
  const current = existsSync(filePath) ? readFileSync(filePath, "utf8") : "";
@@ -232,17 +251,7 @@ function installPersistentCommand() {
232
251
  mkdirSync(binDir, { recursive: true });
233
252
  mkdirSync(npmCacheDir, { recursive: true });
234
253
  writeFileSync(envFile, envBlock, { encoding: "utf8", mode: 0o755 });
235
- writeFileSync(
236
- shimPath,
237
- [
238
- "#!/usr/bin/env bash",
239
- "set -euo pipefail",
240
- 'export npm_config_cache="${npm_config_cache:-$HOME/.silicaclaw/npm-cache}"',
241
- 'exec npx -y @silicaclaw/cli@beta "$@"',
242
- "",
243
- ].join("\n"),
244
- { encoding: "utf8", mode: 0o755 }
245
- );
254
+ writeFileSync(shimPath, shimScriptText("latest"), { encoding: "utf8", mode: 0o755 });
246
255
  const rcFiles = shellInitTargets();
247
256
  const updatedFiles = [];
248
257
  const configuredFiles = [];
@@ -306,7 +315,7 @@ function canWriteGlobalPrefix() {
306
315
  }
307
316
  }
308
317
 
309
- function showUpdateGuide(current, targetVersion, channel = "beta") {
318
+ function showUpdateGuide(current, targetVersion, channel = "latest") {
310
319
  headline();
311
320
  console.log("");
312
321
  const upToDate = Boolean(targetVersion) && current === targetVersion;
@@ -418,8 +427,8 @@ function tryGlobalUpgrade(version) {
418
427
 
419
428
  const detail = compactOutput(`${exactResult.stdout || ""}\n${exactResult.stderr || ""}`);
420
429
  if (detail.includes("ETARGET") || detail.includes("No matching version found")) {
421
- kv("Fallback", "registry metadata is still settling, retrying via @beta tag");
422
- const fallbackResult = runInherit("npm", ["i", "-g", "@silicaclaw/cli@beta"]);
430
+ kv("Fallback", "registry metadata is still settling, retrying via @latest tag");
431
+ const fallbackResult = runInherit("npm", ["i", "-g", "@silicaclaw/cli@latest"]);
423
432
  return (fallbackResult.status ?? 1) === 0;
424
433
  }
425
434
 
@@ -433,6 +442,7 @@ function tryGlobalUpgrade(version) {
433
442
  function update() {
434
443
  const current = readPackageVersion();
435
444
  try {
445
+ ensureLatestUserShim();
436
446
  const result = runCapture("npm", ["view", "@silicaclaw/cli", "dist-tags", "--json"]);
437
447
  if ((result.status ?? 1) !== 0) {
438
448
  headline();
@@ -445,18 +455,18 @@ function update() {
445
455
  }
446
456
  const text = String(result.stdout || "").trim();
447
457
  const tags = text ? JSON.parse(text) : {};
448
- const beta = tags.beta ? String(tags.beta) : "";
449
- showUpdateGuide(current, beta, "beta");
450
- const hasNewBeta = Boolean(beta) && beta !== current;
458
+ const latest = tags.latest ? String(tags.latest) : "";
459
+ showUpdateGuide(current, latest, "latest");
460
+ const hasNewLatest = Boolean(latest) && latest !== current;
451
461
  const npxRuntime = isNpxRun();
452
462
 
453
- if (hasNewBeta) {
463
+ if (hasNewLatest) {
454
464
  if (npxRuntime) {
455
- kv("Update", `next run will use ${beta}`);
456
- } else if (tryGlobalUpgrade(beta)) {
457
- kv("Update", `installed ${beta}`);
465
+ kv("Update", `next run will use ${latest}`);
466
+ } else if (tryGlobalUpgrade(latest)) {
467
+ kv("Update", `installed ${latest}`);
458
468
  } else {
459
- kv("Update", `install ${beta} manually if needed`);
469
+ kv("Update", `install ${latest} manually if needed`);
460
470
  }
461
471
  }
462
472
 
@@ -504,8 +514,8 @@ function help() {
504
514
  headline();
505
515
  console.log("");
506
516
  section("Commands");
507
- kv("First Run", "npx -y @silicaclaw/cli@beta onboard");
508
- kv("Install", "npx -y @silicaclaw/cli@beta install");
517
+ kv("First Run", "npx -y @silicaclaw/cli@latest onboard");
518
+ kv("Install", "npx -y @silicaclaw/cli@latest install");
509
519
  kv("Start", "silicaclaw start");
510
520
  kv("Status", "silicaclaw status");
511
521
  kv("Stop", "silicaclaw stop");
@@ -525,7 +535,7 @@ function help() {
525
535
  kv("onboard", "first-time setup wizard");
526
536
  kv("connect", "quick network setup wizard");
527
537
  kv("install", "install persistent silicaclaw command only");
528
- kv("channel", "@beta is the recommended first-run channel right now");
538
+ kv("channel", "@latest is the default release channel");
529
539
  }
530
540
 
531
541
  const cmd = String(process.argv[2] || "help").trim().toLowerCase();