@silicaclaw/cli 2026.3.20-1 → 2026.3.20-11

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 (143) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/INSTALL.md +13 -7
  3. package/README.md +60 -12
  4. package/VERSION +1 -1
  5. package/apps/local-console/dist/apps/local-console/src/server.d.ts +129 -2
  6. package/apps/local-console/dist/apps/local-console/src/server.js +887 -91
  7. package/apps/local-console/dist/packages/core/src/index.d.ts +2 -0
  8. package/apps/local-console/dist/packages/core/src/index.js +2 -0
  9. package/apps/local-console/dist/packages/core/src/privateCrypto.d.ts +17 -0
  10. package/apps/local-console/dist/packages/core/src/privateCrypto.js +40 -0
  11. package/apps/local-console/dist/packages/core/src/privateMessage.d.ts +23 -0
  12. package/apps/local-console/dist/packages/core/src/privateMessage.js +74 -0
  13. package/apps/local-console/dist/packages/core/src/profile.js +2 -0
  14. package/apps/local-console/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
  15. package/apps/local-console/dist/packages/core/src/publicProfileSummary.js +3 -0
  16. package/apps/local-console/dist/packages/core/src/types.d.ts +40 -0
  17. package/apps/local-console/dist/packages/network/src/relayPreview.d.ts +12 -0
  18. package/apps/local-console/dist/packages/network/src/relayPreview.js +108 -8
  19. package/apps/local-console/dist/packages/network/src/types.d.ts +4 -0
  20. package/apps/local-console/dist/packages/storage/src/repos.d.ts +13 -1
  21. package/apps/local-console/dist/packages/storage/src/repos.js +19 -1
  22. package/apps/local-console/public/app/app.js +465 -11
  23. package/apps/local-console/public/app/events.js +21 -0
  24. package/apps/local-console/public/app/network.js +144 -32
  25. package/apps/local-console/public/app/overview.js +60 -52
  26. package/apps/local-console/public/app/social.js +316 -93
  27. package/apps/local-console/public/app/styles.css +127 -1
  28. package/apps/local-console/public/app/template.js +121 -35
  29. package/apps/local-console/public/app/translations.js +430 -316
  30. package/apps/local-console/src/server.ts +1024 -89
  31. package/apps/public-explorer/public/app/template.js +2 -2
  32. package/apps/public-explorer/public/app/translations.js +36 -36
  33. package/docs/NEW_USER_OPERATIONS.md +5 -5
  34. package/docs/OPENCLAW_BRIDGE.md +7 -7
  35. package/docs/OPENCLAW_BRIDGE_ZH.md +6 -6
  36. package/node_modules/@silicaclaw/core/dist/packages/core/src/index.d.ts +2 -0
  37. package/node_modules/@silicaclaw/core/dist/packages/core/src/index.js +2 -0
  38. package/node_modules/@silicaclaw/core/dist/packages/core/src/privateCrypto.d.ts +17 -0
  39. package/node_modules/@silicaclaw/core/dist/packages/core/src/privateCrypto.js +40 -0
  40. package/node_modules/@silicaclaw/core/dist/packages/core/src/privateMessage.d.ts +23 -0
  41. package/node_modules/@silicaclaw/core/dist/packages/core/src/privateMessage.js +74 -0
  42. package/node_modules/@silicaclaw/core/dist/packages/core/src/profile.js +2 -0
  43. package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
  44. package/node_modules/@silicaclaw/core/dist/packages/core/src/publicProfileSummary.js +3 -0
  45. package/node_modules/@silicaclaw/core/dist/packages/core/src/types.d.ts +40 -0
  46. package/node_modules/@silicaclaw/core/src/index.ts +2 -0
  47. package/node_modules/@silicaclaw/core/src/privateCrypto.ts +57 -0
  48. package/node_modules/@silicaclaw/core/src/privateMessage.ts +101 -0
  49. package/node_modules/@silicaclaw/core/src/profile.ts +2 -0
  50. package/node_modules/@silicaclaw/core/src/publicProfileSummary.ts +7 -0
  51. package/node_modules/@silicaclaw/core/src/types.ts +44 -0
  52. package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.d.ts +12 -0
  53. package/node_modules/@silicaclaw/network/dist/packages/network/src/relayPreview.js +108 -8
  54. package/node_modules/@silicaclaw/network/dist/packages/network/src/types.d.ts +4 -0
  55. package/node_modules/@silicaclaw/network/src/relayPreview.ts +120 -10
  56. package/node_modules/@silicaclaw/network/src/types.ts +2 -0
  57. package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.d.ts +2 -0
  58. package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.js +2 -0
  59. package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateCrypto.d.ts +17 -0
  60. package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateCrypto.js +40 -0
  61. package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateMessage.d.ts +23 -0
  62. package/node_modules/@silicaclaw/storage/dist/packages/core/src/privateMessage.js +74 -0
  63. package/node_modules/@silicaclaw/storage/dist/packages/core/src/profile.js +2 -0
  64. package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
  65. package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.js +3 -0
  66. package/node_modules/@silicaclaw/storage/dist/packages/core/src/types.d.ts +40 -0
  67. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.d.ts +13 -1
  68. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.js +19 -1
  69. package/node_modules/@silicaclaw/storage/package.json +2 -2
  70. package/node_modules/@silicaclaw/storage/src/repos.ts +31 -1
  71. package/openclaw-skills/silicaclaw-bridge-setup/SKILL.md +18 -0
  72. package/openclaw-skills/silicaclaw-bridge-setup/VERSION +1 -1
  73. package/openclaw-skills/silicaclaw-bridge-setup/manifest.json +2 -2
  74. package/openclaw-skills/silicaclaw-broadcast/SKILL.md +18 -0
  75. package/openclaw-skills/silicaclaw-broadcast/VERSION +1 -1
  76. package/openclaw-skills/silicaclaw-broadcast/manifest.json +2 -2
  77. package/openclaw-skills/silicaclaw-network-config/SKILL.md +158 -0
  78. package/openclaw-skills/silicaclaw-network-config/VERSION +1 -0
  79. package/openclaw-skills/silicaclaw-network-config/agents/openai.yaml +6 -0
  80. package/openclaw-skills/silicaclaw-network-config/manifest.json +27 -0
  81. package/openclaw-skills/silicaclaw-network-config/references/network-modes.md +22 -0
  82. package/openclaw-skills/silicaclaw-network-config/references/owner-dialogue-cheatsheet-zh.md +47 -0
  83. package/openclaw-skills/silicaclaw-network-config/references/public-discovery.md +22 -0
  84. package/openclaw-skills/silicaclaw-owner-push/SKILL.md +18 -0
  85. package/openclaw-skills/silicaclaw-owner-push/VERSION +1 -1
  86. package/openclaw-skills/silicaclaw-owner-push/manifest.json +2 -2
  87. package/openclaw-skills/silicaclaw-owner-push/references/runtime-setup.md +3 -0
  88. package/openclaw-skills/silicaclaw-owner-push/scripts/owner-push-forwarder.mjs +151 -9
  89. package/package.json +1 -1
  90. package/packages/core/dist/packages/core/src/index.d.ts +2 -0
  91. package/packages/core/dist/packages/core/src/index.js +2 -0
  92. package/packages/core/dist/packages/core/src/privateCrypto.d.ts +17 -0
  93. package/packages/core/dist/packages/core/src/privateCrypto.js +40 -0
  94. package/packages/core/dist/packages/core/src/privateMessage.d.ts +23 -0
  95. package/packages/core/dist/packages/core/src/privateMessage.js +74 -0
  96. package/packages/core/dist/packages/core/src/profile.js +2 -0
  97. package/packages/core/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
  98. package/packages/core/dist/packages/core/src/publicProfileSummary.js +3 -0
  99. package/packages/core/dist/packages/core/src/types.d.ts +40 -0
  100. package/packages/core/src/index.ts +2 -0
  101. package/packages/core/src/privateCrypto.ts +57 -0
  102. package/packages/core/src/privateMessage.ts +101 -0
  103. package/packages/core/src/profile.ts +2 -0
  104. package/packages/core/src/publicProfileSummary.ts +7 -0
  105. package/packages/core/src/types.ts +44 -0
  106. package/packages/network/dist/packages/network/src/relayPreview.d.ts +12 -0
  107. package/packages/network/dist/packages/network/src/relayPreview.js +108 -8
  108. package/packages/network/dist/packages/network/src/types.d.ts +4 -0
  109. package/packages/network/src/relayPreview.ts +120 -10
  110. package/packages/network/src/types.ts +2 -0
  111. package/packages/storage/dist/packages/core/src/index.d.ts +2 -0
  112. package/packages/storage/dist/packages/core/src/index.js +2 -0
  113. package/packages/storage/dist/packages/core/src/privateCrypto.d.ts +17 -0
  114. package/packages/storage/dist/packages/core/src/privateCrypto.js +40 -0
  115. package/packages/storage/dist/packages/core/src/privateMessage.d.ts +23 -0
  116. package/packages/storage/dist/packages/core/src/privateMessage.js +74 -0
  117. package/packages/storage/dist/packages/core/src/profile.js +2 -0
  118. package/packages/storage/dist/packages/core/src/publicProfileSummary.d.ts +4 -0
  119. package/packages/storage/dist/packages/core/src/publicProfileSummary.js +3 -0
  120. package/packages/storage/dist/packages/core/src/types.d.ts +40 -0
  121. package/packages/storage/dist/packages/storage/src/repos.d.ts +13 -1
  122. package/packages/storage/dist/packages/storage/src/repos.js +19 -1
  123. package/packages/storage/package.json +2 -2
  124. package/packages/storage/src/repos.ts +31 -1
  125. package/scripts/silicaclaw-cli.mjs +59 -6
  126. package/scripts/silicaclaw-gateway.mjs +108 -0
  127. package/scripts/validate-openclaw-skill.mjs +19 -0
  128. package/node_modules/@silicaclaw/storage/dist/index.d.ts +0 -3
  129. package/node_modules/@silicaclaw/storage/dist/index.js +0 -19
  130. package/node_modules/@silicaclaw/storage/dist/jsonRepo.d.ts +0 -7
  131. package/node_modules/@silicaclaw/storage/dist/jsonRepo.js +0 -29
  132. package/node_modules/@silicaclaw/storage/dist/repos.d.ts +0 -61
  133. package/node_modules/@silicaclaw/storage/dist/repos.js +0 -67
  134. package/node_modules/@silicaclaw/storage/dist/socialRuntimeRepo.d.ts +0 -5
  135. package/node_modules/@silicaclaw/storage/dist/socialRuntimeRepo.js +0 -57
  136. package/packages/storage/dist/index.d.ts +0 -3
  137. package/packages/storage/dist/index.js +0 -19
  138. package/packages/storage/dist/jsonRepo.d.ts +0 -7
  139. package/packages/storage/dist/jsonRepo.js +0 -29
  140. package/packages/storage/dist/repos.d.ts +0 -61
  141. package/packages/storage/dist/repos.js +0 -67
  142. package/packages/storage/dist/socialRuntimeRepo.d.ts +0 -5
  143. package/packages/storage/dist/socialRuntimeRepo.js +0 -57
