TypeScript 55.4%
Python 43.2%
SQL 1.2%
1{2 "app": "websensor",3 "label": "WebSensor — Detect What Changed. Know Why It Matters.",4 "domain": "www.websensor.io",5 "port": 8260,6 "health_path": "/api/ready",7 "dir": "~/apps/websensor",8 "extra_paths": [],9 "sync_excludes": [10 "node_modules/",11 ".next/",12 ".git/",13 ".env",14 ".env.*",15 "!.env.example",16 "*.tsbuildinfo",17 ".turbo/",18 "logs/",19 "tmp/",20 "data/",21 ".DS_Store",22 ".claude/",23 "qa/",24 "apps/web/.next/",25 "apps/web/next-env.d.ts",26 "deploy/*.mld.json",27 "/coverage/",28 "apps/*/coverage/",29 "packages/*/coverage/"30 ],31 "requires": {32 "runtimes": [33 "pm2",34 "node",35 "pnpm",36 "postgresql@17",37 "redis"38 ],39 "ram_gb": 8,40 "ports": [41 8260,42 8261,43 826244 ]45 },46 "ram_mb_observed": 1500,47 "size_mb": 40,48 "placement": {49 "pin": "M4M64b",50 "prefer": null,51 "avoid": [52 "M3U96b",53 "M1M32"54 ],55 "reason": "PostgreSQL 17 + Redis + pnpm présents ; 64 Go RAM ; M3U96a déjà chargé (25 processus PM2)"56 },57 "processes": [58 {59 "name": "websensor-engine",60 "manager": "pm2",61 "script": "/opt/homebrew/bin/node",62 "args": [63 "node_modules/tsx/dist/cli.mjs",64 "apps/engine/src/index.ts"65 ],66 "interpreter": null,67 "cwd": "{{HOME}}/apps/websensor",68 "env": {69 "NODE_ENV": "production",70 "DATABASE_URL": "postgres://localhost:5432/websensor",71 "REDIS_URL": "redis://127.0.0.1:6379",72 "BLOB_STORE_DIR": "{{HOME}}/websensor-data/blobs",73 "WS_SOURCES_FILE": "./config/sources.yaml",74 "WS_FETCH_CONCURRENCY": "48",75 "WS_PER_HOST_CONCURRENCY": "2",76 "ENGINE_METRICS_PORT": "8262",77 "WS_USER_AGENT": "WebSensorBot/0.3 (+https://www.websensor.io/bot; contact@websensor.io)",78 "ANTHROPIC_API_KEY": "<set me>",79 "WS_LLM_MODEL_FAST": "claude-haiku-4-5",80 "WS_LLM_MODEL_DEEP": "claude-opus-5",81 "WS_LLM_DAILY_CALL_BUDGET": "600",82 "WS_LLM_MIN_IMPORTANCE": "35",83 "WS_LLM_DEEP_MIN_IMPORTANCE": "78",84 "SCRAPFLY_API_KEY": "<set me>",85 "WS_SCRAPFLY_DAILY_BUDGET": "300",86 "LOG_LEVEL": "info",87 "WS_RETENTION_RAW_DAYS": "21",88 "WS_RETENTION_CHANGED_RAW_DAYS": "60",89 "WS_SILENT_MIN_IMPORTANCE": "45"90 },91 "cron_restart": null,92 "autorestart": true,93 "max_memory_restart": "2G"94 },95 {96 "name": "websensor-factory",97 "manager": "pm2",98 "script": "/opt/homebrew/bin/node",99 "args": [100 "node_modules/tsx/dist/cli.mjs",101 "apps/engine/src/factory-main.ts"102 ],103 "interpreter": null,104 "cwd": "{{HOME}}/apps/websensor",105 "env": {106 "NODE_ENV": "production",107 "DATABASE_URL": "postgres://localhost:5432/websensor",108 "REDIS_URL": "redis://127.0.0.1:6379",109 "BLOB_STORE_DIR": "{{HOME}}/websensor-data/blobs",110 "WS_SOURCES_FILE": "./config/sources.yaml",111 "WS_USER_AGENT": "WebSensorBot/0.3 (+https://www.websensor.io/bot; contact@websensor.io)",112 "LOG_LEVEL": "info",113 "WS_FACTORY": "1",114 "WS_FACTORY_CONCURRENCY": "10",115 "WS_FACTORY_BUDGET": "90",116 "WS_FACTORY_MIN_SCORE": "0.35",117 "WS_FACTORY_SHADOW_MIN_CHECKS": "5",118 "WS_FACTORY_SHADOW_MIN_HOURS": "24",119 "WS_FACTORY_SHADOW_MAX_HOURS": "120",120 "WS_FACTORY_TICK_SECONDS": "20",121 "WS_COVERAGE_DIR": "./config/coverage",122 "WS_EDGAR_USER_AGENT": "WebSensor (contact@websensor.io)",123 "WS_APP_NAME": "websensor-factory",124 "WS_FACTORY_DEADLINE_MS": "120000"125 },126 "cron_restart": null,127 "autorestart": true,128 "max_memory_restart": "1500M"129 },130 {131 "name": "websensor-api",132 "manager": "pm2",133 "script": "/opt/homebrew/bin/node",134 "args": [135 "node_modules/tsx/dist/cli.mjs",136 "apps/api/src/server.ts"137 ],138 "interpreter": null,139 "cwd": "{{HOME}}/apps/websensor",140 "env": {141 "NODE_ENV": "production",142 "DATABASE_URL": "postgres://localhost:5432/websensor",143 "REDIS_URL": "redis://127.0.0.1:6379",144 "BLOB_STORE_DIR": "{{HOME}}/websensor-data/blobs",145 "API_PORT": "8260",146 "API_HOST": "0.0.0.0",147 "WEB_URL": "http://127.0.0.1:8261",148 "PUBLIC_BASE_URL": "https://www.websensor.io",149 "CANONICAL_HOST": "www.websensor.io",150 "LOG_LEVEL": "info",151 "WS_ADMIN_TOKEN": "<set me>",152 "WS_MONITORS_PER_OWNER": "5"153 },154 "cron_restart": null,155 "autorestart": true,156 "max_memory_restart": "1G"157 },158 {159 "name": "websensor-web",160 "manager": "pm2",161 "script": "/opt/homebrew/bin/node",162 "args": [163 "node_modules/next/dist/bin/next",164 "start",165 "-p",166 "8261",167 "-H",168 "127.0.0.1"169 ],170 "interpreter": null,171 "cwd": "{{HOME}}/apps/websensor/apps/web",172 "env": {173 "NODE_ENV": "production",174 "API_URL": "http://127.0.0.1:8260",175 "NEXT_PUBLIC_SITE_URL": "https://www.websensor.io",176 "NEXT_TELEMETRY_DISABLED": "1"177 },178 "cron_restart": null,179 "autorestart": true,180 "max_memory_restart": "1G"181 }182 ],183 "ngrok": null,184 "launchd": [],185 "env_overrides": {},186 "hooks": {187 "post_sync": [188 "export PATH=\"/opt/homebrew/bin:$PATH\"; pnpm install --frozen-lockfile --silent && echo ' deps ok'",189 "set -o pipefail; export PATH=\"/opt/homebrew/bin:$PATH\"; psql -d postgres -Atc \"select 1 from pg_database where datname='websensor'\" | grep -q 1 || createdb websensor; DATABASE_URL=postgres://localhost:5432/websensor pnpm db:migrate 2>&1 | tail -1 && echo ' db ok'",190 "export PATH=\"/opt/homebrew/bin:$PATH\"; mkdir -p $HOME/websensor-data/blobs && DATABASE_URL=postgres://localhost:5432/websensor node node_modules/tsx/dist/cli.mjs apps/engine/src/cli.ts sync 2>&1 | tail -1 && echo ' registry ok'",191 "export PATH=\"/opt/homebrew/bin:$PATH\"; DATABASE_URL=postgres://localhost:5432/websensor node node_modules/tsx/dist/cli.mjs apps/engine/src/cli.ts factory seed --mode=hinted 2>&1 | tail -1 && echo ' factory seeds ok'",192 "set -o pipefail; export PATH=\"/opt/homebrew/bin:$PATH\"; export API_URL=http://127.0.0.1:8260 NEXT_PUBLIC_SITE_URL=https://www.websensor.io NEXT_TELEMETRY_DISABLED=1; pnpm --filter @websensor/web build 2>&1 | tail -3 && echo ' web build ok'"193 ],194 "post_start": []195 },196 "notes": "v0.1.0 (2026-09-08) : gateway Fastify :8260 (REST + WS /api/v1/live + proxy → Next :8261), engine (scheduler/pipeline, métriques :8262), 200 sources / ~290 capteurs (config/sources.yaml), Postgres 17 + Redis locaux, blobs zstd dans ~/websensor-data/blobs. Secrets uniquement dans ce manifeste (M1M32).",197 "tunnel": {198 "domain": "www.websensor.io",199 "gateway": "BHS64",200 "note": "MacLustr Tunnel depuis 2026-09-10 ; ngrok retiré"201 }202}