@journeykit/canon 0.1.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.
- package/bin.js +2 -0
- package/dist/index.js +154 -0
- package/package.json +44 -0
package/bin.js
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { spawnSync, execSync } from "node:child_process";
|
|
5
|
+
import { existsSync, readdirSync, realpathSync } from "node:fs";
|
|
6
|
+
import { resolve, join, basename } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
var binaryName = process.platform === "win32" ? "canon.exe" : "canon";
|
|
9
|
+
var currentDir = fileURLToPath(new URL(".", import.meta.url));
|
|
10
|
+
var dirName = basename(currentDir);
|
|
11
|
+
var isSubDir = dirName === "dist" || dirName === "src";
|
|
12
|
+
var cliDir = isSubDir ? resolve(currentDir, "..") : currentDir;
|
|
13
|
+
var scopeDir = resolve(cliDir, "..");
|
|
14
|
+
var workspaceRoot = resolve(scopeDir, "..");
|
|
15
|
+
function detectLibcKind() {
|
|
16
|
+
const override = process.env.CANON_LIBC?.trim().toLowerCase();
|
|
17
|
+
if (override === "musl")
|
|
18
|
+
return "musl";
|
|
19
|
+
if (override === "gnu" || override === "glibc")
|
|
20
|
+
return "gnu";
|
|
21
|
+
const report = process.report?.getReport?.();
|
|
22
|
+
if (report?.header?.glibcVersionRuntime) {
|
|
23
|
+
return "gnu";
|
|
24
|
+
}
|
|
25
|
+
if (Array.isArray(report?.sharedObjects) && report.sharedObjects.some((obj) => obj.toLowerCase().includes("musl"))) {
|
|
26
|
+
return "musl";
|
|
27
|
+
}
|
|
28
|
+
if (report?.header?.release?.sourceUrl?.toLowerCase().includes("musl")) {
|
|
29
|
+
return "musl";
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const output = execSync("ldd --version", {
|
|
33
|
+
encoding: "utf-8",
|
|
34
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
35
|
+
}).toLowerCase();
|
|
36
|
+
if (output.includes("musl"))
|
|
37
|
+
return "musl";
|
|
38
|
+
if (output.includes("glibc") || output.includes("gnu"))
|
|
39
|
+
return "gnu";
|
|
40
|
+
} catch (error) {
|
|
41
|
+
const { stdout, stderr } = error ?? {};
|
|
42
|
+
const combined = `${stdout ?? ""}
|
|
43
|
+
${stderr ?? ""}`.toLowerCase();
|
|
44
|
+
if (combined.includes("musl"))
|
|
45
|
+
return "musl";
|
|
46
|
+
if (combined.includes("glibc") || combined.includes("gnu"))
|
|
47
|
+
return "gnu";
|
|
48
|
+
}
|
|
49
|
+
const hasGnuLoader = loaderPresent("ld-linux-");
|
|
50
|
+
const hasMuslLoader = loaderPresent("ld-musl-");
|
|
51
|
+
if (hasGnuLoader !== hasMuslLoader)
|
|
52
|
+
return hasMuslLoader ? "musl" : "gnu";
|
|
53
|
+
if (hasGnuLoader && hasMuslLoader) {
|
|
54
|
+
return existsSync("/etc/alpine-release") ? "musl" : "gnu";
|
|
55
|
+
}
|
|
56
|
+
return "gnu";
|
|
57
|
+
}
|
|
58
|
+
function loaderPresent(prefix) {
|
|
59
|
+
for (const dir of ["/lib", "/lib64"]) {
|
|
60
|
+
try {
|
|
61
|
+
if (readdirSync(dir).some((entry) => entry.startsWith(prefix))) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
} catch {}
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
function resolveTargetPackageName() {
|
|
69
|
+
const arch = process.arch;
|
|
70
|
+
if (process.platform === "darwin") {
|
|
71
|
+
if (arch === "arm64")
|
|
72
|
+
return "core-darwin-arm64";
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
if (process.platform === "linux") {
|
|
76
|
+
const libc = detectLibcKind();
|
|
77
|
+
if (arch === "x64" && libc === "gnu")
|
|
78
|
+
return "core-linux-x64";
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
function resolveRustTargetTriple() {
|
|
84
|
+
const arch = process.arch;
|
|
85
|
+
if (process.platform === "darwin") {
|
|
86
|
+
if (arch === "arm64")
|
|
87
|
+
return "aarch64-apple-darwin";
|
|
88
|
+
if (arch === "x64")
|
|
89
|
+
return "x86_64-apple-darwin";
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
if (process.platform === "linux") {
|
|
93
|
+
const libc = detectLibcKind();
|
|
94
|
+
if (arch === "arm64") {
|
|
95
|
+
return libc === "musl" ? "aarch64-unknown-linux-musl" : "aarch64-unknown-linux-gnu";
|
|
96
|
+
}
|
|
97
|
+
if (arch === "x64") {
|
|
98
|
+
return libc === "musl" ? "x86_64-unknown-linux-musl" : "x86_64-unknown-linux-gnu";
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
if (process.platform === "win32") {
|
|
103
|
+
if (arch === "arm64")
|
|
104
|
+
return "aarch64-pc-windows-msvc";
|
|
105
|
+
if (arch === "x64")
|
|
106
|
+
return "x86_64-pc-windows-msvc";
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
var targetPackage = resolveTargetPackageName();
|
|
112
|
+
var rustTargetTriple = resolveRustTargetTriple();
|
|
113
|
+
var searchPaths = [];
|
|
114
|
+
if (rustTargetTriple) {
|
|
115
|
+
searchPaths.push(join(workspaceRoot, "target", rustTargetTriple, "release", binaryName));
|
|
116
|
+
}
|
|
117
|
+
searchPaths.push(join(workspaceRoot, "target", "release", binaryName));
|
|
118
|
+
searchPaths.push(join(cliDir, "bin", binaryName));
|
|
119
|
+
var scope = "@journeykit";
|
|
120
|
+
var platformBareName = targetPackage ? `canon-${targetPackage}` : null;
|
|
121
|
+
var platformPkgName = platformBareName ? `${scope}/${platformBareName}` : null;
|
|
122
|
+
if (targetPackage) {
|
|
123
|
+
searchPaths.push(join(workspaceRoot, "packages", targetPackage, "bin", binaryName));
|
|
124
|
+
}
|
|
125
|
+
if (platformBareName) {
|
|
126
|
+
searchPaths.push(join(scopeDir, platformBareName, "bin", binaryName), join(cliDir, "node_modules", scope, platformBareName, "bin", binaryName), join(scopeDir, "node_modules", scope, platformBareName, "bin", binaryName), join(workspaceRoot, "node_modules", scope, platformBareName, "bin", binaryName));
|
|
127
|
+
}
|
|
128
|
+
function tryRealpath(p) {
|
|
129
|
+
try {
|
|
130
|
+
return realpathSync(p);
|
|
131
|
+
} catch {
|
|
132
|
+
return p;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
var selfPaths = new Set([
|
|
136
|
+
tryRealpath(fileURLToPath(import.meta.url)),
|
|
137
|
+
tryRealpath(join(cliDir, "bin.js"))
|
|
138
|
+
]);
|
|
139
|
+
if (process.argv[1]) {
|
|
140
|
+
selfPaths.add(tryRealpath(process.argv[1]));
|
|
141
|
+
}
|
|
142
|
+
var binary = searchPaths.find((p) => existsSync(p) && !selfPaths.has(tryRealpath(p)));
|
|
143
|
+
if (!binary) {
|
|
144
|
+
console.error(`canon: no binary found for ${process.platform}/${process.arch}`);
|
|
145
|
+
if (platformPkgName) {
|
|
146
|
+
console.error(` expected optional package: ${platformPkgName}`);
|
|
147
|
+
} else {
|
|
148
|
+
console.error(" no @journeykit/canon-core-<platform> package exists for this platform/arch yet");
|
|
149
|
+
}
|
|
150
|
+
console.error(" build from source: cargo build --release -p canon-cli");
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
var result = spawnSync(binary, process.argv.slice(2), { stdio: "inherit" });
|
|
154
|
+
process.exit(result.status ?? 1);
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@journeykit/canon",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "canon — harness knowledge substrate. JS launcher: platform detection + native binary resolution.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"bin": {
|
|
9
|
+
"canon": "./bin.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin.js",
|
|
13
|
+
"dist/**/*"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"registry": "https://registry.npmjs.org/",
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/journeyWorker/canon.git",
|
|
22
|
+
"directory": "packages/cli"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "bun build src/index.ts --outdir dist --target node --format esm",
|
|
26
|
+
"dev": "bun src/index.ts",
|
|
27
|
+
"start": "node dist/index.js"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {},
|
|
30
|
+
"optionalDependencies": {
|
|
31
|
+
"@journeykit/canon-core-darwin-arm64": "0.1.0",
|
|
32
|
+
"@journeykit/canon-core-linux-x64": "0.1.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^20.0.0",
|
|
36
|
+
"typescript": "^5.0.0"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"canon",
|
|
40
|
+
"harness",
|
|
41
|
+
"spec-driven",
|
|
42
|
+
"cli"
|
|
43
|
+
]
|
|
44
|
+
}
|