@ijfw/install 1.2.10 → 1.3.1
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/CHANGELOG.md +19 -0
- package/README.md +5 -3
- package/dist/ijfw.js +45 -24
- package/dist/install.js +1888 -86
- package/docs/GUIDE.md +4 -4
- package/package.json +2 -3
- package/src/install.ps1 +8 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.3.1] -- 2026-05-12
|
|
4
|
+
|
|
5
|
+
**Codex hook cleanup + release cadence hardening.** Tightens IJFW's Codex integration for Codex 0.130+, reduces the default dependency footprint, and moves more release drift into automated gates before it reaches users.
|
|
6
|
+
|
|
7
|
+
- Codex `SessionStart` now emits `additionalContext` inside `hookSpecificOutput` with `hookEventName: "SessionStart"`, matching Codex's strict hook response shape. This closes the `SessionStart hook (failed): hook returned invalid session start JSON output` error.
|
|
8
|
+
- Codex `PostToolUse` is now stdout-silent. IJFW still records local observations and failure signals, but it no longer re-injects cleaned tool output as `systemMessage`, which Codex renders as visible hook warning spam.
|
|
9
|
+
- Codex hook Node shims now pass user/tool text after `--`, so tool output beginning with `---` is treated as data instead of a Node CLI option. This closes the `node: bad option: ---` failure.
|
|
10
|
+
- Codex `UserPromptSubmit` and `PreToolUse` advisory output now use the same `hookSpecificOutput.additionalContext` shape when they do emit context.
|
|
11
|
+
- Codex `Stop` now stays stdout-silent on routine session saves. Normal receipts are written locally; only actionable compression notices can surface by default. This closes the `Stop hook (completed) warning: [ijfw] Session #... saved` noise.
|
|
12
|
+
- Codex bundle tests now cover strict `SessionStart` JSON and silent `PostToolUse` behavior for both routine output and failure-looking output.
|
|
13
|
+
- The shipped MCP server no longer installs `@xenova/transformers` by default. Cold semantic vectors are explicit opt-in and `IJFW_VECTORS` now defaults to `off`, keeping the production install smaller and quieter under package audits.
|
|
14
|
+
- The preflight audit gate now runs against both `installer` and `mcp-server`, so server-side dependency drift is covered by the same release gate as the installer.
|
|
15
|
+
- `ijfw preflight` now routes through the canonical 11-gate preflight entrypoint from both installer and MCP CLI paths instead of falling back to `scripts/check-all.sh`.
|
|
16
|
+
- Platform capability drift is now gated by `platform-capabilities.json` plus `scripts/check-platform-drift.js`, covering skill counts, hook-event counts, and marketplace/plugin manifest claims.
|
|
17
|
+
- Update-check changelog URLs now point at GitLab releases, matching the canonical repository.
|
|
18
|
+
- D2 graph-write lock timeout handling now throws the intended `EBUSY_GRAPH_WRITE` error instead of tripping an undeclared variable path under collision.
|
|
19
|
+
|
|
20
|
+
Files: `codex/.codex/hooks/session-start.sh`, `codex/.codex/hooks/post-tool-use.sh`, `codex/.codex/hooks/pre-prompt.sh`, `codex/.codex/hooks/pre-tool-use.sh`, `codex/.codex/hooks/session-end.sh`, `scripts/observation/test-envelope-invariant-codex.sh`, `mcp-server/test-codex-bundle.js`, `mcp-server/src/vectors.js`, `mcp-server/package.json`, `installer/src/preflight/gates/audit-ci.js`, `installer/src/preflight.js`, `mcp-server/src/cross-orchestrator-cli.js`, `mcp-server/src/compute/graph-lock.js`, `platform-capabilities.json`, `scripts/check-platform-drift.js`.
|
|
21
|
+
|
|
3
22
|
## [1.2.6] -- 2026-05-01
|
|
4
23
|
|
|
5
24
|
**Token sandbox + parallel workflow dispatch + DeepSeek frontier upgrade.** A new `ijfw_run` MCP tool keeps large command output out of your context window entirely -- builds, test suites, grep runs, and log tails are sandboxed to disk and summarized in a few lines instead of flooding thousands of tokens. The `ijfw-workflow` execution engine gains a formal Wave Table that makes parallel agent dispatch deterministic rather than inferred. DeepSeek moves to `deepseek-v4-pro` -- the actual frontier model -- so the Trident gets Frontier AI checking Frontier AI.
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @ijfw/install
|
|
2
2
|
|
|
3
3
|
One-command installer for [IJFW](https://gitlab.com/therealseandonahoe/ijfw) -- the AI
|
|
4
|
-
efficiency layer for Claude Code, Codex, Gemini, Cursor, Windsurf, Copilot.
|
|
4
|
+
efficiency layer for 14 AI coding agents: Claude Code, Codex, Gemini, Cursor, Windsurf, Copilot, Hermes, Wayland, OpenCode, Qwen Code, Cline, Kimi Code, OpenClaw, and Aider.
|
|
5
5
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
@@ -39,8 +39,10 @@ Memory is preserved across re-runs by default.
|
|
|
39
39
|
|
|
40
40
|
## Preflight
|
|
41
41
|
|
|
42
|
-
Requires `node >=18
|
|
43
|
-
installer
|
|
42
|
+
Requires `node >=18` and `git` (used for the initial repo clone). The
|
|
43
|
+
installer is Node-native end to end -- no bash, no WSL, no Git for Windows
|
|
44
|
+
shell. On native Windows use the PowerShell installer (PS 5.1+), which
|
|
45
|
+
delegates to Node directly:
|
|
44
46
|
|
|
45
47
|
```powershell
|
|
46
48
|
iwr https://gitlab.com/therealseandonahoe/ijfw/-/raw/main/installer/src/install.ps1 -OutFile install.ps1
|
package/dist/ijfw.js
CHANGED
|
@@ -582,27 +582,35 @@ async function run7(ctx) {
|
|
|
582
582
|
const t0 = Date.now();
|
|
583
583
|
const ver = ctx.versions["audit-ci"] || "latest";
|
|
584
584
|
const configPath = join4(ctx.repoRoot, ".audit-ci.jsonc");
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
585
|
+
const packageDirs = ["installer", "mcp-server"];
|
|
586
|
+
const runs = packageDirs.map((dir) => {
|
|
587
|
+
const res = spawnSync7(
|
|
588
|
+
"npx",
|
|
589
|
+
["--yes", `audit-ci@${ver}`, "--config", configPath],
|
|
590
|
+
{
|
|
591
|
+
encoding: "utf8",
|
|
592
|
+
cwd: join4(ctx.repoRoot, dir),
|
|
593
|
+
timeout: 6e4
|
|
594
|
+
}
|
|
595
|
+
);
|
|
596
|
+
return { dir, status: res.status, output: (res.stdout || "") + (res.stderr || "") };
|
|
597
|
+
});
|
|
594
598
|
const durationMs = Date.now() - t0;
|
|
595
|
-
const
|
|
596
|
-
|
|
597
|
-
if (res.status === 0) {
|
|
599
|
+
const failed = runs.filter((r) => r.status !== 0);
|
|
600
|
+
if (failed.length === 0) {
|
|
598
601
|
return {
|
|
599
602
|
name: "audit-ci",
|
|
600
603
|
status: "PASS",
|
|
601
|
-
message: "audit-ci: no high/critical vulnerabilities",
|
|
602
|
-
details:
|
|
604
|
+
message: "audit-ci: no high/critical vulnerabilities in installer or mcp-server",
|
|
605
|
+
details: runs.map((r) => `${r.dir}: pass`),
|
|
603
606
|
durationMs
|
|
604
607
|
};
|
|
605
608
|
}
|
|
609
|
+
const lines = [];
|
|
610
|
+
for (const r of failed) {
|
|
611
|
+
lines.push(`${r.dir}: audit failed`);
|
|
612
|
+
lines.push(...r.output.split("\n").filter(Boolean).slice(0, 10));
|
|
613
|
+
}
|
|
606
614
|
return {
|
|
607
615
|
name: "audit-ci",
|
|
608
616
|
status: "FAIL",
|
|
@@ -1045,7 +1053,7 @@ __export(preflight_exports, {
|
|
|
1045
1053
|
runPreflightCommand: () => runPreflightCommand
|
|
1046
1054
|
});
|
|
1047
1055
|
import { readFileSync as readFileSync2, existsSync as existsSync3 } from "node:fs";
|
|
1048
|
-
import { join as join8, dirname } from "node:path";
|
|
1056
|
+
import { join as join8, dirname, resolve as resolve3 } from "node:path";
|
|
1049
1057
|
import { fileURLToPath } from "node:url";
|
|
1050
1058
|
function printHelp() {
|
|
1051
1059
|
console.log(`
|
|
@@ -1144,11 +1152,24 @@ async function runPreflightCommand(argv, repoRoot2) {
|
|
|
1144
1152
|
const report = await runPreflight(gates, ctx);
|
|
1145
1153
|
process.exit(report.outcome === "pass" ? 0 : 1);
|
|
1146
1154
|
}
|
|
1155
|
+
function defaultRepoRoot() {
|
|
1156
|
+
let dir = __dirname;
|
|
1157
|
+
for (let i = 0; i < 8; i++) {
|
|
1158
|
+
if (existsSync3(join8(dir, "package.json")) && existsSync3(join8(dir, "mcp-server"))) return dir;
|
|
1159
|
+
const next = resolve3(dir, "..");
|
|
1160
|
+
if (next === dir) break;
|
|
1161
|
+
dir = next;
|
|
1162
|
+
}
|
|
1163
|
+
return process.cwd();
|
|
1164
|
+
}
|
|
1147
1165
|
var __dirname;
|
|
1148
1166
|
var init_preflight = __esm({
|
|
1149
|
-
"src/preflight.js"() {
|
|
1167
|
+
async "src/preflight.js"() {
|
|
1150
1168
|
init_runner();
|
|
1151
1169
|
__dirname = dirname(fileURLToPath(import.meta.url));
|
|
1170
|
+
if (process.argv[1] && resolve3(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
1171
|
+
await runPreflightCommand(process.argv, defaultRepoRoot());
|
|
1172
|
+
}
|
|
1152
1173
|
}
|
|
1153
1174
|
});
|
|
1154
1175
|
|
|
@@ -2412,7 +2433,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
2412
2433
|
});
|
|
2413
2434
|
|
|
2414
2435
|
// src/ijfw.js
|
|
2415
|
-
import { dirname as dirname2, join as join9, resolve as
|
|
2436
|
+
import { dirname as dirname2, join as join9, resolve as resolve4, basename } from "node:path";
|
|
2416
2437
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
2417
2438
|
import { existsSync as existsSync4, mkdirSync as mkdirSync3, copyFileSync, readdirSync as readdirSync4, rmSync as rmSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "node:fs";
|
|
2418
2439
|
import { homedir, platform as platform2 } from "node:os";
|
|
@@ -2422,7 +2443,7 @@ function repoRoot() {
|
|
|
2422
2443
|
let dir = __dirname2;
|
|
2423
2444
|
for (let i = 0; i < 6; i++) {
|
|
2424
2445
|
if (existsSync4(join9(dir, "package.json")) && existsSync4(join9(dir, ".git"))) return dir;
|
|
2425
|
-
dir =
|
|
2446
|
+
dir = resolve4(dir, "..");
|
|
2426
2447
|
}
|
|
2427
2448
|
return process.cwd();
|
|
2428
2449
|
}
|
|
@@ -2437,7 +2458,7 @@ COMMANDS
|
|
|
2437
2458
|
install Install IJFW into your AI coding agents
|
|
2438
2459
|
uninstall Remove IJFW from your AI coding agents
|
|
2439
2460
|
help Open the full IJFW guide (terminal, or --browser for rendered)
|
|
2440
|
-
preflight Run
|
|
2461
|
+
preflight Run 11-gate quality pipeline before publishing
|
|
2441
2462
|
dashboard Start / stop / check the local observability dashboard
|
|
2442
2463
|
design Manage the visual design companion
|
|
2443
2464
|
doctor Diagnose IJFW installation health
|
|
@@ -2494,19 +2515,19 @@ async function main() {
|
|
|
2494
2515
|
}
|
|
2495
2516
|
switch (sub) {
|
|
2496
2517
|
case "install": {
|
|
2497
|
-
const installBin =
|
|
2518
|
+
const installBin = resolve4(__dirname2, "..", "dist", "install.js");
|
|
2498
2519
|
const r = spawnSync12("node", [installBin, ...argv.slice(3)], { stdio: "inherit" });
|
|
2499
2520
|
process.exit(r.status ?? 1);
|
|
2500
2521
|
break;
|
|
2501
2522
|
}
|
|
2502
2523
|
case "uninstall": {
|
|
2503
|
-
const uninstallBin =
|
|
2524
|
+
const uninstallBin = resolve4(__dirname2, "..", "dist", "uninstall.js");
|
|
2504
2525
|
const r = spawnSync12("node", [uninstallBin, ...argv.slice(3)], { stdio: "inherit" });
|
|
2505
2526
|
process.exit(r.status ?? 1);
|
|
2506
2527
|
break;
|
|
2507
2528
|
}
|
|
2508
2529
|
case "preflight": {
|
|
2509
|
-
const { runPreflightCommand: runPreflightCommand2 } = await
|
|
2530
|
+
const { runPreflightCommand: runPreflightCommand2 } = await init_preflight().then(() => preflight_exports);
|
|
2510
2531
|
await runPreflightCommand2([argv[0], argv[1], ...argv.slice(3)], repoRoot());
|
|
2511
2532
|
break;
|
|
2512
2533
|
}
|
|
@@ -2563,7 +2584,7 @@ async function main() {
|
|
|
2563
2584
|
console.error("Usage: ijfw design push <file.html>");
|
|
2564
2585
|
process.exit(1);
|
|
2565
2586
|
}
|
|
2566
|
-
const abs =
|
|
2587
|
+
const abs = resolve4(filePath);
|
|
2567
2588
|
if (!existsSync4(abs)) {
|
|
2568
2589
|
console.error(`File not found: ${abs}`);
|
|
2569
2590
|
process.exit(1);
|
|
@@ -2587,7 +2608,7 @@ async function main() {
|
|
|
2587
2608
|
const wantsBrowser = argv.slice(3).includes("--browser");
|
|
2588
2609
|
const candidates = [
|
|
2589
2610
|
join9(repoRoot(), "docs", "GUIDE.md"),
|
|
2590
|
-
|
|
2611
|
+
resolve4(__dirname2, "..", "docs", "GUIDE.md"),
|
|
2591
2612
|
join9(homedir(), ".ijfw", "docs", "GUIDE.md")
|
|
2592
2613
|
];
|
|
2593
2614
|
const guidePath = candidates.find((p) => existsSync4(p));
|