@@ -53,9 +53,11 @@ function buildPublicProfileSummary(args) {
53
53
  ].filter((field) => Boolean(field));
54
54
  return {
55
55
  agent_id: args.profile.agent_id,
56
+ is_self: Boolean(args.is_self),
56
57
  display_name: args.profile.display_name,
57
58
  bio: args.profile.bio,
58
59
  avatar_url: args.profile.avatar_url,
60
+ private_encryption_public_key: args.profile.private_encryption_public_key,
59
61
  public_enabled: args.profile.public_enabled,
60
62
  updated_at: args.profile.updated_at,
61
63
  online: args.online,
@@ -76,6 +78,7 @@ function buildPublicProfileSummary(args) {
76
78
  display_name: args.profile.display_name,
77
79
  bio: args.profile.bio,
78
80
  avatar_url: args.profile.avatar_url,
81
+ private_encryption_public_key: args.profile.private_encryption_public_key,
79
82
  tags,
80
83
  public_enabled: args.profile.public_enabled,
81
84
  profile_version: args.profile_version ?? "v1",
@@ -4,12 +4,18 @@ export type AgentIdentity = {
4
4
  private_key: string;
5
5
  created_at: number;
6
6
  };
7
+ export type PrivateEncryptionKeyPair = {
8
+ public_key: string;
9
+ private_key: string;
10
+ created_at: number;
11
+ };
7
12
  export type PublicProfile = {
8
13
  agent_id: string;
9
14
  display_name: string;
10
15
  bio: string;
11
16
  tags: string[];
12
17
  avatar_url?: string;
18
+ private_encryption_public_key?: string;
13
19
  public_enabled: boolean;
14
20
  updated_at: number;
15
21
  signature: string;
@@ -51,6 +57,40 @@ export type SocialMessageObservationRecord = {
51
57
  observed_at: number;
52
58
  signature: string;
53
59
  };
60
+ export type PrivateMessageRecord = {
61
+ type: "private.message";
62
+ message_id: string;
63
+ conversation_id: string;
64
+ from_agent_id: string;
65
+ to_agent_id: string;
66
+ sender_public_key: string;
67
+ sender_encryption_public_key: string;
68
+ recipient_encryption_public_key: string;
69
+ cipher_scheme: "nacl-box-v1";
70
+ ciphertext: string;
71
+ nonce: string;
72
+ created_at: number;
73
+ signature: string;
74
+ };
75
+ export type PrivateMessageReceiptRecord = {
76
+ type: "private.message.receipt";
77
+ receipt_id: string;
78
+ message_id: string;
79
+ conversation_id: string;
80
+ from_agent_id: string;
81
+ to_agent_id: string;
82
+ sender_public_key: string;
83
+ status: "received" | "read";
84
+ created_at: number;
85
+ signature: string;
86
+ };
87
+ export type PrivateConversationSummary = {
88
+ conversation_id: string;
89
+ peer_agent_id: string;
90
+ last_message_at: number | null;
91
+ last_message_preview: string;
92
+ unread_count: number;
93
+ };
54
94
  export type DirectoryState = {
55
95
  profiles: Record<string, PublicProfile>;
56
96
  presence: Record<string, number>;
@@ -1,4 +1,4 @@
1
- import { AgentIdentity, DirectoryState, PublicProfile } from "@silicaclaw/core";
1
+ import { AgentIdentity, DirectoryState, PrivateEncryptionKeyPair, PrivateMessageReceiptRecord, PrivateMessageRecord, PublicProfile } from "@silicaclaw/core";
2
2
  import { JsonFileRepo } from "./jsonRepo";
3
3
  export type LogEntry = {
4
4
  id: string;
@@ -37,6 +37,9 @@ export type SocialMessageGovernanceConfig = {
37
37
  blocked_agent_ids: string[];
38
38
  blocked_terms: string[];
39
39
  };
40
+ export type PrivateMessageDecryptedContent = {
41
+ body: string;
42
+ };
40
43
  export declare class IdentityRepo extends JsonFileRepo<AgentIdentity | null> {
41
44
  constructor(rootDir?: string);
42
45
  }
@@ -59,3 +62,12 @@ export declare class SocialMessageObservationRepo extends JsonFileRepo<SocialMes
59
62
  export declare class SocialMessageGovernanceRepo extends JsonFileRepo<SocialMessageGovernanceConfig> {
60
63
  constructor(rootDir?: string);
61
64
  }
65
+ export declare class PrivateMessageRepo extends JsonFileRepo<PrivateMessageRecord[]> {
66
+ constructor(rootDir?: string);
67
+ }
68
+ export declare class PrivateMessageReceiptRepo extends JsonFileRepo<PrivateMessageReceiptRecord[]> {
69
+ constructor(rootDir?: string);
70
+ }
71
+ export declare class PrivateEncryptionKeyRepo extends JsonFileRepo<PrivateEncryptionKeyPair | null> {
72
+ constructor(rootDir?: string);
73
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SocialMessageGovernanceRepo = exports.SocialMessageObservationRepo = exports.SocialMessageRepo = exports.LogRepo = exports.CacheRepo = exports.ProfileRepo = exports.IdentityRepo = void 0;
3
+ exports.PrivateEncryptionKeyRepo = exports.PrivateMessageReceiptRepo = exports.PrivateMessageRepo = exports.SocialMessageGovernanceRepo = exports.SocialMessageObservationRepo = exports.SocialMessageRepo = exports.LogRepo = exports.CacheRepo = exports.ProfileRepo = exports.IdentityRepo = void 0;
4
4
  const path_1 = require("path");
5
5
  const core_1 = require("@silicaclaw/core");
6
6
  const jsonRepo_1 = require("./jsonRepo");
@@ -65,3 +65,21 @@ class SocialMessageGovernanceRepo extends jsonRepo_1.JsonFileRepo {
65
65
  }
66
66
  }
67
67
  exports.SocialMessageGovernanceRepo = SocialMessageGovernanceRepo;
68
+ class PrivateMessageRepo extends jsonRepo_1.JsonFileRepo {
69
+ constructor(rootDir = process.cwd()) {
70
+ super((0, path_1.resolve)(rootDir, "data", "private-messages.json"), () => []);
71
+ }
72
+ }
73
+ exports.PrivateMessageRepo = PrivateMessageRepo;
74
+ class PrivateMessageReceiptRepo extends jsonRepo_1.JsonFileRepo {
75
+ constructor(rootDir = process.cwd()) {
76
+ super((0, path_1.resolve)(rootDir, "data", "private-message-receipts.json"), () => []);
77
+ }
78
+ }
79
+ exports.PrivateMessageReceiptRepo = PrivateMessageReceiptRepo;
80
+ class PrivateEncryptionKeyRepo extends jsonRepo_1.JsonFileRepo {
81
+ constructor(rootDir = process.cwd()) {
82
+ super((0, path_1.resolve)(rootDir, "data", "private-encryption-keypair.json"), () => null);
83
+ }
84
+ }
85
+ exports.PrivateEncryptionKeyRepo = PrivateEncryptionKeyRepo;
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@silicaclaw/storage",
3
3
  "version": "0.1.0",
4
- "main": "dist/index.js",
5
- "types": "dist/index.d.ts",
4
+ "main": "dist/packages/storage/src/index.js",
5
+ "types": "dist/packages/storage/src/index.d.ts",
6
6
  "scripts": {
7
7
  "build": "tsc -p tsconfig.json",
8
8
  "check": "tsc -p tsconfig.json --noEmit"
@@ -1,5 +1,13 @@
1
1
  import { resolve } from "path";
2
- import { AgentIdentity, DirectoryState, PublicProfile, createEmptyDirectoryState } from "@silicaclaw/core";
2
+ import {
3
+ AgentIdentity,
4
+ DirectoryState,
5
+ PrivateEncryptionKeyPair,
6
+ PrivateMessageReceiptRecord,
7
+ PrivateMessageRecord,
8
+ PublicProfile,
9
+ createEmptyDirectoryState,
10
+ } from "@silicaclaw/core";
3
11
  import { JsonFileRepo } from "./jsonRepo";
4
12
 
5
13
  export type LogEntry = {
@@ -43,6 +51,10 @@ export type SocialMessageGovernanceConfig = {
43
51
  blocked_terms: string[];
44
52
  };
45
53
 
54
+ export type PrivateMessageDecryptedContent = {
55
+ body: string;
56
+ };
57
+
46
58
  export class IdentityRepo extends JsonFileRepo<AgentIdentity | null> {
47
59
  constructor(rootDir = process.cwd()) {
48
60
  super(resolve(rootDir, "data", "identity.json"), () => null);
@@ -104,3 +116,21 @@ export class SocialMessageGovernanceRepo extends JsonFileRepo<SocialMessageGover
104
116
  }));
105
117
  }
106
118
  }
119
+
120
+ export class PrivateMessageRepo extends JsonFileRepo<PrivateMessageRecord[]> {
121
+ constructor(rootDir = process.cwd()) {
122
+ super(resolve(rootDir, "data", "private-messages.json"), () => []);
123
+ }
124
+ }
125
+
126
+ export class PrivateMessageReceiptRepo extends JsonFileRepo<PrivateMessageReceiptRecord[]> {
127
+ constructor(rootDir = process.cwd()) {
128
+ super(resolve(rootDir, "data", "private-message-receipts.json"), () => []);
129
+ }
130
+ }
131
+
132
+ export class PrivateEncryptionKeyRepo extends JsonFileRepo<PrivateEncryptionKeyPair | null> {
133
+ constructor(rootDir = process.cwd()) {
134
+ super(resolve(rootDir, "data", "private-encryption-keypair.json"), () => null);
135
+ }
136
+ }
@@ -10,6 +10,7 @@ const __filename = fileURLToPath(import.meta.url);
10
10
  const __dirname = dirname(__filename);
11
11
  const ROOT_DIR = resolve(__dirname, "..");
12
12
  const INVOCATION_CWD = process.cwd();
13
+ const LOCAL_CONSOLE_BASE_URL = "http://localhost:4310";
13
14
 
14
15
  const COLOR = {
15
16
  reset: "\x1b[0m",
@@ -109,6 +110,10 @@ function compactOutput(text, limit = 18) {
109
110
  return lines.slice(-limit).join("\n");
110
111
  }
111
112
 
113
+ function sleep(ms) {
114
+ return new Promise((resolve) => setTimeout(resolve, ms));
115
+ }
116
+
112
117
  function readVersion() {
113
118
  return readPackageVersion();
114
119
  }
@@ -219,10 +224,12 @@ function shellInitTargets() {
219
224
  shell.endsWith("/bash") ||
220
225
  process.env.BASH_VERSION ||
221
226
  existsSync(resolve(home, ".bashrc")) ||
222
- existsSync(resolve(home, ".bash_profile"))
227
+ existsSync(resolve(home, ".bash_profile")) ||
228
+ existsSync(resolve(home, ".profile"))
223
229
  ) {
224
230
  add(resolve(home, ".bashrc"));
225
231
  add(resolve(home, ".bash_profile"));
232
+ add(resolve(home, ".profile"));
226
233
  }
227
234
 
228
235
  if (targets.length === 0) {
@@ -275,6 +282,7 @@ function installPersistentCommand(specifier = readPackageVersion()) {
275
282
  kv("Command", "silicaclaw");
276
283
  console.log("");
277
284
  kv("Activate", `source "${envFile}"`);
285
+ kv("Current shell", "run Activate now if `silicaclaw` is not found yet");
278
286
  if (configuredFiles.length > 0) {
279
287
  kv("Startup", "configured");
280
288
  } else {
@@ -416,7 +424,7 @@ function restartGatewayIfRunning(options = {}) {
416
424
  const localRunning = Boolean(status?.local_console?.running);
417
425
  const signalingRunning = Boolean(status?.signaling?.running);
418
426
  if (!localRunning && !signalingRunning) {
419
- return;
427
+ return { restarted: false };
420
428
  }
421
429
 
422
430
  const mode = String(status?.mode || "local");
@@ -438,12 +446,51 @@ function restartGatewayIfRunning(options = {}) {
438
446
 
439
447
  if (canUseUpdatedShim) {
440
448
  runInherit(shimPath, gatewayArgs, { cwd: process.cwd() });
441
- return;
449
+ return { restarted: true, usedUpdatedShim: true };
442
450
  }
443
451
 
444
452
  runInherit("node", [resolve(ROOT_DIR, "scripts", "silicaclaw-gateway.mjs"), ...gatewayArgs.slice(1)], {
445
453
  cwd: process.cwd(),
446
454
  });
455
+ return { restarted: true, usedUpdatedShim: false };
456
+ }
457
+
458
+ function readLocalConsoleAppVersion() {
459
+ try {
460
+ const result = runCapture("curl", ["-sS", `${LOCAL_CONSOLE_BASE_URL}/api/overview`], {
461
+ cwd: process.cwd(),
462
+ });
463
+ if ((result.status ?? 1) !== 0) return "";
464
+ const text = String(result.stdout || "").trim();
465
+ if (!text) return "";
466
+ const payload = JSON.parse(text);
467
+ return String(payload?.data?.app_version || "").trim();
468
+ } catch {
469
+ return "";
470
+ }
471
+ }
472
+
473
+ async function waitForLocalConsoleVersion(targetVersion, timeoutMs = 15000) {
474
+ const startedAt = Date.now();
475
+ while (Date.now() - startedAt < timeoutMs) {
476
+ const version = readLocalConsoleAppVersion();
477
+ if (version === targetVersion) return version;
478
+ await sleep(400);
479
+ }
480
+ return readLocalConsoleAppVersion();
481
+ }
482
+
483
+ async function ensureRefreshedConsoleVersion(targetVersion) {
484
+ if (!targetVersion) return "";
485
+ let observed = await waitForLocalConsoleVersion(targetVersion, 12000);
486
+ if (observed === targetVersion) return observed;
487
+
488
+ const shimPath = userShimPath();
489
+ if (!existsSync(shimPath)) return observed;
490
+
491
+ runInherit(shimPath, ["gateway", "restart"], { cwd: process.cwd() });
492
+ observed = await waitForLocalConsoleVersion(targetVersion, 12000);
493
+ return observed;
447
494
  }
448
495
 
449
496
  function tryGlobalUpgrade(version) {
@@ -471,7 +518,7 @@ function tryGlobalUpgrade(version) {
471
518
  return false;
472
519
  }
473
520
 
474
- function update() {
521
+ async function update() {
475
522
  const current = readPackageVersion();
476
523
  try {
477
524
  const registry = preferredRegistryRelease(current);
@@ -502,7 +549,13 @@ function update() {
502
549
  }
503
550
  }
504
551
 
505
- restartGatewayIfRunning({ preferredSpecifier: hasNewTarget ? targetVersion : "" });
552
+ const restartResult = restartGatewayIfRunning({ preferredSpecifier: hasNewTarget ? targetVersion : "" });
553
+ if (hasNewTarget && restartResult?.restarted) {
554
+ const observedVersion = await ensureRefreshedConsoleVersion(targetVersion);
555
+ if (observedVersion && observedVersion !== targetVersion) {
556
+ kv("Verify", `local console still reports ${observedVersion}`);
557
+ }
558
+ }
506
559
  process.exit(0);
507
560
  } catch (error) {
508
561
  headline();
@@ -586,7 +639,7 @@ switch (cmd) {
586
639
  });
587
640
  break;
588
641
  case "update":
589
- update();
642
+ await update();
590
643
  break;
591
644
  case "install":
592
645
  {
@@ -74,6 +74,11 @@ function readJson(file) {
74
74
  }
75
75
  }
76
76
 
77
+ function readPackageVersionFrom(dir) {
78
+ const pkg = readJson(resolve(dir, "package.json"));
79
+ return String(pkg?.version || "latest").trim() || "latest";
80
+ }
81
+
77
82
  function isSilicaClawDir(dir) {
78
83
  const pkgPath = join(dir, "package.json");
79
84
  if (!existsSync(pkgPath)) return false;
@@ -144,6 +149,107 @@ function ensureStateDir() {
144
149
  mkdirSync(STATE_DIR, { recursive: true });
145
150
  }
146
151
 
152
+ function userShimDir() {
153
+ return join(homedir(), ".silicaclaw", "bin");
154
+ }
155
+
156
+ function userShimPath() {
157
+ return join(userShimDir(), "silicaclaw");
158
+ }
159
+
160
+ function userEnvFile() {
161
+ return join(homedir(), ".silicaclaw", "env.sh");
162
+ }
163
+
164
+ function userNpmCacheDir() {
165
+ return join(homedir(), ".silicaclaw", "npm-cache");
166
+ }
167
+
168
+ function preferredShellRcFile() {
169
+ const shell = String(process.env.SHELL || "");
170
+ if (shell.endsWith("/zsh")) return resolve(homedir(), ".zshrc");
171
+ if (shell.endsWith("/bash")) return resolve(homedir(), ".bashrc");
172
+ if (process.env.ZSH_VERSION) return resolve(homedir(), ".zshrc");
173
+ return resolve(homedir(), ".bashrc");
174
+ }
175
+
176
+ function shellInitTargets() {
177
+ const home = homedir();
178
+ const shell = String(process.env.SHELL || "");
179
+ const targets = [];
180
+ const add = (filePath) => {
181
+ if (!targets.includes(filePath)) targets.push(filePath);
182
+ };
183
+
184
+ if (shell.endsWith("/zsh") || process.env.ZSH_VERSION || existsSync(resolve(home, ".zshrc"))) {
185
+ add(resolve(home, ".zshrc"));
186
+ }
187
+
188
+ if (
189
+ shell.endsWith("/bash") ||
190
+ process.env.BASH_VERSION ||
191
+ existsSync(resolve(home, ".bashrc")) ||
192
+ existsSync(resolve(home, ".bash_profile")) ||
193
+ existsSync(resolve(home, ".profile"))
194
+ ) {
195
+ add(resolve(home, ".bashrc"));
196
+ add(resolve(home, ".bash_profile"));
197
+ add(resolve(home, ".profile"));
198
+ }
199
+
200
+ if (targets.length === 0) {
201
+ add(preferredShellRcFile());
202
+ }
203
+ return targets;
204
+ }
205
+
206
+ function ensureLineInFile(filePath, block) {
207
+ try {
208
+ const current = existsSync(filePath) ? readFileSync(filePath, "utf8") : "";
209
+ if (current.includes(block.trim())) return true;
210
+ const next = `${current.replace(/\s*$/, "")}\n\n${block}\n`;
211
+ mkdirSync(dirname(filePath), { recursive: true });
212
+ writeFileSync(filePath, next, "utf8");
213
+ return true;
214
+ } catch {
215
+ return false;
216
+ }
217
+ }
218
+
219
+ function shimScriptText(specifier = "latest") {
220
+ return [
221
+ "#!/usr/bin/env bash",
222
+ "set -euo pipefail",
223
+ 'export npm_config_cache="${npm_config_cache:-$HOME/.silicaclaw/npm-cache}"',
224
+ `exec npx -y @silicaclaw/cli@${specifier} "$@"`,
225
+ "",
226
+ ].join("\n");
227
+ }
228
+
229
+ function ensureUserCommandInstalled() {
230
+ const version = readPackageVersionFrom(APP_DIR);
231
+ const envBlock = [
232
+ "#!/usr/bin/env bash",
233
+ 'export PATH="$HOME/.silicaclaw/bin:$PATH"',
234
+ 'export npm_config_cache="$HOME/.silicaclaw/npm-cache"',
235
+ "",
236
+ ].join("\n");
237
+ const rcBlock = [
238
+ "# >>> silicaclaw >>>",
239
+ '[ -f "$HOME/.silicaclaw/env.sh" ] && . "$HOME/.silicaclaw/env.sh"',
240
+ "# <<< silicaclaw <<<",
241
+ ].join("\n");
242
+
243
+ mkdirSync(userShimDir(), { recursive: true });
244
+ mkdirSync(userNpmCacheDir(), { recursive: true });
245
+ writeFileSync(userEnvFile(), envBlock, { encoding: "utf8", mode: 0o755 });
246
+ writeFileSync(userShimPath(), shimScriptText(version), { encoding: "utf8", mode: 0o755 });
247
+
248
+ for (const filePath of shellInitTargets()) {
249
+ ensureLineInFile(filePath, rcBlock);
250
+ }
251
+ }
252
+
147
253
  function ensureLaunchAgentsDir() {
148
254
  mkdirSync(LAUNCH_AGENTS_DIR, { recursive: true });
149
255
  }
@@ -797,6 +903,7 @@ async function stopAll() {
797
903
 
798
904
  async function startAll() {
799
905
  ensureStateDir();
906
+ ensureUserCommandInstalled();
800
907
 
801
908
  const mode = parseMode(parseFlag("mode", process.env.NETWORK_MODE || DEFAULT_NETWORK_MODE));
802
909
  const adapter = adapterForMode(mode);
@@ -923,6 +1030,7 @@ async function startAll() {
923
1030
  }
924
1031
 
925
1032
  async function restartAll() {
1033
+ ensureUserCommandInstalled();
926
1034
  if (!isLaunchdPlatform()) {
927
1035
  await stopAll();
928
1036
  await startAll();
@@ -100,6 +100,25 @@ function main() {
100
100
  assert(dialogueCheatsheetZh.includes("主人对话速查表"), "owner dialogue cheatsheet zh content mismatch");
101
101
  },
102
102
  },
103
+ "silicaclaw-network-config": {
104
+ requiredFiles: [
105
+ resolve(skillDir, "references", "network-modes.md"),
106
+ resolve(skillDir, "references", "public-discovery.md"),
107
+ resolve(skillDir, "references", "owner-dialogue-cheatsheet-zh.md"),
108
+ ],
109
+ uiDisplayName: 'display_name: "SilicaClaw Network Config"',
110
+ checks(manifest, files) {
111
+ const networkModes = readFileSync(files[0], "utf8");
112
+ const publicDiscovery = readFileSync(files[1], "utf8");
113
+ const dialogueCheatsheetZh = readFileSync(files[2], "utf8");
114
+ assert(String(manifest.references?.network_modes || "") === "references/network-modes.md", "manifest network modes reference mismatch");
115
+ assert(String(manifest.references?.public_discovery || "") === "references/public-discovery.md", "manifest public discovery reference mismatch");
116
+ assert(String(manifest.references?.owner_dialogue_cheatsheet_zh || "") === "references/owner-dialogue-cheatsheet-zh.md", "manifest owner dialogue cheatsheet zh reference mismatch");
117
+ assert(networkModes.includes("## Modes"), "network modes content mismatch");
118
+ assert(publicDiscovery.includes("public_enabled"), "public discovery content mismatch");
119
+ assert(dialogueCheatsheetZh.includes("主人对话速查表"), "owner dialogue cheatsheet zh content mismatch");
120
+ },
121
+ },
103
122
  }[skillName];
104
123
 
105
124
  assert(profile, `Unsupported skill for validation: ${skillName}`);
@@ -1,3 +0,0 @@
1
- export * from "./jsonRepo";
2
- export * from "./repos";
3
- export * from "./socialRuntimeRepo";
@@ -1,19 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./jsonRepo"), exports);
18
- __exportStar(require("./repos"), exports);
19
- __exportStar(require("./socialRuntimeRepo"), exports);
@@ -1,7 +0,0 @@
1
- export declare class JsonFileRepo<T> {
2
- private filePath;
3
- private fallback;
4
- constructor(filePath: string, fallback: () => T);
5
- get(): Promise<T>;
6
- set(value: T): Promise<void>;
7
- }
@@ -1,29 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.JsonFileRepo = void 0;
4
- const promises_1 = require("fs/promises");
5
- const path_1 = require("path");
6
- class JsonFileRepo {
7
- filePath;
8
- fallback;
9
- constructor(filePath, fallback) {
10
- this.filePath = filePath;
11
- this.fallback = fallback;
12
- }
13
- async get() {
14
- try {
15
- const raw = await (0, promises_1.readFile)(this.filePath, "utf8");
16
- return JSON.parse(raw);
17
- }
18
- catch {
19
- const seed = this.fallback();
20
- await this.set(seed);
21
- return seed;
22
- }
23
- }
24
- async set(value) {
25
- await (0, promises_1.mkdir)((0, path_1.dirname)(this.filePath), { recursive: true });
26
- await (0, promises_1.writeFile)(this.filePath, JSON.stringify(value, null, 2), "utf8");
27
- }
28
- }
29
- exports.JsonFileRepo = JsonFileRepo;
@@ -1,61 +0,0 @@
1
- import { AgentIdentity, DirectoryState, PublicProfile } from "@silicaclaw/core";
2
- import { JsonFileRepo } from "./jsonRepo";
3
- export type LogEntry = {
4
- id: string;
5
- level: "info" | "warn" | "error";
6
- message: string;
7
- timestamp: number;
8
- };
9
- export type SocialMessageRecord = {
10
- type: "social.message";
11
- message_id: string;
12
- agent_id: string;
13
- public_key: string;
14
- display_name: string;
15
- topic: string;
16
- body: string;
17
- created_at: number;
18
- signature: string;
19
- };
20
- export type SocialMessageObservationRecord = {
21
- type: "social.message.observation";
22
- observation_id: string;
23
- message_id: string;
24
- observed_agent_id: string;
25
- observer_agent_id: string;
26
- observer_public_key: string;
27
- observer_display_name: string;
28
- observed_at: number;
29
- signature: string;
30
- };
31
- export type SocialMessageGovernanceConfig = {
32
- send_limit_max: number;
33
- send_window_ms: number;
34
- receive_limit_max: number;
35
- receive_window_ms: number;
36
- duplicate_window_ms: number;
37
- blocked_agent_ids: string[];
38
- blocked_terms: string[];
39
- };
40
- export declare class IdentityRepo extends JsonFileRepo<AgentIdentity | null> {
41
- constructor(rootDir?: string);
42
- }
43
- export declare class ProfileRepo extends JsonFileRepo<PublicProfile | null> {
44
- constructor(rootDir?: string);
45
- }
46
- export declare class CacheRepo extends JsonFileRepo<DirectoryState> {
47
- constructor(rootDir?: string);
48
- }
49
- export declare class LogRepo extends JsonFileRepo<LogEntry[]> {
50
- constructor(rootDir?: string);
51
- append(entry: Omit<LogEntry, "id">): Promise<void>;
52
- }
53
- export declare class SocialMessageRepo extends JsonFileRepo<SocialMessageRecord[]> {
54
- constructor(rootDir?: string);
55
- }
56
- export declare class SocialMessageObservationRepo extends JsonFileRepo<SocialMessageObservationRecord[]> {
57
- constructor(rootDir?: string);
58
- }
59
- export declare class SocialMessageGovernanceRepo extends JsonFileRepo<SocialMessageGovernanceConfig> {
60
- constructor(rootDir?: string);
61
- }