hajimi-claw 0.1.1 → 0.1.3

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 (51) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +74 -1
  3. package/bin/hajimi-claw.js +77 -3
  4. package/config.example.toml +3 -0
  5. package/npm/platforms/linux-arm64-gnu/LICENSE +1 -0
  6. package/npm/platforms/linux-arm64-gnu/README.md +3 -0
  7. package/npm/platforms/linux-arm64-gnu/bin/.gitkeep +1 -0
  8. package/npm/platforms/linux-arm64-gnu/index.js +3 -0
  9. package/npm/platforms/linux-arm64-gnu/package.json +21 -0
  10. package/npm/platforms/linux-x64-gnu/LICENSE +1 -0
  11. package/npm/platforms/linux-x64-gnu/README.md +3 -0
  12. package/npm/platforms/linux-x64-gnu/bin/.gitkeep +1 -0
  13. package/npm/platforms/linux-x64-gnu/index.js +3 -0
  14. package/npm/platforms/linux-x64-gnu/package.json +21 -0
  15. package/npm/platforms/win32-arm64-msvc/LICENSE +1 -0
  16. package/npm/platforms/win32-arm64-msvc/README.md +3 -0
  17. package/npm/platforms/win32-arm64-msvc/bin/.gitkeep +1 -0
  18. package/npm/platforms/win32-arm64-msvc/index.js +3 -0
  19. package/npm/platforms/win32-arm64-msvc/package.json +18 -0
  20. package/npm/platforms/win32-x64-msvc/LICENSE +1 -0
  21. package/npm/platforms/win32-x64-msvc/README.md +3 -0
  22. package/npm/platforms/win32-x64-msvc/bin/.gitkeep +1 -0
  23. package/npm/platforms/win32-x64-msvc/index.js +3 -0
  24. package/npm/platforms/win32-x64-msvc/package.json +18 -0
  25. package/package.json +19 -13
  26. package/scripts/stage-prebuilt.js +91 -0
  27. package/scripts/sync-npm-versions.js +46 -0
  28. package/Cargo.lock +0 -2762
  29. package/Cargo.toml +0 -60
  30. package/crates/hajimi-claw-agent/Cargo.toml +0 -26
  31. package/crates/hajimi-claw-agent/src/lib.rs +0 -983
  32. package/crates/hajimi-claw-bot/Cargo.toml +0 -22
  33. package/crates/hajimi-claw-bot/src/lib.rs +0 -1345
  34. package/crates/hajimi-claw-daemon/Cargo.toml +0 -30
  35. package/crates/hajimi-claw-daemon/src/lib.rs +0 -1874
  36. package/crates/hajimi-claw-exec/Cargo.toml +0 -21
  37. package/crates/hajimi-claw-exec/src/lib.rs +0 -419
  38. package/crates/hajimi-claw-gateway/Cargo.toml +0 -27
  39. package/crates/hajimi-claw-gateway/src/lib.rs +0 -1359
  40. package/crates/hajimi-claw-llm/Cargo.toml +0 -19
  41. package/crates/hajimi-claw-llm/src/lib.rs +0 -416
  42. package/crates/hajimi-claw-policy/Cargo.toml +0 -14
  43. package/crates/hajimi-claw-policy/src/lib.rs +0 -404
  44. package/crates/hajimi-claw-store/Cargo.toml +0 -17
  45. package/crates/hajimi-claw-store/src/lib.rs +0 -785
  46. package/crates/hajimi-claw-tools/Cargo.toml +0 -21
  47. package/crates/hajimi-claw-tools/src/lib.rs +0 -869
  48. package/crates/hajimi-claw-types/Cargo.toml +0 -16
  49. package/crates/hajimi-claw-types/src/lib.rs +0 -303
  50. package/scripts/npm-install.js +0 -45
  51. package/src/main.rs +0 -4
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Dongshan_Randeng
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dongshan_Randeng
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
package/README.md CHANGED
@@ -60,7 +60,67 @@ The Linux installer copies the binary to `PREFIX/bin/hajimi-claw`, creates the `
60
60
  - Global install from the repo:
61
61
  `npm install -g .`
62
62
 
63
- The npm package exposes both `hajimi` and `hajimi-claw`, and builds the Rust binary locally during `postinstall`, so `cargo` must already be installed on the target machine.
63
+ The npm package exposes both `hajimi` and `hajimi-claw`, but it no longer compiles Rust during
64
+ install. Instead:
65
+
66
+ - The root package is a small launcher package
67
+ - Platform-specific binaries are published as optional npm packages
68
+ - `npm install -g hajimi-claw` installs the matching prebuilt binary package when one is available
69
+
70
+ Supported prebuilt package names:
71
+
72
+ - `hajimi-claw-win32-x64-msvc`
73
+ - `hajimi-claw-win32-arm64-msvc`
74
+ - `hajimi-claw-linux-x64-gnu`
75
+ - `hajimi-claw-linux-arm64-gnu`
76
+
77
+ For local testing from the repo, stage a binary into the local platform package first:
78
+
79
+ ```bash
80
+ cargo build --release
81
+ npm run stage:binary
82
+ npm install -g .
83
+ ```
84
+
85
+ For CI or release staging, you can target a specific package explicitly:
86
+
87
+ ```bash
88
+ node scripts/stage-prebuilt.js win32-x64-msvc path/to/hajimi-claw.exe
89
+ node scripts/stage-prebuilt.js linux-x64-gnu path/to/hajimi-claw
90
+ ```
91
+
92
+ Recommended publish order:
93
+
94
+ 1. Build each platform binary in CI
95
+ 2. Stage it into the matching `npm/platforms/<target>/bin/`
96
+ 3. Publish each platform package
97
+ 4. Publish the root `hajimi-claw` package last
98
+
99
+ Current GitHub Actions automation is wired for:
100
+
101
+ - `hajimi-claw-win32-x64-msvc`
102
+ - `hajimi-claw-linux-x64-gnu`
103
+
104
+ The arm64 package skeletons are present in the repo, but they are not yet part of the automated
105
+ publish matrix.
106
+
107
+ ## npm Versioning
108
+
109
+ For npm releases, the root `package.json` is the single version source.
110
+
111
+ When you change `package.json.version`, run:
112
+
113
+ ```bash
114
+ npm run sync:npm-versions
115
+ ```
116
+
117
+ That script updates:
118
+
119
+ - the root package `optionalDependencies`
120
+ - every platform package version under `npm/platforms/*/package.json`
121
+
122
+ The release workflow also runs this sync step automatically, so you do not need to edit platform
123
+ package versions by hand.
64
124
 
65
125
  ## Channels
66
126
 
@@ -82,6 +142,16 @@ Current Feishu limitations:
82
142
  ## CLI
83
143
 
84
144
  - `hajimi`
145
+ - `hajimi ask <prompt>`
146
+ - `hajimi tasks`
147
+ - `hajimi approvals`
148
+ - `hajimi approve <request-id>`
149
+ - `hajimi shell open [name]`
150
+ - `hajimi shell status <session-id>`
151
+ - `hajimi shell exec <session-id> <command>`
152
+ - `hajimi shell close <session-id>`
153
+ - `hajimi profile show`
154
+ - `hajimi profile use <ops-safe|dev-agent|computer-use>`
85
155
  - `hajimi daemon`
86
156
  - `hajimi launch`
87
157
  - `hajimi stop`
@@ -98,6 +168,9 @@ Current Feishu limitations:
98
168
  - `hajimi restart`
99
169
  - `hajimi help`
100
170
 
171
+ `hajimi ask` now records task state and tool invocations in SQLite. If a guarded command blocks on
172
+ approval, `hajimi approve <request-id>` resumes the blocked task instead of asking you to rerun it.
173
+
101
174
  ## Multi-Agent
102
175
 
103
176
  `hajimi` can split one natural-language request into multiple sub-agents. This is configured in
@@ -6,11 +6,85 @@ const { spawn } = require("child_process");
6
6
 
7
7
  const root = path.resolve(__dirname, "..");
8
8
  const binaryName = process.platform === "win32" ? "hajimi-claw.exe" : "hajimi-claw";
9
- const binaryPath = path.join(root, "npm-dist", binaryName);
10
9
 
11
- if (!fs.existsSync(binaryPath)) {
10
+ function detectLinuxLibc() {
11
+ if (process.platform !== "linux") {
12
+ return null;
13
+ }
14
+ const report = process.report && typeof process.report.getReport === "function"
15
+ ? process.report.getReport()
16
+ : null;
17
+ const glibc = report && report.header && report.header.glibcVersionRuntime;
18
+ return glibc ? "gnu" : "musl";
19
+ }
20
+
21
+ function platformPackageName() {
22
+ if (process.platform === "win32" && process.arch === "x64") {
23
+ return "hajimi-claw-win32-x64-msvc";
24
+ }
25
+ if (process.platform === "win32" && process.arch === "arm64") {
26
+ return "hajimi-claw-win32-arm64-msvc";
27
+ }
28
+ const libc = detectLinuxLibc();
29
+ if (process.platform === "linux" && process.arch === "x64" && libc === "gnu") {
30
+ return "hajimi-claw-linux-x64-gnu";
31
+ }
32
+ if (process.platform === "linux" && process.arch === "arm64" && libc === "gnu") {
33
+ return "hajimi-claw-linux-arm64-gnu";
34
+ }
35
+ return null;
36
+ }
37
+
38
+ function resolveInstalledBinary() {
39
+ const packageName = platformPackageName();
40
+ if (!packageName) {
41
+ return null;
42
+ }
43
+ try {
44
+ const entry = require.resolve(packageName, { paths: [root] });
45
+ const binaryPath = require(entry);
46
+ if (typeof binaryPath === "string" && fs.existsSync(binaryPath)) {
47
+ return binaryPath;
48
+ }
49
+ } catch (_) {
50
+ return null;
51
+ }
52
+ return null;
53
+ }
54
+
55
+ function resolveLocalFallback() {
56
+ const localDirMap = {
57
+ "hajimi-claw-win32-x64-msvc": "win32-x64-msvc",
58
+ "hajimi-claw-win32-arm64-msvc": "win32-arm64-msvc",
59
+ "hajimi-claw-linux-x64-gnu": "linux-x64-gnu",
60
+ "hajimi-claw-linux-arm64-gnu": "linux-arm64-gnu",
61
+ };
62
+ const packageName = platformPackageName();
63
+ const candidates = [];
64
+ if (process.env.HAJIMI_CLAW_BINARY_PATH) {
65
+ candidates.push(process.env.HAJIMI_CLAW_BINARY_PATH);
66
+ }
67
+ if (packageName && localDirMap[packageName]) {
68
+ candidates.push(
69
+ path.join(root, "npm", "platforms", localDirMap[packageName], "bin", binaryName)
70
+ );
71
+ }
72
+ candidates.push(path.join(root, "npm-dist", binaryName));
73
+ candidates.push(path.join(root, "target", "release", binaryName));
74
+ return candidates.find((candidate) => fs.existsSync(candidate)) || null;
75
+ }
76
+
77
+ const binaryPath = resolveInstalledBinary() || resolveLocalFallback();
78
+
79
+ if (!binaryPath) {
80
+ const packageName = platformPackageName();
81
+ const targetLabel = packageName || `${process.platform}-${process.arch}`;
12
82
  console.error(
13
- "hajimi-claw binary is not installed. Reinstall the npm package or run `npm rebuild hajimi-claw`."
83
+ [
84
+ `No prebuilt hajimi binary is available for ${targetLabel}.`,
85
+ "Install a published platform package, or stage a local binary with `npm run stage:binary`.",
86
+ "If you are publishing releases, publish the matching platform package before the root package."
87
+ ].join("\n")
14
88
  );
15
89
  process.exit(1);
16
90
  }
@@ -34,6 +34,9 @@ master_key_env = "HAJIMI_CLAW_MASTER_KEY"
34
34
 
35
35
  [execution]
36
36
  mode = "auto"
37
+ profile = "ops-safe"
38
+ browser_enabled = false
39
+ computer_enabled = false
37
40
 
38
41
  [multi_agent]
39
42
  enabled = true
@@ -0,0 +1 @@
1
+ MIT
@@ -0,0 +1,3 @@
1
+ # hajimi-claw-linux-arm64-gnu
2
+
3
+ Prebuilt Linux arm64 glibc binary package for `hajimi-claw`.
@@ -0,0 +1,3 @@
1
+ const path = require("path");
2
+
3
+ module.exports = path.join(__dirname, "bin", "hajimi-claw");
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "hajimi-claw-linux-arm64-gnu",
3
+ "version": "0.1.3",
4
+ "description": "Prebuilt Linux arm64 glibc binary for hajimi-claw",
5
+ "os": [
6
+ "linux"
7
+ ],
8
+ "cpu": [
9
+ "arm64"
10
+ ],
11
+ "libc": [
12
+ "glibc"
13
+ ],
14
+ "files": [
15
+ "bin",
16
+ "index.js",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "license": "MIT"
21
+ }
@@ -0,0 +1 @@
1
+ MIT
@@ -0,0 +1,3 @@
1
+ # hajimi-claw-linux-x64-gnu
2
+
3
+ Prebuilt Linux x64 glibc binary package for `hajimi-claw`.
@@ -0,0 +1,3 @@
1
+ const path = require("path");
2
+
3
+ module.exports = path.join(__dirname, "bin", "hajimi-claw");
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "hajimi-claw-linux-x64-gnu",
3
+ "version": "0.1.3",
4
+ "description": "Prebuilt Linux x64 glibc binary for hajimi-claw",
5
+ "os": [
6
+ "linux"
7
+ ],
8
+ "cpu": [
9
+ "x64"
10
+ ],
11
+ "libc": [
12
+ "glibc"
13
+ ],
14
+ "files": [
15
+ "bin",
16
+ "index.js",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "license": "MIT"
21
+ }
@@ -0,0 +1 @@
1
+ MIT
@@ -0,0 +1,3 @@
1
+ # hajimi-claw-win32-arm64-msvc
2
+
3
+ Prebuilt Windows arm64 binary package for `hajimi-claw`.
@@ -0,0 +1,3 @@
1
+ const path = require("path");
2
+
3
+ module.exports = path.join(__dirname, "bin", "hajimi-claw.exe");
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "hajimi-claw-win32-arm64-msvc",
3
+ "version": "0.1.3",
4
+ "description": "Prebuilt Windows arm64 binary for hajimi-claw",
5
+ "os": [
6
+ "win32"
7
+ ],
8
+ "cpu": [
9
+ "arm64"
10
+ ],
11
+ "files": [
12
+ "bin",
13
+ "index.js",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "license": "MIT"
18
+ }
@@ -0,0 +1 @@
1
+ MIT
@@ -0,0 +1,3 @@
1
+ # hajimi-claw-win32-x64-msvc
2
+
3
+ Prebuilt Windows x64 binary package for `hajimi-claw`.
@@ -0,0 +1,3 @@
1
+ const path = require("path");
2
+
3
+ module.exports = path.join(__dirname, "bin", "hajimi-claw.exe");
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "hajimi-claw-win32-x64-msvc",
3
+ "version": "0.1.3",
4
+ "description": "Prebuilt Windows x64 binary for hajimi-claw",
5
+ "os": [
6
+ "win32"
7
+ ],
8
+ "cpu": [
9
+ "x64"
10
+ ],
11
+ "files": [
12
+ "bin",
13
+ "index.js",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "license": "MIT"
18
+ }
package/package.json CHANGED
@@ -1,27 +1,33 @@
1
1
  {
2
2
  "name": "hajimi-claw",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Single-user Telegram-first ops agent in Rust",
5
5
  "bin": {
6
6
  "hajimi": "bin/hajimi-claw.js",
7
7
  "hajimi-claw": "bin/hajimi-claw.js"
8
8
  },
9
+ "preferGlobal": true,
10
+ "license": "MIT",
11
+ "engines": {
12
+ "node": ">=18"
13
+ },
14
+ "optionalDependencies": {
15
+ "hajimi-claw-linux-arm64-gnu": "0.1.3",
16
+ "hajimi-claw-linux-x64-gnu": "0.1.3",
17
+ "hajimi-claw-win32-arm64-msvc": "0.1.3",
18
+ "hajimi-claw-win32-x64-msvc": "0.1.3"
19
+ },
9
20
  "files": [
10
- "Cargo.toml",
11
- "Cargo.lock",
12
- "src",
13
- "crates",
14
21
  "bin",
15
- "scripts/npm-install.js",
22
+ "npm/platforms",
23
+ "scripts/sync-npm-versions.js",
24
+ "scripts/stage-prebuilt.js",
16
25
  "config.example.toml",
17
- "README.md"
26
+ "README.md",
27
+ "LICENSE"
18
28
  ],
19
29
  "scripts": {
20
- "postinstall": "node scripts/npm-install.js"
21
- },
22
- "preferGlobal": true,
23
- "license": "MIT",
24
- "engines": {
25
- "node": ">=18"
30
+ "sync:npm-versions": "node scripts/sync-npm-versions.js",
31
+ "stage:binary": "npm run sync:npm-versions && node scripts/stage-prebuilt.js"
26
32
  }
27
33
  }
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ const root = path.resolve(__dirname, "..");
7
+
8
+ const TARGETS = {
9
+ "win32-x64-msvc": {
10
+ packageName: "hajimi-claw-win32-x64-msvc",
11
+ dir: path.join(root, "npm", "platforms", "win32-x64-msvc"),
12
+ binaryName: "hajimi-claw.exe",
13
+ },
14
+ "win32-arm64-msvc": {
15
+ packageName: "hajimi-claw-win32-arm64-msvc",
16
+ dir: path.join(root, "npm", "platforms", "win32-arm64-msvc"),
17
+ binaryName: "hajimi-claw.exe",
18
+ },
19
+ "linux-x64-gnu": {
20
+ packageName: "hajimi-claw-linux-x64-gnu",
21
+ dir: path.join(root, "npm", "platforms", "linux-x64-gnu"),
22
+ binaryName: "hajimi-claw",
23
+ },
24
+ "linux-arm64-gnu": {
25
+ packageName: "hajimi-claw-linux-arm64-gnu",
26
+ dir: path.join(root, "npm", "platforms", "linux-arm64-gnu"),
27
+ binaryName: "hajimi-claw",
28
+ },
29
+ };
30
+
31
+ function fail(message) {
32
+ console.error(message);
33
+ process.exit(1);
34
+ }
35
+
36
+ function detectLinuxLibc() {
37
+ if (process.platform !== "linux") {
38
+ return null;
39
+ }
40
+ const report = process.report && typeof process.report.getReport === "function"
41
+ ? process.report.getReport()
42
+ : null;
43
+ const glibc = report && report.header && report.header.glibcVersionRuntime;
44
+ return glibc ? "gnu" : "musl";
45
+ }
46
+
47
+ function currentTarget() {
48
+ if (process.platform === "win32" && process.arch === "x64") {
49
+ return "win32-x64-msvc";
50
+ }
51
+ if (process.platform === "win32" && process.arch === "arm64") {
52
+ return "win32-arm64-msvc";
53
+ }
54
+ const libc = detectLinuxLibc();
55
+ if (process.platform === "linux" && process.arch === "x64" && libc === "gnu") {
56
+ return "linux-x64-gnu";
57
+ }
58
+ if (process.platform === "linux" && process.arch === "arm64" && libc === "gnu") {
59
+ return "linux-arm64-gnu";
60
+ }
61
+ return null;
62
+ }
63
+
64
+ const targetId = process.argv[2] || process.env.HAJIMI_NPM_TARGET || currentTarget();
65
+ if (!targetId || !TARGETS[targetId]) {
66
+ fail(
67
+ `unsupported or missing target. Supported targets: ${Object.keys(TARGETS).join(", ")}`
68
+ );
69
+ }
70
+
71
+ const target = TARGETS[targetId];
72
+ const sourceBinary =
73
+ process.argv[3] ||
74
+ process.env.HAJIMI_BINARY_PATH ||
75
+ path.join(root, "target", "release", target.binaryName);
76
+
77
+ if (!fs.existsSync(sourceBinary)) {
78
+ fail(`source binary not found: ${sourceBinary}`);
79
+ }
80
+
81
+ const outputDir = path.join(target.dir, "bin");
82
+ const outputBinary = path.join(outputDir, target.binaryName);
83
+ fs.mkdirSync(outputDir, { recursive: true });
84
+ fs.copyFileSync(sourceBinary, outputBinary);
85
+ if (target.binaryName.endsWith(".exe") === false) {
86
+ fs.chmodSync(outputBinary, 0o755);
87
+ }
88
+
89
+ console.log(`staged ${target.packageName}`);
90
+ console.log(`source: ${sourceBinary}`);
91
+ console.log(`dest: ${outputBinary}`);
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ const root = path.resolve(__dirname, "..");
7
+ const rootPackagePath = path.join(root, "package.json");
8
+ const platformsRoot = path.join(root, "npm", "platforms");
9
+
10
+ function readJson(filePath) {
11
+ return JSON.parse(fs.readFileSync(filePath, "utf8"));
12
+ }
13
+
14
+ function writeJson(filePath, value) {
15
+ fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
16
+ }
17
+
18
+ const rootPackage = readJson(rootPackagePath);
19
+ const version = rootPackage.version;
20
+
21
+ const platformDirs = fs
22
+ .readdirSync(platformsRoot, { withFileTypes: true })
23
+ .filter((entry) => entry.isDirectory())
24
+ .map((entry) => path.join(platformsRoot, entry.name));
25
+
26
+ const optionalDependencies = {
27
+ ...(rootPackage.optionalDependencies || {}),
28
+ };
29
+
30
+ for (const dir of platformDirs) {
31
+ const packagePath = path.join(dir, "package.json");
32
+ const manifest = readJson(packagePath);
33
+ manifest.version = version;
34
+ writeJson(packagePath, manifest);
35
+ optionalDependencies[manifest.name] = version;
36
+ }
37
+
38
+ rootPackage.optionalDependencies = Object.fromEntries(
39
+ Object.entries(optionalDependencies).sort(([left], [right]) =>
40
+ left.localeCompare(right)
41
+ )
42
+ );
43
+
44
+ writeJson(rootPackagePath, rootPackage);
45
+
46
+ console.log(`Synced npm package versions to ${version}`);