enigma-cli 1.57.2 → 1.58.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/anti-overengineering-policy/skill.json +1 -1
- package/assets/skills/anti-overengineering-review/skill.json +1 -1
- 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/email-policy/skill.json +1 -1
- package/assets/skills/frontend-design/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/logo-sourcing-policy/skill.json +1 -1
- package/assets/skills/security-policy/skill.json +1 -1
- package/assets/skills/skill-creator/skill.json +1 -1
- package/assets/skills/task-completion-policy/skill.json +1 -1
- package/assets/skills/technical-writing-policy/skill.json +1 -1
- package/assets/skills/testing-policy/SKILL.md +1 -0
- package/assets/skills/testing-policy/skill.json +2 -2
- package/assets/skills/validation-policy/skill.json +1 -1
- package/bin/checksums.json +4 -4
- package/dist/ci-watch.js +1 -0
- package/dist/codegraph-hook.js +1 -0
- package/dist/guardrails.js +19 -11
- package/dist/post-edit.js +20 -11
- package/package.json +1 -1
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "On-demand over-engineering review - diff review, whole-repo audit, and enigma: debt-marker ledger (tags delete/stdlib/native/yagni/shrink, line/dep scoring); lists cuts, applies nothing.",
|
|
6
6
|
"updated": "2026-06-16T11:24:30+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "f742a2be3f328b9ea1ff9a35a449177c2cbec35ad16e46f7054b7a873a2ab017"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Backend/API architecture: controller-service-repository layering, modern TypeScript project configuration (module resolution, strict flags, @/* path alias), API and request optimization (batching, avoiding redundant calls, skipping no-op writes), server-side caching (Redis), and Zod boundary validation.",
|
|
6
6
|
"updated": "2026-08-02T19:59:01+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "652637f818b4ce4f4d5d83fa68fa57fe7842e32fb179523958c5496af54bb938"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Ciphera code style conventions (formatting, naming, imports incl. namespace imports for wide module surfaces, path-alias specifiers and no file extensions, comments, code-level anti-patterns; TypeScript-first, language-agnostic).",
|
|
6
6
|
"updated": "2026-08-02T19:59:01+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "3beb0383a9cb0331ef8a579308a2517d24d57a8ba33751ad17d16d0a4f66e344"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Pre-delivery self-review gate, prioritized review dimensions, and change-quality criteria.",
|
|
6
6
|
"updated": "2026-08-19T12:37:59+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "6b8a924cc11b61d4b45b73384aeb095ce622229359b7cc2c6ce4bb0cf3015ed7"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Senior database architecture policy: engine selection (PostgreSQL by default, SQLite only for local-first/embedded stores), ORM selection (Prisma in TypeScript/JavaScript), query optimization, anti-duplication/normalization, scalability, and RGPD/GDPR encryption.",
|
|
6
6
|
"updated": "2026-08-04T18:33:27+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "26fddc14caf697e830448a2cc453ddc470fe83d098d50bd67b278effba63274e"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Reproduce-isolate-fix debugging methodology with root-cause discipline and regression verification.",
|
|
6
6
|
"updated": "2026-08-02T04:15:47+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "968876bcac9ce6e5a20be05c89ac97191b112c9e08679a8dc506d150c375fec4"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
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
6
|
"updated": "2026-06-01T00:45:28+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "6375d835c2aef2c9bd31ce116444dc3d796f510f9970a213aa3ac4696d7e21b9"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Transactional email: React Email templates instead of hand-written HTML tables, server-side rendering, one send module behind the provider SDK, plain-text alternatives, idempotent background sending, link safety, and deliverability (SPF/DKIM/DMARC, bounce suppression, unsubscribe).",
|
|
6
6
|
"updated": "2026-09-28T21:34:15+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "648c7ae3d95d5a033f4955a87613e20b40b265bfcc24d41a5732d415abe778f9"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one.",
|
|
6
6
|
"updated": "2026-09-28T21:34:15+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "5d532c2dc467f960ff800c5cd7021db09911599347959cd04481f2054abd9baa"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Frontend architecture: reusable components, abstraction thresholds, state management, real-time form validation where an emptied or not-yet-filled field is incomplete rather than invalid (a `*` on the label and an aria-disabled submit, never \"email is not valid\" over an empty input), no-op detection (skip any operation whose result equals current state, not just form saves; dirty means different from the loaded snapshot, not touched), instant first paint (render the shell, load data async, skeletons), perceived performance (prefetch on intent, debounce/throttle, cancel stale requests, avoid waterfalls, lazy widgets), large-list rendering (infinite scroll is the preferred default, pagination the deliberate exception when the design or the user calls for it, virtualization, skeletons, progressive loading), data views that ship their own affordances by default (a log, expense, transaction or history table is not done when the rows render: fuse.js search, the filters its column kinds imply, a date range, sort, filter state in the URL, and an export of the filtered set), every reference to an entity being a way into it (a name, id, project or path in a row links to that record, reveals it in a hover card, or at minimum copies and filters by it, never inert text; machine codes get human labels and raw payloads are never dumped into a cell), optimistic UI with rollback, visual restraint (one card level, spacing before borders, one elevation scale), icon actions (repeated row/card actions are icon-only buttons with aria-label plus title, not text labels), responsive/adaptive layout (fluid units, breakpoints, no overlap/overflow, viewport meta, touch targets), form fields that declare their keyboard and casing (autocapitalize/autocomplete/inputmode per field kind, set once in the shared Input, normalized on blur), variable-length text (min-width:0 in flex/grid, wrap vs truncate, long unbroken strings, worst-case content checks), auth screens (breached-password feedback, strength meter, cookie consent before login/register), and AI chat/agent interfaces via Vercel's AI Elements registry instead of hand-rolled message threads.",
|
|
6
6
|
"updated": "2026-10-02T12:11:30+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "2571746934548e64ee30348bbf29b1d971d3afa0a7b32277b137150bf8803f90"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Git & contribution policy (senior engineering standards).",
|
|
6
6
|
"updated": "2026-10-02T14:54:11+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "c6ffef058397ac22310053af1f96d768c36eb8761336258cfef2b97cff3fb0e9"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Application and AI-agent security: secrets, authn/authz (least privilege, object- and role-level checks), credential flows with breach-checked passwords (Have I Been Pwned), OWASP Top 10 with vetted helpers for SSRF, redirects and uploads, transport/crypto baseline, cookies and consent, secure logging, and agent/MCP/tool-use safety.",
|
|
6
6
|
"updated": "2026-09-28T21:34:15+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "544359122f127cccedfe469232da915b04f7f4aa4795297281bd4bc9cd07d371"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Create new skills, modify and improve existing skills, and measure skill performance with evals and benchmarks.",
|
|
6
6
|
"updated": "2026-08-03T00:16:54+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "a49f6166f57d734e0f13487332da37903e925f32257447856af0fbd6a5f1dc84"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Exhaustive completion discipline for long/multi-item tasks - inventory, coverage ledger, verified done.",
|
|
6
6
|
"updated": "2026-10-02T12:38:13+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "ee8447d5ca9e5d77e0a338d1e762c30e1527ded4665c10ddf21f2c4c9ce3f2d5"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Concise, realistic copy for UI, landing/sales, SEO, email and docs - the user's outcome instead of the mechanism, no full enumerations or \"powered by\" lineage, none of the recognizable AI-writing tells, and never a typographic dash.",
|
|
6
6
|
"updated": "2026-09-28T21:34:15+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "e32623f37f1bf90fa611968ca8b216e3381771254b6af7c81a953c17a8889ddb"
|
|
9
9
|
}
|
|
@@ -39,6 +39,7 @@ description: Test strategy (test pyramid), coverage gates, deterministic tests,
|
|
|
39
39
|
- Test edge cases: empty, null, max size, invalid input, concurrency, and timezone/locale where relevant.
|
|
40
40
|
- Test public behavior and contracts, not private implementation details.
|
|
41
41
|
- For input handling, assert that invalid input is rejected as defined in validation-policy.
|
|
42
|
+
- A UI, flow or load-speed change is checked in a real browser before it is called done, when the `chrome-devtools` MCP tools are available (enigma registers them; `enigma config browser`): open the page, do what the user will do, then read the console and failed network requests, and run a performance trace or Lighthouse audit for speed claims. A passing unit test does not show that a button works, a page renders, or a view loads fast.
|
|
42
43
|
|
|
43
44
|
---
|
|
44
45
|
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Test strategy, coverage gates, deterministic tests, mocking discipline, regression-first bug fixing, and test-suite organization (layout by type/domain, mirrored paths, file naming, fixture/helper placement).",
|
|
6
6
|
"updated": "2026-06-16T17:11:49+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
8
|
-
"sha": "
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
|
+
"sha": "5dd665ba23faf604db1a89421c5d9d9a03a489c5784d1da8b90f57b09f95d1ca"
|
|
9
9
|
}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
"provider": "FJRG2007/enigma",
|
|
5
5
|
"description": "Strict frontend + backend schema validation, normalization before validation (shared normalizers: trim, lowercase email, capitalize names, canonicalize links and handles), real-time error timing (an emptied or not-yet-filled field is incomplete, not invalid: a `*` and an aria-disabled submit instead of \"not valid\" over an empty input), schema consistency, and safe client-facing error handling.",
|
|
6
6
|
"updated": "2026-10-02T19:07:57+02:00",
|
|
7
|
-
"cliVersion": "1.
|
|
7
|
+
"cliVersion": "1.58.0",
|
|
8
8
|
"sha": "7b39ded6b82cb7a8424aea7b8d59a293791205d57e7272ff63d9fa558772ecb1"
|
|
9
9
|
}
|
package/bin/checksums.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"enigma-darwin-arm64": "
|
|
3
|
-
"enigma-linux-arm64": "
|
|
4
|
-
"enigma-linux-x64": "
|
|
5
|
-
"enigma-win32-x64.exe": "
|
|
2
|
+
"enigma-darwin-arm64": "d2837e5ac43d80a4893c06cb77f77e229f64bd34bdeac31a28623739549f89f8",
|
|
3
|
+
"enigma-linux-arm64": "bb17533398f1ce60206694d9f30a58f0a32ce933fe6c5ec3c266303e543b0a5d",
|
|
4
|
+
"enigma-linux-x64": "79984615c8cc42b525ecd6d5dfa006b6a969b42b2eb631d4b505a580b83fcfc7",
|
|
5
|
+
"enigma-win32-x64.exe": "034ae55213f1d63cfbecbc17466e56e626a875798cfa4035a0b7a3bd9acae985"
|
|
6
6
|
}
|
package/dist/ci-watch.js
CHANGED
package/dist/codegraph-hook.js
CHANGED
package/dist/guardrails.js
CHANGED
|
@@ -3350,26 +3350,33 @@ function operatorHome() {
|
|
|
3350
3350
|
return env?.trim() || homedir();
|
|
3351
3351
|
}
|
|
3352
3352
|
function operatorHomePathLeak(content) {
|
|
3353
|
+
const re = operatorHomeRegex("i");
|
|
3354
|
+
if (re === null) return [];
|
|
3355
|
+
const out = [];
|
|
3356
|
+
const lines = content.split("\n");
|
|
3357
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3358
|
+
if (re.test(lines[i])) out.push({ line: i + 1, detail: "the path resolves to this machine's home directory" });
|
|
3359
|
+
}
|
|
3360
|
+
return out;
|
|
3361
|
+
}
|
|
3362
|
+
function redactOperatorHome(text) {
|
|
3363
|
+
const re = operatorHomeRegex("gi");
|
|
3364
|
+
return re === null ? text : text.replace(re, "~");
|
|
3365
|
+
}
|
|
3366
|
+
function operatorHomeRegex(flags) {
|
|
3353
3367
|
const home = operatorHome();
|
|
3354
|
-
if (!home || home.length < 6) return
|
|
3368
|
+
if (!home || home.length < 6) return null;
|
|
3355
3369
|
const account = home.replace(/[\\/]+$/, "").split(/[\\/]/).pop() || "";
|
|
3356
|
-
if (!account || GENERIC_ACCOUNTS.has(account.toLowerCase())) return
|
|
3370
|
+
if (!account || GENERIC_ACCOUNTS.has(account.toLowerCase())) return null;
|
|
3357
3371
|
const forms = [home];
|
|
3358
3372
|
const drive = /^([A-Za-z]):[\\/](.*)$/.exec(home);
|
|
3359
3373
|
if (drive) forms.push(`/${drive[1].toLowerCase()}/${drive[2]}`);
|
|
3360
3374
|
const alt = forms.map((f) => f.split(/[\\/]/).map((s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("[\\\\/]")).join("|");
|
|
3361
|
-
let re;
|
|
3362
3375
|
try {
|
|
3363
|
-
|
|
3376
|
+
return new RegExp(`(?:${alt})(?![A-Za-z0-9_-]|\\.[A-Za-z0-9_-])`, flags);
|
|
3364
3377
|
} catch {
|
|
3365
|
-
return
|
|
3366
|
-
}
|
|
3367
|
-
const out = [];
|
|
3368
|
-
const lines = content.split("\n");
|
|
3369
|
-
for (let i = 0; i < lines.length; i++) {
|
|
3370
|
-
if (re.test(lines[i])) out.push({ line: i + 1, detail: "the path resolves to this machine's home directory" });
|
|
3378
|
+
return null;
|
|
3371
3379
|
}
|
|
3372
|
-
return out;
|
|
3373
3380
|
}
|
|
3374
3381
|
function readStringLiteral(src, start, python) {
|
|
3375
3382
|
let i = start;
|
|
@@ -4818,6 +4825,7 @@ export {
|
|
|
4818
4825
|
readLedger,
|
|
4819
4826
|
readReplyLedger,
|
|
4820
4827
|
recordFindings,
|
|
4828
|
+
redactOperatorHome,
|
|
4821
4829
|
redirectFromInput,
|
|
4822
4830
|
redirectPrefixCheck,
|
|
4823
4831
|
remoteCollectionNames,
|
package/dist/post-edit.js
CHANGED
|
@@ -282,6 +282,7 @@ var init_config = __esm({
|
|
|
282
282
|
selfAudit: true,
|
|
283
283
|
compress: false,
|
|
284
284
|
codeGraph: true,
|
|
285
|
+
browser: true,
|
|
285
286
|
gate: true,
|
|
286
287
|
dashboard: "off",
|
|
287
288
|
tokenPrice: 0,
|
|
@@ -605,6 +606,7 @@ __export(guardrails_exports, {
|
|
|
605
606
|
readLedger: () => readLedger,
|
|
606
607
|
readReplyLedger: () => readReplyLedger,
|
|
607
608
|
recordFindings: () => recordFindings,
|
|
609
|
+
redactOperatorHome: () => redactOperatorHome,
|
|
608
610
|
redirectFromInput: () => redirectFromInput,
|
|
609
611
|
redirectPrefixCheck: () => redirectPrefixCheck,
|
|
610
612
|
remoteCollectionNames: () => remoteCollectionNames,
|
|
@@ -1137,26 +1139,33 @@ function operatorHome() {
|
|
|
1137
1139
|
return env?.trim() || homedir2();
|
|
1138
1140
|
}
|
|
1139
1141
|
function operatorHomePathLeak(content) {
|
|
1142
|
+
const re = operatorHomeRegex("i");
|
|
1143
|
+
if (re === null) return [];
|
|
1144
|
+
const out = [];
|
|
1145
|
+
const lines = content.split("\n");
|
|
1146
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1147
|
+
if (re.test(lines[i])) out.push({ line: i + 1, detail: "the path resolves to this machine's home directory" });
|
|
1148
|
+
}
|
|
1149
|
+
return out;
|
|
1150
|
+
}
|
|
1151
|
+
function redactOperatorHome(text) {
|
|
1152
|
+
const re = operatorHomeRegex("gi");
|
|
1153
|
+
return re === null ? text : text.replace(re, "~");
|
|
1154
|
+
}
|
|
1155
|
+
function operatorHomeRegex(flags) {
|
|
1140
1156
|
const home = operatorHome();
|
|
1141
|
-
if (!home || home.length < 6) return
|
|
1157
|
+
if (!home || home.length < 6) return null;
|
|
1142
1158
|
const account = home.replace(/[\\/]+$/, "").split(/[\\/]/).pop() || "";
|
|
1143
|
-
if (!account || GENERIC_ACCOUNTS.has(account.toLowerCase())) return
|
|
1159
|
+
if (!account || GENERIC_ACCOUNTS.has(account.toLowerCase())) return null;
|
|
1144
1160
|
const forms = [home];
|
|
1145
1161
|
const drive = /^([A-Za-z]):[\\/](.*)$/.exec(home);
|
|
1146
1162
|
if (drive) forms.push(`/${drive[1].toLowerCase()}/${drive[2]}`);
|
|
1147
1163
|
const alt = forms.map((f) => f.split(/[\\/]/).map((s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("[\\\\/]")).join("|");
|
|
1148
|
-
let re;
|
|
1149
1164
|
try {
|
|
1150
|
-
|
|
1165
|
+
return new RegExp(`(?:${alt})(?![A-Za-z0-9_-]|\\.[A-Za-z0-9_-])`, flags);
|
|
1151
1166
|
} catch {
|
|
1152
|
-
return
|
|
1153
|
-
}
|
|
1154
|
-
const out = [];
|
|
1155
|
-
const lines = content.split("\n");
|
|
1156
|
-
for (let i = 0; i < lines.length; i++) {
|
|
1157
|
-
if (re.test(lines[i])) out.push({ line: i + 1, detail: "the path resolves to this machine's home directory" });
|
|
1167
|
+
return null;
|
|
1158
1168
|
}
|
|
1159
|
-
return out;
|
|
1160
1169
|
}
|
|
1161
1170
|
function readStringLiteral(src, start, python) {
|
|
1162
1171
|
let i = start;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "enigma-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.58.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": {
|