elanous 0.2.21 → 0.2.23
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/NOTICE +7 -0
- package/README.md +32 -22
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
- package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
- package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
- package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
- package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
- package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
- package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
- package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
- package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
- package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
- package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
- package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
- package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
- package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
- package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
- package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
- package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
- package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
- package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
- package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
- package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
- package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
- package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
- package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ad3bd8084048bee4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/{page-111cabe4d1fd69ae.js → page-6168a7c43e6ef8f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-a648bc464c9dc754.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-48fb31810693c357.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-cb154acadb025414.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +1 -0
- package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
- package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +1 -0
- package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
- package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → rfkMm4movqkqMebBrCXiR}/_buildManifest.js +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +24 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +24 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/catalog/models/anthropic/claude-haiku-5-5.yaml +32 -0
- package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
- package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
- package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
- package/catalog/models/openai/gpt-6-astra.yaml +6 -0
- package/catalog/models/openai/gpt-6-luna.yaml +6 -0
- package/catalog/models/openai/gpt-6-sol.yaml +6 -0
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/drafts/recipes.yaml +2 -2
- package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
- package/graphs/log-horizon/recipes.yaml +3 -0
- package/graphs/release/recipes.yaml +1 -1
- package/graphs/release/release-loop.yaml +6 -2
- package/graphs/release-rehearsal/recipes.yaml +12 -0
- package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
- package/graphs/test-diet/recipes.yaml +3 -0
- package/graphs/test-diet/test-diet.yaml +3 -1
- package/package.json +4 -1
- package/scripts/bench-report.ts +82 -3
- package/scripts/ci-typecheck-changed.ts +10 -1
- package/scripts/f-session-monitor.ts +69 -0
- package/scripts/hq/hq-fence-wrapper.sh +148 -0
- package/scripts/hq/standby-snapshot.ts +7 -3
- package/scripts/knowledge-compress.ts +11 -0
- package/scripts/lib/typecheck-ratchet.ts +51 -0
- package/scripts/nightly-docops.ts +90 -3
- package/scripts/openai-relay-server.ts +5 -1
- package/scripts/release-loop/docs-node.ts +258 -43
- package/scripts/release-loop/gate-method.ts +59 -0
- package/scripts/release-loop/gate-node.ts +73 -7
- package/scripts/release-loop/gate-wall.ts +208 -0
- package/scripts/release-loop/known-issues-node.ts +53 -8
- package/scripts/release-loop/publish-at.ts +14 -0
- package/scripts/release-loop/publish-node.ts +17 -2
- package/scripts/release-loop/resume-release.ts +34 -4
- package/scripts/release-loop/resume.ts +53 -0
- package/scripts/release-loop/shard-plan.ts +3 -11
- package/scripts/release-loop/tui-node-checks.ts +22 -0
- package/scripts/release-loop/unattended-release.ts +8 -1
- package/scripts/research-coo-admin-dates.ts +39 -0
- package/scripts/rhythm/daily.ts +51 -2
- package/scripts/rhythm/weekly.ts +3 -2
- package/scripts/skills/public-check.ts +7 -2
- package/scripts/smart-merge/resync-shadow.ts +5 -3
- package/scripts/test-diet/lib.ts +81 -1
- package/scripts/test-diet/node.ts +48 -2
- package/scripts/tsc-main-safety-net.ts +189 -0
- package/scripts/usage-rollup.ts +8 -4
- package/scripts/verify-coo-admin-evidence.ts +83 -0
- package/src/acp/client.ts +4 -2
- package/src/acp/codex-plugins.ts +48 -6
- package/src/agent/monad-agent-turn.ts +67 -5
- package/src/agent/run-context.ts +14 -0
- package/src/agent/tool-profile.ts +28 -2
- package/src/agent-env/profile.ts +25 -5
- package/src/agent-mission/acp-judge.ts +8 -2
- package/src/agent-mission/capabilities-cli.ts +16 -1
- package/src/agent-mission/driver.ts +27 -13
- package/src/agent-mission/pr-review-watch.ts +6 -2
- package/src/agent-mission/review-loop.ts +33 -5
- package/src/agent-mission/supervisor-metrics.ts +17 -2
- package/src/agent-substrate/acp-reviewer.ts +25 -9
- package/src/agent-substrate/pr-reviewer.ts +175 -32
- package/src/agent-substrate/review-intent.ts +106 -5
- package/src/agent-substrate/self-review-cli.ts +111 -16
- package/src/agent-substrate/shard-boundary-intent.ts +92 -26
- package/src/ask-user-question/pending-questions.ts +8 -2
- package/src/autopilot/build/llm-conflict-merge.ts +238 -20
- package/src/autopilot/codebase-grounding.ts +44 -0
- package/src/autopilot/llm-control-brain.ts +13 -1
- package/src/autopilot/mission-codebase-gate.ts +8 -77
- package/src/autopilot/pr-manager.ts +30 -11
- package/src/away/release-watch.ts +47 -8
- package/src/boot/acp-server.ts +4 -7
- package/src/boot/acp-socket-path.ts +7 -0
- package/src/briefing/brief-items.ts +123 -22
- package/src/chat/index.ts +13 -3
- package/src/cli/agent-cli.ts +20 -0
- package/src/cli/brief-cli.ts +46 -22
- package/src/cli/cli-user-error.ts +9 -2
- package/src/cli/config-classify.ts +83 -0
- package/src/cli/control-cli.ts +14 -0
- package/src/cli/decisions-cli.ts +26 -16
- package/src/cli/log-event-names.ts +3 -0
- package/src/cli/logs-cli.ts +1 -0
- package/src/cli/logs-model-input.ts +1 -1
- package/src/cli/mcp-login.ts +111 -37
- package/src/cli/plugin-cli.ts +21 -1
- package/src/cli/pod-cli.ts +26 -0
- package/src/cli/pr-cli.ts +94 -9
- package/src/cli/pr-land-overlap-evidence.ts +131 -0
- package/src/cli/release-cli.ts +74 -15
- package/src/cli/self-update.ts +173 -10
- package/src/cli/skills-cli.ts +12 -3
- package/src/cli/tasks-cli.ts +241 -28
- package/src/connectors/types.ts +6 -6
- package/src/context-bus/context-first.ts +51 -2
- package/src/context-bus/context-now-surfaces.ts +29 -0
- package/src/context-bus/coord-events.ts +32 -4
- package/src/context-bus/long-term-memory.ts +26 -7
- package/src/context-bus/nightly-condense.ts +170 -21
- package/src/control/control-status.ts +87 -0
- package/src/control-plane/light-member.ts +5 -3
- package/src/control-plane/member.ts +172 -7
- package/src/core-turn/run-goal-loop.ts +108 -3
- package/src/dashboard/chat-fold.ts +20 -0
- package/src/dashboard/first-screen-band.ts +151 -1
- package/src/dashboard/index.ts +27 -5
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +14 -3
- package/src/dashboard/stale-install-check.ts +13 -2
- package/src/dashboard/turn-stream-formatter.ts +25 -0
- package/src/debug/log-diet.ts +159 -0
- package/src/debug/log.ts +52 -17
- package/src/decisions/decision-cards.ts +20 -1
- package/src/decisions/decision-ledger.ts +11 -8
- package/src/decisions/web-push-decision-cards.ts +19 -3
- package/src/discord-self-message.ts +2 -2
- package/src/display/coordinator.ts +25 -2
- package/src/domains/coo-admin-dates.evidence.json +876 -0
- package/src/domains/coo-admin-tool.ts +75 -14
- package/src/domains/cron-match.ts +1 -0
- package/src/domains/ops-status.ts +53 -0
- package/src/domains/outbound-alert.ts +41 -7
- package/src/domains/release-tool.ts +119 -10
- package/src/domains/schedule-registry.ts +10 -7
- package/src/domains/schedule-runner.ts +1 -0
- package/src/elanous-config-dir.ts +2 -2
- package/src/elanous-daemon.ts +3 -3
- package/src/exec-requests/planner.ts +6 -0
- package/src/execution-loop/launch-gate.ts +1 -1
- package/src/expression/i18n/messages.en.ts +5 -0
- package/src/expression/i18n/messages.ja.ts +5 -0
- package/src/expression/i18n/messages.ko.ts +5 -0
- package/src/expression/i18n/messages.zh.ts +5 -0
- package/src/expression/i18n/types.ts +8 -0
- package/src/github/pr-labels.ts +1 -0
- package/src/graph-kinds/registry.ts +6 -6
- package/src/graph-runner/graph-cli.ts +34 -2
- package/src/graph-runner/graph-run-api.ts +7 -0
- package/src/graph-runner/graph-tick.ts +73 -12
- package/src/graph-runner/runner.ts +94 -13
- package/src/graph-unify/wf-to-graph.ts +79 -0
- package/src/graph-wizard/generate.ts +34 -2
- package/src/graph-wizard/steps.ts +13 -0
- package/src/harness/dispatch-backpressure.ts +259 -0
- package/src/harness/harness-cli-command.ts +227 -50
- package/src/harness/harness-queue.ts +58 -14
- package/src/harness/harness-seams.ts +2 -20
- package/src/harness/harness-substrate-default.ts +72 -1
- package/src/harness/launch-advice.ts +23 -0
- package/src/harness/nested-elanous-policy.ts +4 -2
- package/src/hq/fence-wrapper.ts +7 -0
- package/src/hq/hq.ts +33 -2
- package/src/hq/lease.ts +13 -0
- package/src/hq/seats.ts +114 -18
- package/src/index.ts +199 -71
- package/src/intake-plane/collect-github.ts +19 -1
- package/src/intake-plane/digest.ts +45 -20
- package/src/intake-plane/lens.ts +36 -8
- package/src/intelligence-map/model-alias.ts +6 -0
- package/src/intelligence-map/model-catalog.ts +41 -0
- package/src/knowledge/conclusion-compress.ts +93 -0
- package/src/knowledge/kgs/pack.ts +5 -2
- package/src/knowledge/kgs/sqlite-store.ts +15 -0
- package/src/knowledge/know-find.ts +9 -2
- package/src/knowledge/query.ts +20 -0
- package/src/knowledge/tools/knowledge-query.ts +20 -2
- package/src/knowledge/write.ts +234 -2
- package/src/llm/bedrock-provider.ts +175 -0
- package/src/llm/bedrock.ts +345 -0
- package/src/llm/provider-credentials.ts +3 -1
- package/src/llm.ts +332 -51
- package/src/loops/budget.ts +150 -0
- package/src/loops/neighbor-runtime.ts +88 -0
- package/src/loops/orchestrator/author-depth.ts +29 -11
- package/src/loops/orchestrator/overlap.ts +7 -1
- package/src/loops/orchestrator/resync-shadow.ts +1 -1
- package/src/loops/orchestrator/seat-share.ts +6 -49
- package/src/loops/orchestrator/tick.ts +35 -2
- package/src/loops/orchestrator/traffic.ts +6 -80
- package/src/loops/registry.ts +5 -0
- package/src/market/publish.ts +17 -1
- package/src/market/signed-index.ts +42 -0
- package/src/maturity/feature-maturity.ts +2 -1
- package/src/mcp/mcp-oauth.ts +136 -17
- package/src/model-tier/llm-tier-map.ts +48 -4
- package/src/models/prompts.ts +22 -1
- package/src/mss/logging/horizon-watch.ts +168 -0
- package/src/mss/logging/log-store.ts +204 -15
- package/src/mss/logging/redaction.ts +17 -0
- package/src/native-tool-catalog.ts +1 -1
- package/src/nexus/api/consult-requests.ts +7 -10
- package/src/nexus/api/discord-trigger-bot.ts +6 -3
- package/src/nexus/api/draft-metrics.ts +22 -8
- package/src/nexus/api/error-reports.ts +30 -8
- package/src/nexus/api/graph-peer-edit.ts +77 -0
- package/src/nexus/api/graph-wizard-api.ts +9 -1
- package/src/nexus/api/graphs-api.ts +145 -7
- package/src/nexus/api/http-server.ts +101 -8
- package/src/nexus/api/loop-resources.ts +42 -0
- package/src/nexus/api/outbound-report.ts +8 -3
- package/src/nexus/api/plugins-market.ts +24 -0
- package/src/nexus/api/telegram-trigger-bot.ts +6 -3
- package/src/nexus/index.ts +13 -2
- package/src/nexus/outbound/format.ts +2 -0
- package/src/nexus/outbound/router.ts +198 -13
- package/src/oauth/claude-pty-maturity.ts +24 -0
- package/src/oauth/codex-account-rotation.ts +16 -18
- package/src/oauth/codex-account-store.ts +134 -5
- package/src/oauth/fallback-chain.ts +50 -15
- package/src/onboarding.ts +2 -1
- package/src/plugins/adapters/claude-package.ts +4 -12
- package/src/plugins/core/capability-policy.ts +141 -0
- package/src/plugins/core/host.ts +21 -8
- package/src/plugins/core/manifest.ts +19 -2
- package/src/plugins/core/trust-store.ts +15 -0
- package/src/plugins/core/types.ts +12 -0
- package/src/plugins/install/market-fetch.ts +68 -16
- package/src/plugins/install/plugin-install.ts +187 -16
- package/src/plugins/maker/market-bundle.ts +9 -0
- package/src/plugins/maker/plugin-maker.ts +32 -21
- package/src/plugins/maker/wizard-generate.ts +87 -9
- package/src/policy/llm-policy.ts +24 -6
- package/src/process/pid-liveness.ts +1 -1
- package/src/prompt-cache/openai.ts +10 -6
- package/src/prompt-cache/openrouter.ts +94 -0
- package/src/prompt-enhance/enhance.ts +46 -5
- package/src/prompt-library/family-prompt-coverage.ts +1 -0
- package/src/prompt-library/universal-preamble.ts +2 -2
- package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
- package/src/registry/loader.ts +6 -1
- package/src/release-loop/checklist-board.ts +27 -0
- package/src/release-loop/checklist.ts +62 -9
- package/src/release-loop/feature-store.ts +3 -0
- package/src/release-loop/gate-shards.ts +48 -4
- package/src/release-loop/landed-to-green.ts +81 -0
- package/src/release-loop/light-rc.ts +11 -1
- package/src/release-loop/merged-pr-checklist.ts +10 -0
- package/src/release-loop/placement.ts +91 -22
- package/src/release-loop/rehearsal.ts +317 -0
- package/src/release-loop/release-schedule.ts +13 -1
- package/src/release-loop/rubric-types.ts +1 -0
- package/src/release-loop/rubric.ts +2 -2
- package/src/retro/daily.ts +23 -9
- package/src/seat-address/seat-address.ts +1 -0
- package/src/seat-loop/seat-loop.ts +208 -21
- package/src/seat-loop/seat-report.ts +29 -1
- package/src/seat-loop/traffic-signal.ts +44 -0
- package/src/self-dev/ask-launch-flow.ts +2 -2
- package/src/self-dev/dev-cli.ts +157 -11
- package/src/self-dev/dev-pipeline.ts +18 -1
- package/src/self-dev/draft-residue.ts +463 -0
- package/src/self-dev/draft-sweep.ts +195 -17
- package/src/self-dev/draft-triage-rules.ts +27 -1
- package/src/self-dev/launch-preflight-text.ts +549 -0
- package/src/self-dev/launch-preflight.ts +10 -545
- package/src/self-dev/orchestrate-cli.ts +57 -2
- package/src/self-dev/orchestrate-summary-line.ts +13 -0
- package/src/self-dev/orchestrate.ts +9 -133
- package/src/self-dev/review-provider-fallback.ts +179 -0
- package/src/self-dev/run-store.ts +1 -3
- package/src/self-dev/run-supervisor.ts +8 -23
- package/src/self-dev/run-types.ts +178 -0
- package/src/self-dev/shard-aggregate.ts +61 -13
- package/src/self-dev/shard-plan.ts +5 -1
- package/src/self-dev/shard-run.ts +23 -5
- package/src/self-dev/supervisor-verdict-edges.ts +2 -4
- package/src/self-implement/blocked-draft-policy.ts +3 -19
- package/src/self-implement/draft-on-stop-mode.ts +18 -0
- package/src/self-implement/follow-up-goals.ts +114 -38
- package/src/self-implement/gate-baseline-reap.ts +157 -0
- package/src/self-implement/gate-baseline.ts +78 -16
- package/src/self-implement/gate-cli.ts +12 -2
- package/src/self-implement/gate-remote.ts +17 -6
- package/src/self-implement/goal-author.ts +24 -4
- package/src/self-implement/goal-digest.ts +19 -0
- package/src/self-implement/graph-overlay-condition.ts +4 -0
- package/src/self-implement/harness-policy-gates.ts +7 -5
- package/src/self-implement/headless-elanous-driver.ts +11 -9
- package/src/self-implement/host-regate.ts +148 -43
- package/src/self-implement/l8-merge-queue.ts +147 -13
- package/src/self-implement/merge-train.ts +131 -0
- package/src/self-implement/off-diff-evidence.ts +9 -0
- package/src/self-implement/orchestrator.ts +201 -43
- package/src/self-implement/review-finding-recurrence.ts +28 -0
- package/src/self-implement/rework-policy.ts +2 -1
- package/src/self-implement/round-summary-card.ts +63 -0
- package/src/self-implement/run-ledger.ts +4 -3
- package/src/self-implement/run-step-projection.ts +147 -0
- package/src/self-implement/run-stop.ts +1 -1
- package/src/self-implement/seams.ts +41 -6
- package/src/self-implement/self-implement-cli.ts +6 -0
- package/src/self-implement/train-gate-remote.ts +158 -0
- package/src/session-runtime/index.ts +10 -1
- package/src/session-runtime/retry-api.ts +11 -1
- package/src/shell-env-bootstrap.ts +19 -4
- package/src/skills/gift-install.ts +119 -0
- package/src/skills/runner.ts +59 -2
- package/src/skills/skill-feedback.ts +31 -1
- package/src/skills/skill-tier.ts +1 -0
- package/src/smart-wizard/capability-index.ts +231 -0
- package/src/smart-wizard/rung.ts +74 -0
- package/src/steward/launch.ts +20 -9
- package/src/steward/triage.ts +29 -10
- package/src/storage/file-lock.ts +40 -4
- package/src/task-agent/actions.ts +4 -0
- package/src/task-agent/card-evidence.ts +59 -13
- package/src/task-agent/completion-evidence.ts +31 -3
- package/src/task-agent/cover.ts +61 -0
- package/src/task-agent/judge.ts +4 -3
- package/src/task-agent/land-worktree.ts +201 -0
- package/src/task-agent/live-move-history.ts +133 -0
- package/src/task-agent/live-moves.ts +222 -12
- package/src/task-agent/parent-host.ts +117 -8
- package/src/task-agent/rejudge-on-head.ts +297 -0
- package/src/task-agent/review-result-capture.ts +218 -0
- package/src/task-agent/shadow.ts +118 -7
- package/src/task-agent/task-hand.ts +138 -11
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
- package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
- package/src/task-orchestrator/surfaces/pod-pool.ts +203 -28
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
- package/src/task-orchestrator/surfaces/self-implement.ts +11 -0
- package/src/telegram-commands.ts +8 -0
- package/src/telegram-project-command.ts +6 -0
- package/src/telegram-service.ts +5 -1
- package/src/telegram.ts +17 -4
- package/src/time/format.ts +13 -4
- package/src/tool-runtime/goal-author-runtime.ts +1 -0
- package/src/tool-runtime/self-cognition-catalog.ts +23 -0
- package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
- package/src/typecheck-ratchet.ts +2 -1
- package/src/user-config.ts +167 -28
- package/src/ux-sim/slash-menu-frames.ts +168 -0
- package/src/version/packed-revision.json +1 -1
- package/src/web-terminal/preview-tap-registry.ts +5 -2
- package/src/workflow-runtime/executor.ts +24 -2
- package/src/workflow-runtime/triggers/registry.ts +27 -0
- package/src/workflow-runtime/triggers/schedule-source.ts +30 -3
- package/src/workflow-runtime/triggers/scheduler.ts +1 -0
- package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
- package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
- package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
- package/apps/pwa/out/_next/static/chunks/1307-c97eba9fb72a9a5e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
- package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
- package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
- package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
- package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
- package/apps/pwa/out/_next/static/chunks/2489-ff55a35b202c0f94.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
- package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
- package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
- package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
- package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
- package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
- package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5977-59fedea50d13c762.js +0 -1
- package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
- package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
- package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
- package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
- package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
- package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
- package/apps/pwa/out/_next/static/chunks/8857-f1762140ef9a96b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
- package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9247-7581825d511a64c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
- package/apps/pwa/out/_next/static/chunks/9497-b0e758d1cd4ae8d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-937c92292a4ab4f0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d781be3e3a9cfd74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-b0a80997903852d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-2b1263165630d9c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ea998f7f5d156bea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-33c328b64ca508f8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-e2d6bed48ac20120.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-544dd4bd4847eeb7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-3ee191319bf97d87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e4bcb2c503dab04b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-300897dcbbd5ed76.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a449f1ed472b81c2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-9045094d6d3b5cd0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-c06673596849ef45.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-103fa3191c1b2e08.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-9f81233f29dcd409.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-be8b4615c919e36c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-c685b104e0dfa609.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-8d693331cfbb6add.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-cef4f30a4c22fae1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66ea1b54fc83fa15.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-7a12f61be4a579d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-c85b0589591a99c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-725a4da02dd129eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8cc707bd09a497d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-90b55be1f15ce0e8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cb16606e08be65db.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-16dc64b74ed6a40a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-21bec4afeb2f0917.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-dc39ee7a36d26385.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-84ae759f76053672.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-3db58ddb61fe2be9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c5315e30f3528dc4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-2fe368efb6de3b6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8d04132dd0ac5e10.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-f23484de467c9ea3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-c69762987b751174.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-5456692bda39aafb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-d75f7cd65845ce98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-5603f5e568b25ce3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-d2cc0f4e89f42028.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-a6eb73b8a4840f1c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-c0a3f4d10edb83fa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6c0b88068c143f15.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-7f8d7fcdf058a845.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-22163556cd38bc88.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-141436fd26dd56fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
- package/apps/pwa/out/_next/static/css/e81df11490b4413b.css +0 -1
- /package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
package/src/dashboard/index.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
7
7
|
import { join } from 'path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
|
-
import { createStaleInstallCheck, readCurrentInstalledCommit, readDashboardBootCommit, STALE_INSTALL_CHECK_INTERVAL_MS, versionedDashboardInstallDir } from './stale-install-check.js';
|
|
9
|
+
import { createStaleInstallCheck, formatStaleInstallNotice, readCurrentInstalledCommit, readDashboardBootCommit, STALE_INSTALL_CHECK_INTERVAL_MS, versionedDashboardInstallDir } from './stale-install-check.js';
|
|
10
10
|
import { spawn, spawnSync } from 'node:child_process';
|
|
11
11
|
import { $ } from 'bun';
|
|
12
12
|
import { LOCAL_SKILLS_DIR, SERVICE_NAMES, DATA_DIR, OBSIDIAN_VAULT } from '../config.js';
|
|
@@ -896,7 +896,7 @@ import { inspectActiveProvider } from '../provider-summary.js';
|
|
|
896
896
|
import { activeCodexAccountView } from '../oauth/codex-account-store.js';
|
|
897
897
|
import { buildDashboardStatusLines } from './dashboard-status-lines.js';
|
|
898
898
|
import { readSlashContextNow, seatsNowLine } from '../context-bus/context-now-surfaces.js';
|
|
899
|
-
import { buildFirstScreenBand } from './first-screen-band.js';
|
|
899
|
+
import { buildFirstScreenBand, resolveTuiDaemonLink, type TuiDaemonLink } from './first-screen-band.js';
|
|
900
900
|
import { runNexusShow, type NexusShowResult } from '../cli/nexus-show.js';
|
|
901
901
|
import {
|
|
902
902
|
workingDirSegment, sessionCwdSegment, modelSegment, gitSegment,
|
|
@@ -2128,15 +2128,22 @@ export function renderDashboardFirstScreenBand(input: {
|
|
|
2128
2128
|
readonly draw: () => void;
|
|
2129
2129
|
readonly observe: (data: { daemon: boolean; hasPwa: boolean; hasTailnet: boolean }) => void;
|
|
2130
2130
|
readonly show?: () => Promise<Pick<NexusShowResult, 'status' | 'urls'>>;
|
|
2131
|
+
readonly daemonLink?: () => Promise<TuiDaemonLink>;
|
|
2131
2132
|
}): Promise<void> {
|
|
2132
2133
|
if (input.history.some((message) => message.role !== 'system')) return Promise.resolve();
|
|
2133
|
-
const band = buildFirstScreenBand({ width: input.width, daemon: false });
|
|
2134
|
+
const band = buildFirstScreenBand({ width: input.width, daemon: false, link: { status: 'checking' } });
|
|
2134
2135
|
input.lines.unshift(...band);
|
|
2136
|
+
const daemonLink = input.daemonLink ?? resolveTuiDaemonLink;
|
|
2137
|
+
const linkPending = Promise.resolve().then(() => daemonLink()).catch((): TuiDaemonLink => ({ status: 'error', stage: 'health' })).then((link) => {
|
|
2138
|
+
if (input.lines[0] !== band[0]) return;
|
|
2139
|
+
input.lines[0] = buildFirstScreenBand({ width: input.width, daemon: false, link })[0]!;
|
|
2140
|
+
try { input.draw(); } catch { /* screen may have closed */ }
|
|
2141
|
+
});
|
|
2135
2142
|
const show = input.show ?? (() => runNexusShow({ format: 'json', out: { log: () => {}, error: () => {} } }));
|
|
2136
2143
|
const observe = (data: { daemon: boolean; hasPwa: boolean; hasTailnet: boolean }): void => {
|
|
2137
2144
|
try { input.observe(data); } catch { /* observation cannot interrupt the transcript */ }
|
|
2138
2145
|
};
|
|
2139
|
-
|
|
2146
|
+
const pwaPending = Promise.resolve().then(show).then((result) => {
|
|
2140
2147
|
const daemon = result.status !== 'absent';
|
|
2141
2148
|
const pwa = result.urls?.pwa;
|
|
2142
2149
|
const hasPwa = !!pwa;
|
|
@@ -2148,6 +2155,7 @@ export function renderDashboardFirstScreenBand(input: {
|
|
|
2148
2155
|
}).catch(() => {
|
|
2149
2156
|
observe({ daemon: false, hasPwa: false, hasTailnet: false });
|
|
2150
2157
|
});
|
|
2158
|
+
return Promise.all([linkPending, pwaPending]).then(() => {});
|
|
2151
2159
|
}
|
|
2152
2160
|
|
|
2153
2161
|
export async function showDashboard(opts: ShowDashboardOptions = {}): Promise<DashboardAction> {
|
|
@@ -4361,13 +4369,27 @@ Mode- and sync-specific instructions are injected per-turn when relevant — do
|
|
|
4361
4369
|
now: Date.now,
|
|
4362
4370
|
});
|
|
4363
4371
|
if (versionDir) {
|
|
4372
|
+
let staleNoticeIndex = -1;
|
|
4373
|
+
let staleNoticeLine: string | undefined;
|
|
4374
|
+
let staleNoticeCount = 0;
|
|
4364
4375
|
const checkInstall = (): void => {
|
|
4365
4376
|
const result = staleInstallCheck.check();
|
|
4366
4377
|
debug.log('dashboard.version', 'install-check', {
|
|
4367
4378
|
state: result.state, bootCommit: result.bootCommit, installedCommit: result.installedCommit,
|
|
4368
4379
|
});
|
|
4369
4380
|
if (staleInstallCheck.shouldNotify(result)) {
|
|
4370
|
-
|
|
4381
|
+
staleNoticeCount++;
|
|
4382
|
+
const notice = C.warning(formatStaleInstallNotice(result, staleNoticeCount));
|
|
4383
|
+
if (chatLines[staleNoticeIndex] !== staleNoticeLine || staleNoticeLine === undefined) {
|
|
4384
|
+
staleNoticeIndex = staleNoticeLine === undefined ? -1 : chatLines.indexOf(staleNoticeLine);
|
|
4385
|
+
}
|
|
4386
|
+
if (staleNoticeIndex < 0) {
|
|
4387
|
+
chatLines.push(notice);
|
|
4388
|
+
staleNoticeIndex = chatLines.length - 1;
|
|
4389
|
+
} else {
|
|
4390
|
+
chatLines[staleNoticeIndex] = notice;
|
|
4391
|
+
}
|
|
4392
|
+
staleNoticeLine = notice;
|
|
4371
4393
|
chatScrollOffset = -1;
|
|
4372
4394
|
try { draw(); } catch { /* TUI torn down */ }
|
|
4373
4395
|
}
|
|
@@ -343,7 +343,7 @@ import { terminalModalRouter } from '../input/terminal-modal-router.js';
|
|
|
343
343
|
import { termSize, stripAnsi } from '../../tui.js';
|
|
344
344
|
import { SLASH_COMMANDS } from '../../chat/index.js';
|
|
345
345
|
import { buildEssentialHelpLines } from './help-from-registry.js';
|
|
346
|
-
import { HUMAN_MODEL_WORDS, MODEL_CODE_NAMES, modelChangeLine, modelOverviewLines, resolveModelChoice } from './model-choices.js';
|
|
346
|
+
import { HUMAN_MODEL_WORDS, MODEL_CODE_NAMES, humanWordForModel, modelChangeLine, modelOverviewLines, resolveModelChoice } from './model-choices.js';
|
|
347
347
|
import type { FoldMode } from '../../log-entry.js';
|
|
348
348
|
import { resolveDashboardChatMainLogCommand } from '../input/chat-main-log-command.js';
|
|
349
349
|
import {
|
|
@@ -395,6 +395,8 @@ import { dispatchTerminalModalObserve } from '../../skills/tools/terminal-modal.
|
|
|
395
395
|
import { SlashCommandRegistry } from './registry.js';
|
|
396
396
|
import { cronSecondDueAt, filterLoopRows, formatLoopsTable, localLoopRows, type LoopsTableRow } from './loops-table.js';
|
|
397
397
|
import { loopCronVerdict } from '../../loops/verdict.js';
|
|
398
|
+
import { checklistBoardSlash } from '../../release-loop/checklist-board.js';
|
|
399
|
+
import type { Checklist } from '../../release-loop/checklist.js';
|
|
398
400
|
import { executeImmediateDashboardSlash } from '../input/slash-executor.js';
|
|
399
401
|
import {
|
|
400
402
|
buildContextSlashCommand,
|
|
@@ -1046,6 +1048,8 @@ export interface DashboardSlashContext {
|
|
|
1046
1048
|
|
|
1047
1049
|
/** Test seam for the local read-only loop and cron registry. */
|
|
1048
1050
|
loopsLocalRows?: (now: Date) => LoopsTableRow[];
|
|
1051
|
+
/** Test seam for the read-only release checklist. */
|
|
1052
|
+
checklistRead?: (version: string) => Checklist;
|
|
1049
1053
|
|
|
1050
1054
|
sessionSlash: {
|
|
1051
1055
|
/** opts.remote — when the dashboard is attached to a remote daemon. */
|
|
@@ -1467,6 +1471,11 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
|
|
|
1467
1471
|
ctx.setChatScrollOffset(-1);
|
|
1468
1472
|
});
|
|
1469
1473
|
|
|
1474
|
+
registry.register('board', (args, ctx) => {
|
|
1475
|
+
for (const line of checklistBoardSlash(args, ctx.checklistRead).split('\n')) ctx.pushChatLine(line);
|
|
1476
|
+
ctx.setChatScrollOffset(-1);
|
|
1477
|
+
});
|
|
1478
|
+
|
|
1470
1479
|
registry.register('wish', (args, ctx) => {
|
|
1471
1480
|
const text = args.join(' ').trim();
|
|
1472
1481
|
if (!text) {
|
|
@@ -6188,8 +6197,10 @@ export function buildDashboardSlashRegistry(nowDeps?: ContextNowDeps, decideLedg
|
|
|
6188
6197
|
const curModel = curCfg.llm.model;
|
|
6189
6198
|
const curReasoning = effectiveReasoningLevel(curCfg.llm, curProvider, curModel);
|
|
6190
6199
|
if (!arg) {
|
|
6191
|
-
const [
|
|
6192
|
-
|
|
6200
|
+
const [, codes] = modelOverviewLines(curProvider, curModel, curReasoning);
|
|
6201
|
+
// A model outside the 빠름/보통/깊음 map (codename or custom) says so explicitly instead of dropping the tier slot.
|
|
6202
|
+
const tierName = humanWordForModel(curProvider, curModel, curReasoning) ?? '단계 밖';
|
|
6203
|
+
ctx.chatLines.push(`지금: ${curModel?.trim() || '기본 모델'} (${tierName} · 생각 ${curReasoning}) · 고르기: /model ${HUMAN_MODEL_WORDS.join(' | ')}`);
|
|
6193
6204
|
ctx.chatLines.push(ctx.muted(codes));
|
|
6194
6205
|
ctx.setChatScrollOffset(-1);
|
|
6195
6206
|
return;
|
|
@@ -12,6 +12,11 @@ export type StaleInstallResult = {
|
|
|
12
12
|
|
|
13
13
|
export const STALE_INSTALL_CHECK_INTERVAL_MS = 60_000;
|
|
14
14
|
|
|
15
|
+
export function formatStaleInstallNotice(result: StaleInstallResult, notifiedCount: number): string {
|
|
16
|
+
const message = `새 판이 깔렸습니다 (부팅 판 ${result.bootCommit!.slice(0, 7)} → 지금 ${result.installedCommit!.slice(0, 7)}) · TUI 를 다시 띄우면 새 판으로 돕니다`;
|
|
17
|
+
return notifiedCount >= 2 ? `${message} · 이 TUI 가 뜬 뒤 ${notifiedCount}번째 새 판` : message;
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
/** Identify the immutable installed version containing this module, never the session cwd. */
|
|
16
21
|
export function versionedDashboardInstallDir(
|
|
17
22
|
codeRoot: string,
|
|
@@ -21,8 +26,14 @@ export function versionedDashboardInstallDir(
|
|
|
21
26
|
const packageRoot = realpathSync(codeRoot);
|
|
22
27
|
if (basename(packageRoot) !== 'elanous' || basename(dirname(packageRoot)) !== 'node_modules') return undefined;
|
|
23
28
|
const versionDir = dirname(dirname(packageRoot));
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
let canonicalInstallRoot: string;
|
|
30
|
+
try { canonicalInstallRoot = realpathSync(installRoot); }
|
|
31
|
+
catch { canonicalInstallRoot = resolve(installRoot); }
|
|
32
|
+
if (dirname(versionDir) !== join(canonicalInstallRoot, 'versions')) return undefined;
|
|
33
|
+
const requestedVersionDir = dirname(dirname(resolve(codeRoot)));
|
|
34
|
+
return dirname(requestedVersionDir) === resolve(installRoot, 'versions')
|
|
35
|
+
&& realpathSync(requestedVersionDir) === versionDir
|
|
36
|
+
? requestedVersionDir : versionDir;
|
|
26
37
|
} catch {
|
|
27
38
|
return undefined;
|
|
28
39
|
}
|
|
@@ -20,6 +20,7 @@ import type { ToolRenderModel } from '../chat/tool-render/types.js';
|
|
|
20
20
|
import { toolOperationKind, type FoldMode } from '../log-entry.js';
|
|
21
21
|
import { stripAnsi } from '../tui.js';
|
|
22
22
|
import type { TurnStreamPresentationEvent } from './turn-stream-presentation-applier.js';
|
|
23
|
+
import { buildFoldedTailLine, splitNoSynthesisTail } from './chat-fold.js';
|
|
23
24
|
|
|
24
25
|
/** Drop leading/trailing blank (whitespace-only, ANSI-stripped) rows
|
|
25
26
|
* from a rendered assistant block. Codex-family models frequently
|
|
@@ -181,6 +182,7 @@ export function createTurnStreamFormatter(
|
|
|
181
182
|
const toolArgsByCallId = new Map<string, Record<string, unknown>>();
|
|
182
183
|
const nonGenericCallIds = new Set<string>();
|
|
183
184
|
let toolCallCount = 0;
|
|
185
|
+
let noSynthesisTailCount = 0;
|
|
184
186
|
|
|
185
187
|
const emitAssistantBlock = (): void => {
|
|
186
188
|
deps.thinking.update('Streaming');
|
|
@@ -219,6 +221,29 @@ export function createTurnStreamFormatter(
|
|
|
219
221
|
}
|
|
220
222
|
if (chunk === '') {
|
|
221
223
|
// Path 2 — authoritative replacement (W5-E/F/G force-synthesis).
|
|
224
|
+
const split = splitNoSynthesisTail(accumulated);
|
|
225
|
+
if (split) {
|
|
226
|
+
perRoundText = split.head;
|
|
227
|
+
emitAssistantBlock();
|
|
228
|
+
closeRound();
|
|
229
|
+
deps.emit({ type: 'assistant.commit' });
|
|
230
|
+
const callId = `no-synthesis-tail-${++noSynthesisTailCount}`;
|
|
231
|
+
const expandedLines = trimBlankEdges(
|
|
232
|
+
deps.formatResponse(split.tail, deps.termCols() - 6, deps.wrapOpts),
|
|
233
|
+
).map(deps.text);
|
|
234
|
+
const collapsedLines = [buildFoldedTailLine(expandedLines.length)];
|
|
235
|
+
if (debug.enabled) {
|
|
236
|
+
debug.log('dashboard.chat.stream', 'formatter.noSynthesisTail.folded', {
|
|
237
|
+
callId,
|
|
238
|
+
headLen: split.head.length,
|
|
239
|
+
tailLen: split.tail.length,
|
|
240
|
+
expandedLineCount: expandedLines.length,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
deps.emit({ type: 'tool.appendBlock', callId, lines: collapsedLines, args: {} });
|
|
244
|
+
deps.emit({ type: 'tool.replaceBlock', callId, collapsedLines, expandedLines });
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
222
247
|
perRoundText = accumulated;
|
|
223
248
|
} else {
|
|
224
249
|
// Path 3 — streaming delta. accumulated 무시 (cross-turn fullText).
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import type { DebugEvent } from './log.js';
|
|
2
|
+
|
|
3
|
+
export const LOG_DIET_WINDOW_MS = 60_000;
|
|
4
|
+
|
|
5
|
+
export const LOG_DIET_KEYS: Readonly<Record<string, 'repeat' | 'consecutive'>> = {
|
|
6
|
+
'watchdog/activity': 'consecutive',
|
|
7
|
+
'user-config.llm/provider-resolved': 'repeat',
|
|
8
|
+
'hitl.card-bridge/skipped': 'repeat',
|
|
9
|
+
'input.cursor.claim/chat-main': 'repeat',
|
|
10
|
+
'tox.loop/waiting-capacity': 'repeat',
|
|
11
|
+
'tox.loop/tick': 'repeat',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export interface LogDietSummary {
|
|
15
|
+
category: string;
|
|
16
|
+
event: string;
|
|
17
|
+
count: number;
|
|
18
|
+
windowMs: number;
|
|
19
|
+
firstSuppressedAt: string;
|
|
20
|
+
lastSuppressedAt: string;
|
|
21
|
+
runId?: string;
|
|
22
|
+
sessionId?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type Policy = 'repeat' | 'consecutive';
|
|
26
|
+
type DietRecord = Pick<DebugEvent, 'category' | 'event' | 'data' | 'level' | 'session_id' | 'runId'>;
|
|
27
|
+
|
|
28
|
+
interface Stream {
|
|
29
|
+
category: string;
|
|
30
|
+
event: string;
|
|
31
|
+
runId?: string;
|
|
32
|
+
sessionId?: string;
|
|
33
|
+
value: string;
|
|
34
|
+
lastEmittedAt: number;
|
|
35
|
+
count: number;
|
|
36
|
+
firstSuppressedAt?: string;
|
|
37
|
+
lastSuppressedAt?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Canonicalize objects (not arrays) so payload property insertion order is not an identity. */
|
|
41
|
+
function stableValue(value: unknown): string {
|
|
42
|
+
const seen = new WeakSet<object>();
|
|
43
|
+
return JSON.stringify(value, (_key, item: unknown) => {
|
|
44
|
+
if (typeof item === 'bigint') return `${item}n`;
|
|
45
|
+
if (item && typeof item === 'object') {
|
|
46
|
+
if (seen.has(item)) return '<circular>';
|
|
47
|
+
seen.add(item);
|
|
48
|
+
if (Array.isArray(item)) return item;
|
|
49
|
+
return Object.fromEntries(Object.entries(item).sort(([a], [b]) => a.localeCompare(b)));
|
|
50
|
+
}
|
|
51
|
+
return item;
|
|
52
|
+
}) ?? 'undefined';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export class LogDietGuard {
|
|
56
|
+
private readonly windowMs: number;
|
|
57
|
+
private readonly now: () => number;
|
|
58
|
+
private readonly keys: Readonly<Record<string, Policy>>;
|
|
59
|
+
private readonly maxStreams: number;
|
|
60
|
+
private readonly disabled: boolean;
|
|
61
|
+
private readonly streams = new Map<string, Stream>();
|
|
62
|
+
|
|
63
|
+
constructor(opts: { windowMs?: number; now?: () => number; keys?: Readonly<Record<string, Policy>>; maxStreams?: number } = {}) {
|
|
64
|
+
this.windowMs = opts.windowMs ?? LOG_DIET_WINDOW_MS;
|
|
65
|
+
this.now = opts.now ?? Date.now;
|
|
66
|
+
this.keys = opts.keys ?? LOG_DIET_KEYS;
|
|
67
|
+
this.maxStreams = Math.max(1, opts.maxStreams ?? 2000);
|
|
68
|
+
this.disabled = process.env.ELANOUS_LOG_DIET === 'off';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private summary(stream: Stream): LogDietSummary | undefined {
|
|
72
|
+
if (!stream.count) return undefined;
|
|
73
|
+
return {
|
|
74
|
+
category: stream.category,
|
|
75
|
+
event: stream.event,
|
|
76
|
+
count: stream.count,
|
|
77
|
+
windowMs: this.windowMs,
|
|
78
|
+
firstSuppressedAt: stream.firstSuppressedAt!,
|
|
79
|
+
lastSuppressedAt: stream.lastSuppressedAt!,
|
|
80
|
+
...(stream.runId !== undefined ? { runId: stream.runId } : {}),
|
|
81
|
+
...(stream.sessionId !== undefined ? { sessionId: stream.sessionId } : {}),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
admit(rec: DietRecord): { pass: boolean; summaries: LogDietSummary[] } {
|
|
86
|
+
const policy = this.keys[`${rec.category}/${rec.event}`];
|
|
87
|
+
if (this.disabled || !policy || rec.category === 'log.diet'
|
|
88
|
+
|| rec.level === 'warn' || rec.level === 'error' || rec.level === 'critical') {
|
|
89
|
+
return { pass: true, summaries: [] };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const runId = rec.runId ?? (rec.data && typeof rec.data === 'object' && !Array.isArray(rec.data)
|
|
93
|
+
? (rec.data as Record<string, unknown>).runId : undefined);
|
|
94
|
+
const sessionId = rec.session_id;
|
|
95
|
+
let value: string;
|
|
96
|
+
try {
|
|
97
|
+
value = stableValue([stableValue(rec.data), rec.level ?? 'debug', sessionId, runId]);
|
|
98
|
+
} catch {
|
|
99
|
+
return { pass: true, summaries: [] }; // Logging must remain fail-open for unusual payloads.
|
|
100
|
+
}
|
|
101
|
+
const key = stableValue(policy === 'repeat'
|
|
102
|
+
? [rec.category, rec.event, value]
|
|
103
|
+
: [rec.category, rec.event, sessionId, runId]);
|
|
104
|
+
const time = this.now();
|
|
105
|
+
const summaries: LogDietSummary[] = [];
|
|
106
|
+
const stream = this.streams.get(key);
|
|
107
|
+
if (stream) {
|
|
108
|
+
this.streams.delete(key); // Evict the least recently observed flow.
|
|
109
|
+
this.streams.set(key, stream);
|
|
110
|
+
if ((policy === 'repeat' || stream.value === value) && time - stream.lastEmittedAt < this.windowMs) {
|
|
111
|
+
stream.count++;
|
|
112
|
+
const at = new Date(time).toISOString();
|
|
113
|
+
stream.firstSuppressedAt ??= at;
|
|
114
|
+
stream.lastSuppressedAt = at;
|
|
115
|
+
return { pass: false, summaries };
|
|
116
|
+
}
|
|
117
|
+
const pending = this.summary(stream);
|
|
118
|
+
if (pending) summaries.push(pending);
|
|
119
|
+
stream.count = 0;
|
|
120
|
+
stream.firstSuppressedAt = undefined;
|
|
121
|
+
stream.lastSuppressedAt = undefined;
|
|
122
|
+
stream.value = value;
|
|
123
|
+
stream.lastEmittedAt = time;
|
|
124
|
+
return { pass: true, summaries };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (this.streams.size >= this.maxStreams) {
|
|
128
|
+
const oldestKey = this.streams.keys().next().value!;
|
|
129
|
+
const oldest = this.streams.get(oldestKey)!;
|
|
130
|
+
const pending = this.summary(oldest);
|
|
131
|
+
if (pending) summaries.push(pending);
|
|
132
|
+
this.streams.delete(oldestKey);
|
|
133
|
+
}
|
|
134
|
+
this.streams.set(key, { category: rec.category, event: rec.event,
|
|
135
|
+
...(typeof runId === 'string' ? { runId } : {}),
|
|
136
|
+
...(sessionId !== undefined ? { sessionId } : {}),
|
|
137
|
+
value, lastEmittedAt: time, count: 0 });
|
|
138
|
+
return { pass: true, summaries };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Emit pending counts without reopening the current sample windows. */
|
|
142
|
+
flushPending(): LogDietSummary[] {
|
|
143
|
+
const summaries: LogDietSummary[] = [];
|
|
144
|
+
for (const stream of this.streams.values()) {
|
|
145
|
+
const pending = this.summary(stream);
|
|
146
|
+
if (pending) summaries.push(pending);
|
|
147
|
+
stream.count = 0;
|
|
148
|
+
stream.firstSuppressedAt = undefined;
|
|
149
|
+
stream.lastSuppressedAt = undefined;
|
|
150
|
+
}
|
|
151
|
+
return summaries;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
drain(): LogDietSummary[] {
|
|
155
|
+
const summaries = this.flushPending();
|
|
156
|
+
this.streams.clear();
|
|
157
|
+
return summaries;
|
|
158
|
+
}
|
|
159
|
+
}
|
package/src/debug/log.ts
CHANGED
|
@@ -81,8 +81,7 @@ import { redactLogRecord } from '../mss/logging/redaction.js';
|
|
|
81
81
|
import { isRenderCategory } from '../mss/logging/render-categories.js';
|
|
82
82
|
import type { LogSource, LogLevel } from '../mss/logging/record.js';
|
|
83
83
|
import { cleanupLogDir } from '../mss/logging/retention.js';
|
|
84
|
-
import {
|
|
85
|
-
import { createOtelGenAISinkFromFlags } from '../mss/logging/sinks/otel-genai-sink.js';
|
|
84
|
+
import { LogDietGuard, type LogDietSummary } from './log-diet.js';
|
|
86
85
|
|
|
87
86
|
/** DebugEvent is the legacy shape. Pre-MSS callers only read/write
|
|
88
87
|
* `ts` / `category` / `event` / `data`. MSS M2.1 adds four optional
|
|
@@ -285,6 +284,7 @@ class DebugLog {
|
|
|
285
284
|
private readonly _ringSink = new RingSink(500);
|
|
286
285
|
private readonly _mirrorSink = new MirrorSink(formatLine);
|
|
287
286
|
private readonly _extraSinks: LogSink[] = [];
|
|
287
|
+
private _logDietGuard: LogDietGuard | null = new LogDietGuard();
|
|
288
288
|
private readonly _redactEnabled: boolean;
|
|
289
289
|
|
|
290
290
|
constructor() {
|
|
@@ -550,8 +550,20 @@ class DebugLog {
|
|
|
550
550
|
return this._ringSink.events().map(formatLine).join('\n');
|
|
551
551
|
}
|
|
552
552
|
|
|
553
|
+
/** Replace the guard for isolated sink tests; return the previous guard. */
|
|
554
|
+
setLogDietGuard(guard: LogDietGuard | null): LogDietGuard | null {
|
|
555
|
+
const previous = this._logDietGuard;
|
|
556
|
+
this._logDietGuard = guard;
|
|
557
|
+
return previous;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
private emitLogDietSummaries(summaries: LogDietSummary[]): void {
|
|
561
|
+
for (const summary of summaries) this.log('log.diet', 'suppressed', summary);
|
|
562
|
+
}
|
|
563
|
+
|
|
553
564
|
/** Force any buffered events to disk immediately. */
|
|
554
565
|
flush(): void {
|
|
566
|
+
if (this._logDietGuard) this.emitLogDietSummaries(this._logDietGuard.flushPending());
|
|
555
567
|
this._fileSink.flush();
|
|
556
568
|
this._chatFileSink.flush();
|
|
557
569
|
for (const sink of this._extraSinks) {
|
|
@@ -600,6 +612,12 @@ class DebugLog {
|
|
|
600
612
|
// when off).
|
|
601
613
|
if (this._redactEnabled) rec = redactLogRecord(rec) as DebugEvent;
|
|
602
614
|
|
|
615
|
+
if (this._logDietGuard) {
|
|
616
|
+
const decision = this._logDietGuard.admit(rec);
|
|
617
|
+
this.emitLogDietSummaries(decision.summaries);
|
|
618
|
+
if (!decision.pass) return;
|
|
619
|
+
}
|
|
620
|
+
|
|
603
621
|
// Ring buffer — always populated when at least one sink is live so
|
|
604
622
|
// `/debug tail` shows activity even when the file write failed.
|
|
605
623
|
this._ringSink.emit(rec);
|
|
@@ -767,7 +785,18 @@ function safeStringSlice(value: string, limit: number, fromEnd = false): string
|
|
|
767
785
|
/** Format a single event as a compact one-line string. Long payloads
|
|
768
786
|
* get truncated at ~400 chars so the chat mirror doesn't flood the
|
|
769
787
|
* log pane on a big LLM response. */
|
|
788
|
+
let configTimeZoneRegistrationLoaded = false;
|
|
789
|
+
|
|
770
790
|
export function formatLine(ev: DebugEvent): string {
|
|
791
|
+
// Standalone logger consumers can format before application bootstrap. Load
|
|
792
|
+
// the config owner once on demand without a static or type import edge.
|
|
793
|
+
if (!configTimeZoneRegistrationLoaded) {
|
|
794
|
+
try {
|
|
795
|
+
const configModulePath: string = '../user-config.js';
|
|
796
|
+
require(configModulePath);
|
|
797
|
+
configTimeZoneRegistrationLoaded = true;
|
|
798
|
+
} catch { /* config unavailable during startup — formatter falls back to env/OS */ }
|
|
799
|
+
}
|
|
771
800
|
const time = formatClock(ev.ts, { millis: true }); // 사용자 시간대 HH:MM:SS.mmm
|
|
772
801
|
const head = `[${time}] [${ev.category}] ${ev.event}`;
|
|
773
802
|
if (ev.data === undefined) return head;
|
|
@@ -905,6 +934,8 @@ const SECRET_TEXT_RULES: readonly { readonly id: string; readonly re: RegExp; re
|
|
|
905
934
|
{ id: 'generic-api-key', re: /\b(api[_-]?key|secret|password|passwd|token|credential)\b(\s*[:=]\s*)["']?[^\s"',;)]{4,}/gi, to: '$1$2***' },
|
|
906
935
|
// 환경변수 형태 `OPENROUTER_API_KEY=…` — 위 규칙은 `_API_KEY` 앞에 단어 경계가 없어 못 잡는다. 값에 글자가 있어야 한다(`MAX_TOKEN=4096` 은 그대로).
|
|
907
936
|
{ id: 'env-secret', re: /\b([A-Z][A-Z0-9]*_(?:[A-Z0-9]+_)*(?:API_KEY|TOKEN|SECRET|PASSWORD|ACCESS_KEY))(\s*[:=]\s*)["']?(?=[^\s"',;)]*[A-Za-z])[^\s"',;)]{8,}/g, to: '$1$2***' },
|
|
937
|
+
// BEDROCK-PROVIDER — `AWS_BEARER_TOKEN_BEDROCK=…` 은 이름이 TOKEN 으로 «끝나지» 않아 위 규칙이 못 잡는다.
|
|
938
|
+
{ id: 'aws-bedrock-bearer-env', re: /\b(AWS_BEARER_TOKEN_BEDROCK)(\s*[:=]\s*)["']?[^\s"',;)]{8,}/g, to: '$1$2***' },
|
|
908
939
|
// Authorization 헤더(로그에서 흔하다).
|
|
909
940
|
{ id: 'authorization-header', re: /\b(Bearer|Basic)\s+[A-Za-z0-9._~+/-]{8,}={0,2}/gi, to: '$1 ***' },
|
|
910
941
|
];
|
|
@@ -959,19 +990,23 @@ export function redactSecrets<T>(obj: T): T {
|
|
|
959
990
|
/** The singleton. Import as `debug` from this module. */
|
|
960
991
|
export const debug = new DebugLog();
|
|
961
992
|
|
|
962
|
-
//
|
|
963
|
-
//
|
|
964
|
-
// the
|
|
965
|
-
// sinks should register themselves from their consuming subsystem
|
|
966
|
-
// rather than being listed here, so this stays small.
|
|
967
|
-
try {
|
|
968
|
-
const stderrSink = createStderrSinkFromFlags(getFlags());
|
|
969
|
-
if (stderrSink) debug.registerSink(stderrSink);
|
|
970
|
-
} catch { /* flag-parse failure must not block the rest of the tracer */ }
|
|
971
|
-
|
|
972
|
-
// PLAN §4.6 / Arc 2.2 — opt-in OTel GenAI sink. Default off; wire only
|
|
973
|
-
// when `MSS_OTEL_ENDPOINT` is set so a missing collector is silent.
|
|
993
|
+
// Optional sinks register synchronously after the singleton exists, before
|
|
994
|
+
// its first caller can log. Non-literal require keeps their type graph out of
|
|
995
|
+
// the foundation and avoids losing records during asynchronous import.
|
|
974
996
|
try {
|
|
975
|
-
const
|
|
976
|
-
if (
|
|
977
|
-
|
|
997
|
+
const flags = getFlags();
|
|
998
|
+
if (flags.stderrSink) {
|
|
999
|
+
try {
|
|
1000
|
+
const sinkModulePath: string = '../mss/logging/sinks/stderr-sink.js';
|
|
1001
|
+
const sink = require(sinkModulePath).createStderrSinkFromFlags(flags) as LogSink | null;
|
|
1002
|
+
if (sink) debug.registerSink(sink);
|
|
1003
|
+
} catch { /* one optional sink must not block the other */ }
|
|
1004
|
+
}
|
|
1005
|
+
if (flags.otelEndpoint) {
|
|
1006
|
+
try {
|
|
1007
|
+
const sinkModulePath: string = '../mss/logging/sinks/otel-genai-sink.js';
|
|
1008
|
+
const sink = require(sinkModulePath).createOtelGenAISinkFromFlags(flags) as LogSink | null;
|
|
1009
|
+
if (sink) debug.registerSink(sink);
|
|
1010
|
+
} catch { /* optional sink must not block the tracer */ }
|
|
1011
|
+
}
|
|
1012
|
+
} catch { /* flag-parse failure must not block the tracer */ }
|
|
@@ -34,7 +34,9 @@ export function isIrreversible(entry: Pick<DecisionEntry, 'category'>): boolean
|
|
|
34
34
|
return IRREVERSIBLE.has(entry.category);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
const kst = (at: string) =>
|
|
37
|
+
const kst = (at: string) => Number.isFinite(Date.parse(at))
|
|
38
|
+
? new Intl.DateTimeFormat('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(at))
|
|
39
|
+
: '읽을 수 없음';
|
|
38
40
|
|
|
39
41
|
/** The card opens with a short pitch; the full question and choice buttons remain below it. */
|
|
40
42
|
export function renderCardText(e: DecisionEntry, extra: { note?: string; confirm?: string } = {}): string {
|
|
@@ -101,6 +103,7 @@ interface CardState {
|
|
|
101
103
|
* deploy); they stay reachable through `/decisions`. */
|
|
102
104
|
since?: string;
|
|
103
105
|
cards: Record<string, { refs: CardRef[]; closed?: boolean; remindedAt?: string; note?: string; attempts?: number; noSubscribers?: boolean }>;
|
|
106
|
+
deferred?: Record<string, true>;
|
|
104
107
|
testOriginQuestions?: Record<string, true>;
|
|
105
108
|
}
|
|
106
109
|
|
|
@@ -113,6 +116,10 @@ export interface DecisionCardServiceOptions {
|
|
|
113
116
|
/** Where this platform keeps which card it sent (one file per platform — the two bots may run in different processes). */
|
|
114
117
|
statePath?: string;
|
|
115
118
|
now?: () => Date;
|
|
119
|
+
/** Optional gate for new-card delivery. Omit to send every eligible open decision. */
|
|
120
|
+
sendFilter?: (entry: DecisionEntry, now: Date) => boolean;
|
|
121
|
+
/** Label recorded in the `push-deferred` observation when `sendFilter` holds a decision back. */
|
|
122
|
+
deferredReason?: (entry: DecisionEntry, now: Date) => string;
|
|
116
123
|
/** Tell the seat that raised it. Default: none (observed only). */
|
|
117
124
|
replyToRaiser?: (entry: DecisionEntry, via: CardPlatform) => Promise<void>;
|
|
118
125
|
}
|
|
@@ -223,6 +230,18 @@ export class DecisionCardService {
|
|
|
223
230
|
const card = state.cards[e.id];
|
|
224
231
|
if (e.status === 'open' && (!card || (platform === 'webpush' && !card.refs.length && (card.attempts ?? 0) < WEBPUSH_MAX_SEND_ATTEMPTS))
|
|
225
232
|
&& e.options.length >= 2 && e.raisedAt !== undefined && e.raisedAt >= state.since) {
|
|
233
|
+
if (this.opts.sendFilter) {
|
|
234
|
+
const now = this.now();
|
|
235
|
+
if (!this.opts.sendFilter(e, now)) {
|
|
236
|
+
if (!state.deferred?.[e.id]) {
|
|
237
|
+
(state.deferred ??= {})[e.id] = true;
|
|
238
|
+
dirty = true;
|
|
239
|
+
debug.log(platform === 'webpush' ? 'decisions.webpush' : 'decisions.telegram', 'push-deferred',
|
|
240
|
+
{ ...(platform === 'webpush' ? {} : { platform }), id: e.id, urgency: this.opts.deferredReason?.(e, now) ?? 'filtered' });
|
|
241
|
+
}
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
226
245
|
if (platform === 'webpush' && !chats.length) {
|
|
227
246
|
if (!card?.noSubscribers) {
|
|
228
247
|
state.cards[e.id] = { ...(card ?? { refs: [] }), noSubscribers: true };
|
|
@@ -5,6 +5,8 @@ import { readPendingQuestionAnswer, readPendingQuestions, writePendingQuestionAn
|
|
|
5
5
|
import { debug, redactSecretText } from '../debug/log.js';
|
|
6
6
|
import { createVersionResolver, type VersionOptions, type Versions } from '../directives/version-at.js';
|
|
7
7
|
import { getUserConfig } from '../user-config.js';
|
|
8
|
+
import { registeredSeats, resolveSeat } from '../seat-address/seat-address.js';
|
|
9
|
+
import { isSeatId } from '../seat-dispatch/seat-questions.js';
|
|
8
10
|
|
|
9
11
|
export type DecisionCategory = 'secret' | 'publish' | 'money' | 'security' | 'scope' | 'irreversible' | 'other';
|
|
10
12
|
/** Old track letters (S·T·F·O) stay readable; seat names (OP·MK·TC·UX) are the current identities. */
|
|
@@ -53,7 +55,8 @@ export class DecisionAnswerDeliveryError extends Error {
|
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
const CATEGORIES: readonly string[] = ['secret', 'publish', 'money', 'security', 'scope', 'irreversible', 'other'];
|
|
56
|
-
const
|
|
58
|
+
const isDecisionTrack = (value: string): boolean => registeredSeats().some(({ id, alias }) => value === id || value === alias);
|
|
59
|
+
const isRegisteredSeat = (value: string): boolean => isSeatId(value) && resolveSeat(value)?.id === value;
|
|
57
60
|
|
|
58
61
|
function required(value: string, name: string): string {
|
|
59
62
|
if (typeof value !== 'string' || !value.trim()) throw new Error(`${name} is required`);
|
|
@@ -88,7 +91,7 @@ function validate(input: RaiseInput, historical = false): RaiseInput {
|
|
|
88
91
|
const title = safe(single(input.title, 'title'));
|
|
89
92
|
if (!CATEGORIES.includes(input.category)) throw new Error('invalid category');
|
|
90
93
|
if (!input.raisedBy?.agent) throw new Error('raisedBy.agent is required');
|
|
91
|
-
if (input.raisedBy.track && !
|
|
94
|
+
if (input.raisedBy.track && !isDecisionTrack(input.raisedBy.track)) throw new Error('invalid track');
|
|
92
95
|
const s = scqaField(input.scqa.s, 's');
|
|
93
96
|
const c = scqaField(input.scqa.c, 'c');
|
|
94
97
|
const q = input.scqa.q?.trim() ? scqaField(input.scqa.q, 'q') : undefined;
|
|
@@ -117,7 +120,7 @@ function validate(input: RaiseInput, historical = false): RaiseInput {
|
|
|
117
120
|
if (input.crossCheck !== undefined && !Array.isArray(input.crossCheck)) throw new Error('cross-check must be a list');
|
|
118
121
|
const crossCheck = input.crossCheck?.map(check => {
|
|
119
122
|
const seat = single(check.seat, 'cross-check seat');
|
|
120
|
-
if (!
|
|
123
|
+
if (!isRegisteredSeat(seat)) throw new Error('invalid cross-check seat');
|
|
121
124
|
return { seat, at: utc(check.at), note: safe(single(check.note, 'cross-check note')) };
|
|
122
125
|
});
|
|
123
126
|
const crossCheckSkipped = input.crossCheckSkipped === undefined ? undefined : safe(single(input.crossCheckSkipped, 'cross-check skipped reason'));
|
|
@@ -242,7 +245,7 @@ export class DecisionLedger {
|
|
|
242
245
|
/** Delegated decisions are already made: they share the append-only ledger, never the owner's open-card state machine. */
|
|
243
246
|
recordSeatDecision(input: SeatDecisionInput): SeatDecisionRecord {
|
|
244
247
|
const seat = input.seat;
|
|
245
|
-
if (!
|
|
248
|
+
if (!isRegisteredSeat(seat)) throw new Error('invalid seat');
|
|
246
249
|
const title = safe(single(input.title, 'title'));
|
|
247
250
|
const decision = safe(single(input.decision, 'decision'));
|
|
248
251
|
const delegation = safe(single(input.delegation, 'delegation'));
|
|
@@ -263,7 +266,7 @@ export class DecisionLedger {
|
|
|
263
266
|
}
|
|
264
267
|
seatReport(filters: { since?: string; seat?: Seat } = {}): SeatDecisionRecord[] {
|
|
265
268
|
const since = filters.since === undefined ? undefined : utc(filters.since);
|
|
266
|
-
if (filters.seat && !
|
|
269
|
+
if (filters.seat && !isRegisteredSeat(filters.seat)) throw new Error('invalid seat');
|
|
267
270
|
return this.events().filter((event): event is Extract<Event, { type: 'seat-recorded' }> => event.type === 'seat-recorded')
|
|
268
271
|
.map(event => event.entry)
|
|
269
272
|
.filter(entry => (!since || (entry.recordedAt ?? entry.decidedAt ?? '') >= since) && (!filters.seat || entry.seat === filters.seat))
|
|
@@ -307,7 +310,7 @@ export class DecisionLedger {
|
|
|
307
310
|
if (!by || (by.kind !== 'human' && by.kind !== 'auto')) throw new Error('decidedBy is required');
|
|
308
311
|
if (by.kind === 'auto') {
|
|
309
312
|
single(by.delegation, 'delegation'); single(by.agent, 'agent');
|
|
310
|
-
if (by.track && !
|
|
313
|
+
if (by.track && !isDecisionTrack(by.track)) throw new Error('invalid track');
|
|
311
314
|
by = { ...by, agent: safe(single(by.agent, 'agent')), delegation: safe(single(by.delegation, 'delegation')) };
|
|
312
315
|
}
|
|
313
316
|
return this.locked(() => {
|
|
@@ -424,7 +427,7 @@ export class DecisionLedger {
|
|
|
424
427
|
if (choice ? !clean.options.some(o => o.key === choice) : clean.options.length !== 0) throw new Error(`option not found: ${choice}`);
|
|
425
428
|
if (by.kind === 'auto') {
|
|
426
429
|
single(by.agent, 'agent'); single(by.delegation, 'delegation');
|
|
427
|
-
if (by.track && !
|
|
430
|
+
if (by.track && !isDecisionTrack(by.track)) throw new Error('invalid track');
|
|
428
431
|
by = { ...by, agent: safe(single(by.agent, 'agent')), delegation: safe(single(by.delegation, 'delegation')) };
|
|
429
432
|
}
|
|
430
433
|
const cleanNote = safe(single(note, 'note'));
|
|
@@ -449,7 +452,7 @@ export class DecisionLedger {
|
|
|
449
452
|
completeRecorded(id: string, choice: string | undefined, by: DecisionActor, note: string, sourceOptions: DecisionOption[]): DecisionEntry {
|
|
450
453
|
if (by.kind === 'auto') {
|
|
451
454
|
single(by.agent, 'agent'); single(by.delegation, 'delegation');
|
|
452
|
-
if (by.track && !
|
|
455
|
+
if (by.track && !isDecisionTrack(by.track)) throw new Error('invalid track');
|
|
453
456
|
by = { ...by, agent: safe(single(by.agent, 'agent')), delegation: safe(single(by.delegation, 'delegation')) };
|
|
454
457
|
}
|
|
455
458
|
const cleanNote = safe(single(note, 'note'));
|
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
import { debug } from '../debug/log.js';
|
|
2
2
|
import { listSubscriptions } from '../web-push/subscriptions.js';
|
|
3
3
|
import { sendPushToAll } from '../web-push/sender.js';
|
|
4
|
-
import { type CardTransport, type CardView } from './decision-cards.js';
|
|
5
|
-
import { DecisionLedger } from './decision-ledger.js';
|
|
4
|
+
import { isIrreversible, type CardTransport, type CardView } from './decision-cards.js';
|
|
5
|
+
import { DecisionLedger, type DecisionEntry } from './decision-ledger.js';
|
|
6
|
+
|
|
7
|
+
/** How close a deadline must be for an otherwise reversible decision to ring the phone. */
|
|
8
|
+
export const WEB_PUSH_URGENT_WINDOW_MS = 24 * 3600_000;
|
|
9
|
+
|
|
10
|
+
export type WebPushUrgency = 'irreversible' | 'due-soon' | 'not-urgent' | 'due-unreadable';
|
|
11
|
+
|
|
12
|
+
/** Web push rings only for urgent decisions; an unreadable deadline is its own value (fail open, never folded into not-urgent). */
|
|
13
|
+
export function webPushUrgency(entry: DecisionEntry, now: Date): WebPushUrgency {
|
|
14
|
+
if (isIrreversible(entry)) return 'irreversible';
|
|
15
|
+
if (entry.dueAt !== undefined) {
|
|
16
|
+
const due = Date.parse(entry.dueAt);
|
|
17
|
+
if (!Number.isFinite(due)) return 'due-unreadable';
|
|
18
|
+
if (due - now.getTime() <= WEB_PUSH_URGENT_WINDOW_MS) return 'due-soon';
|
|
19
|
+
}
|
|
20
|
+
return 'not-urgent';
|
|
21
|
+
}
|
|
6
22
|
|
|
7
23
|
const ID_IN_CARD = /^🗳 결정 요청 (D-\d{8}-\d+)(?: ·|\n)/;
|
|
8
24
|
const ID_IN_REMINDER = /^⏰ 기한 2시간 전 — (D-\d{8}-\d+) /;
|
|
@@ -26,7 +42,7 @@ export function webPushDecisionTransport(
|
|
|
26
42
|
const entry = ledger.show(id);
|
|
27
43
|
if (entry.status !== 'open') return null;
|
|
28
44
|
const recommendation = 'skipped' in entry.recommendation ? '추천안 없음' : `추천안: ${entry.recommendation.option.toUpperCase()}`;
|
|
29
|
-
const body = `${recommendation}${entry.dueAt ? ` · 기한: ${new Intl.DateTimeFormat('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(entry.dueAt))}` : ''}`;
|
|
45
|
+
const body = `${recommendation}${entry.dueAt ? ` · 기한: ${Number.isFinite(Date.parse(entry.dueAt)) ? new Intl.DateTimeFormat('ko-KR', { timeZone: 'Asia/Seoul', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).format(new Date(entry.dueAt)) : '읽을 수 없음'}` : ''}`;
|
|
30
46
|
const result = await push({ title: title('대표 결정 · ', entry.title), body, url: url(id), tag: tag(id) });
|
|
31
47
|
if (result.attempted) debug.log('decisions.webpush', 'card-sent', { id, delivered: result.delivered });
|
|
32
48
|
return result.delivered ? { chat: 'webpush', message: id } : null;
|