@sleep2agi/tmcode 1.17.4 → 1.18.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 +27 -16
  2. package/package.json +14 -5
  3. package/postinstall.mjs +55 -12
package/README.md CHANGED
@@ -1,31 +1,42 @@
1
1
  # @sleep2agi/tmcode (scoped alias)
2
2
 
3
- > **`@sleep2agi/tmcode` is a scoped alias of [`tmcode-ai`](https://www.npmjs.com/package/tmcode-ai).**
4
- >
5
- > Same wrapper, same binary, same CLI command (`tmcode`). Published as a scoped
6
- > name to give users another way to install while we wait for npm support to
7
- > release the bare name `tmcode` (currently blocked by a similarity-gate
8
- > false-positive — see [GitHub issue](https://github.com/sleep2agi/tmcode)).
3
+ > Scoped alias of [`tianma-ai`](https://www.npmjs.com/package/tianma-ai)
4
+ > (天马, the primary npm name). Same wrapper, same binary, same CLI command
5
+ > (`tmcode`).
9
6
 
10
- ## Three install paths (pick any)
7
+ ## Install
11
8
 
12
9
  ```bash
13
- # 1) Default (recommended) — matches upstream opencode-ai naming
10
+ npm install -g @sleep2agi/tmcode
11
+ ```
12
+
13
+ Then run:
14
+
15
+ ```bash
16
+ tmcode
17
+ ```
18
+
19
+ ## Equivalent install commands
20
+
21
+ ```bash
22
+ # Primary (recommended)
23
+ npm install -g tianma-ai
24
+
25
+ # Pattern-match upstream opencode-ai
14
26
  npm install -g tmcode-ai
15
27
 
16
- # 2) Scoped alias — same wrapper, scoped npm name
28
+ # This package (scoped fallback)
17
29
  npm install -g @sleep2agi/tmcode
18
30
 
19
- # 3) Bare name (pending npm support review)
20
- # npm install -g tmcode ← currently 403, in review
31
+ # Bare name (pending npm support review)
32
+ # npm install -g tmcode ← currently 403
21
33
  ```
22
34
 
23
- All three install the same `tmcode` CLI command. The binary is opencode 1.17.4
24
- unmodified (v0 wrapper-only release). A v1 deep source rebuild is in progress.
35
+ All four install the same `tmcode` 1.18.0 binary (opencode 1.17.4
36
+ source-rebuilt with renamed config dirs at `~/.config/tmcode`).
25
37
 
26
- See the [main repo](https://github.com/sleep2agi/tmcode) for full attribution
27
- and v1 plan.
38
+ See <https://github.com/sleep2agi/tmcode> for the full story.
28
39
 
29
40
  ## License
30
41
 
31
- MIT — same as upstream opencode.
42
+ MIT.
package/package.json CHANGED
@@ -6,16 +6,25 @@
6
6
  "scripts": {
7
7
  "postinstall": "node ./postinstall.mjs"
8
8
  },
9
- "version": "1.17.4",
10
- "description": "tmcode v0 (scoped) = opencode 1.17.4 renamed distribution. Same wrapper as tmcode-ai, scoped alias.",
9
+ "version": "1.18.0",
10
+ "description": "tmcode v1 (scoped alias) = opencode 1.17.4 source-rebuilt distribution. Same as tianma-ai / tmcode-ai.",
11
11
  "license": "MIT",
12
12
  "homepage": "https://github.com/sleep2agi/tmcode",
13
13
  "repository": { "type": "git", "url": "https://github.com/sleep2agi/tmcode.git" },
14
14
  "os": ["darwin", "linux", "win32"],
15
15
  "cpu": ["arm64", "x64"],
16
16
  "optionalDependencies": {
17
- "tmcode-darwin-arm64": "1.17.4",
18
- "tmcode-linux-x64": "1.17.4",
19
- "tmcode-windows-x64": "1.17.4"
17
+ "tmcode-darwin-arm64": "1.18.0",
18
+ "tmcode-darwin-x64": "1.18.0",
19
+ "tmcode-darwin-x64-baseline": "1.18.0",
20
+ "tmcode-linux-arm64": "1.18.0",
21
+ "tmcode-linux-arm64-musl": "1.18.0",
22
+ "tmcode-linux-x64": "1.18.0",
23
+ "tmcode-linux-x64-baseline": "1.18.0",
24
+ "tmcode-linux-x64-baseline-musl": "1.18.0",
25
+ "tmcode-linux-x64-musl": "1.18.0",
26
+ "tmcode-windows-arm64": "1.18.0",
27
+ "tmcode-windows-x64": "1.18.0",
28
+ "tmcode-windows-x64-baseline": "1.18.0"
20
29
  }
21
30
  }
package/postinstall.mjs CHANGED
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env node
2
- // tmcode v0 postinstall — copies the platform-specific binary
3
- // (from `tmcode-<platform>-<arch>` optional dependency) into
4
- // `bin/tmcode.exe`. Mirrors upstream opencode's pattern; the
5
- // binary itself is opencode 1.17.4 unmodified pending v1 deep
6
- // rebrand.
2
+ // tmcode v1 postinstall — locates the platform-specific binary from the
3
+ // `tmcode-<base>` optional dependency (matching upstream opencode's
4
+ // resolution strategy with avx2/musl variants) and copies it to
5
+ // `bin/tmcode.exe` so the npm `bin` field resolves cleanly across
6
+ // platforms.
7
7
 
8
+ import childProcess from "child_process"
8
9
  import fs from "fs"
9
10
  import os from "os"
10
11
  import path from "path"
@@ -23,19 +24,61 @@ const base = `tmcode-${platform}-${arch}`
23
24
  const sourceBinary = platform === "windows" ? "tmcode.exe" : "tmcode"
24
25
  const targetBinary = path.join(__dirname, "bin", "tmcode.exe")
25
26
 
27
+ function supportsAvx2() {
28
+ if (arch !== "x64") return false
29
+ if (platform === "linux") {
30
+ try {
31
+ return /(^|\s)avx2(\s|$)/i.test(fs.readFileSync("/proc/cpuinfo", "utf8"))
32
+ } catch {
33
+ return false
34
+ }
35
+ }
36
+ if (platform === "darwin") {
37
+ try {
38
+ const r = childProcess.spawnSync("sysctl", ["-n", "hw.optional.avx2_0"], { encoding: "utf8", timeout: 1500 })
39
+ return r.status === 0 && (r.stdout || "").trim() === "1"
40
+ } catch { return false }
41
+ }
42
+ return false // windows: skip the heavyweight powershell probe in postinstall, prefer the avx2 variant
43
+ }
44
+
45
+ function muslLinux() {
46
+ if (platform !== "linux") return false
47
+ try { if (fs.existsSync("/etc/alpine-release")) return true } catch {}
48
+ try {
49
+ const r = childProcess.spawnSync("ldd", ["--version"], { encoding: "utf8" })
50
+ return ((r.stdout || "") + (r.stderr || "")).toLowerCase().includes("musl")
51
+ } catch { return false }
52
+ }
53
+
54
+ const baseline = arch === "x64" && !supportsAvx2()
55
+ const musl = muslLinux()
56
+ const candidates = []
57
+ if (musl && baseline) candidates.push(`${base}-baseline-musl`, `${base}-musl`, `${base}-baseline`, base)
58
+ else if (musl) candidates.push(`${base}-musl`, base)
59
+ else if (baseline) candidates.push(`${base}-baseline`, base)
60
+ else candidates.push(base)
61
+
26
62
  let resolved
27
- try {
28
- resolved = require.resolve(`${base}/package.json`)
29
- } catch (e) {
30
- console.error(`tmcode: no prebuilt binary for ${platform}/${arch}.`)
31
- console.error(` Tried to load: ${base}`)
32
- console.error(` Supported platforms (v0): darwin-arm64, linux-x64, windows-x64`)
63
+ let usedName
64
+ for (const name of candidates) {
65
+ try {
66
+ resolved = require.resolve(`${name}/package.json`)
67
+ usedName = name
68
+ break
69
+ } catch {}
70
+ }
71
+
72
+ if (!resolved) {
73
+ console.error(`tmcode: no prebuilt binary found for ${platform}/${arch}.`)
74
+ console.error(` Tried: ${candidates.join(", ")}`)
75
+ console.error(` Supported v1 platforms: darwin-arm64, darwin-x64, linux-x64 (glibc/musl/baseline), linux-arm64 (glibc/musl), windows-x64, windows-arm64`)
33
76
  process.exit(0)
34
77
  }
35
78
 
36
79
  const sourcePath = path.join(path.dirname(resolved), "bin", sourceBinary)
37
80
  if (!fs.existsSync(sourcePath)) {
38
- console.error(`tmcode: binary missing in ${base}: ${sourcePath}`)
81
+ console.error(`tmcode: binary missing in ${usedName}: ${sourcePath}`)
39
82
  process.exit(0)
40
83
  }
41
84