enigma-cli 1.3.0 → 1.4.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/assets/skills/backend-policy/skill.json +1 -1
- package/assets/skills/ciphera-style-policy/skill.json +1 -1
- package/assets/skills/code-review-policy/skill.json +1 -1
- package/assets/skills/core-engineering-policy/skill.json +1 -1
- package/assets/skills/database-expert/skill.json +1 -1
- package/assets/skills/debugging-policy/skill.json +1 -1
- package/assets/skills/dependency-policy/skill.json +1 -1
- package/assets/skills/frontend-policy/skill.json +1 -1
- package/assets/skills/git-policy/skill.json +1 -1
- package/assets/skills/security-policy/skill.json +1 -1
- package/assets/skills/testing-policy/skill.json +1 -1
- package/assets/skills/validation-policy/skill.json +1 -1
- package/bin/checksums.json +6 -0
- package/bin/download.mjs +98 -0
- package/bin/enigma.mjs +67 -0
- package/bin/platform.mjs +78 -0
- package/bin/postinstall.mjs +31 -0
- package/package.json +10 -12
- package/dist/enigma.js +0 -2425
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Backend/API architecture: controller-service-repository layering, API and request optimization, server-side caching (Redis), and Zod boundary validation.",
|
|
6
|
-
"cliVersion": "1.
|
|
6
|
+
"cliVersion": "1.4.0",
|
|
7
7
|
"sha": "c442bc9e39a7710cb709ef2abb8d15ecd8aa16ed4f5c8af92b7af6877401cba4"
|
|
8
8
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"version": "1.1.1",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Ciphera code style conventions (formatting, naming, imports, comments, code-level anti-patterns; TypeScript-first, language-agnostic).",
|
|
6
|
-
"cliVersion": "1.
|
|
6
|
+
"cliVersion": "1.4.0",
|
|
7
7
|
"sha": "74f638aec13e8c93257fe1ad604c28b07e9a7c456796a4ceefcc99217d9e7039"
|
|
8
8
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Pre-delivery self-review gate, prioritized review dimensions, and change-quality criteria.",
|
|
6
|
-
"cliVersion": "1.
|
|
6
|
+
"cliVersion": "1.4.0",
|
|
7
7
|
"sha": "3d3bbe0602d5bbb4afe37648fe3c2fa39376b1bcbac5d8c441f01fad1e866ed0"
|
|
8
8
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"version": "1.4.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Core engineering execution policy and harness orchestration (highest-authority rules).",
|
|
6
|
-
"cliVersion": "1.
|
|
6
|
+
"cliVersion": "1.4.0",
|
|
7
7
|
"sha": "c9c69c59516794311cb7b306ed4d4ad971824de3689a39c2b86c7669c73f2e8b"
|
|
8
8
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Senior database architecture policy: query optimization, anti-duplication/normalization, scalability, and RGPD/GDPR encryption.",
|
|
6
|
-
"cliVersion": "1.
|
|
6
|
+
"cliVersion": "1.4.0",
|
|
7
7
|
"sha": "c4617ee8d1a57d9621c81bef3093e94de91f79eec0cc0ead41f6d18dd443e623"
|
|
8
8
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Reproduce-isolate-fix debugging methodology with root-cause discipline and regression verification.",
|
|
6
|
-
"cliVersion": "1.
|
|
6
|
+
"cliVersion": "1.4.0",
|
|
7
7
|
"sha": "14b0064c8b33a0dc85e51464b05005cf5801c756b1101789a6924b9548420f6b"
|
|
8
8
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Dependency and supply-chain security: lockfiles and reproducible installs, version pinning, vulnerability auditing, vetting/minimizing packages, vendoring, and SBOM/provenance.",
|
|
6
|
-
"cliVersion": "1.
|
|
6
|
+
"cliVersion": "1.4.0",
|
|
7
7
|
"sha": "6375d835c2aef2c9bd31ce116444dc3d796f510f9970a213aa3ac4696d7e21b9"
|
|
8
8
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"version": "1.1.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Frontend architecture: reusable components, abstraction thresholds, state management, and optimistic UI with rollback.",
|
|
6
|
-
"cliVersion": "1.
|
|
6
|
+
"cliVersion": "1.4.0",
|
|
7
7
|
"sha": "33fa1e9f667ef26203a3d6c892121efe12b0cddb706c195492fa97e080fba115"
|
|
8
8
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Application and AI-agent security: secrets, authn/authz (least privilege), OWASP Top 10, transport/crypto baseline, secure logging, and agent/MCP/tool-use safety.",
|
|
6
|
-
"cliVersion": "1.
|
|
6
|
+
"cliVersion": "1.4.0",
|
|
7
7
|
"sha": "9971e9d9127397d0152e89d24aad3191e2935e55a8483db7fd15f5d4d7a60e7a"
|
|
8
8
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Test strategy, coverage gates, deterministic tests, mocking discipline, and regression-first bug fixing.",
|
|
6
|
-
"cliVersion": "1.
|
|
6
|
+
"cliVersion": "1.4.0",
|
|
7
7
|
"sha": "d19fa8ec7985ed231478be504d3c80360897f555d0bc0624bea19c091f459fb0"
|
|
8
8
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Strict frontend + backend schema validation, schema consistency, and safe client-facing error handling.",
|
|
6
|
-
"cliVersion": "1.
|
|
6
|
+
"cliVersion": "1.4.0",
|
|
7
7
|
"sha": "a33622a2f810ee4cea39824cb1a7ca34b355a917d4224025df50d77dd74f0b3a"
|
|
8
8
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"enigma-darwin-arm64": "e1fa090b07a2cda913537376924b782768ae815d68564fa728153642b2ff139f",
|
|
3
|
+
"enigma-linux-arm64": "cb3223bd52e9c0ded2799f84de6f0f5ea470d33ec66f3ca7d11130396bd5f7c1",
|
|
4
|
+
"enigma-linux-x64": "4f27225470f9bf741c1a58731fb423fa42ecac607867a06f29bcdfb15004760a",
|
|
5
|
+
"enigma-win32-x64.exe": "cd877742df52d74d7a43580dbbc611b000691351fc29123375dae08abc87789f"
|
|
6
|
+
}
|
package/bin/download.mjs
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Download and install the host's Bun-compiled enigma binary from its GitHub
|
|
3
|
+
* Release, the way `npm i -g enigma-cli` obtains the native OpenTUI executable
|
|
4
|
+
* without shipping a per-platform npm package.
|
|
5
|
+
*
|
|
6
|
+
* Integrity: the binary is verified against the SHA256 recorded in bin/checksums.json,
|
|
7
|
+
* which is published INSIDE the npm tarball (covered by npm provenance), so the trust
|
|
8
|
+
* chain is tarball -> checksums.json -> downloaded binary. Downloads must be HTTPS and
|
|
9
|
+
* a checksum entry is mandatory - it fails closed if either is missing.
|
|
10
|
+
*
|
|
11
|
+
* Used by bin/postinstall.mjs (at install) and bin/enigma.mjs (lazy, first run when
|
|
12
|
+
* install scripts were skipped). Node builtins only.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { createHash } from "node:crypto";
|
|
16
|
+
import { chmodSync, existsSync, mkdirSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
17
|
+
import { dirname } from "node:path";
|
|
18
|
+
import {
|
|
19
|
+
ARCH,
|
|
20
|
+
PLATFORM,
|
|
21
|
+
assetName,
|
|
22
|
+
binTargetPath,
|
|
23
|
+
isWindows,
|
|
24
|
+
loadChecksums,
|
|
25
|
+
packageVersion,
|
|
26
|
+
platformKeys,
|
|
27
|
+
} from "./platform.mjs";
|
|
28
|
+
|
|
29
|
+
const DEFAULT_BASE = "https://github.com/FJRG2007/enigma/releases/download";
|
|
30
|
+
const DOWNLOAD_TIMEOUT_MS = 120_000;
|
|
31
|
+
|
|
32
|
+
/** Pick the first platform key with a published checksum. */
|
|
33
|
+
function selectAsset() {
|
|
34
|
+
const checksums = loadChecksums();
|
|
35
|
+
for (const key of platformKeys()) {
|
|
36
|
+
const asset = assetName(key);
|
|
37
|
+
if (checksums[asset]) return { asset, sha256: checksums[asset] };
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Resolve the release-asset URL, allowing an env override for mirrors/tests. */
|
|
43
|
+
function assetUrl(asset) {
|
|
44
|
+
const base = (process.env.ENIGMA_DOWNLOAD_BASE || `${DEFAULT_BASE}/v${packageVersion()}`).replace(/\/+$/, "");
|
|
45
|
+
const url = `${base}/${asset}`;
|
|
46
|
+
if (!url.startsWith("https://")) throw new Error(`Refusing non-HTTPS download URL: ${url}`);
|
|
47
|
+
return url;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Returns the installed binary path if already present, else null. */
|
|
51
|
+
export function installedBinary() {
|
|
52
|
+
const target = binTargetPath();
|
|
53
|
+
return existsSync(target) ? target : null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Download, verify and atomically install the binary. Returns its path.
|
|
58
|
+
* Throws on any failure (no checksum, network error, hash mismatch).
|
|
59
|
+
*/
|
|
60
|
+
export async function downloadBinary({ log = () => {} } = {}) {
|
|
61
|
+
const choice = selectAsset();
|
|
62
|
+
if (!choice) {
|
|
63
|
+
const tried = platformKeys().map(assetName).join(", ") || `${PLATFORM}-${ARCH}`;
|
|
64
|
+
throw new Error(`No prebuilt enigma binary is available for this platform (looked for: ${tried}).`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const url = assetUrl(choice.asset);
|
|
68
|
+
log(`Downloading ${choice.asset}...`);
|
|
69
|
+
|
|
70
|
+
const controller = new AbortController();
|
|
71
|
+
const timer = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS);
|
|
72
|
+
let buffer;
|
|
73
|
+
try {
|
|
74
|
+
const response = await fetch(url, { redirect: "follow", signal: controller.signal });
|
|
75
|
+
if (!response.ok) throw new Error(`HTTP ${response.status} fetching ${url}`);
|
|
76
|
+
buffer = Buffer.from(await response.arrayBuffer());
|
|
77
|
+
} finally {
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const actual = createHash("sha256").update(buffer).digest("hex");
|
|
82
|
+
if (actual !== choice.sha256) {
|
|
83
|
+
throw new Error(`Checksum mismatch for ${choice.asset}: expected ${choice.sha256}, got ${actual}.`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const target = binTargetPath();
|
|
87
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
88
|
+
const tmp = `${target}.download-${process.pid}`;
|
|
89
|
+
writeFileSync(tmp, buffer);
|
|
90
|
+
if (!isWindows) chmodSync(tmp, 0o755);
|
|
91
|
+
// rename is atomic on POSIX; on Windows it fails over an existing file, so drop it first.
|
|
92
|
+
if (existsSync(target)) {
|
|
93
|
+
try { unlinkSync(target); } catch { /* in use; rename will surface the error */ }
|
|
94
|
+
}
|
|
95
|
+
renameSync(tmp, target);
|
|
96
|
+
log(`Installed ${choice.asset} -> ${target}`);
|
|
97
|
+
return target;
|
|
98
|
+
}
|
package/bin/enigma.mjs
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* enigma launcher. This is the ONLY thing that runs under the user's Node: it locates
|
|
4
|
+
* the Bun-compiled binary for this platform and execs it. The binary embeds the Bun
|
|
5
|
+
* runtime plus the OpenTUI native core, so the rich TUI (with mouse) works on any npm
|
|
6
|
+
* install without the user having Bun.
|
|
7
|
+
*
|
|
8
|
+
* Distribution (opencode-style mechanism, single npm package): the binary is NOT an
|
|
9
|
+
* npm dependency. It is downloaded from the matching GitHub Release by the postinstall
|
|
10
|
+
* hook, or lazily here on first run if install scripts were skipped, and verified
|
|
11
|
+
* against bin/checksums.json (shipped in the tarball, covered by npm provenance).
|
|
12
|
+
*
|
|
13
|
+
* The app's assets (skills/memory) and the commit guard ship as REAL files in this
|
|
14
|
+
* package, not inside the binary. The binary reads them from disk via the env vars set
|
|
15
|
+
* here, since its own __dirname lives in Bun's virtual filesystem.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { spawn } from "node:child_process";
|
|
19
|
+
import { existsSync } from "node:fs";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import os from "node:os";
|
|
22
|
+
import { ARCH, PLATFORM, packageVersion, pkgRoot } from "./platform.mjs";
|
|
23
|
+
import { downloadBinary, installedBinary } from "./download.mjs";
|
|
24
|
+
|
|
25
|
+
/** Resolve the binary, downloading it on first run if the postinstall was skipped. */
|
|
26
|
+
async function resolveBinary() {
|
|
27
|
+
if (process.env.ENIGMA_BIN_PATH && existsSync(process.env.ENIGMA_BIN_PATH)) return process.env.ENIGMA_BIN_PATH;
|
|
28
|
+
const existing = installedBinary();
|
|
29
|
+
if (existing) return existing;
|
|
30
|
+
// Lazy path (e.g. `npm i --ignore-scripts`): fetch + verify before first use.
|
|
31
|
+
return downloadBinary({ log: (message) => process.stderr.write(`enigma: ${message}\n`) });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let binary;
|
|
35
|
+
try {
|
|
36
|
+
binary = await resolveBinary();
|
|
37
|
+
} catch (error) {
|
|
38
|
+
const platform = PLATFORM && ARCH ? `${PLATFORM}-${ARCH}` : `${os.platform()}-${os.arch()}`;
|
|
39
|
+
process.stderr.write(
|
|
40
|
+
`Could not obtain the enigma binary for ${platform}: ${error.message}\n` +
|
|
41
|
+
`Check your network/proxy, or set ENIGMA_BIN_PATH to a compatible binary.\n`,
|
|
42
|
+
);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Tell the binary where the on-disk assets, guard, and version live (its own
|
|
47
|
+
// __dirname points into Bun's virtual fs and cannot see these).
|
|
48
|
+
const env = { ...process.env };
|
|
49
|
+
env.ENIGMA_ASSETS_DIR ??= join(pkgRoot, "assets");
|
|
50
|
+
env.ENIGMA_GUARD_PATH ??= join(pkgRoot, "dist", "guard.js");
|
|
51
|
+
try {
|
|
52
|
+
env.ENIGMA_VERSION ??= packageVersion();
|
|
53
|
+
} catch { /* version is best-effort */ }
|
|
54
|
+
|
|
55
|
+
const child = spawn(binary, process.argv.slice(2), { stdio: "inherit", env });
|
|
56
|
+
|
|
57
|
+
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) {
|
|
58
|
+
process.on(signal, () => { try { child.kill(signal); } catch { /* already gone */ } });
|
|
59
|
+
}
|
|
60
|
+
child.on("error", (err) => {
|
|
61
|
+
process.stderr.write(`Failed to launch enigma binary: ${err.message}\n`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
|
64
|
+
child.on("exit", (code, signal) => {
|
|
65
|
+
if (signal) { try { process.kill(process.pid, signal); } catch { /* fall through */ } }
|
|
66
|
+
process.exit(code ?? 1);
|
|
67
|
+
});
|
package/bin/platform.mjs
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared platform identity for the single-package distribution model.
|
|
3
|
+
*
|
|
4
|
+
* enigma ships as ONE npm package (`enigma-cli`). The Bun-compiled binary for the
|
|
5
|
+
* host is NOT an npm dependency; it is downloaded from the matching GitHub Release
|
|
6
|
+
* (see bin/download.mjs) and verified against bin/checksums.json, which travels
|
|
7
|
+
* inside the npm tarball and is therefore covered by npm provenance.
|
|
8
|
+
*
|
|
9
|
+
* The launcher, the postinstall hook and the downloader all import this module so
|
|
10
|
+
* they agree on the platform key, the release asset name and the on-disk binary
|
|
11
|
+
* path. Node builtins only - no dependencies (it runs during install).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
15
|
+
import { dirname, join } from "node:path";
|
|
16
|
+
import { fileURLToPath } from "node:url";
|
|
17
|
+
import os from "node:os";
|
|
18
|
+
|
|
19
|
+
// npm/Node "os" identifiers (win32, not "windows"); kept stable across the toolchain.
|
|
20
|
+
const PLATFORMS = { win32: "win32", darwin: "darwin", linux: "linux" };
|
|
21
|
+
const ARCHES = { x64: "x64", arm64: "arm64" };
|
|
22
|
+
|
|
23
|
+
export const PLATFORM = PLATFORMS[os.platform()];
|
|
24
|
+
export const ARCH = ARCHES[os.arch()];
|
|
25
|
+
export const isWindows = PLATFORM === "win32";
|
|
26
|
+
|
|
27
|
+
/** This package's root (the directory holding package.json), i.e. <pkg>/bin/.. */
|
|
28
|
+
export const pkgRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
29
|
+
|
|
30
|
+
/** Detect musl libc (Alpine) so Linux can prefer a musl build when one exists. */
|
|
31
|
+
function isMusl() {
|
|
32
|
+
if (PLATFORM !== "linux") return false;
|
|
33
|
+
try {
|
|
34
|
+
// glibc runtimes expose glibcVersionRuntime in the process report; musl does not.
|
|
35
|
+
const header = process.report?.getReport()?.header;
|
|
36
|
+
return header ? !header.glibcVersionRuntime : false;
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Ordered platform keys to try for this host, most specific first. The downloader
|
|
44
|
+
* uses the first key that has a checksum entry, so a musl host falls back to the
|
|
45
|
+
* glibc build when no musl asset is published.
|
|
46
|
+
*/
|
|
47
|
+
export function platformKeys() {
|
|
48
|
+
if (!PLATFORM || !ARCH) return [];
|
|
49
|
+
const base = `${PLATFORM}-${ARCH}`;
|
|
50
|
+
if (PLATFORM === "linux" && isMusl()) return [`${base}-musl`, base];
|
|
51
|
+
return [base];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Release asset name for a platform key, e.g. "enigma-win32-x64.exe". */
|
|
55
|
+
export function assetName(key) {
|
|
56
|
+
return `enigma-${key}${isWindows ? ".exe" : ""}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** On-disk path of the installed binary inside this package's bin/ directory. */
|
|
60
|
+
export function binTargetPath() {
|
|
61
|
+
return join(pkgRoot, "bin", isWindows ? "enigma-bin.exe" : "enigma-bin");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** This package's declared version (release tag is `v<version>`). */
|
|
65
|
+
export function packageVersion() {
|
|
66
|
+
return JSON.parse(readFileSync(join(pkgRoot, "package.json"), "utf8")).version;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Parsed bin/checksums.json (asset name -> sha256 hex), or {} if absent. */
|
|
70
|
+
export function loadChecksums() {
|
|
71
|
+
const path = join(pkgRoot, "bin", "checksums.json");
|
|
72
|
+
if (!existsSync(path)) return {};
|
|
73
|
+
try {
|
|
74
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
75
|
+
} catch {
|
|
76
|
+
return {};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install-time hook: fetch the host's enigma binary from its GitHub Release.
|
|
3
|
+
*
|
|
4
|
+
* This is best-effort and NEVER fails the install. If the download fails (offline,
|
|
5
|
+
* proxy, unsupported platform) or scripts are skipped entirely (`npm i
|
|
6
|
+
* --ignore-scripts`), the launcher (bin/enigma.mjs) downloads on first run instead.
|
|
7
|
+
* That keeps `npm install` robust while still verifying the binary before use.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { loadChecksums } from "./platform.mjs";
|
|
11
|
+
import { downloadBinary, installedBinary } from "./download.mjs";
|
|
12
|
+
|
|
13
|
+
async function main() {
|
|
14
|
+
// An explicit binary (dev/CI) or one already installed: nothing to do.
|
|
15
|
+
if (process.env.ENIGMA_BIN_PATH || installedBinary()) return;
|
|
16
|
+
// No checksums.json means this is a source checkout / workspace install, not a
|
|
17
|
+
// published tarball - there is no release to fetch from, so stay silent.
|
|
18
|
+
if (Object.keys(loadChecksums()).length === 0) return;
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
await downloadBinary({ log: (message) => process.stdout.write(`enigma: ${message}\n`) });
|
|
22
|
+
} catch (error) {
|
|
23
|
+
process.stdout.write(
|
|
24
|
+
`enigma: could not download the binary now (${error.message}). ` +
|
|
25
|
+
`It will be fetched automatically the first time you run \`enigma\`.\n`,
|
|
26
|
+
);
|
|
27
|
+
// Intentionally exit 0: a failed postinstall must not break `npm install`.
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
await main();
|
package/package.json
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "enigma-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Everything you need to work with a coding agent: install shared policy skills for Claude Code, OpenAI Codex and opencode, and set up portable git security hooks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"enigma": "
|
|
7
|
+
"enigma": "bin/enigma.mjs"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"enigma": "tsx src/bin/enigma.ts",
|
|
11
11
|
"build": "tsup",
|
|
12
|
+
"build:binaries": "bun scripts/build-binaries.ts",
|
|
12
13
|
"dev": "node scripts/dev.mjs",
|
|
13
|
-
"dev:
|
|
14
|
+
"dev:node": "node scripts/dev.mjs --node",
|
|
14
15
|
"dev:watch": "tsup --watch",
|
|
15
16
|
"typecheck": "tsc --noEmit",
|
|
16
17
|
"seal": "tsx src/bin/enigma.ts seal",
|
|
17
18
|
"check": "tsx src/bin/enigma.ts check",
|
|
18
19
|
"guard": "tsx src/guard.ts --all",
|
|
19
20
|
"verify": "npm run typecheck && npm run check && npm run guard",
|
|
20
|
-
"prepublishOnly": "npm run verify && npm run build"
|
|
21
|
+
"prepublishOnly": "npm run verify && npm run build",
|
|
22
|
+
"postinstall": "node bin/postinstall.mjs"
|
|
21
23
|
},
|
|
22
24
|
"files": [
|
|
25
|
+
"bin",
|
|
23
26
|
"dist",
|
|
24
27
|
"assets",
|
|
25
28
|
"README.md",
|
|
@@ -28,18 +31,13 @@
|
|
|
28
31
|
"engines": {
|
|
29
32
|
"node": ">=18"
|
|
30
33
|
},
|
|
31
|
-
"
|
|
34
|
+
"devDependencies": {
|
|
32
35
|
"@clack/prompts": "^0.7.0",
|
|
33
|
-
"ink": "^7.0.5",
|
|
34
|
-
"react": "^19.2.0"
|
|
35
|
-
},
|
|
36
|
-
"optionalDependencies": {
|
|
37
36
|
"@opentui/core": "^0.3.1",
|
|
38
|
-
"@opentui/react": "^0.3.1"
|
|
39
|
-
},
|
|
40
|
-
"devDependencies": {
|
|
37
|
+
"@opentui/react": "^0.3.1",
|
|
41
38
|
"@types/node": "^22.0.0",
|
|
42
39
|
"@types/react": "^19.2.0",
|
|
40
|
+
"react": "^19.2.0",
|
|
43
41
|
"tsup": "^8.0.0",
|
|
44
42
|
"tsx": "^4.0.0",
|
|
45
43
|
"typescript": "^5.0.0"
|