agent-relay 1.1.0 → 1.2.3
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/.gitattributes +3 -0
- package/.nvmrc +1 -0
- package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.json +65 -0
- package/.trajectories/completed/2026-01/traj_1dviorhnkcb5.md +37 -0
- package/.trajectories/completed/2026-01/traj_1k5if5snst2e.json +65 -0
- package/.trajectories/completed/2026-01/traj_1k5if5snst2e.md +37 -0
- package/.trajectories/completed/2026-01/traj_1rp3rges5811.json +49 -0
- package/.trajectories/completed/2026-01/traj_1rp3rges5811.md +31 -0
- package/.trajectories/completed/2026-01/traj_22bhyulruouw.json +113 -0
- package/.trajectories/completed/2026-01/traj_22bhyulruouw.md +57 -0
- package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.json +53 -0
- package/.trajectories/completed/2026-01/traj_2dao7ddgnta0.md +32 -0
- package/.trajectories/completed/2026-01/traj_3t0440mjeunc.json +26 -0
- package/.trajectories/completed/2026-01/traj_3t0440mjeunc.md +6 -0
- package/.trajectories/completed/2026-01/traj_45x9494d9xnr.json +47 -0
- package/.trajectories/completed/2026-01/traj_45x9494d9xnr.md +32 -0
- package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.json +53 -0
- package/.trajectories/completed/2026-01/traj_4aa0bb77s4nh.md +32 -0
- package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.json +59 -0
- package/.trajectories/completed/2026-01/traj_5lhmzq8rxpqv.md +33 -0
- package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.json +53 -0
- package/.trajectories/completed/2026-01/traj_5vr4e9erb1fs.md +32 -0
- package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.json +48 -0
- package/.trajectories/completed/2026-01/traj_6fgiwdoklvym.md +24 -0
- package/.trajectories/completed/2026-01/traj_7ludwvz45veh.json +209 -0
- package/.trajectories/completed/2026-01/traj_7ludwvz45veh.md +97 -0
- package/.trajectories/completed/2026-01/traj_9921cuhel0pj.json +48 -0
- package/.trajectories/completed/2026-01/traj_9921cuhel0pj.md +24 -0
- package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.json +49 -0
- package/.trajectories/completed/2026-01/traj_ajs7zqfux4wc.md +23 -0
- package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.json +53 -0
- package/.trajectories/completed/2026-01/traj_cvtqhlwcq9s0.md +32 -0
- package/.trajectories/completed/2026-01/traj_cxofprm2m2en.json +49 -0
- package/.trajectories/completed/2026-01/traj_cxofprm2m2en.md +31 -0
- package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.json +26 -0
- package/.trajectories/completed/2026-01/traj_d2hhz3k0vrhn.md +6 -0
- package/.trajectories/completed/2026-01/traj_dfuvww9pege5.json +59 -0
- package/.trajectories/completed/2026-01/traj_dfuvww9pege5.md +37 -0
- package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.json +77 -0
- package/.trajectories/completed/2026-01/traj_g0fisy9h51mf.md +42 -0
- package/.trajectories/completed/2026-01/traj_gjdre5voouod.json +53 -0
- package/.trajectories/completed/2026-01/traj_gjdre5voouod.md +32 -0
- package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.json +25 -0
- package/.trajectories/completed/2026-01/traj_gtlyqtta3x8l.md +15 -0
- package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.json +101 -0
- package/.trajectories/completed/2026-01/traj_h4xijiuip3w4.md +44 -0
- package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.json +22 -0
- package/.trajectories/completed/2026-01/traj_hhxte7w4gjjx.md +5 -0
- package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.json +53 -0
- package/.trajectories/completed/2026-01/traj_hpungyhoj6v5.md +32 -0
- package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.json +25 -0
- package/.trajectories/completed/2026-01/traj_m2xkjv0w2sq7.md +15 -0
- package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.json +53 -0
- package/.trajectories/completed/2026-01/traj_noq5zbvnrdvz.md +32 -0
- package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.json +53 -0
- package/.trajectories/completed/2026-01/traj_ntbs6ppopf46.md +32 -0
- package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.json +48 -0
- package/.trajectories/completed/2026-01/traj_ozd98si6a7ns.md +24 -0
- package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.json +53 -0
- package/.trajectories/completed/2026-01/traj_prdza7a5cxp5.md +32 -0
- package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.json +77 -0
- package/.trajectories/completed/2026-01/traj_qb3twvvywfwi.md +42 -0
- package/.trajectories/completed/2026-01/traj_qft54mi7nfor.json +53 -0
- package/.trajectories/completed/2026-01/traj_qft54mi7nfor.md +32 -0
- package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.json +83 -0
- package/.trajectories/completed/2026-01/traj_qx9uhf8whhxo.md +47 -0
- package/.trajectories/completed/2026-01/traj_rd9toccj18a0.json +59 -0
- package/.trajectories/completed/2026-01/traj_rd9toccj18a0.md +37 -0
- package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.json +48 -0
- package/.trajectories/completed/2026-01/traj_rt4fiw3ecp50.md +16 -0
- package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.json +59 -0
- package/.trajectories/completed/2026-01/traj_st8j35b0hrlc.md +37 -0
- package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.json +53 -0
- package/.trajectories/completed/2026-01/traj_t1yy8m7hbuxp.md +32 -0
- package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.json +84 -0
- package/.trajectories/completed/2026-01/traj_tmux_orchestrator_analysis.md +109 -0
- package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.json +53 -0
- package/.trajectories/completed/2026-01/traj_u9n9eqasw16k.md +32 -0
- package/.trajectories/completed/2026-01/traj_v87hypnongqx.json +71 -0
- package/.trajectories/completed/2026-01/traj_v87hypnongqx.md +42 -0
- package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.json +53 -0
- package/.trajectories/completed/2026-01/traj_wkp2fgzdyinb.md +32 -0
- package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.json +20 -0
- package/.trajectories/completed/2026-01/traj_x14t8w8rn7xg.md +6 -0
- package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.json +175 -0
- package/.trajectories/completed/2026-01/traj_xnwbznkvv8ua.md +82 -0
- package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.json +47 -0
- package/.trajectories/completed/2026-01/traj_ysjc8zaeqtd3.md +32 -0
- package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.json +59 -0
- package/.trajectories/completed/2026-01/traj_yvdadtvdgnz3.md +37 -0
- package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.json +53 -0
- package/.trajectories/completed/2026-01/traj_z0vcw1wrzide.md +32 -0
- package/.trajectories/index.json +314 -0
- package/ARCHITECTURE.md +1245 -0
- package/README.md +1 -1
- package/TESTING.md +278 -0
- package/deploy/init-db.sql +5 -0
- package/deploy/scripts/setup-fly-workspaces.sh +69 -0
- package/deploy/scripts/setup-railway.sh +75 -0
- package/deploy/workspace/entrypoint-browser.sh +118 -0
- package/deploy/workspace/entrypoint.sh +348 -0
- package/deploy/workspace/git-credential-relay +111 -0
- package/dist/bridge/spawner.d.ts +53 -0
- package/dist/bridge/spawner.js +203 -19
- package/dist/bridge/types.d.ts +12 -0
- package/dist/cli/index.js +618 -5
- package/dist/cloud/api/auth.d.ts +3 -2
- package/dist/cloud/api/auth.js +10 -98
- package/dist/cloud/api/billing.js +30 -9
- package/dist/cloud/api/cli-pty-runner.d.ts +54 -0
- package/dist/cloud/api/cli-pty-runner.js +119 -0
- package/dist/cloud/api/codex-auth-helper.d.ts +15 -0
- package/dist/cloud/api/codex-auth-helper.js +100 -0
- package/dist/cloud/api/generic-webhooks.d.ts +8 -0
- package/dist/cloud/api/generic-webhooks.js +129 -0
- package/dist/cloud/api/git.d.ts +8 -0
- package/dist/cloud/api/git.js +152 -0
- package/dist/cloud/api/github-app.d.ts +11 -0
- package/dist/cloud/api/github-app.js +189 -0
- package/dist/cloud/api/middleware/planLimits.d.ts +7 -0
- package/dist/cloud/api/middleware/planLimits.js +39 -1
- package/dist/cloud/api/monitoring.d.ts +11 -0
- package/dist/cloud/api/monitoring.js +578 -0
- package/dist/cloud/api/nango-auth.d.ts +9 -0
- package/dist/cloud/api/nango-auth.js +377 -0
- package/dist/cloud/api/onboarding.d.ts +8 -1
- package/dist/cloud/api/onboarding.js +313 -119
- package/dist/cloud/api/policy.d.ts +8 -0
- package/dist/cloud/api/policy.js +229 -0
- package/dist/cloud/api/providers.js +114 -42
- package/dist/cloud/api/repos.d.ts +1 -0
- package/dist/cloud/api/repos.js +186 -0
- package/dist/cloud/api/test-helpers.d.ts +10 -0
- package/dist/cloud/api/test-helpers.js +575 -0
- package/dist/cloud/api/webhooks.d.ts +8 -0
- package/dist/cloud/api/webhooks.js +645 -0
- package/dist/cloud/api/workspaces.js +320 -12
- package/dist/cloud/billing/plans.js +32 -19
- package/dist/cloud/billing/types.d.ts +9 -3
- package/dist/cloud/config.d.ts +9 -2
- package/dist/cloud/config.js +13 -4
- package/dist/cloud/db/drizzle.d.ts +84 -1
- package/dist/cloud/db/drizzle.js +470 -0
- package/dist/cloud/db/index.d.ts +9 -4
- package/dist/cloud/db/index.js +11 -3
- package/dist/cloud/db/schema.d.ts +3283 -556
- package/dist/cloud/db/schema.js +314 -1
- package/dist/cloud/index.d.ts +1 -0
- package/dist/cloud/index.js +2 -0
- package/dist/cloud/provisioner/index.d.ts +56 -0
- package/dist/cloud/provisioner/index.js +676 -34
- package/dist/cloud/server.d.ts +1 -0
- package/dist/cloud/server.js +362 -13
- package/dist/cloud/services/auto-scaler.d.ts +152 -0
- package/dist/cloud/services/auto-scaler.js +439 -0
- package/dist/cloud/services/capacity-manager.d.ts +148 -0
- package/dist/cloud/services/capacity-manager.js +449 -0
- package/dist/cloud/services/ci-agent-spawner.d.ts +49 -0
- package/dist/cloud/services/ci-agent-spawner.js +373 -0
- package/dist/cloud/services/index.d.ts +12 -0
- package/dist/cloud/services/index.js +15 -0
- package/dist/cloud/services/mention-handler.d.ts +65 -0
- package/dist/cloud/services/mention-handler.js +405 -0
- package/dist/cloud/services/nango.d.ts +186 -0
- package/dist/cloud/services/nango.js +344 -0
- package/dist/cloud/services/persistence.d.ts +131 -0
- package/dist/cloud/services/persistence.js +200 -0
- package/dist/cloud/services/planLimits.d.ts +37 -0
- package/dist/cloud/services/planLimits.js +86 -5
- package/dist/cloud/services/scaling-orchestrator.d.ts +159 -0
- package/dist/cloud/services/scaling-orchestrator.js +502 -0
- package/dist/cloud/services/scaling-policy.d.ts +121 -0
- package/dist/cloud/services/scaling-policy.js +415 -0
- package/dist/cloud/vault/index.js +1 -1
- package/dist/cloud/webhooks/index.d.ts +24 -0
- package/dist/cloud/webhooks/index.js +29 -0
- package/dist/cloud/webhooks/parsers/github.d.ts +8 -0
- package/dist/cloud/webhooks/parsers/github.js +234 -0
- package/dist/cloud/webhooks/parsers/index.d.ts +23 -0
- package/dist/cloud/webhooks/parsers/index.js +30 -0
- package/dist/cloud/webhooks/parsers/linear.d.ts +9 -0
- package/dist/cloud/webhooks/parsers/linear.js +258 -0
- package/dist/cloud/webhooks/parsers/slack.d.ts +9 -0
- package/dist/cloud/webhooks/parsers/slack.js +214 -0
- package/dist/cloud/webhooks/responders/github.d.ts +8 -0
- package/dist/cloud/webhooks/responders/github.js +73 -0
- package/dist/cloud/webhooks/responders/index.d.ts +23 -0
- package/dist/cloud/webhooks/responders/index.js +30 -0
- package/dist/cloud/webhooks/responders/linear.d.ts +9 -0
- package/dist/cloud/webhooks/responders/linear.js +149 -0
- package/dist/cloud/webhooks/responders/slack.d.ts +20 -0
- package/dist/cloud/webhooks/responders/slack.js +178 -0
- package/dist/cloud/webhooks/router.d.ts +25 -0
- package/dist/cloud/webhooks/router.js +504 -0
- package/dist/cloud/webhooks/rules-engine.d.ts +24 -0
- package/dist/cloud/webhooks/rules-engine.js +287 -0
- package/dist/cloud/webhooks/types.d.ts +186 -0
- package/dist/cloud/webhooks/types.js +8 -0
- package/dist/continuity/formatter.d.ts +51 -0
- package/dist/continuity/formatter.js +313 -0
- package/dist/continuity/handoff-store.d.ts +67 -0
- package/dist/continuity/handoff-store.js +472 -0
- package/dist/continuity/index.d.ts +45 -0
- package/dist/continuity/index.js +48 -0
- package/dist/continuity/ledger-store.d.ts +110 -0
- package/dist/continuity/ledger-store.js +500 -0
- package/dist/continuity/manager.d.ts +178 -0
- package/dist/continuity/manager.js +562 -0
- package/dist/continuity/parser.d.ts +76 -0
- package/dist/continuity/parser.js +579 -0
- package/dist/continuity/types.d.ts +180 -0
- package/dist/continuity/types.js +9 -0
- package/dist/daemon/agent-manager.d.ts +27 -0
- package/dist/daemon/agent-manager.js +107 -6
- package/dist/daemon/agent-registry.d.ts +32 -0
- package/dist/daemon/agent-registry.js +42 -2
- package/dist/daemon/api.d.ts +12 -0
- package/dist/daemon/api.js +131 -2
- package/dist/daemon/cli-auth.d.ts +67 -0
- package/dist/daemon/cli-auth.js +537 -0
- package/dist/daemon/cloud-sync.js +9 -7
- package/dist/daemon/orchestrator.js +30 -0
- package/dist/daemon/router.d.ts +5 -0
- package/dist/daemon/router.js +78 -26
- package/dist/daemon/server.d.ts +5 -0
- package/dist/daemon/server.js +9 -1
- package/dist/daemon/services/browser-testing.d.ts +88 -0
- package/dist/daemon/services/browser-testing.js +244 -0
- package/dist/daemon/services/container-spawner.d.ts +135 -0
- package/dist/daemon/services/container-spawner.js +313 -0
- package/dist/daemon/types.d.ts +5 -1
- package/dist/dashboard/out/404.html +1 -1
- package/dist/dashboard/out/_next/static/chunks/116-2502180def231162.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/699-3b1cd6618a45d259.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/724-2dae7627550ab88f.js +9 -0
- package/dist/dashboard/out/_next/static/chunks/766-1f2dd8cb7f766b0b.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-3fdfa60e53f2810d.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/page-e6381e5a6e1fbcfd.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-3538dfe0ffe984b8.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/history/{page-b6edd4dde8d08194.js → page-abb9ab2d329f56e9.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/app/layout-c0d118c0f92d969c.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/login/page-c22d080201cbd9fb.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-67a3e98d9a43a6ed.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/page-77e9c65420a06cfb.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-b08ed1c34d14434a.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/providers/page-e88bc117ef7671c3.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/signup/page-68d34f50baa8ab6b.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +18 -0
- package/dist/dashboard/out/_next/static/chunks/{main-app-5d692157a8eb1fd9.js → main-app-6e8e8d3ef4e0192a.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/{main-c2f423b9c9f4591b.js → main-ed4e1fb6f29c34cf.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +1 -0
- package/dist/dashboard/out/_next/static/css/29852f26181969a0.css +1 -0
- package/dist/dashboard/out/_next/static/css/7c3ae9e8617d42a5.css +1 -0
- package/dist/dashboard/out/app/onboarding.html +1 -0
- package/dist/dashboard/out/app/onboarding.txt +7 -0
- package/dist/dashboard/out/app.html +1 -14
- package/dist/dashboard/out/app.txt +2 -2
- package/dist/dashboard/out/connect-repos.html +1 -0
- package/dist/dashboard/out/connect-repos.txt +7 -0
- package/dist/dashboard/out/history.html +1 -1
- package/dist/dashboard/out/history.txt +2 -2
- package/dist/dashboard/out/index.html +1 -1
- package/dist/dashboard/out/index.txt +2 -2
- package/dist/dashboard/out/login.html +6 -0
- package/dist/dashboard/out/login.txt +7 -0
- package/dist/dashboard/out/metrics.html +1 -1
- package/dist/dashboard/out/metrics.txt +2 -2
- package/dist/dashboard/out/pricing.html +3 -3
- package/dist/dashboard/out/pricing.txt +2 -2
- package/dist/dashboard/out/providers.html +1 -0
- package/dist/dashboard/out/providers.txt +7 -0
- package/dist/dashboard/out/signup.html +6 -0
- package/dist/dashboard/out/signup.txt +7 -0
- package/dist/dashboard-server/server.js +1308 -8
- package/dist/hooks/emitter.d.ts +40 -0
- package/dist/hooks/emitter.js +63 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.js +3 -0
- package/dist/hooks/registry.d.ts +173 -0
- package/dist/hooks/registry.js +476 -0
- package/dist/hooks/trajectory-hooks.d.ts +52 -0
- package/dist/hooks/trajectory-hooks.js +183 -0
- package/dist/hooks/types.d.ts +141 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/memory/adapters/index.d.ts +8 -0
- package/dist/memory/adapters/index.js +8 -0
- package/dist/memory/adapters/inmemory.d.ts +59 -0
- package/dist/memory/adapters/inmemory.js +195 -0
- package/dist/memory/adapters/supermemory.d.ts +71 -0
- package/dist/memory/adapters/supermemory.js +338 -0
- package/dist/memory/factory.d.ts +48 -0
- package/dist/memory/factory.js +143 -0
- package/dist/memory/index.d.ts +32 -0
- package/dist/memory/index.js +32 -0
- package/dist/memory/memory-hooks.d.ts +60 -0
- package/dist/memory/memory-hooks.js +313 -0
- package/dist/memory/service.d.ts +49 -0
- package/dist/memory/service.js +146 -0
- package/dist/memory/types.d.ts +195 -0
- package/dist/memory/types.js +8 -0
- package/dist/policy/agent-policy.d.ts +225 -0
- package/dist/policy/agent-policy.js +665 -0
- package/dist/policy/cloud-policy-fetcher.d.ts +12 -0
- package/dist/policy/cloud-policy-fetcher.js +64 -0
- package/dist/resiliency/crash-insights.d.ts +156 -0
- package/dist/resiliency/crash-insights.js +492 -0
- package/dist/resiliency/gossip-health.d.ts +137 -0
- package/dist/resiliency/gossip-health.js +241 -0
- package/dist/resiliency/index.d.ts +5 -0
- package/dist/resiliency/index.js +5 -0
- package/dist/resiliency/leader-watchdog.d.ts +109 -0
- package/dist/resiliency/leader-watchdog.js +189 -0
- package/dist/resiliency/memory-monitor.d.ts +172 -0
- package/dist/resiliency/memory-monitor.js +593 -0
- package/dist/resiliency/stateless-lead.d.ts +149 -0
- package/dist/resiliency/stateless-lead.js +308 -0
- package/dist/resiliency/supervisor.d.ts +38 -0
- package/dist/resiliency/supervisor.js +122 -0
- package/dist/shared/cli-auth-config.d.ts +91 -0
- package/dist/shared/cli-auth-config.js +264 -0
- package/dist/storage/adapter.d.ts +1 -1
- package/dist/trajectory/config.d.ts +84 -0
- package/dist/trajectory/config.js +163 -0
- package/dist/trajectory/index.d.ts +8 -0
- package/dist/trajectory/index.js +8 -0
- package/dist/trajectory/integration.d.ts +292 -0
- package/dist/trajectory/integration.js +834 -0
- package/dist/utils/logger.js +1 -1
- package/dist/utils/project-namespace.d.ts +24 -0
- package/dist/utils/project-namespace.js +84 -0
- package/dist/wrapper/parser.d.ts +10 -0
- package/dist/wrapper/parser.js +100 -33
- package/dist/wrapper/pty-wrapper.d.ts +197 -16
- package/dist/wrapper/pty-wrapper.js +943 -106
- package/dist/wrapper/shared.d.ts +165 -0
- package/dist/wrapper/shared.js +270 -0
- package/dist/wrapper/tmux-wrapper.d.ts +73 -11
- package/dist/wrapper/tmux-wrapper.js +541 -120
- package/package.json +16 -16
- package/scripts/postinstall.js +60 -0
- package/test-push.txt +1 -0
- package/bin/tmux +0 -0
- package/dist/bridge/config.d.ts.map +0 -1
- package/dist/bridge/config.js.map +0 -1
- package/dist/bridge/index.d.ts.map +0 -1
- package/dist/bridge/index.js.map +0 -1
- package/dist/bridge/multi-project-client.d.ts.map +0 -1
- package/dist/bridge/multi-project-client.js.map +0 -1
- package/dist/bridge/shadow-cli.d.ts.map +0 -1
- package/dist/bridge/shadow-cli.js.map +0 -1
- package/dist/bridge/shadow-config.d.ts.map +0 -1
- package/dist/bridge/shadow-config.js.map +0 -1
- package/dist/bridge/spawner.d.ts.map +0 -1
- package/dist/bridge/spawner.js.map +0 -1
- package/dist/bridge/teams-config.d.ts.map +0 -1
- package/dist/bridge/teams-config.js.map +0 -1
- package/dist/bridge/types.d.ts.map +0 -1
- package/dist/bridge/types.js.map +0 -1
- package/dist/bridge/utils.d.ts.map +0 -1
- package/dist/bridge/utils.js.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/cloud/api/auth.d.ts.map +0 -1
- package/dist/cloud/api/auth.js.map +0 -1
- package/dist/cloud/api/billing.d.ts.map +0 -1
- package/dist/cloud/api/billing.js.map +0 -1
- package/dist/cloud/api/coordinators.d.ts.map +0 -1
- package/dist/cloud/api/coordinators.js.map +0 -1
- package/dist/cloud/api/daemons.d.ts.map +0 -1
- package/dist/cloud/api/daemons.js.map +0 -1
- package/dist/cloud/api/middleware/planLimits.d.ts.map +0 -1
- package/dist/cloud/api/middleware/planLimits.js.map +0 -1
- package/dist/cloud/api/onboarding.d.ts.map +0 -1
- package/dist/cloud/api/onboarding.js.map +0 -1
- package/dist/cloud/api/providers.d.ts.map +0 -1
- package/dist/cloud/api/providers.js.map +0 -1
- package/dist/cloud/api/repos.d.ts.map +0 -1
- package/dist/cloud/api/repos.js.map +0 -1
- package/dist/cloud/api/teams.d.ts.map +0 -1
- package/dist/cloud/api/teams.js.map +0 -1
- package/dist/cloud/api/usage.d.ts.map +0 -1
- package/dist/cloud/api/usage.js.map +0 -1
- package/dist/cloud/api/workspaces.d.ts.map +0 -1
- package/dist/cloud/api/workspaces.js.map +0 -1
- package/dist/cloud/billing/index.d.ts.map +0 -1
- package/dist/cloud/billing/index.js.map +0 -1
- package/dist/cloud/billing/plans.d.ts.map +0 -1
- package/dist/cloud/billing/plans.js.map +0 -1
- package/dist/cloud/billing/service.d.ts.map +0 -1
- package/dist/cloud/billing/service.js.map +0 -1
- package/dist/cloud/billing/types.d.ts.map +0 -1
- package/dist/cloud/billing/types.js.map +0 -1
- package/dist/cloud/config.d.ts.map +0 -1
- package/dist/cloud/config.js.map +0 -1
- package/dist/cloud/db/drizzle.d.ts.map +0 -1
- package/dist/cloud/db/drizzle.js.map +0 -1
- package/dist/cloud/db/index.d.ts.map +0 -1
- package/dist/cloud/db/index.js.map +0 -1
- package/dist/cloud/db/schema.d.ts.map +0 -1
- package/dist/cloud/db/schema.js.map +0 -1
- package/dist/cloud/index.d.ts.map +0 -1
- package/dist/cloud/index.js.map +0 -1
- package/dist/cloud/provisioner/index.d.ts.map +0 -1
- package/dist/cloud/provisioner/index.js.map +0 -1
- package/dist/cloud/server.d.ts.map +0 -1
- package/dist/cloud/server.js.map +0 -1
- package/dist/cloud/services/coordinator.d.ts.map +0 -1
- package/dist/cloud/services/coordinator.js.map +0 -1
- package/dist/cloud/services/planLimits.d.ts.map +0 -1
- package/dist/cloud/services/planLimits.js.map +0 -1
- package/dist/cloud/vault/index.d.ts.map +0 -1
- package/dist/cloud/vault/index.js.map +0 -1
- package/dist/daemon/agent-manager.d.ts.map +0 -1
- package/dist/daemon/agent-manager.js.map +0 -1
- package/dist/daemon/agent-registry.d.ts.map +0 -1
- package/dist/daemon/agent-registry.js.map +0 -1
- package/dist/daemon/api.d.ts.map +0 -1
- package/dist/daemon/api.js.map +0 -1
- package/dist/daemon/auth.d.ts.map +0 -1
- package/dist/daemon/auth.js.map +0 -1
- package/dist/daemon/cloud-sync.d.ts.map +0 -1
- package/dist/daemon/cloud-sync.js.map +0 -1
- package/dist/daemon/connection.d.ts.map +0 -1
- package/dist/daemon/connection.js.map +0 -1
- package/dist/daemon/index.d.ts.map +0 -1
- package/dist/daemon/index.js.map +0 -1
- package/dist/daemon/orchestrator.d.ts.map +0 -1
- package/dist/daemon/orchestrator.js.map +0 -1
- package/dist/daemon/registry.d.ts.map +0 -1
- package/dist/daemon/registry.js.map +0 -1
- package/dist/daemon/router.d.ts.map +0 -1
- package/dist/daemon/router.js.map +0 -1
- package/dist/daemon/server.d.ts.map +0 -1
- package/dist/daemon/server.js.map +0 -1
- package/dist/daemon/types.d.ts.map +0 -1
- package/dist/daemon/types.js.map +0 -1
- package/dist/daemon/workspace-manager.d.ts.map +0 -1
- package/dist/daemon/workspace-manager.js.map +0 -1
- package/dist/dashboard/out/_next/static/chunks/693-7b3301d8f6bc5014.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/713-f78477eb185f1f4d.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/766-e53e1cfe39b0b5b5.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/900-037c64bfd797fb2a.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/app/page-e3d9e1f4466b9bae.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/layout-2433bb48965f4333.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-e68825a81db67ba1.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/page-cc108bf68c8a657f.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-d80e03a5297f95b6.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/webpack-a5acc2831d094776.js +0 -1
- package/dist/dashboard/out/_next/static/css/79b80143647a07d7.css +0 -1
- package/dist/dashboard/out/_next/static/css/8cf277370ad48cfe.css +0 -1
- package/dist/dashboard-server/metrics.d.ts.map +0 -1
- package/dist/dashboard-server/metrics.js.map +0 -1
- package/dist/dashboard-server/needs-attention.d.ts.map +0 -1
- package/dist/dashboard-server/needs-attention.js.map +0 -1
- package/dist/dashboard-server/server.d.ts.map +0 -1
- package/dist/dashboard-server/server.js.map +0 -1
- package/dist/dashboard-server/start.d.ts.map +0 -1
- package/dist/dashboard-server/start.js.map +0 -1
- package/dist/hooks/inbox-check/hook.d.ts.map +0 -1
- package/dist/hooks/inbox-check/hook.js.map +0 -1
- package/dist/hooks/inbox-check/index.d.ts.map +0 -1
- package/dist/hooks/inbox-check/index.js.map +0 -1
- package/dist/hooks/inbox-check/types.d.ts.map +0 -1
- package/dist/hooks/inbox-check/types.js.map +0 -1
- package/dist/hooks/inbox-check/utils.d.ts.map +0 -1
- package/dist/hooks/inbox-check/utils.js.map +0 -1
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/types.d.ts.map +0 -1
- package/dist/hooks/types.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/protocol/framing.d.ts.map +0 -1
- package/dist/protocol/framing.js.map +0 -1
- package/dist/protocol/index.d.ts.map +0 -1
- package/dist/protocol/index.js.map +0 -1
- package/dist/protocol/types.d.ts.map +0 -1
- package/dist/protocol/types.js.map +0 -1
- package/dist/resiliency/context-persistence.d.ts.map +0 -1
- package/dist/resiliency/context-persistence.js.map +0 -1
- package/dist/resiliency/health-monitor.d.ts.map +0 -1
- package/dist/resiliency/health-monitor.js.map +0 -1
- package/dist/resiliency/index.d.ts.map +0 -1
- package/dist/resiliency/index.js.map +0 -1
- package/dist/resiliency/logger.d.ts.map +0 -1
- package/dist/resiliency/logger.js.map +0 -1
- package/dist/resiliency/metrics.d.ts.map +0 -1
- package/dist/resiliency/metrics.js.map +0 -1
- package/dist/resiliency/provider-context.d.ts.map +0 -1
- package/dist/resiliency/provider-context.js.map +0 -1
- package/dist/resiliency/supervisor.d.ts.map +0 -1
- package/dist/resiliency/supervisor.js.map +0 -1
- package/dist/state/agent-state.d.ts.map +0 -1
- package/dist/state/agent-state.js.map +0 -1
- package/dist/storage/adapter.d.ts.map +0 -1
- package/dist/storage/adapter.js.map +0 -1
- package/dist/storage/sqlite-adapter.d.ts.map +0 -1
- package/dist/storage/sqlite-adapter.js.map +0 -1
- package/dist/utils/agent-config.d.ts.map +0 -1
- package/dist/utils/agent-config.js.map +0 -1
- package/dist/utils/command-resolver.d.ts.map +0 -1
- package/dist/utils/command-resolver.js.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/name-generator.d.ts.map +0 -1
- package/dist/utils/name-generator.js.map +0 -1
- package/dist/utils/project-namespace.d.ts.map +0 -1
- package/dist/utils/project-namespace.js.map +0 -1
- package/dist/utils/tmux-resolver.d.ts.map +0 -1
- package/dist/utils/tmux-resolver.js.map +0 -1
- package/dist/utils/update-checker.d.ts.map +0 -1
- package/dist/utils/update-checker.js.map +0 -1
- package/dist/wrapper/client.d.ts.map +0 -1
- package/dist/wrapper/client.js.map +0 -1
- package/dist/wrapper/inbox.d.ts.map +0 -1
- package/dist/wrapper/inbox.js.map +0 -1
- package/dist/wrapper/index.d.ts.map +0 -1
- package/dist/wrapper/index.js.map +0 -1
- package/dist/wrapper/parser.d.ts.map +0 -1
- package/dist/wrapper/parser.js.map +0 -1
- package/dist/wrapper/pty-wrapper.d.ts.map +0 -1
- package/dist/wrapper/pty-wrapper.js.map +0 -1
- package/dist/wrapper/tmux-wrapper.d.ts.map +0 -1
- package/dist/wrapper/tmux-wrapper.js.map +0 -1
- package/docs/AGENTS.md +0 -513
- package/docs/ARCHITECTURE_DECISIONS.md +0 -175
- package/docs/CHANGELOG.md +0 -11
- package/docs/CLI-SIMPLIFICATION-COMPLETE.md +0 -48
- package/docs/CLOUD-ARCHITECTURE.md +0 -652
- package/docs/CLOUD-ONBOARDING-DESIGN.md +0 -1983
- package/docs/COMPETITIVE_ANALYSIS.md +0 -897
- package/docs/CONTRIBUTING.md +0 -151
- package/docs/DESIGN_BRIDGE_STAFFING.md +0 -878
- package/docs/DESIGN_V2.md +0 -1079
- package/docs/INTEGRATION-GUIDE.md +0 -926
- package/docs/MONETIZATION.md +0 -1679
- package/docs/PROPOSAL-trajectories.md +0 -1582
- package/docs/PROTOCOL.md +0 -325
- package/docs/SCALING_ANALYSIS.md +0 -280
- package/docs/TESTING_PRESENCE_FEATURES.md +0 -327
- package/docs/TMUX_IMPLEMENTATION_NOTES.md +0 -364
- package/docs/TMUX_IMPROVEMENTS.md +0 -968
- package/docs/agent-relay-snippet.md +0 -168
- package/docs/competitive-analysis-mcp-agent-mail.md +0 -389
- package/docs/dashboard-v2-plan.md +0 -179
- package/docs/guides/CLOUD.md +0 -236
- package/docs/guides/LOCAL.md +0 -535
- package/docs/guides/SELF-HOSTED.md +0 -494
- package/docs/proposals/shadow-as-subagent.md +0 -765
- package/docs/proposals/slack-bot-integration.md +0 -1457
- package/docs/removable-code-analysis.md +0 -24
- package/scripts/dev/PUBLIC_RELEASE_PLAN.md +0 -88
- package/scripts/dev/dev-team-setup.sh +0 -431
- package/scripts/e2e-test.sh +0 -119
- package/scripts/games/game-protocol.md +0 -79
- package/scripts/games/hearts-setup.sh +0 -264
- package/scripts/tictactoe-setup.sh +0 -181
- /package/dist/dashboard/out/_next/static/chunks/{117-b2cd8d6485aacf2b.js → 117-f7b8ab0809342e77.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/{648-8f3f26864ce515e5.js → 648-5cc6e1921389a58a.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/app/_not-found/{page-0b990dbb71d72a98.js → page-53b8a69f76db17d0.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/{fd9d1056-bf46c09eb57e019c.js → fd9d1056-609918ca7b6280bb.js} +0 -0
- /package/dist/dashboard/out/_next/static/{6HHWb2ZmnJ4OSm0zUP7h4 → wPgKJtcOmTFLpUncDg16A}/_buildManifest.js +0 -0
- /package/dist/dashboard/out/_next/static/{6HHWb2ZmnJ4OSm0zUP7h4 → wPgKJtcOmTFLpUncDg16A}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crash Insights Service
|
|
3
|
+
*
|
|
4
|
+
* Captures and analyzes agent crashes to provide actionable insights:
|
|
5
|
+
* - Memory state at crash time
|
|
6
|
+
* - Crash history and patterns
|
|
7
|
+
* - Root cause analysis
|
|
8
|
+
* - Recommendations for prevention
|
|
9
|
+
*/
|
|
10
|
+
import { EventEmitter } from 'events';
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
import * as path from 'path';
|
|
13
|
+
import * as os from 'os';
|
|
14
|
+
import { formatBytes, } from './memory-monitor.js';
|
|
15
|
+
export class CrashInsightsService extends EventEmitter {
|
|
16
|
+
crashes = [];
|
|
17
|
+
memoryMonitor = null;
|
|
18
|
+
persistPath;
|
|
19
|
+
maxCrashHistory = 1000;
|
|
20
|
+
constructor(memoryMonitor) {
|
|
21
|
+
super();
|
|
22
|
+
this.memoryMonitor = memoryMonitor || null;
|
|
23
|
+
// Set up persistence path
|
|
24
|
+
const dataDir = process.env.AGENT_RELAY_DATA_DIR ||
|
|
25
|
+
path.join(os.homedir(), '.local', 'share', 'agent-relay');
|
|
26
|
+
this.persistPath = path.join(dataDir, 'crash-insights.json');
|
|
27
|
+
// Load existing crash history
|
|
28
|
+
this.loadCrashes();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Set the memory monitor instance
|
|
32
|
+
*/
|
|
33
|
+
setMemoryMonitor(monitor) {
|
|
34
|
+
this.memoryMonitor = monitor;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Record a crash event
|
|
38
|
+
*/
|
|
39
|
+
recordCrash(params) {
|
|
40
|
+
const id = `crash-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
41
|
+
const crashTime = new Date();
|
|
42
|
+
// Get memory context from memory monitor
|
|
43
|
+
const memoryContext = this.memoryMonitor
|
|
44
|
+
? this.memoryMonitor.getCrashContext(params.agentName)
|
|
45
|
+
: this.createEmptyMemoryContext(params.agentName, params.pid, crashTime);
|
|
46
|
+
// Analyze the crash
|
|
47
|
+
const analysis = this.analyzeCrash({
|
|
48
|
+
...params,
|
|
49
|
+
memoryContext,
|
|
50
|
+
});
|
|
51
|
+
const record = {
|
|
52
|
+
id,
|
|
53
|
+
agentName: params.agentName,
|
|
54
|
+
pid: params.pid,
|
|
55
|
+
crashTime,
|
|
56
|
+
exitCode: params.exitCode,
|
|
57
|
+
signal: params.signal,
|
|
58
|
+
reason: params.reason,
|
|
59
|
+
memoryContext,
|
|
60
|
+
stackTrace: params.stackTrace,
|
|
61
|
+
lastOutput: params.lastOutput?.slice(-2000), // Keep last 2KB
|
|
62
|
+
environment: {
|
|
63
|
+
nodeVersion: process.version,
|
|
64
|
+
platform: process.platform,
|
|
65
|
+
arch: process.arch,
|
|
66
|
+
systemMemory: {
|
|
67
|
+
total: os.totalmem(),
|
|
68
|
+
free: os.freemem(),
|
|
69
|
+
},
|
|
70
|
+
uptime: process.uptime(),
|
|
71
|
+
},
|
|
72
|
+
analysis,
|
|
73
|
+
};
|
|
74
|
+
// Add to history
|
|
75
|
+
this.crashes.unshift(record);
|
|
76
|
+
// Trim history
|
|
77
|
+
if (this.crashes.length > this.maxCrashHistory) {
|
|
78
|
+
this.crashes = this.crashes.slice(0, this.maxCrashHistory);
|
|
79
|
+
}
|
|
80
|
+
// Persist
|
|
81
|
+
this.saveCrashes();
|
|
82
|
+
// Emit event
|
|
83
|
+
this.emit('crash', record);
|
|
84
|
+
this.log('error', `Crash recorded for ${params.agentName}`, {
|
|
85
|
+
id,
|
|
86
|
+
cause: analysis.likelyCause,
|
|
87
|
+
confidence: analysis.confidence,
|
|
88
|
+
});
|
|
89
|
+
return record;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get crash history for an agent
|
|
93
|
+
*/
|
|
94
|
+
getCrashHistory(agentName, limit = 50) {
|
|
95
|
+
let history = this.crashes;
|
|
96
|
+
if (agentName) {
|
|
97
|
+
history = history.filter((c) => c.agentName === agentName);
|
|
98
|
+
}
|
|
99
|
+
return history.slice(0, limit);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get a specific crash record
|
|
103
|
+
*/
|
|
104
|
+
getCrash(id) {
|
|
105
|
+
return this.crashes.find((c) => c.id === id);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get crash statistics
|
|
109
|
+
*/
|
|
110
|
+
getStats() {
|
|
111
|
+
const crashesByAgent = {};
|
|
112
|
+
const crashesByCause = {};
|
|
113
|
+
const agentCrashTimes = {};
|
|
114
|
+
for (const crash of this.crashes) {
|
|
115
|
+
crashesByAgent[crash.agentName] = (crashesByAgent[crash.agentName] || 0) + 1;
|
|
116
|
+
crashesByCause[crash.analysis.likelyCause] =
|
|
117
|
+
(crashesByCause[crash.analysis.likelyCause] || 0) + 1;
|
|
118
|
+
if (!agentCrashTimes[crash.agentName]) {
|
|
119
|
+
agentCrashTimes[crash.agentName] = [];
|
|
120
|
+
}
|
|
121
|
+
agentCrashTimes[crash.agentName].push(crash.crashTime.getTime());
|
|
122
|
+
}
|
|
123
|
+
// Find most crash-prone agent
|
|
124
|
+
let mostCrashProne = null;
|
|
125
|
+
for (const [agent, count] of Object.entries(crashesByAgent)) {
|
|
126
|
+
if (!mostCrashProne || count > mostCrashProne.count) {
|
|
127
|
+
mostCrashProne = { agent, count };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Calculate average time between crashes
|
|
131
|
+
let totalIntervals = 0;
|
|
132
|
+
let intervalCount = 0;
|
|
133
|
+
for (const times of Object.values(agentCrashTimes)) {
|
|
134
|
+
if (times.length > 1) {
|
|
135
|
+
const sorted = times.sort((a, b) => a - b);
|
|
136
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
137
|
+
totalIntervals += sorted[i] - sorted[i - 1];
|
|
138
|
+
intervalCount++;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const avgTimeBetweenCrashes = intervalCount > 0 ? totalIntervals / intervalCount : 0;
|
|
143
|
+
// Detect patterns
|
|
144
|
+
const patterns = this.detectPatterns();
|
|
145
|
+
return {
|
|
146
|
+
totalCrashes: this.crashes.length,
|
|
147
|
+
crashesByAgent,
|
|
148
|
+
crashesByCause,
|
|
149
|
+
avgTimeBetweenCrashes,
|
|
150
|
+
mostCrashProne,
|
|
151
|
+
recentCrashes: this.crashes.slice(0, 10),
|
|
152
|
+
patterns,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get insights and recommendations
|
|
157
|
+
*/
|
|
158
|
+
getInsights() {
|
|
159
|
+
const stats = this.getStats();
|
|
160
|
+
const issues = [];
|
|
161
|
+
const trends = [];
|
|
162
|
+
// Analyze OOM crashes
|
|
163
|
+
const oomCrashes = stats.crashesByCause['oom'] || 0;
|
|
164
|
+
if (oomCrashes > 0) {
|
|
165
|
+
issues.push({
|
|
166
|
+
issue: `${oomCrashes} crash${oomCrashes > 1 ? 'es' : ''} caused by out of memory`,
|
|
167
|
+
severity: 'high',
|
|
168
|
+
recommendation: 'Increase memory limits or optimize agent memory usage',
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
// Analyze memory leaks
|
|
172
|
+
const leakCrashes = stats.crashesByCause['memory_leak'] || 0;
|
|
173
|
+
if (leakCrashes > 0) {
|
|
174
|
+
issues.push({
|
|
175
|
+
issue: `${leakCrashes} crash${leakCrashes > 1 ? 'es' : ''} likely caused by memory leaks`,
|
|
176
|
+
severity: 'high',
|
|
177
|
+
recommendation: 'Investigate agent code for memory leaks, consider periodic restarts',
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
// Check crash frequency
|
|
181
|
+
const recentCrashes = this.crashes.filter((c) => Date.now() - c.crashTime.getTime() < 24 * 60 * 60 * 1000).length;
|
|
182
|
+
if (recentCrashes > 5) {
|
|
183
|
+
issues.push({
|
|
184
|
+
issue: `${recentCrashes} crashes in the last 24 hours`,
|
|
185
|
+
severity: recentCrashes > 10 ? 'high' : 'medium',
|
|
186
|
+
recommendation: 'Investigate root cause, consider rolling back recent changes',
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
// Check repeat offenders
|
|
190
|
+
if (stats.mostCrashProne && stats.mostCrashProne.count > 5) {
|
|
191
|
+
issues.push({
|
|
192
|
+
issue: `Agent "${stats.mostCrashProne.agent}" has crashed ${stats.mostCrashProne.count} times`,
|
|
193
|
+
severity: 'medium',
|
|
194
|
+
recommendation: 'Investigate why this agent is unstable',
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
// Calculate health score (0-100)
|
|
198
|
+
let healthScore = 100;
|
|
199
|
+
healthScore -= oomCrashes * 10;
|
|
200
|
+
healthScore -= leakCrashes * 8;
|
|
201
|
+
healthScore -= recentCrashes * 3;
|
|
202
|
+
healthScore = Math.max(0, Math.min(100, healthScore));
|
|
203
|
+
// Analyze trends
|
|
204
|
+
const last24h = this.crashes.filter((c) => Date.now() - c.crashTime.getTime() < 24 * 60 * 60 * 1000).length;
|
|
205
|
+
const prev24h = this.crashes.filter((c) => Date.now() - c.crashTime.getTime() >= 24 * 60 * 60 * 1000 &&
|
|
206
|
+
Date.now() - c.crashTime.getTime() < 48 * 60 * 60 * 1000).length;
|
|
207
|
+
let crashTrend = 'stable';
|
|
208
|
+
if (last24h < prev24h * 0.7)
|
|
209
|
+
crashTrend = 'improving';
|
|
210
|
+
else if (last24h > prev24h * 1.3)
|
|
211
|
+
crashTrend = 'degrading';
|
|
212
|
+
trends.push({
|
|
213
|
+
metric: 'Crash frequency',
|
|
214
|
+
trend: crashTrend,
|
|
215
|
+
details: `${last24h} crashes in last 24h vs ${prev24h} in previous 24h`,
|
|
216
|
+
});
|
|
217
|
+
return {
|
|
218
|
+
summary: this.generateSummary(stats),
|
|
219
|
+
topIssues: issues.sort((a, b) => {
|
|
220
|
+
const severityOrder = { high: 0, medium: 1, low: 2 };
|
|
221
|
+
return severityOrder[a.severity] - severityOrder[b.severity];
|
|
222
|
+
}),
|
|
223
|
+
healthScore,
|
|
224
|
+
trends,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Analyze a crash and determine likely cause
|
|
229
|
+
*/
|
|
230
|
+
analyzeCrash(params) {
|
|
231
|
+
const details = [];
|
|
232
|
+
const recommendations = [];
|
|
233
|
+
let likelyCause = 'unknown';
|
|
234
|
+
let confidence = 'low';
|
|
235
|
+
// Check memory-based causes first
|
|
236
|
+
if (params.memoryContext.likelyCause !== 'unknown') {
|
|
237
|
+
likelyCause = params.memoryContext.likelyCause;
|
|
238
|
+
confidence = 'high';
|
|
239
|
+
details.push(...params.memoryContext.analysisNotes);
|
|
240
|
+
}
|
|
241
|
+
// Check signal
|
|
242
|
+
if (params.signal) {
|
|
243
|
+
details.push(`Process received signal: ${params.signal}`);
|
|
244
|
+
if (params.signal === 'SIGKILL') {
|
|
245
|
+
if (likelyCause === 'unknown') {
|
|
246
|
+
likelyCause = 'oom';
|
|
247
|
+
confidence = 'medium';
|
|
248
|
+
}
|
|
249
|
+
details.push('SIGKILL often indicates OOM killer intervention');
|
|
250
|
+
recommendations.push('Check system logs for OOM killer activity');
|
|
251
|
+
}
|
|
252
|
+
else if (params.signal === 'SIGSEGV') {
|
|
253
|
+
likelyCause = 'error';
|
|
254
|
+
confidence = 'high';
|
|
255
|
+
details.push('Segmentation fault - memory access violation');
|
|
256
|
+
recommendations.push('Check for native module issues or memory corruption');
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// Check exit code
|
|
260
|
+
if (params.exitCode !== null) {
|
|
261
|
+
details.push(`Exit code: ${params.exitCode}`);
|
|
262
|
+
if (params.exitCode === 137) {
|
|
263
|
+
// 128 + 9 (SIGKILL)
|
|
264
|
+
if (likelyCause === 'unknown') {
|
|
265
|
+
likelyCause = 'oom';
|
|
266
|
+
confidence = 'high';
|
|
267
|
+
}
|
|
268
|
+
details.push('Exit code 137 typically indicates OOM kill');
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// Check stack trace for clues
|
|
272
|
+
if (params.stackTrace) {
|
|
273
|
+
if (params.stackTrace.includes('FATAL ERROR: CALL_AND_RETRY_LAST')) {
|
|
274
|
+
likelyCause = 'oom';
|
|
275
|
+
confidence = 'high';
|
|
276
|
+
details.push('V8 heap allocation failure detected');
|
|
277
|
+
recommendations.push('Increase Node.js memory limit with --max-old-space-size');
|
|
278
|
+
}
|
|
279
|
+
if (params.stackTrace.includes('RangeError: Invalid array length')) {
|
|
280
|
+
likelyCause = 'memory_leak';
|
|
281
|
+
confidence = 'medium';
|
|
282
|
+
details.push('Array grew too large - possible unbounded growth');
|
|
283
|
+
recommendations.push('Review array handling code for unbounded growth');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// Add memory-specific recommendations
|
|
287
|
+
if (likelyCause === 'oom' || likelyCause === 'memory_leak') {
|
|
288
|
+
recommendations.push('Review agent memory usage patterns');
|
|
289
|
+
recommendations.push('Consider implementing memory limits or checkpoints');
|
|
290
|
+
if (params.memoryContext.peakMemory > 1024 * 1024 * 1024) {
|
|
291
|
+
recommendations.push(`Peak memory was ${formatBytes(params.memoryContext.peakMemory)} - consider memory profiling`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
// Find related crashes
|
|
295
|
+
const relatedCrashes = this.findRelatedCrashes(params.agentName, likelyCause);
|
|
296
|
+
// Generate summary
|
|
297
|
+
const summary = this.generateCrashSummary(likelyCause, confidence, params);
|
|
298
|
+
return {
|
|
299
|
+
likelyCause,
|
|
300
|
+
confidence,
|
|
301
|
+
summary,
|
|
302
|
+
details,
|
|
303
|
+
recommendations: recommendations.length > 0
|
|
304
|
+
? recommendations
|
|
305
|
+
: ['Monitor agent for recurrence', 'Check logs for additional context'],
|
|
306
|
+
relatedCrashes,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Find related crashes
|
|
311
|
+
*/
|
|
312
|
+
findRelatedCrashes(agentName, cause) {
|
|
313
|
+
return this.crashes
|
|
314
|
+
.filter((c) => (c.agentName === agentName || c.analysis.likelyCause === cause) &&
|
|
315
|
+
Date.now() - c.crashTime.getTime() < 7 * 24 * 60 * 60 * 1000 // Last 7 days
|
|
316
|
+
)
|
|
317
|
+
.slice(0, 5)
|
|
318
|
+
.map((c) => c.id);
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Detect crash patterns
|
|
322
|
+
*/
|
|
323
|
+
detectPatterns() {
|
|
324
|
+
const patterns = [];
|
|
325
|
+
const causeGroups = {};
|
|
326
|
+
// Group by cause
|
|
327
|
+
for (const crash of this.crashes) {
|
|
328
|
+
const cause = crash.analysis.likelyCause;
|
|
329
|
+
if (!causeGroups[cause]) {
|
|
330
|
+
causeGroups[cause] = [];
|
|
331
|
+
}
|
|
332
|
+
causeGroups[cause].push(crash);
|
|
333
|
+
}
|
|
334
|
+
// Create patterns for significant groups
|
|
335
|
+
for (const [cause, crashes] of Object.entries(causeGroups)) {
|
|
336
|
+
if (crashes.length >= 3) {
|
|
337
|
+
const agents = [...new Set(crashes.map((c) => c.agentName))];
|
|
338
|
+
const avgMemory = crashes.reduce((sum, c) => sum + (c.memoryContext.peakMemory || 0), 0) /
|
|
339
|
+
crashes.length;
|
|
340
|
+
patterns.push({
|
|
341
|
+
pattern: `${cause}_pattern`,
|
|
342
|
+
occurrences: crashes.length,
|
|
343
|
+
lastSeen: crashes[0].crashTime,
|
|
344
|
+
affectedAgents: agents,
|
|
345
|
+
avgMemoryAtCrash: avgMemory,
|
|
346
|
+
commonCause: cause,
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return patterns;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Generate crash summary
|
|
354
|
+
*/
|
|
355
|
+
generateCrashSummary(cause, confidence, params) {
|
|
356
|
+
const causeDescriptions = {
|
|
357
|
+
oom: 'ran out of memory',
|
|
358
|
+
memory_leak: 'experienced a memory leak',
|
|
359
|
+
sudden_spike: 'had a sudden memory spike',
|
|
360
|
+
signal: 'was terminated by a signal',
|
|
361
|
+
error: 'encountered an error',
|
|
362
|
+
unknown: 'crashed for unknown reasons',
|
|
363
|
+
};
|
|
364
|
+
return `Agent "${params.agentName}" ${causeDescriptions[cause] || 'crashed'} (${confidence} confidence). ${params.reason}`;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Generate overall summary
|
|
368
|
+
*/
|
|
369
|
+
generateSummary(stats) {
|
|
370
|
+
if (stats.totalCrashes === 0) {
|
|
371
|
+
return 'No crashes recorded. System is stable.';
|
|
372
|
+
}
|
|
373
|
+
const parts = [];
|
|
374
|
+
parts.push(`${stats.totalCrashes} total crash${stats.totalCrashes > 1 ? 'es' : ''} recorded.`);
|
|
375
|
+
if (stats.mostCrashProne) {
|
|
376
|
+
parts.push(`Most unstable: "${stats.mostCrashProne.agent}" (${stats.mostCrashProne.count} crashes).`);
|
|
377
|
+
}
|
|
378
|
+
const topCause = Object.entries(stats.crashesByCause).sort((a, b) => b[1] - a[1])[0];
|
|
379
|
+
if (topCause) {
|
|
380
|
+
parts.push(`Primary cause: ${topCause[0]} (${topCause[1]} occurrences).`);
|
|
381
|
+
}
|
|
382
|
+
return parts.join(' ');
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Create empty memory context when no monitor available
|
|
386
|
+
*/
|
|
387
|
+
createEmptyMemoryContext(agentName, pid, crashTime) {
|
|
388
|
+
return {
|
|
389
|
+
agentName,
|
|
390
|
+
pid,
|
|
391
|
+
crashTime,
|
|
392
|
+
lastKnownMemory: null,
|
|
393
|
+
peakMemory: 0,
|
|
394
|
+
averageMemory: 0,
|
|
395
|
+
memoryTrend: 'unknown',
|
|
396
|
+
recentHistory: [],
|
|
397
|
+
likelyCause: 'unknown',
|
|
398
|
+
analysisNotes: ['Memory monitoring was not enabled'],
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Load crashes from disk
|
|
403
|
+
*/
|
|
404
|
+
loadCrashes() {
|
|
405
|
+
try {
|
|
406
|
+
if (fs.existsSync(this.persistPath)) {
|
|
407
|
+
const data = fs.readFileSync(this.persistPath, 'utf-8');
|
|
408
|
+
const parsed = JSON.parse(data);
|
|
409
|
+
this.crashes = parsed.crashes.map((c) => ({
|
|
410
|
+
...c,
|
|
411
|
+
crashTime: new Date(c.crashTime),
|
|
412
|
+
memoryContext: {
|
|
413
|
+
...c.memoryContext,
|
|
414
|
+
crashTime: new Date(c.memoryContext.crashTime),
|
|
415
|
+
lastKnownMemory: c.memoryContext.lastKnownMemory
|
|
416
|
+
? {
|
|
417
|
+
...c.memoryContext.lastKnownMemory,
|
|
418
|
+
timestamp: new Date(c.memoryContext.lastKnownMemory.timestamp),
|
|
419
|
+
}
|
|
420
|
+
: null,
|
|
421
|
+
recentHistory: c.memoryContext.recentHistory.map((h) => ({
|
|
422
|
+
...h,
|
|
423
|
+
timestamp: new Date(h.timestamp),
|
|
424
|
+
})),
|
|
425
|
+
},
|
|
426
|
+
}));
|
|
427
|
+
this.log('info', `Loaded ${this.crashes.length} crash records`);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
catch (error) {
|
|
431
|
+
this.log('warn', 'Failed to load crash history', { error: String(error) });
|
|
432
|
+
this.crashes = [];
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Save crashes to disk
|
|
437
|
+
*/
|
|
438
|
+
saveCrashes() {
|
|
439
|
+
try {
|
|
440
|
+
const dir = path.dirname(this.persistPath);
|
|
441
|
+
if (!fs.existsSync(dir)) {
|
|
442
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
443
|
+
}
|
|
444
|
+
fs.writeFileSync(this.persistPath, JSON.stringify({ crashes: this.crashes }, null, 2));
|
|
445
|
+
}
|
|
446
|
+
catch (error) {
|
|
447
|
+
this.log('error', 'Failed to save crash history', { error: String(error) });
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Clear all crash history
|
|
452
|
+
*/
|
|
453
|
+
clear() {
|
|
454
|
+
this.crashes = [];
|
|
455
|
+
this.saveCrashes();
|
|
456
|
+
this.emit('cleared');
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Structured logging
|
|
460
|
+
*/
|
|
461
|
+
log(level, message, context) {
|
|
462
|
+
const entry = {
|
|
463
|
+
timestamp: new Date().toISOString(),
|
|
464
|
+
level,
|
|
465
|
+
component: 'crash-insights',
|
|
466
|
+
message,
|
|
467
|
+
...context,
|
|
468
|
+
};
|
|
469
|
+
this.emit('log', entry);
|
|
470
|
+
const prefix = `[crash-insights]`;
|
|
471
|
+
switch (level) {
|
|
472
|
+
case 'info':
|
|
473
|
+
console.log(prefix, message, context ? JSON.stringify(context) : '');
|
|
474
|
+
break;
|
|
475
|
+
case 'warn':
|
|
476
|
+
console.warn(prefix, message, context ? JSON.stringify(context) : '');
|
|
477
|
+
break;
|
|
478
|
+
case 'error':
|
|
479
|
+
console.error(prefix, message, context ? JSON.stringify(context) : '');
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
// Singleton instance
|
|
485
|
+
let _crashInsights = null;
|
|
486
|
+
export function getCrashInsights(memoryMonitor) {
|
|
487
|
+
if (!_crashInsights) {
|
|
488
|
+
_crashInsights = new CrashInsightsService(memoryMonitor);
|
|
489
|
+
}
|
|
490
|
+
return _crashInsights;
|
|
491
|
+
}
|
|
492
|
+
//# sourceMappingURL=crash-insights.js.map
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gossip-Based Health Broadcast
|
|
3
|
+
*
|
|
4
|
+
* Implements P4: Agents broadcast heartbeats via relay.
|
|
5
|
+
* Collective failure detection without central monitor.
|
|
6
|
+
*
|
|
7
|
+
* Each agent:
|
|
8
|
+
* - Periodically broadcasts HEARTBEAT message to all agents
|
|
9
|
+
* - Tracks health of all known peers
|
|
10
|
+
* - Detects failures when peer heartbeats go stale
|
|
11
|
+
* - Emits events for peer health changes
|
|
12
|
+
*/
|
|
13
|
+
import { EventEmitter } from 'events';
|
|
14
|
+
/**
|
|
15
|
+
* Peer health state
|
|
16
|
+
*/
|
|
17
|
+
export interface PeerHealth {
|
|
18
|
+
name: string;
|
|
19
|
+
lastHeartbeat: number;
|
|
20
|
+
load: number;
|
|
21
|
+
healthy: boolean;
|
|
22
|
+
isLeader: boolean;
|
|
23
|
+
taskCount: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Heartbeat payload (broadcast via relay)
|
|
27
|
+
*/
|
|
28
|
+
export interface GossipHeartbeat {
|
|
29
|
+
type: 'HEARTBEAT';
|
|
30
|
+
agent: string;
|
|
31
|
+
agentId: string;
|
|
32
|
+
timestamp: number;
|
|
33
|
+
load: number;
|
|
34
|
+
healthy: boolean;
|
|
35
|
+
isLeader: boolean;
|
|
36
|
+
taskCount: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Gossip health configuration
|
|
40
|
+
*/
|
|
41
|
+
export interface GossipHealthConfig {
|
|
42
|
+
/** This agent's name */
|
|
43
|
+
agentName: string;
|
|
44
|
+
/** This agent's unique ID */
|
|
45
|
+
agentId: string;
|
|
46
|
+
/** How often to broadcast heartbeat (ms) */
|
|
47
|
+
broadcastIntervalMs: number;
|
|
48
|
+
/** Peer considered stale after this duration (ms) */
|
|
49
|
+
staleThresholdMs: number;
|
|
50
|
+
/** How often to check for stale peers (ms) */
|
|
51
|
+
checkIntervalMs: number;
|
|
52
|
+
/** Callback to broadcast message to all agents */
|
|
53
|
+
broadcast: (message: string) => Promise<void>;
|
|
54
|
+
/** Callback to get current load (0-1) */
|
|
55
|
+
getLoad?: () => number;
|
|
56
|
+
/** Callback to get current task count */
|
|
57
|
+
getTaskCount?: () => number;
|
|
58
|
+
/** Callback to check if this agent is leader */
|
|
59
|
+
isLeader?: () => boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Gossip Health Monitor
|
|
63
|
+
*
|
|
64
|
+
* Broadcasts heartbeats and tracks peer health via gossip protocol.
|
|
65
|
+
*/
|
|
66
|
+
export declare class GossipHealthMonitor extends EventEmitter {
|
|
67
|
+
private config;
|
|
68
|
+
private peers;
|
|
69
|
+
private broadcastInterval?;
|
|
70
|
+
private checkInterval?;
|
|
71
|
+
private isRunning;
|
|
72
|
+
private healthy;
|
|
73
|
+
constructor(config: GossipHealthConfig);
|
|
74
|
+
/**
|
|
75
|
+
* Start gossip health monitoring
|
|
76
|
+
*/
|
|
77
|
+
start(): void;
|
|
78
|
+
/**
|
|
79
|
+
* Stop gossip health monitoring
|
|
80
|
+
*/
|
|
81
|
+
stop(): void;
|
|
82
|
+
/**
|
|
83
|
+
* Broadcast heartbeat to all agents
|
|
84
|
+
*/
|
|
85
|
+
private broadcastHeartbeat;
|
|
86
|
+
/**
|
|
87
|
+
* Process incoming heartbeat from another agent
|
|
88
|
+
*/
|
|
89
|
+
processHeartbeat(heartbeat: GossipHeartbeat): void;
|
|
90
|
+
/**
|
|
91
|
+
* Parse heartbeat from relay message
|
|
92
|
+
*/
|
|
93
|
+
static parseHeartbeat(message: string): GossipHeartbeat | null;
|
|
94
|
+
/**
|
|
95
|
+
* Check for stale peers
|
|
96
|
+
*/
|
|
97
|
+
private checkStalePeers;
|
|
98
|
+
/**
|
|
99
|
+
* Set this agent's health status
|
|
100
|
+
*/
|
|
101
|
+
setHealthy(healthy: boolean): void;
|
|
102
|
+
/**
|
|
103
|
+
* Get all known peers
|
|
104
|
+
*/
|
|
105
|
+
getPeers(): PeerHealth[];
|
|
106
|
+
/**
|
|
107
|
+
* Get healthy peers
|
|
108
|
+
*/
|
|
109
|
+
getHealthyPeers(): PeerHealth[];
|
|
110
|
+
/**
|
|
111
|
+
* Get current leader from gossip
|
|
112
|
+
*/
|
|
113
|
+
getLeader(): PeerHealth | null;
|
|
114
|
+
/**
|
|
115
|
+
* Get peer by name
|
|
116
|
+
*/
|
|
117
|
+
getPeer(name: string): PeerHealth | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* Get status
|
|
120
|
+
*/
|
|
121
|
+
getStatus(): {
|
|
122
|
+
isRunning: boolean;
|
|
123
|
+
agentName: string;
|
|
124
|
+
peerCount: number;
|
|
125
|
+
healthyPeerCount: number;
|
|
126
|
+
leader: string | null;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Create gossip health monitor with defaults
|
|
131
|
+
*/
|
|
132
|
+
export declare function createGossipHealth(agentName: string, agentId: string, broadcast: (message: string) => Promise<void>, options?: {
|
|
133
|
+
getLoad?: () => number;
|
|
134
|
+
getTaskCount?: () => number;
|
|
135
|
+
isLeader?: () => boolean;
|
|
136
|
+
}): GossipHealthMonitor;
|
|
137
|
+
//# sourceMappingURL=gossip-health.d.ts.map
|