failproofai 1.0.8 → 1.0.9-beta.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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +4 -4
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +3 -3
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/_09dz7xv._.js +20 -20
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +2 -2
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_1aveq0u._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0tmz862._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15578wp._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m_svbe._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0-vcssj._.js → _0n0lja6._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1gb0ifp._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1p3iz2d._.js +23 -0
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +3 -3
- package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_effective-reviewers_ts_1h4wtvo._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_semantic_pack-policies_ts_0gh_bu_._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +23 -23
- package/.next/standalone/.next/static/chunks/{3c3qbmosdjl6w.js → 0247hc9ath5t-.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0m-9d6yn9hx4j.js → 03001k9jy-kst.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2qdpj67x6ifk_.js → 06k7gsfnb7jkh.js} +1 -1
- package/.next/standalone/.next/static/chunks/0qejem4-zt-hy.js +1 -0
- package/.next/standalone/.next/static/chunks/{21uv-uusw329x.js → 0snylg3y1i47a.js} +1 -1
- package/.next/standalone/.next/static/chunks/1h0if8ky362as.js +1 -0
- package/.next/standalone/.next/static/chunks/{0wbjy0zo-m7is.js → 2qsrrrl2maqsb.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0bhidk90e-07f.css → 3_e_wg5_oay87.css} +1 -1
- package/.next/standalone/.next/static/chunks/3ns-egfh8i8i5.js +6 -0
- package/.next/standalone/.next/static/chunks/3rq7fjj9we0v3.js +1 -0
- package/.next/standalone/.next/static/chunks/42m0f2hh8vfb1.js +1 -0
- package/.next/standalone/app/actions/get-jev-config.ts +2 -2
- package/.next/standalone/app/actions/update-jev-config.ts +12 -9
- package/.next/standalone/app/components/jev-notices.tsx +10 -10
- package/.next/standalone/app/settings/jev-panel.tsx +11 -11
- package/.next/standalone/fp-cloud-cli/CHANGELOG.md +2 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/output.py +26 -0
- package/.next/standalone/fp-cloud-cli/tests/test_output.py +27 -0
- package/.next/standalone/hermes-plugin/README.md +18 -8
- package/.next/standalone/package.json +10 -10
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +33 -7
- package/dist/cli.mjs +556 -521
- package/dist/worker.mjs +56 -375
- package/hermes-plugin/README.md +18 -8
- package/package.json +10 -10
- package/scripts/build-policy-pack.mjs +6 -9
- package/src/hooks/cloud-connection.ts +12 -6
- package/src/hooks/custom-hooks-loader.ts +1 -1
- package/src/hooks/effective-reviewers.ts +50 -43
- package/src/hooks/handler.ts +25 -16
- package/src/hooks/hermes-update.ts +74 -0
- package/src/hooks/hook-activity-store.ts +3 -3
- package/src/hooks/integrations.ts +349 -55
- package/src/hooks/jev-activity.ts +3 -3
- package/src/hooks/jev-cli.ts +17 -17
- package/src/hooks/jev-cloud-connection.ts +4 -4
- package/src/hooks/manager.ts +3 -2
- package/src/hooks/pack-cli.ts +24 -23
- package/src/hooks/pack-manifest.ts +25 -2
- package/src/hooks/pack-store.ts +2 -2
- package/src/hooks/policy-authority.ts +51 -32
- package/src/hooks/policy-evaluator.ts +5 -5
- package/src/hooks/policy-registry.ts +5 -7
- package/src/hooks/policy-reviewability.ts +26 -10
- package/src/hooks/policy-types.ts +4 -4
- package/src/hooks/semantic/combine.ts +13 -13
- package/src/hooks/semantic/evaluator.ts +5 -5
- package/src/hooks/semantic/jev-client.ts +1 -1
- package/src/hooks/semantic/jev-config.ts +21 -12
- package/src/hooks/semantic/jev-review.ts +3 -3
- package/src/hooks/semantic/jev-stats.ts +17 -17
- package/src/hooks/semantic/pack-policies.ts +48 -48
- package/src/hooks/semantic/policies.ts +13 -425
- package/src/hooks/semantic/precondition-names.ts +1 -1
- package/src/hooks/semantic/preconditions.ts +1 -1
- package/src/hooks/semantic/types.ts +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13t1zkw._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_13kfn90._.js +0 -23
- package/.next/standalone/.next/static/chunks/06dnzbolj00mc.js +0 -6
- package/.next/standalone/.next/static/chunks/16f3fa-lx38hk.js +0 -1
- package/.next/standalone/.next/static/chunks/2g2tki08kdhie.js +0 -1
- package/.next/standalone/.next/static/chunks/3-nbtkhg9y-1j.js +0 -1
- package/.next/standalone/.next/static/chunks/355km0ihuqo1p.js +0 -1
- /package/.next/standalone/.next/static/{5yKM8NoTOpUI0MoQl8eo5 → z1C0kJVF0NCtWn5R88hW3}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{5yKM8NoTOpUI0MoQl8eo5 → z1C0kJVF0NCtWn5R88hW3}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{5yKM8NoTOpUI0MoQl8eo5 → z1C0kJVF0NCtWn5R88hW3}/_ssgManifest.js +0 -0
|
@@ -6217,6 +6217,22 @@ def render_deploy_plan(plan: Any, *, applied: bool = False) -> None:
|
|
|
6217
6217
|
_stdout.print(); _stdout.print(Padding(card, (0, 0, 0, 2))); _stdout.print()
|
|
6218
6218
|
|
|
6219
6219
|
|
|
6220
|
+
def jev_machine_counts(summary: dict) -> tuple:
|
|
6221
|
+
"""``(observe, enforce)`` machines running Jev, from the summary's ``jev.machines``.
|
|
6222
|
+
|
|
6223
|
+
``(0, 0)`` when the server says nothing about Jev.
|
|
6224
|
+
"""
|
|
6225
|
+
jev = summary.get("jev") if isinstance(summary, dict) else None
|
|
6226
|
+
machines = jev.get("machines") if isinstance(jev, dict) else None
|
|
6227
|
+
if not isinstance(machines, dict):
|
|
6228
|
+
return 0, 0
|
|
6229
|
+
|
|
6230
|
+
def count(v) -> int:
|
|
6231
|
+
return v if isinstance(v, int) and not isinstance(v, bool) and v > 0 else 0
|
|
6232
|
+
|
|
6233
|
+
return count(machines.get("observe")), count(machines.get("enforce"))
|
|
6234
|
+
|
|
6235
|
+
|
|
6220
6236
|
def render_guardrails(summary: dict, timeline: Optional[dict] = None) -> None:
|
|
6221
6237
|
"""``fp guardrails`` — what actually happened, as opposed to what was intended."""
|
|
6222
6238
|
totals = summary.get("totals") or {}
|
|
@@ -6230,6 +6246,16 @@ def render_guardrails(summary: dict, timeline: Optional[dict] = None) -> None:
|
|
|
6230
6246
|
stat.append(" machines enforcing", style=theme.LABEL)
|
|
6231
6247
|
body = [stat]
|
|
6232
6248
|
|
|
6249
|
+
observe, enforce = jev_machine_counts(summary)
|
|
6250
|
+
if observe or enforce:
|
|
6251
|
+
jev = Text()
|
|
6252
|
+
jev.append("jev ", style=theme.LABEL)
|
|
6253
|
+
jev.append(str(observe), style="bold white")
|
|
6254
|
+
jev.append(" observe ", style=theme.LABEL)
|
|
6255
|
+
jev.append(str(enforce), style="bold white")
|
|
6256
|
+
jev.append(" enforce", style=theme.LABEL)
|
|
6257
|
+
body.append(jev)
|
|
6258
|
+
|
|
6233
6259
|
if timeline:
|
|
6234
6260
|
# Every source, summed — a sparkline drawn from series[0] alone sat
|
|
6235
6261
|
# beside a headline number computed from ALL sources, so the shape and
|
|
@@ -1730,3 +1730,30 @@ def test_guardrails_sparkline_uses_every_source(capsys):
|
|
|
1730
1730
|
truncated_spark = sparkline([1])
|
|
1731
1731
|
assert merged_spark != truncated_spark, "the fixture no longer distinguishes the two paths"
|
|
1732
1732
|
assert merged_spark in out, f"sparkline is not drawn from every source: {out!r}"
|
|
1733
|
+
|
|
1734
|
+
|
|
1735
|
+
def test_jev_machine_counts_reads_observe_and_enforce():
|
|
1736
|
+
from fp_cli.output import jev_machine_counts
|
|
1737
|
+
|
|
1738
|
+
assert jev_machine_counts({"jev": {"machines": {"observe": 3, "enforce": 2}}}) == (3, 2)
|
|
1739
|
+
assert jev_machine_counts({"jev": {"machines": {"enforce": 1}}}) == (0, 1)
|
|
1740
|
+
assert jev_machine_counts({}) == (0, 0)
|
|
1741
|
+
assert jev_machine_counts({"jev": None}) == (0, 0)
|
|
1742
|
+
assert jev_machine_counts({"jev": {"machines": {"observe": "x", "enforce": True}}}) == (0, 0)
|
|
1743
|
+
|
|
1744
|
+
|
|
1745
|
+
def test_guardrails_shows_jev_machines_per_mode(capsys):
|
|
1746
|
+
from fp_cli.output import render_guardrails
|
|
1747
|
+
|
|
1748
|
+
summary = {
|
|
1749
|
+
"hours": 24,
|
|
1750
|
+
"policies": [],
|
|
1751
|
+
"totals": {"evaluated": 1, "blocked": 0, "enforcingMachines": 1, "reportingMachines": 1},
|
|
1752
|
+
"jev": {"machines": {"observe": 2, "enforce": 1}},
|
|
1753
|
+
}
|
|
1754
|
+
render_guardrails(summary)
|
|
1755
|
+
out = capsys.readouterr().out
|
|
1756
|
+
assert "2 observe" in out and "1 enforce" in out
|
|
1757
|
+
|
|
1758
|
+
render_guardrails({**summary, "jev": {"machines": {"observe": 0, "enforce": 0}}})
|
|
1759
|
+
assert "jev" not in capsys.readouterr().out
|
|
@@ -21,11 +21,20 @@ Then run:
|
|
|
21
21
|
failproofai policies --install --cli hermes --scope user
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
The installer symlinks `<HERMES_HOME>/plugins/failproofai` in every discovered
|
|
25
|
+
profile to this directory and adds `failproofai` to `plugins.enabled` in that
|
|
26
|
+
profile's `config.yaml`. Hermes' plugin scan follows the link, so an npm
|
|
27
|
+
upgrade updates the plugin with no reinstall. Where a symlink cannot be
|
|
28
|
+
created, the files are copied instead and marked `.failproofai-managed`.
|
|
29
|
+
Reinstall replaces only such a marked copy or a link into a FailproofAI
|
|
30
|
+
`hermes-plugin/`; an unrelated plugin with the same name is never overwritten.
|
|
31
|
+
Python may write `__pycache__/` here when the package directory is writable;
|
|
32
|
+
it goes with the package on upgrade and is skipped when it cannot be written.
|
|
33
|
+
|
|
34
|
+
`failproofai update` moves profiles that already use FailproofAI (legacy shell
|
|
35
|
+
hooks or a copied plugin) to the link. Legacy shell hooks never ran for Hermes
|
|
36
|
+
cron jobs, so `update` exits non-zero and keeps the shell hooks when the
|
|
37
|
+
running daemon cannot serve the plugin.
|
|
29
38
|
|
|
30
39
|
Legacy FailproofAI shell hooks are removed during migration. Operator-owned
|
|
31
40
|
hooks and unrelated plugin settings are preserved. No dashboard deployment or
|
|
@@ -118,7 +127,8 @@ untrusted evaluation failures.
|
|
|
118
127
|
## Diagnostics and rollback
|
|
119
128
|
|
|
120
129
|
`failproofai config --status` reports each existing Hermes profile as healthy,
|
|
121
|
-
disabled, incomplete,
|
|
130
|
+
disabled, incomplete, duplicated with a legacy shell hook, or still on legacy
|
|
131
|
+
shell hooks alone (Hermes cron jobs are not checked). Hermes-side load
|
|
122
132
|
errors are available through:
|
|
123
133
|
|
|
124
134
|
```bash
|
|
@@ -134,5 +144,5 @@ the integration with:
|
|
|
134
144
|
failproofai policies --uninstall --cli hermes --scope user
|
|
135
145
|
```
|
|
136
146
|
|
|
137
|
-
Uninstall removes the config registration and
|
|
138
|
-
|
|
147
|
+
Uninstall removes the config registration and the profile's link (or marked
|
|
148
|
+
copy); it never removes this package directory.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "failproofai",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9-beta.0",
|
|
4
4
|
"description": "Observability and enforcement for AI agent harnesses. 40 built-in policies hooked into 12 of them — Claude Code, Codex, Cursor, Hermes, OpenClaw and more — blocking the tool call before it runs. Local dashboard included, no account needed.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"failproofai": "./dist/cli.mjs",
|
|
@@ -116,21 +116,21 @@
|
|
|
116
116
|
"postcss": "8.5.26",
|
|
117
117
|
"eslint-plugin-react-hooks": "7.0.1",
|
|
118
118
|
"vite": "8.0.16",
|
|
119
|
-
"undici": "7.29.
|
|
119
|
+
"undici": "7.29.1",
|
|
120
120
|
"brace-expansion": "5.0.9",
|
|
121
121
|
"sharp": "0.35.4",
|
|
122
122
|
"browserslist": "4.28.8"
|
|
123
123
|
},
|
|
124
124
|
"optionalDependencies": {
|
|
125
|
-
"@failproofai/failproofaid-linux-x64": "1.0.
|
|
126
|
-
"@failproofai/failproofaid-linux-arm64": "1.0.
|
|
127
|
-
"@failproofai/failproofaid-darwin-x64": "1.0.
|
|
128
|
-
"@failproofai/failproofaid-darwin-arm64": "1.0.
|
|
125
|
+
"@failproofai/failproofaid-linux-x64": "1.0.9-beta.0",
|
|
126
|
+
"@failproofai/failproofaid-linux-arm64": "1.0.9-beta.0",
|
|
127
|
+
"@failproofai/failproofaid-darwin-x64": "1.0.9-beta.0",
|
|
128
|
+
"@failproofai/failproofaid-darwin-arm64": "1.0.9-beta.0"
|
|
129
129
|
},
|
|
130
130
|
"failproofaidBinaries": {
|
|
131
|
-
"linux-x64": "
|
|
132
|
-
"linux-arm64": "
|
|
133
|
-
"darwin-x64": "
|
|
134
|
-
"darwin-arm64": "
|
|
131
|
+
"linux-x64": "044b6619007227b8aa1fc1095b8c61a17bd90e11da53183ac1f5adecdcae6839",
|
|
132
|
+
"linux-arm64": "479450d7d15c52a59bd1a8cf4c7086be9210e8d31ad4f98d99b123f571e944bd",
|
|
133
|
+
"darwin-x64": "11562912ff726195bfb966ed24a774ffea38d01acc3edc1f9bfa3ea9c298977f",
|
|
134
|
+
"darwin-arm64": "5bbaee1ec89d2d8032b7f16e502fb96891fbc6aa2ee6c861f43a64a0a60e61ba"
|
|
135
135
|
}
|
|
136
136
|
}
|
|
@@ -9,7 +9,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
|
|
|
9
9
|
const hostname = process.env.HOSTNAME || '0.0.0.0'
|
|
10
10
|
|
|
11
11
|
let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
|
|
12
|
-
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"1.0.
|
|
12
|
+
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"1.0.9-beta.0"},"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"instrumentationClientInject":[],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/failproofai/failproofai","enablePrerenderSourceMaps":true,"cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":true,"coldCacheBadge":false,"devValidationWorker":true,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"dynamicOnHover":false,"useOffline":false,"varyParams":true,"optimisticRouting":true,"instrumentationClientRouterTransitionEvents":false,"prefetchInlining":{"maxSize":2048,"maxBundleSize":10240},"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptOperationCache":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"devMemoryThresholdRestart":true,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"requestInsights":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"useTypeScriptCli":true,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":true,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"serverComponentsHmrCancellation":false,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":true,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","turbopackMemoryEvictionMode":"auto","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"useCacheTimeout":54,"instantInsights":{"validationLevel":"warning"},"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","outputFileTracingExcludes":{"*":["node_modules/@img/**","node_modules/sharp/**"]},"turbopack":{"root":"/home/runner/work/failproofai/failproofai"},"repoRoot":"/home/runner/work/failproofai/failproofai","distDirRoot":".next"}
|
|
13
13
|
|
|
14
14
|
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
|
|
15
15
|
|
package/bin/failproofai.mjs
CHANGED
|
@@ -965,7 +965,7 @@ async function runCli() {
|
|
|
965
965
|
"",
|
|
966
966
|
"FailproofAI Cloud needs no setup here: `failproofai config --token",
|
|
967
967
|
"<key>` with a key that carries jev:evaluate (the \"machine\" preset)",
|
|
968
|
-
"turns it on in
|
|
968
|
+
"turns it on in observe mode when there is no jev.json yet — except",
|
|
969
969
|
"with --no-transcripts, which only stores the key; then",
|
|
970
970
|
"`failproofai jev setup --provider failproofai` switches it on. Its",
|
|
971
971
|
"key stays in credentials.json; no --url ever selects it.",
|
|
@@ -982,7 +982,7 @@ async function runCli() {
|
|
|
982
982
|
["--account-id <id>", "Cloudflare account id (32 hex characters)."],
|
|
983
983
|
["--base-url <url>", "Override the API base; `default` clears it."],
|
|
984
984
|
["--model <id>", "Override the model id; `default` clears it."],
|
|
985
|
-
["--mode <m>", "enforce (default),
|
|
985
|
+
["--mode <m>", "enforce (default), observe (log Jev, enforce regex), or off."],
|
|
986
986
|
["--timeout-ms <n>", "Per-call budget before falling back. Default 3000."],
|
|
987
987
|
],
|
|
988
988
|
},
|
|
@@ -993,7 +993,7 @@ async function runCli() {
|
|
|
993
993
|
" else can read — or one in a directory anyone else can WRITE, who",
|
|
994
994
|
" could replace it — is refused; a repository can never set it.",
|
|
995
995
|
"• Re-running setup for the same provider keeps the key, so",
|
|
996
|
-
" `failproofai jev setup --mode
|
|
996
|
+
" `failproofai jev setup --mode observe` just switches the mode.",
|
|
997
997
|
"• The daemon does not see your shell's environment: keep the key in",
|
|
998
998
|
" the file on a machine set up with `failproofai config`.",
|
|
999
999
|
"• --token is the fast path, not the safe one: your shell history keeps",
|
|
@@ -1007,7 +1007,7 @@ async function runCli() {
|
|
|
1007
1007
|
"failproofai jev --url https://openrouter.ai/api/v1 --token <token>",
|
|
1008
1008
|
"failproofai jev setup --provider typesafe --key-stdin < ~/typesafe.key",
|
|
1009
1009
|
"failproofai jev setup --provider cloudflare --account-id <id> --key-stdin",
|
|
1010
|
-
"failproofai config --token <key> (FailproofAI Cloud,
|
|
1010
|
+
"failproofai config --token <key> (FailproofAI Cloud, observe mode)",
|
|
1011
1011
|
"failproofai jev setup --mode enforce (switch the configured route's mode)",
|
|
1012
1012
|
"failproofai jev setup --mode off (keep the config, stop asking Jev)",
|
|
1013
1013
|
"failproofai jev test",
|
|
@@ -1180,6 +1180,9 @@ async function runCli() {
|
|
|
1180
1180
|
"",
|
|
1181
1181
|
"This does the rest of the upgrade: runs any pending layout migrations,",
|
|
1182
1182
|
"puts the matching daemon binary in place, and restarts the service.",
|
|
1183
|
+
"Hermes profiles already using failproofai are moved to the linked",
|
|
1184
|
+
"native plugin (legacy shell hooks never checked Hermes cron jobs).",
|
|
1185
|
+
"Exits non-zero when any half could not be brought current.",
|
|
1183
1186
|
],
|
|
1184
1187
|
},
|
|
1185
1188
|
{
|
|
@@ -1270,17 +1273,40 @@ async function runCli() {
|
|
|
1270
1273
|
}
|
|
1271
1274
|
}
|
|
1272
1275
|
|
|
1276
|
+
// Hermes is migrated AFTER the daemon, and gated on what the daemon that is
|
|
1277
|
+
// now running can do: the native plugin needs `policyEvaluation`, which
|
|
1278
|
+
// ≤1.0.5 daemons lack, so when the swap above could not happen (a sudo
|
|
1279
|
+
// system service with no sudo) the shell hooks stay and this fails loudly.
|
|
1280
|
+
let hermesOk = true;
|
|
1281
|
+
let hermesMigrated = 0;
|
|
1282
|
+
try {
|
|
1283
|
+
const { runHermesUpdateMigration } = await import("../src/hooks/hermes-update");
|
|
1284
|
+
const svc = await import("../src/hooks/daemon-service");
|
|
1285
|
+
const hermesResult = await runHermesUpdateMigration({
|
|
1286
|
+
daemonSupportsPolicyEvaluation: () => svc.probeDaemonPolicyEvaluation(),
|
|
1287
|
+
});
|
|
1288
|
+
if (hermesResult.lines.length > 0) report.push("", ...hermesResult.lines);
|
|
1289
|
+
hermesOk = hermesResult.ok;
|
|
1290
|
+
hermesMigrated = hermesResult.profiles.filter((p) => p.status === "migrated").length;
|
|
1291
|
+
} catch (err) {
|
|
1292
|
+
report.push("", `Hermes migration failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1293
|
+
hermesOk = false;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
const updateOk = daemonOk && !migrationFailed && hermesOk;
|
|
1273
1297
|
await printReport("update", report, {
|
|
1274
|
-
ok:
|
|
1298
|
+
ok: updateOk,
|
|
1275
1299
|
meta: `v${version}`,
|
|
1276
1300
|
});
|
|
1277
1301
|
await track("cli_update", {
|
|
1278
|
-
ok:
|
|
1302
|
+
ok: updateOk,
|
|
1279
1303
|
migrations: migrationsRan,
|
|
1280
1304
|
migration_failed: migrationFailed,
|
|
1305
|
+
hermes_ok: hermesOk,
|
|
1306
|
+
hermes_migrated: hermesMigrated,
|
|
1281
1307
|
});
|
|
1282
1308
|
lastSubcommand = null;
|
|
1283
|
-
await exitAfterFlush(
|
|
1309
|
+
await exitAfterFlush(updateOk ? 0 : 1);
|
|
1284
1310
|
return;
|
|
1285
1311
|
}
|
|
1286
1312
|
|