elanous 0.2.37 → 0.2.40
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/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/{8kITumG9GAZ1LwT9POrAR → HjeK7zONHfR7op1hKXp4k}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{1746.3563617ea64023a3.js → 1060.014f1f01a17aec26.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9151.a2c51e93f9156dae.js → 1281.d81877e35b9068f4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1350.59f40e39e02d91b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1452.162bb2d9d699e82a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +286 -0
- package/apps/pwa/out/_next/static/chunks/1537-6bb97b5214928ea9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +149 -0
- package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +90 -0
- package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{3578.4e9f9948a9a6f2f4.js → 2047.8f23e210995d4548.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7424.c0fe2a595d4232b5.js → 2066.a77257c8c350770a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4931.95cc6dbd230774ca.js → 2177.df8547f9d7215c4e.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6680.6a693c28aae4cd19.js → 2226.2cf61ec781827219.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/2281-b8cede695c6c650e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2499.02fbfd18126c10c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6252.240578f10952e091.js → 2522.f2766b76d22c8bdf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1262.a89bb27a5b2f844e.js → 2566.beaffc3a5e1fcd2e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/261.0d471e8aded799f3.js +226 -0
- package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +27 -0
- package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2318-450e75d07605b8fe.js → 2774-719820e3f5b2a3eb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4725-34bed25720cc326b.js → 2829-734fe8bf2eee7347.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3330.7443183b7e6fdbdf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3746-f80a78f220bf37b5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +24 -0
- package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +77 -0
- package/apps/pwa/out/_next/static/chunks/{4337e36d.f42c3b391b3d8f20.js → 3b355b3d.6f73c98bf6f9c749.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +36 -0
- package/apps/pwa/out/_next/static/chunks/{58edce7d.f1b0c72acf13b123.js → 409c787b.e48c5bec8ec10456.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/413-24c8284bda08241d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +287 -0
- package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4351.0f37a6db2b34d50b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5046.7fd5cbd859299448.js → 470.51a72a2348306455.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2375.bf364c85dbb6f085.js → 4769.9fd582071301f382.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/483.725e4a61be922788.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{de8446d3.31b73eb239fecd7b.js → 4864a2ca.1c1c280a7772c5e5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +74 -0
- package/apps/pwa/out/_next/static/chunks/{4383.18e5c54db3a22c88.js → 5383.bdfa5d886e39a826.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5436.fdf6fa8ae3e9588d.js +64 -0
- package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5622.94893f5aea7185d0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +8 -0
- package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +62 -0
- package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +94 -0
- package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6745-5a63492933959dd9.js → 6051-0ae955eedb10adb9.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2283.edd9627b7bdfb546.js → 6257.c0037b8949239f5e.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6624.981ef7caeb680560.js +32 -0
- package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6819.be5c9c4d67f22922.js → 6749.0744ce6eb08d40e9.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6908.06008c67f6380ea9.js +148 -0
- package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6cc1d1d6.9a98dd4622f1afc6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7219-15bdd9a80661af8e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +93 -0
- package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7515.1ad6efe157fa4448.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7611.85f045bf232053ac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8086.1ab9103c41be884f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8099.1cccf31c1baa7e1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2002-a43a3f380df873ec.js → 8272-025653884f9645d2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{7867.e8725745ddd1d940.js → 8357.1aaa713b052a78b1.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8639-92c11d069792429e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8d173e38.18a2f7b4e1848bdb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9069.657590a84afb8fac.js +41 -0
- package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4313.76f232c304a15bde.js → 9175.2de5209a5ce6f68a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9184.45afbf44fec87574.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8c58d09b.e8724a299658d86f.js → 9189505a.980427ac048c8c60.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9992.07ce73c10bd5e6a1.js +79 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ba957ff875a026a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/{page-3337c6a1328c2674.js → page-4edb8df90f4537ce.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-83d27757e2b8060a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-1e5da297557d2354.js → page-fca2e59a81744d9e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-ac2c1e6169cfce57.js → page-139d722de1dcd6c1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/{page-c1c80e345fa9d6f5.js → page-ccde99f07aaf71f7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{d9815f84.4918f682a45a8502.js → b84cad00.594027ebe0531fe2.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{709a918c.4fd3b4e2a32cb4e3.js → ca3702f8.2913182e73889fa2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/d5d3cefc-373c4eb722ed848b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5f6af561-f90b7a67f4f75d13.js → d8de0de2-dd0f4ac8e5ab1832.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-002b472a66935d31.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +22 -22
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +22 -22
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +22 -22
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +21 -21
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +21 -21
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +21 -21
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +21 -21
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +21 -21
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/graphs/demo/persona-marketer/fixtures/marketer-scenario.yaml +10 -0
- package/graphs/demo/persona-marketer/persona-marketer.yaml +25 -0
- package/graphs/demo/persona-marketer/recipes.yaml +19 -0
- package/graphs/release/recipes.yaml +9 -0
- package/graphs/release/release-loop.yaml +26 -18
- package/graphs/video/explainer-line.yaml +4 -1
- package/package.json +1 -1
- package/scripts/ask-op-inbox-once.ts +17 -0
- package/scripts/brand/check.ts +13 -4
- package/scripts/dead-code/report.ts +169 -0
- package/scripts/gate-0226-accepted-remaining-90.txt +91 -0
- package/scripts/gate-0226-failure-census.ts +39 -0
- package/scripts/intake-collect-telegram-saved-stage.ts +48 -0
- package/scripts/lib/morning-report-options.ts +3 -4
- package/scripts/lib/tui-regress-evidence.ts +56 -0
- package/scripts/morning-report.ts +5 -1
- package/scripts/provision-export-redactions.ts +15 -0
- package/scripts/public-copy-lint.ts +122 -0
- package/scripts/public-export.ts +77 -2
- package/scripts/ratchets/next-tui-entry-budget.ts +124 -0
- package/scripts/ratchets/train-side-invariants.sh +7 -1
- package/scripts/release-loop/cut-branch.ts +61 -12
- package/scripts/release-loop/export-check-node.ts +21 -3
- package/scripts/release-loop/gate-node.ts +527 -60
- package/scripts/release-loop/gate-partial.ts +82 -3
- package/scripts/release-loop/gate-prewarm-plan.ts +35 -0
- package/scripts/release-loop/gate-radius-live.ts +4 -2
- package/scripts/release-loop/gate-shard-dispatch.ts +128 -0
- package/scripts/release-loop/gate-shard-receipts.ts +89 -0
- package/scripts/release-loop/gate-wall.ts +5 -5
- package/scripts/release-loop/preflight.ts +6 -2
- package/scripts/release-loop/resume-cap.ts +2 -1
- package/scripts/release-loop/resume-release.ts +317 -13
- package/scripts/release-loop/resume.ts +61 -5
- package/scripts/release-loop/traffic-node.ts +12 -4
- package/scripts/release-loop/traffic-transition.ts +53 -13
- package/scripts/release-loop/version-node.ts +35 -5
- package/scripts/release-story/draft.ts +1 -1
- package/scripts/research-bench/README.md +53 -0
- package/scripts/research-bench/questions.json +66 -0
- package/scripts/research-bench/rubric.md +33 -0
- package/scripts/research-bench/run.ts +523 -0
- package/scripts/tui-regress.ts +85 -10
- package/scripts/ux-sim.ts +1 -1
- package/scripts/video-pipeline.ts +2 -2
- package/src/acp/core-turn-bridge.ts +14 -1
- package/src/agent/autonomous-tools.ts +10 -3
- package/src/agent/monad-agent-turn.ts +4 -1
- package/src/agent/registry.ts +26 -2
- package/src/agent/run-context.ts +1 -1
- package/src/agent/shared-app-tools.ts +1 -1
- package/src/agent/surface-ux/build.ts +12 -3
- package/src/agent/surface-ux/types.ts +1 -1
- package/src/agent/task-notification.ts +78 -7
- package/src/agent/types.ts +3 -0
- package/src/agent-mission/driver.ts +29 -3
- package/src/agent-mission/mission-cli.ts +2 -1
- package/src/agent-substrate/review-context-pack.ts +365 -0
- package/src/agent-substrate/review-observation.ts +10 -0
- package/src/agent-substrate/self-review-cli.ts +419 -42
- package/src/ask-user-question/index.ts +6 -0
- package/src/ask-user-question/inline-resolver.ts +49 -0
- package/src/auto-research/question-ladder-contract.ts +156 -0
- package/src/auto-research/research-turn.ts +467 -0
- package/src/autopilot/agent-loop.ts +1 -1
- package/src/autopilot/discovery/doc-lint.ts +1 -1
- package/src/autopilot/pty-control-loop.ts +8 -1
- package/src/boot/daemon-tools/index.ts +4 -3
- package/src/boot/daemon-tools/self-implement.ts +270 -2
- package/src/boot/daemon-tools/types.ts +2 -0
- package/src/bots/screen-probe.ts +1 -1
- package/src/budget/llm-cost.ts +44 -5
- package/src/budget/unified-usage.ts +17 -1
- package/src/capture/tui-self-report.ts +24 -2
- package/src/chat/index.ts +34 -7
- package/src/chat/tool-render/dispatch.ts +8 -1
- package/src/cli/agent-cli.ts +43 -8
- package/src/cli/guardian-cli.ts +3 -1
- package/src/cli/intake-cli.ts +70 -13
- package/src/cli/lesson-cli.ts +86 -10
- package/src/cli/log-event-names.ts +1 -0
- package/src/cli/pod-cli.ts +17 -2
- package/src/cli/pr-land-overlap-evidence.ts +38 -5
- package/src/cli/pr-land-refusal.ts +1 -1
- package/src/cli/pty-takeover-cli.ts +125 -12
- package/src/cli/release-checklist-read-cli.ts +5 -2
- package/src/cli/release-cli.ts +99 -15
- package/src/cli/repo-cli.ts +2 -1
- package/src/cli/review-carry.ts +77 -0
- package/src/cli/self-update.ts +1 -1
- package/src/cli/tasks-card-show.ts +31 -1
- package/src/cli/tasks-cli.ts +98 -32
- package/src/cli/tasks-read-cli.ts +13 -5
- package/src/context-bus/context-now.ts +86 -2
- package/src/control-plane/ledger.ts +21 -4
- package/src/core-turn/run-core-turn.ts +51 -3
- package/src/core-turn/run-goal-loop.ts +152 -8
- package/src/core-turn/types.ts +12 -0
- package/src/dashboard/chat/acp-chat.ts +2 -2
- package/src/dashboard/classic-sigquit.ts +16 -0
- package/src/dashboard/index.ts +339 -44
- package/src/dashboard/input/chat-main-interaction-opts.ts +3 -0
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +7 -2
- package/src/dashboard/input/chat-main-slash-command.ts +7 -0
- package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
- package/src/dashboard/input/dashboard-priority-key-route.ts +21 -5
- package/src/dashboard/input/external-input-host.ts +2 -0
- package/src/dashboard/input/terminal-modal-router.ts +8 -159
- package/src/dashboard/side-basic-runtime.ts +61 -0
- package/src/dashboard/sidetab-runtime.ts +228 -0
- package/src/dashboard/slash-runtime/ask-clarification.ts +7 -1
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +22 -8
- package/src/dashboard/slash-runtime/help-from-registry.ts +2 -2
- package/src/dashboard/term-slash-runtime.ts +18 -18
- package/src/dashboard/turn-preamble.ts +30 -4
- package/src/domains/guardian-tick.ts +9 -0
- package/src/domains/knowledge.ts +1 -1
- package/src/esc-abort-gate.ts +33 -1
- package/src/execution-loop/launch-gate.ts +206 -1
- package/src/git-fs/watcher.ts +27 -22
- package/src/git-fs/worktree.ts +19 -3
- package/src/graph-runner/graph-cli.ts +6 -4
- package/src/graph-runner/graph-grow.ts +37 -9
- package/src/graph-runner/runner.ts +48 -11
- package/src/graph-wizard/generate.ts +16 -7
- package/src/graph-wizard/mission-compose.ts +201 -0
- package/src/grok/agent-search.ts +8 -2
- package/src/grok/credential.ts +112 -36
- package/src/grounding/ref-index.ts +11 -0
- package/src/grounding/ref-vector.ts +61 -0
- package/src/grounding/sources-cli.ts +2 -2
- package/src/grounding/sources.ts +15 -1
- package/src/harness/harness-cli-command.ts +38 -9
- package/src/harness/harness-pod-dispatch.ts +7 -1
- package/src/hq/fence-wrapper.ts +1 -1
- package/src/hq/transfer.ts +1 -1
- package/src/index.ts +60 -16
- package/src/input/external-input-queue.ts +10 -0
- package/src/intake-plane/collect-telegram-saved.ts +90 -6
- package/src/intake-plane/intake-to-tasks.ts +246 -3
- package/src/interactive-terminal-modal.ts +3 -0
- package/src/keybindings.ts +17 -22
- package/src/lessons/friction-ledger.ts +154 -0
- package/src/live-supply/collector.ts +149 -0
- package/src/live-supply/probes.ts +52 -0
- package/src/live-supply/snapshot.ts +40 -0
- package/src/llm/provider-credentials.ts +1 -1
- package/src/llm-tool-schema.ts +20 -0
- package/src/llm.ts +486 -61
- package/src/loops/orchestrator/inbox-once.ts +28 -0
- package/src/loops/orchestrator/inbox.ts +130 -1
- package/src/loops/orchestrator/tick.ts +14 -3
- package/src/maturity/feature-maturity.ts +1 -0
- package/src/nexus/api/channel-ask-op.ts +96 -0
- package/src/nexus/api/discord-trigger-bot.ts +28 -1
- package/src/nexus/api/harness-api.ts +2 -1
- package/src/nexus/api/telegram-trigger-bot.ts +24 -0
- package/src/nexus/api/terminals.ts +28 -6
- package/src/patents/ledger.ts +18 -1
- package/src/preview/terminal.ts +4 -2
- package/src/prompt-cache/anthropic.ts +2 -0
- package/src/prompt-enhance/enhance.ts +5 -0
- package/src/pty/snapshot.py +132 -0
- package/src/pty-shell/pty-control-ipc.ts +29 -2
- package/src/pty-shell/pty-manifest.ts +75 -5
- package/src/pty-shell/registry.ts +2 -0
- package/src/pty-shell/tui-run-state.ts +80 -3
- package/src/release-loop/gate-host-reservation.ts +13 -4
- package/src/release-loop/gate-shard-ledger.ts +68 -0
- package/src/release-loop/gate-shards.ts +61 -0
- package/src/release-loop/light-rc.ts +7 -4
- package/src/release-loop/merged-pr-checklist.ts +25 -2
- package/src/release-loop/rehearsal-shard-plan.ts +6 -1
- package/src/release-loop/rehearsal.ts +28 -1
- package/src/repl/index.ts +10 -0
- package/src/research/axis-fanout.ts +133 -0
- package/src/research/edge-decision.ts +197 -0
- package/src/research/gap-followup.ts +249 -0
- package/src/research/lenses/counter-evidence.ts +100 -0
- package/src/research/lenses/working-backwards.ts +89 -0
- package/src/research/output-router.ts +127 -0
- package/src/research/plugin-discovery.ts +242 -0
- package/src/research-bridge/format.ts +16 -1
- package/src/research-bridge/index.ts +1 -0
- package/src/research-bridge/invoke.ts +45 -7
- package/src/research-bridge/types.ts +2 -0
- package/src/self-dev/ask-launch-flow.ts +34 -106
- package/src/self-dev/decompose.ts +45 -9
- package/src/self-dev/dev-cli.ts +2 -0
- package/src/self-dev/dev-pipeline.ts +8 -4
- package/src/self-dev/draft-residue.ts +221 -2
- package/src/self-dev/draft-sweep.ts +29 -16
- package/src/self-dev/graph-journey-route.ts +10 -2
- package/src/self-dev/launch-preflight-text.ts +2 -2
- package/src/self-dev/launch-preflight.ts +38 -7
- package/src/self-dev/orchestrate-cli.ts +1 -0
- package/src/self-dev/orchestrate.ts +1 -0
- package/src/self-dev/run-supervisor.ts +41 -7
- package/src/self-dev/shard-run.ts +260 -3
- package/src/self-implement/comment-only-source.ts +54 -0
- package/src/self-implement/device-first.ts +8 -2
- package/src/self-implement/doctor-visit.ts +100 -57
- package/src/self-implement/gate-artifacts.ts +5 -2
- package/src/self-implement/gate-baseline.ts +119 -13
- package/src/self-implement/gate-cli.ts +466 -93
- package/src/self-implement/gate-failure-signature.ts +44 -0
- package/src/self-implement/gate-receipt-registry.ts +180 -0
- package/src/self-implement/gate-remote.ts +147 -22
- package/src/self-implement/goal-author-clarification.ts +178 -24
- package/src/self-implement/goal-author-decompose.ts +24 -15
- package/src/self-implement/goal-author.ts +82 -7
- package/src/self-implement/goal-doc/section.ts +22 -0
- package/src/self-implement/goal-supervisor-fill.ts +38 -4
- package/src/self-implement/host-regate.ts +120 -45
- package/src/self-implement/impl-findings-feedback.ts +188 -0
- package/src/self-implement/knowhow-pack.ts +301 -9
- package/src/self-implement/l8-merge-queue.ts +198 -32
- package/src/self-implement/off-diff-evidence.ts +147 -0
- package/src/self-implement/orchestrator.ts +137 -16
- package/src/self-implement/pod-inplace-worktree.ts +82 -0
- package/src/self-implement/pod-warm-pool-profile.ts +2 -2
- package/src/self-implement/premise-review.ts +7 -5
- package/src/self-implement/run-ledger.ts +304 -8
- package/src/self-implement/run-stop.ts +12 -0
- package/src/self-implement/seams.ts +39 -13
- package/src/self-implement/self-implement-cli.ts +30 -4
- package/src/session/channel-ask-op-envelope.ts +36 -0
- package/src/session/channel-op-reply-route.ts +200 -0
- package/src/session/chat.ts +92 -15
- package/src/session/index.ts +2 -0
- package/src/session-runtime/index.ts +9 -22
- package/src/session-runtime/provider-circuit.ts +140 -0
- package/src/shell-runner/file-engine.ts +1 -0
- package/src/shell-runner/types.ts +4 -0
- package/src/sidetab-core/model.ts +176 -0
- package/src/skills/runner.ts +7 -3
- package/src/skills/tools/dev-harness.ts +2 -2
- package/src/skills/tools/schedule-wakeup.ts +24 -7
- package/src/skills/tools/shell.ts +51 -5
- package/src/status/bar.ts +3 -3
- package/src/steward/directive-audit.ts +354 -0
- package/src/storage/file-lock.ts +17 -4
- package/src/surface/child-process.ts +31 -0
- package/src/surface/tui-stderr-owner.ts +48 -0
- package/src/task-agent/adopt-pr.ts +63 -2
- package/src/task-agent/cover.ts +30 -12
- package/src/task-agent/evidence-command-normalize.ts +42 -0
- package/src/task-agent/export-redactions-provision.ts +43 -0
- package/src/task-agent/judge.ts +56 -0
- package/src/task-agent/parent-host.ts +59 -12
- package/src/task-agent/postland-card.ts +35 -2
- package/src/task-agent/rejudge-on-head.ts +46 -2
- package/src/task-agent/repair-cycle.ts +68 -9
- package/src/task-agent/repair-worker.ts +37 -1
- package/src/task-agent/task-hand.ts +226 -33
- package/src/task-agent/tier-split.ts +142 -24
- package/src/task-orchestrator/surfaces/pod-command-job.ts +330 -2
- package/src/task-orchestrator/surfaces/pod-config-snapshot.ts +123 -0
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +57 -5
- package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +11 -8
- package/src/task-orchestrator/surfaces/pod-pool.ts +27 -4
- package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +74 -6
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +2 -1
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +56 -15
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +310 -79
- package/src/task-orchestrator/surfaces/self-implement.ts +33 -2
- package/src/terminal/session-registry.ts +1 -0
- package/src/terminal/terminal-modal-router.ts +156 -0
- package/src/tool-hints/gate.ts +6 -4
- package/src/tool-hints/signals.ts +33 -1
- package/src/tool-runtime/skill-exec-runtime.ts +95 -5
- package/src/tui/chat/background-job-status.ts +8 -2
- package/src/tui/entry.ts +483 -32
- package/src/tui/inline-choice.ts +188 -0
- package/src/tui/sidetab/attach.ts +304 -0
- package/src/tui/sidetab/list.ts +2 -0
- package/src/tui/sidetab/nl-tool.ts +136 -0
- package/src/tui/slash/resume-command.ts +23 -0
- package/src/tui/slash/resume.ts +3 -23
- package/src/tui/slash/term-next.ts +2 -1
- package/src/tui/slash/term.ts +12 -1
- package/src/tui-client/dashboard-session.ts +7 -1
- package/src/tui-client/local-chat-turn.ts +29 -8
- package/src/user-config.ts +42 -3
- package/src/ux-sim/classic-tui-seat-scenarios.ts +1 -7
- package/src/ux-sim/fake-land-queue.ts +88 -0
- package/src/ux-sim/fake-llm.ts +11 -5
- package/src/ux-sim/gate-shard-host-reroute.ts +82 -0
- package/src/ux-sim/goal-interim-trace.ts +24 -0
- package/src/ux-sim/next-tui-seat-scenarios.ts +61 -14
- package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +4 -1
- package/src/version/packed-revision.json +1 -1
- package/src/video-pipeline/recipes/explainer.ts +54 -2
- package/src/web-search/grok.ts +32 -6
- package/src/web-search/index.ts +8 -7
- package/src/workflow-runtime/node-catalog.ts +53 -4
- package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1224.2ceca6c180d5130b.js +0 -62
- package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1ed5e8af.cf424815c7c0efad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/210.90b2cbd64926cf34.js +0 -32
- package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2479-fe7e188bd9402d14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +0 -148
- package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +0 -27
- package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3199.6a1a9b0e6cd01dc6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +0 -36
- package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4036.d54e55e1ebf5acdc.js +0 -90
- package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +0 -226
- package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +0 -287
- package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4324.c99ba3e83eb1b691.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4833-7934c592c5569f00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +0 -24
- package/apps/pwa/out/_next/static/chunks/4937-28d437999b77c9dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +0 -104
- package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +0 -1
- package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +0 -93
- package/apps/pwa/out/_next/static/chunks/5952.294fc574a8625184.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +0 -74
- package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +0 -149
- package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6971-fb5f9dc0a2cb5d2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +0 -41
- package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +0 -1
- package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +0 -1
- package/apps/pwa/out/_next/static/chunks/757-4fbaf50942b8c424.js +0 -1
- package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7893-e444a1b0809cd1e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7c5ed21f-f286708e57cf88f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +0 -8
- package/apps/pwa/out/_next/static/chunks/8080-40d781e7704d3671.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +0 -77
- package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +0 -1
- package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +0 -286
- package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +0 -79
- package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9175-7d383df15a82e2be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +0 -1
- package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +0 -94
- package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +0 -1
- package/apps/pwa/out/_next/static/chunks/958.53a8dcf4729e6997.js +0 -64
- package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-5c112c6d7c33656e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-89acd5d68c0bc560.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-fe986fe79b107546.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-88a1edbff62eaf1d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-443364c9e4a23b31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-b9af2ac1c4737ce8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-fb9e639c107f5f72.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +0 -1
- package/scripts/migrate-monad-to-elanous.ts +0 -195
- package/scripts/rebrand-elanous.ts +0 -242
- /package/apps/pwa/out/_next/static/{8kITumG9GAZ1LwT9POrAR → HjeK7zONHfR7op1hKXp4k}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
export interface TuiRegressFailureEvidence {
|
|
5
|
+
runId: string;
|
|
6
|
+
event: string;
|
|
7
|
+
verificationCommand: string;
|
|
8
|
+
artifactRoot: string;
|
|
9
|
+
configDir: string;
|
|
10
|
+
check: { id: string; title: string; role: string };
|
|
11
|
+
screens: Record<string, string>;
|
|
12
|
+
pty: { cols: number; rows: number; bootMs: number };
|
|
13
|
+
environment: {
|
|
14
|
+
driveTui: string;
|
|
15
|
+
nodeEnv: string | null;
|
|
16
|
+
credentialVariablesPresent: string[];
|
|
17
|
+
};
|
|
18
|
+
verdict: { ok: boolean; reason: string };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function redactConfig(value: unknown): unknown {
|
|
22
|
+
if (Array.isArray(value)) return value.map(redactConfig);
|
|
23
|
+
if (value && typeof value === 'object') {
|
|
24
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [
|
|
25
|
+
key,
|
|
26
|
+
/api.?key|token|secret|password|credential/i.test(key) ? '[REDACTED]' : redactConfig(child),
|
|
27
|
+
]));
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function preserveTuiRegressFailure(input: TuiRegressFailureEvidence): string {
|
|
33
|
+
mkdirSync(input.artifactRoot, { recursive: true });
|
|
34
|
+
const artifactDir = mkdtempSync(join(input.artifactRoot, `${input.check.id}-`));
|
|
35
|
+
const screensDir = join(artifactDir, 'screens');
|
|
36
|
+
mkdirSync(screensDir);
|
|
37
|
+
for (const [name, screen] of Object.entries(input.screens)) writeFileSync(join(screensDir, `${name}.txt`), screen);
|
|
38
|
+
|
|
39
|
+
const configPath = join(input.configDir, 'config.json');
|
|
40
|
+
let effectiveConfig: unknown = { unavailable: !existsSync(configPath) };
|
|
41
|
+
if (existsSync(configPath)) {
|
|
42
|
+
try { effectiveConfig = redactConfig(JSON.parse(readFileSync(configPath, 'utf8'))); }
|
|
43
|
+
catch (error) { effectiveConfig = { parseError: String(error), bytes: readFileSync(configPath).byteLength }; }
|
|
44
|
+
}
|
|
45
|
+
writeFileSync(join(artifactDir, 'effective-config.json'), `${JSON.stringify(effectiveConfig, null, 2)}\n`);
|
|
46
|
+
writeFileSync(join(artifactDir, 'run.json'), `${JSON.stringify({
|
|
47
|
+
runId: input.runId,
|
|
48
|
+
event: input.event,
|
|
49
|
+
verificationCommand: input.verificationCommand,
|
|
50
|
+
check: input.check,
|
|
51
|
+
pty: input.pty,
|
|
52
|
+
environment: input.environment,
|
|
53
|
+
verdict: input.verdict,
|
|
54
|
+
}, null, 2)}\n`);
|
|
55
|
+
return artifactDir;
|
|
56
|
+
}
|
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
// bun run scripts/morning-report.ts --dry # compose only (stdout, no send)
|
|
5
5
|
// bun run scripts/morning-report.ts --no-narrate # skip the LLM 시장서사 layer
|
|
6
6
|
// bun run scripts/morning-report.ts --no-upload # skip S3 상세 업로드(로컬 미리보기)
|
|
7
|
+
// bun run scripts/morning-report.ts --narrative-model <model> # 시장서사 LLM 모델 명시(A/B)
|
|
7
8
|
|
|
8
9
|
import { composeMorningReport } from '../src/domains/morning-report.js';
|
|
9
10
|
import { explainReportRoute, sendTelegramReport, sendReportPhoto } from '../src/telegram-report.js';
|
|
10
11
|
import { getUserConfig } from '../src/user-config.js';
|
|
11
12
|
import { getFirecrawlConfig } from '../src/registry/discovery/config.js';
|
|
12
13
|
import { captureFinvizMapImageUrl } from '../src/domains/finviz-image.js';
|
|
14
|
+
import { parseNarrativeModelArg } from './lib/morning-report-options.js';
|
|
13
15
|
|
|
14
16
|
import { registerStandaloneLogSink } from '../src/domains/standalone-log-sink.js';
|
|
15
17
|
|
|
@@ -20,6 +22,8 @@ const dry = process.argv.includes('--dry');
|
|
|
20
22
|
const cfg = getUserConfig();
|
|
21
23
|
const narrate = cfg.finance.morningNarrative !== false && !process.argv.includes('--no-narrate');
|
|
22
24
|
const upload = !process.argv.includes('--no-upload');
|
|
25
|
+
// --narrative-model X / =X — 값이 없으면 parseNarrativeModelArg 가 throw(기본 모델로 조용히 대체하지 않는다).
|
|
26
|
+
const model = parseNarrativeModelArg(process.argv.slice(2));
|
|
23
27
|
|
|
24
28
|
// finviz S&P 히트맵 이미지 — HTML 상세 리포트에 임베드 + 텔레그램 포토로도 발송. 키 있을 때만.
|
|
25
29
|
let heatmapImageUrl: string | undefined;
|
|
@@ -31,7 +35,7 @@ if (cfg.finance.morningHeatmapImage !== false) {
|
|
|
31
35
|
} catch (e) { console.error(`[morning-report] heatmap capture error: ${e instanceof Error ? e.message : String(e)}`); }
|
|
32
36
|
}
|
|
33
37
|
|
|
34
|
-
const report = await composeMorningReport(new Date(), { narrate, heatmapImageUrl, upload });
|
|
38
|
+
const report = await composeMorningReport(new Date(), { narrate, heatmapImageUrl, upload, model });
|
|
35
39
|
|
|
36
40
|
if (dry) {
|
|
37
41
|
console.log(report);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { provisionExportRedactions } from '../src/task-agent/export-redactions-provision.js';
|
|
3
|
+
|
|
4
|
+
const host = process.argv[2];
|
|
5
|
+
if (!host || process.argv.length !== 3) {
|
|
6
|
+
console.error('usage: bun scripts/provision-export-redactions.ts <train-host>');
|
|
7
|
+
process.exit(2);
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
provisionExportRedactions(host);
|
|
11
|
+
console.log(`EXPORT_REDACTIONS_PROVISIONED host=${host}`);
|
|
12
|
+
} catch (error) {
|
|
13
|
+
console.error(`EXPORT_REDACTIONS_UNMEASURED host=${host}: ${error instanceof Error ? error.message : 'unknown error'}`);
|
|
14
|
+
process.exitCode = 1;
|
|
15
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/** Warning-only public-copy shadow scan. It never edits source or exposes private candidate text. */
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { extname, normalize, relative, resolve, sep } from 'node:path';
|
|
5
|
+
import { PatentLedger } from '../src/patents/ledger.js';
|
|
6
|
+
import { checkBrandText } from './brand/check.js';
|
|
7
|
+
|
|
8
|
+
export type PublicCopyInput = { label: string; text: string };
|
|
9
|
+
export type PublicCopyFinding = { source: string; line: number; rule: string };
|
|
10
|
+
export type PatentLineMatcher = (text: string) => number[];
|
|
11
|
+
export type PublicCopyScan = {
|
|
12
|
+
findings: PublicCopyFinding[];
|
|
13
|
+
excludedSources: Array<{ source: string; reason: 'internal-goal-document' }>;
|
|
14
|
+
brandRulesAvailable: boolean;
|
|
15
|
+
patentLedgerAvailable: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function normalizedLabel(label: string): string | undefined {
|
|
19
|
+
const slashed = label.replaceAll('\\', '/');
|
|
20
|
+
if (slashed.startsWith('/')) return undefined;
|
|
21
|
+
const normalized = normalize(slashed).replaceAll('\\', '/').replace(/^\.\//, '');
|
|
22
|
+
if (normalized === '..' || normalized.startsWith('../')) return undefined;
|
|
23
|
+
return normalized;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function allowedNormalizedLabel(normalized: string | undefined): boolean {
|
|
27
|
+
if (!normalized) return false;
|
|
28
|
+
if (normalized === 'PR-BODY') return true;
|
|
29
|
+
if (normalized.split('/').some((part) => part === '..' || part === '')) return false;
|
|
30
|
+
if (!['.md', '.mdx', '.txt', '.html', '.htm'].includes(extname(normalized).toLowerCase())) return false;
|
|
31
|
+
return ['docs/', 'release/public/docs/', 'blog/', 'posts/', 'content/blog/', 'content/posts/']
|
|
32
|
+
.some((root) => normalized.startsWith(root));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Brand rule messages intentionally omit matched text; patent matches are private too. */
|
|
36
|
+
export function scanPublicCopy(inputs: readonly PublicCopyInput[], matchPrivateCandidate: PatentLineMatcher, rulesPath?: string): PublicCopyScan {
|
|
37
|
+
const findings: PublicCopyFinding[] = [];
|
|
38
|
+
const excludedSources: PublicCopyScan['excludedSources'] = [];
|
|
39
|
+
let brandRulesAvailable = true;
|
|
40
|
+
let patentLedgerAvailable = true;
|
|
41
|
+
for (const input of inputs) {
|
|
42
|
+
const label = normalizedLabel(input.label);
|
|
43
|
+
if (!allowedNormalizedLabel(label)) throw new Error(`공개 문면 입력 경로가 허용 목록 밖입니다: ${input.label}`);
|
|
44
|
+
// Goal specs are internal execution artifacts, not customer-facing copy.
|
|
45
|
+
// Counting their acceptance criteria as marketing measurements created a
|
|
46
|
+
// high false-positive rate in the 30-PR audit.
|
|
47
|
+
if (label?.startsWith('docs/goals/')) {
|
|
48
|
+
excludedSources.push({ source: input.label, reason: 'internal-goal-document' });
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const brandFindings = checkBrandText(input.text, input.label, 'public-docs', rulesPath);
|
|
53
|
+
// Publication-specific promise/measurement rules apply to this explicit
|
|
54
|
+
// shadow scan without changing the existing generic brand-check scopes.
|
|
55
|
+
const publicationFindings = checkBrandText(input.text, input.label, 'release-notes', rulesPath)
|
|
56
|
+
.filter((hit) => hit.id === 'BRAND-SOON' || hit.id === 'B4-NUMBER-SOURCE');
|
|
57
|
+
for (const hit of [...brandFindings, ...publicationFindings]) {
|
|
58
|
+
findings.push({ source: input.label, line: hit.line, rule: hit.id });
|
|
59
|
+
}
|
|
60
|
+
} catch { brandRulesAvailable = false; }
|
|
61
|
+
try { for (const line of matchPrivateCandidate(input.text)) findings.push({ source: input.label, line, rule: 'PRIVATE-PATENT-CANDIDATE' }); }
|
|
62
|
+
catch { patentLedgerAvailable = false; }
|
|
63
|
+
}
|
|
64
|
+
if (inputs.length === 0 || excludedSources.length === inputs.length) {
|
|
65
|
+
// No scanner ran, so availability must not claim a successful measurement.
|
|
66
|
+
brandRulesAvailable = false;
|
|
67
|
+
patentLedgerAvailable = false;
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
findings: findings.sort((a, b) => a.source.localeCompare(b.source) || a.line - b.line || a.rule.localeCompare(b.rule)),
|
|
71
|
+
excludedSources,
|
|
72
|
+
brandRulesAvailable, patentLedgerAvailable,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function lintPublicCopy(inputs: readonly PublicCopyInput[], matchPrivateCandidate: PatentLineMatcher): PublicCopyFinding[] {
|
|
77
|
+
return scanPublicCopy(inputs, matchPrivateCandidate).findings;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function run(argv: readonly string[], root = process.cwd(), ledger = new PatentLedger()): number {
|
|
81
|
+
const files: string[] = [];
|
|
82
|
+
let bodyFile: string | undefined;
|
|
83
|
+
let bodyLabel = 'PR-BODY';
|
|
84
|
+
let json = false;
|
|
85
|
+
for (let i = 0; i < argv.length; i++) {
|
|
86
|
+
const arg = argv[i]!;
|
|
87
|
+
if (arg === '--json') json = true;
|
|
88
|
+
else if (arg === '--files') {
|
|
89
|
+
while (argv[i + 1] && !argv[i + 1]!.startsWith('--')) files.push(argv[++i]!);
|
|
90
|
+
if (!files.length) throw new Error('--files 에 문면 경로가 필요합니다');
|
|
91
|
+
} else if (arg === '--pr-body-file') {
|
|
92
|
+
bodyFile = argv[++i];
|
|
93
|
+
if (!bodyFile || bodyFile.startsWith('--')) throw new Error('--pr-body-file 에 본문 파일이 필요합니다');
|
|
94
|
+
} else if (arg === '--pr-body-label') {
|
|
95
|
+
bodyLabel = argv[++i] ?? '';
|
|
96
|
+
if (!bodyLabel || bodyLabel.startsWith('--')) throw new Error('--pr-body-label 에 라벨이 필요합니다');
|
|
97
|
+
} else throw new Error(`알 수 없는 옵션: ${arg}`);
|
|
98
|
+
}
|
|
99
|
+
if (!files.length && !bodyFile) throw new Error('usage: bun scripts/public-copy-lint.ts [--files <docs...>] [--pr-body-file <file> [--pr-body-label <repo-relative-label>]] [--json]');
|
|
100
|
+
const inputs: PublicCopyInput[] = files.map((file) => ({
|
|
101
|
+
label: relative(root, resolve(root, file)).split(sep).join('/'), text: readFileSync(resolve(root, file), 'utf8'),
|
|
102
|
+
}));
|
|
103
|
+
if (bodyFile) inputs.push({ label: bodyLabel, text: readFileSync(resolve(root, bodyFile), 'utf8') });
|
|
104
|
+
const matchPrivateCandidate: PatentLineMatcher = (text) => {
|
|
105
|
+
return ledger.unapprovedCandidateLineNumbers(text);
|
|
106
|
+
};
|
|
107
|
+
const scan = scanPublicCopy(inputs, matchPrivateCandidate);
|
|
108
|
+
if (json) console.log(JSON.stringify({ mode: 'warning-only', ...scan }));
|
|
109
|
+
else {
|
|
110
|
+
for (const finding of scan.findings) console.log(`${finding.source}:${finding.line}:WARN:${finding.rule}`);
|
|
111
|
+
for (const excluded of scan.excludedSources) console.log(`${excluded.source}:SKIP:${excluded.reason}`);
|
|
112
|
+
if (!scan.brandRulesAvailable) console.log('WARN:BRAND-RULES-UNMEASURED');
|
|
113
|
+
if (!scan.patentLedgerAvailable) console.log('WARN:PRIVATE-PATENT-LEDGER-UNMEASURED');
|
|
114
|
+
console.log(`public-copy-lint warning-only documents=${inputs.length - scan.excludedSources.length} excluded=${scan.excludedSources.length} findings=${scan.findings.length} brand-rules=${scan.brandRulesAvailable ? 'measured' : 'unmeasured'} patent-ledger=${scan.patentLedgerAvailable ? 'measured' : 'unmeasured'}`);
|
|
115
|
+
}
|
|
116
|
+
return 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (import.meta.main) {
|
|
120
|
+
try { process.exitCode = run(process.argv.slice(2)); }
|
|
121
|
+
catch (error) { console.error(error instanceof Error ? error.message : String(error)); process.exitCode = 2; }
|
|
122
|
+
}
|
package/scripts/public-export.ts
CHANGED
|
@@ -101,14 +101,82 @@ function redactionPattern(from: string): RegExp {
|
|
|
101
101
|
const post = /[A-Za-z0-9]$/.test(from) ? '(?![A-Za-z0-9])' : '';
|
|
102
102
|
return new RegExp(`${pre}${escapeRegExp(from)}${post}`, 'gu');
|
|
103
103
|
}
|
|
104
|
+
const CODE_FILE = /\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/iu;
|
|
105
|
+
type RedactionProblem = { marker: 'private-redaction-identifier' | 'private-redaction-syntax' | 'private-source-syntax'; file: string; line: number; text: string };
|
|
106
|
+
class PrivateRedactionError extends Error {
|
|
107
|
+
constructor(message: string, readonly hits: readonly RedactionProblem[]) { super(message); }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function codeIdentifierRanges(file: string, text: string): Array<{ start: number; end: number; name: string }> {
|
|
111
|
+
if (!CODE_FILE.test(file)) return [];
|
|
112
|
+
// A raw scanner cannot track template-expression braces without rescanning. It can
|
|
113
|
+
// report words in later strings/comments as identifiers after a template literal.
|
|
114
|
+
// The parsed token tree has already resolved those boundaries.
|
|
115
|
+
const kind = /\.(?:tsx|jsx)$/iu.test(file) ? ts.ScriptKind.TSX
|
|
116
|
+
: /\.(?:js|mjs|cjs)$/iu.test(file) ? ts.ScriptKind.JS : ts.ScriptKind.TS;
|
|
117
|
+
const source = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, false, kind);
|
|
118
|
+
const ranges: Array<{ start: number; end: number; name: string }> = [];
|
|
119
|
+
const visit = (node: ts.Node): void => {
|
|
120
|
+
if (ts.isJSDoc(node)) return;
|
|
121
|
+
if (node.kind === ts.SyntaxKind.Identifier || node.kind === ts.SyntaxKind.PrivateIdentifier
|
|
122
|
+
|| node.kind >= ts.SyntaxKind.FirstKeyword && node.kind <= ts.SyntaxKind.LastKeyword) {
|
|
123
|
+
ranges.push({ start: node.getStart(source), end: node.getEnd(), name: node.getText(source) });
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
for (const child of node.getChildren(source)) visit(child);
|
|
127
|
+
};
|
|
128
|
+
visit(source);
|
|
129
|
+
return ranges;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function assertRedactionsAvoidIdentifiers(file: string, text: string, redactions: readonly PrivateRedaction[]): void {
|
|
133
|
+
if (!CODE_FILE.test(file) || !redactions.some((redaction) => text.includes(redaction.from))) return;
|
|
134
|
+
const identifiers = codeIdentifierRanges(file, text);
|
|
135
|
+
if (!identifiers.length) return;
|
|
136
|
+
const hits: RedactionProblem[] = [];
|
|
137
|
+
for (const redaction of redactions) {
|
|
138
|
+
for (const match of text.matchAll(redactionPattern(redaction.from))) {
|
|
139
|
+
const start = match.index;
|
|
140
|
+
const token = identifiers.find((entry) => start < entry.end && start + match[0].length > entry.start);
|
|
141
|
+
if (!token) continue;
|
|
142
|
+
const line = text.slice(0, token.start).split('\n').length;
|
|
143
|
+
hits.push({ marker: 'private-redaction-identifier', file, line, text: token.name });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const unique = [...new Map(hits.map((hit) => [`${hit.file}:${hit.line}:${hit.text}`, hit])).values()];
|
|
147
|
+
if (unique.length) throw new PrivateRedactionError(`private redaction would change code identifiers: ${unique.slice(0, 12).map((hit) => `${hit.file}:${hit.line} ${hit.text}`).join(', ')}${unique.length > 12 ? ` (+${unique.length - 12} more)` : ''}`, unique);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function firstCodeParseError(file: string, text: string): { line: number; message: string } | null {
|
|
151
|
+
if (!CODE_FILE.test(file)) return null;
|
|
152
|
+
const kind = /\.(?:tsx|jsx)$/iu.test(file) ? ts.ScriptKind.TSX
|
|
153
|
+
: /\.(?:js|mjs|cjs)$/iu.test(file) ? ts.ScriptKind.JS : ts.ScriptKind.TS;
|
|
154
|
+
const parsed = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, false, kind) as ts.SourceFile & { parseDiagnostics: readonly ts.Diagnostic[] };
|
|
155
|
+
const first = parsed.parseDiagnostics[0];
|
|
156
|
+
return first ? { line: parsed.getLineAndCharacterOfPosition(first.start ?? 0).line + 1,
|
|
157
|
+
message: ts.flattenDiagnosticMessageText(first.messageText, ' ') } : null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function assertRedactedCodeParses(file: string, before: string, after: string): void {
|
|
161
|
+
const failure = firstCodeParseError(file, after);
|
|
162
|
+
if (!failure) return;
|
|
163
|
+
const baseline = firstCodeParseError(file, before);
|
|
164
|
+
const issue = baseline ?? failure;
|
|
165
|
+
const marker = baseline ? 'private-source-syntax' : 'private-redaction-syntax';
|
|
166
|
+
const label = baseline ? 'source code was already invalid before redaction' : 'private redaction produced invalid code';
|
|
167
|
+
throw new PrivateRedactionError(`${label} at ${file}:${issue.line}: ${issue.message}`,
|
|
168
|
+
[{ marker, file, line: issue.line, text: issue.message }]);
|
|
169
|
+
}
|
|
170
|
+
|
|
104
171
|
export function applyPrivateRedactions(contents: ReadonlyMap<string, string>, redactions: readonly PrivateRedaction[]): { contents: Map<string, string>; files: number; places: number } {
|
|
105
172
|
const result = new Map(contents);
|
|
106
173
|
let files = 0; let places = 0;
|
|
107
174
|
for (const [file, text] of result) {
|
|
108
175
|
if (text.includes('\u0000')) continue;
|
|
176
|
+
assertRedactionsAvoidIdentifiers(file, text, redactions);
|
|
109
177
|
let out = text; let changed = 0;
|
|
110
178
|
for (const r of redactions) out = out.replace(redactionPattern(r.from), () => { changed++; return r.to; });
|
|
111
|
-
if (changed) { result.set(file, out); files++; places += changed; }
|
|
179
|
+
if (changed) { assertRedactedCodeParses(file, text, out); result.set(file, out); files++; places += changed; }
|
|
112
180
|
}
|
|
113
181
|
return { contents: result, files, places };
|
|
114
182
|
}
|
|
@@ -461,7 +529,14 @@ export function run(argv: readonly string[], root = resolve(import.meta.dir, '..
|
|
|
461
529
|
// ⭐ 개인 치환표(저장소 밖) — 규칙 변환 «뒤»에 건다. 없으면 «못 봤다»로 막는다.
|
|
462
530
|
const redactions = loadPrivateRedactions();
|
|
463
531
|
const noPrivateList = argv.includes('--no-private-list');
|
|
464
|
-
|
|
532
|
+
let redacted: ReturnType<typeof applyPrivateRedactions>;
|
|
533
|
+
try { redacted = redactions ? applyPrivateRedactions(transformedByRules.contents, redactions) : { contents: transformedByRules.contents, files: 0, places: 0 }; }
|
|
534
|
+
catch (error) {
|
|
535
|
+
console.error(`⛔ ${error instanceof Error ? error.message : String(error)}`);
|
|
536
|
+
if (json && error instanceof PrivateRedactionError) console.log(JSON.stringify({ files: scanned.length,
|
|
537
|
+
leaks: error.hits.length, hits: error.hits }));
|
|
538
|
+
return 1;
|
|
539
|
+
}
|
|
465
540
|
const transformed = { contents: redacted.contents, counts: transformedByRules.counts };
|
|
466
541
|
const privateRedactions = { table: privateRedactionsPath(), loaded: redactions !== null, entries: redactions?.length ?? 0, files: redacted.files, places: redacted.places };
|
|
467
542
|
if (redactions) console.error(`private redactions: ${redacted.files} files · ${redacted.places} places (${redactions.length} entries · ${privateRedactionsPath()})`);
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
3
|
+
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
4
|
+
|
|
5
|
+
export const ENTRY_LINE_LIMIT = 4_000;
|
|
6
|
+
export const ENTRY_MODULE_LIMIT = 1_188;
|
|
7
|
+
export const INDEX_MODULE_LIMIT = 1_264;
|
|
8
|
+
const DASHBOARD_BASELINE = 'src/dashboard/loop-scheduler.ts';
|
|
9
|
+
|
|
10
|
+
export interface AuditResult { errors: string[]; notes: string[]; entryModules: number; indexModules: number; oversized: Array<{ file: string; lines: number }> }
|
|
11
|
+
|
|
12
|
+
function walkTs(root: string): string[] {
|
|
13
|
+
return readdirSync(root).flatMap((name) => {
|
|
14
|
+
const path = join(root, name);
|
|
15
|
+
return statSync(path).isDirectory() ? walkTs(path) : /\.(?:[cm]?ts|tsx)$/.test(path) ? [path] : [];
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isInside(root: string, path: string): boolean {
|
|
20
|
+
const rel = relative(root, path);
|
|
21
|
+
return rel === '' || (!rel.startsWith(`..${sep}`) && rel !== '..' && !resolve(path).startsWith(`${resolve(root, 'node_modules')}${sep}`));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function staticClosure(repo: string, entry: string): Set<string> {
|
|
25
|
+
const configPath = join(repo, 'tsconfig.json');
|
|
26
|
+
const config = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
27
|
+
if (config.error) throw new Error(ts.flattenDiagnosticMessageText(config.error.messageText, '\n'));
|
|
28
|
+
const parsed = ts.parseJsonConfigFileContent(config.config, ts.sys, repo);
|
|
29
|
+
if (parsed.errors.length) throw new Error(parsed.errors.map((diagnostic) => ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')).join('; '));
|
|
30
|
+
const options = parsed.options;
|
|
31
|
+
const seen = new Set<string>();
|
|
32
|
+
const visit = (file: string): void => {
|
|
33
|
+
const abs = resolve(file);
|
|
34
|
+
if (seen.has(abs)) return;
|
|
35
|
+
seen.add(abs);
|
|
36
|
+
const source = ts.createSourceFile(abs, readFileSync(abs, 'utf8'), ts.ScriptTarget.Latest, true);
|
|
37
|
+
for (const node of source.statements) {
|
|
38
|
+
if (ts.isImportDeclaration(node)) {
|
|
39
|
+
if (node.importClause?.isTypeOnly || !ts.isStringLiteral(node.moduleSpecifier)) continue;
|
|
40
|
+
const specifier = node.moduleSpecifier.text;
|
|
41
|
+
const result = ts.resolveModuleName(specifier, abs, options, ts.sys).resolvedModule;
|
|
42
|
+
if (!result) {
|
|
43
|
+
if (specifier.startsWith('.') || specifier.startsWith('/')) throw new Error(`unresolved static import ${relative(repo, abs)} -> ${specifier}`);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (isInside(repo, result.resolvedFileName)) visit(result.resolvedFileName);
|
|
47
|
+
} else if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
48
|
+
if (node.isTypeOnly) continue;
|
|
49
|
+
const specifier = node.moduleSpecifier.text;
|
|
50
|
+
const result = ts.resolveModuleName(specifier, abs, options, ts.sys).resolvedModule;
|
|
51
|
+
if (!result) {
|
|
52
|
+
if (specifier.startsWith('.') || specifier.startsWith('/')) throw new Error(`unresolved static re-export ${relative(repo, abs)} -> ${specifier}`);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (isInside(repo, result.resolvedFileName)) visit(result.resolvedFileName);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
visit(entry);
|
|
60
|
+
return seen;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function entryBudgetAffected(changedFiles: readonly string[]): boolean {
|
|
64
|
+
if (changedFiles.some((file) => file === 'bin/elanous.mjs' || file === 'tsconfig.json' || file === 'scripts/ratchets/next-tui-entry-budget.ts')) return true;
|
|
65
|
+
// Any source edit can add/remove an importer or delete a module from a base
|
|
66
|
+
// closure. The changed tree alone cannot prove non-membership in the base graph.
|
|
67
|
+
return changedFiles.some((file) => /^src\/.+\.[cm]?[jt]sx?$/.test(file));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function audit(repo: string): AuditResult {
|
|
71
|
+
const errors: string[] = [];
|
|
72
|
+
const notes: string[] = [];
|
|
73
|
+
const tuiFiles = [join(repo, 'src/tui.ts'), ...walkTs(join(repo, 'src/tui'))];
|
|
74
|
+
const oversized = tuiFiles.map((file) => {
|
|
75
|
+
const contents = readFileSync(file, 'utf8');
|
|
76
|
+
const lines = contents.length === 0 ? 0 : contents.split(/\r?\n/).length - (contents.endsWith('\n') ? 1 : 0);
|
|
77
|
+
return { file: relative(repo, file), lines };
|
|
78
|
+
})
|
|
79
|
+
.filter(({ lines }) => lines > ENTRY_LINE_LIMIT);
|
|
80
|
+
for (const item of oversized) errors.push(`${item.file}: ${item.lines} lines exceeds ${ENTRY_LINE_LIMIT}`);
|
|
81
|
+
|
|
82
|
+
const entryClosure = staticClosure(repo, join(repo, 'src/tui/entry.ts'));
|
|
83
|
+
const entryPaths = [...entryClosure].map((file) => relative(repo, file).replaceAll('\\', '/'));
|
|
84
|
+
if (entryClosure.size > ENTRY_MODULE_LIMIT) errors.push(`Next entry static module count ${entryClosure.size} exceeds ${ENTRY_MODULE_LIMIT}`);
|
|
85
|
+
else if (entryClosure.size < ENTRY_MODULE_LIMIT) notes.push(`tighten entry module cap ${ENTRY_MODULE_LIMIT} -> ${entryClosure.size}`);
|
|
86
|
+
const forbiddenIndex = entryPaths.filter((p) => p === 'src/index.ts');
|
|
87
|
+
if (forbiddenIndex.length) errors.push('Next entry statically imports forbidden src/index.ts');
|
|
88
|
+
const dashboard = entryPaths.filter((p) => p.startsWith('src/dashboard/'));
|
|
89
|
+
const unexpectedDashboard = dashboard.filter((p) => p !== DASHBOARD_BASELINE);
|
|
90
|
+
if (unexpectedDashboard.length) errors.push(`forbidden dashboard static imports: ${unexpectedDashboard.join(', ')}`);
|
|
91
|
+
if (dashboard.includes(DASHBOARD_BASELINE)) notes.push(`${DASHBOARD_BASELINE} is temporary baseline; remove at NEXT-TUI-EXTRACT-FROM-INDEX`);
|
|
92
|
+
|
|
93
|
+
const binPath = join(repo, 'bin/elanous.mjs');
|
|
94
|
+
const bin = readFileSync(binPath, 'utf8');
|
|
95
|
+
// The deployment entry sends every unrecognized route to src/index.ts. The current
|
|
96
|
+
// light router does not claim --tui next, so measure that fallback's static closure.
|
|
97
|
+
const binSource = ts.createSourceFile(binPath, bin, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
98
|
+
let importsIndex = false;
|
|
99
|
+
const visitBin = (node: ts.Node): void => {
|
|
100
|
+
if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword
|
|
101
|
+
&& node.arguments[0] && ts.isStringLiteral(node.arguments[0])
|
|
102
|
+
&& /(?:^|\/)src\/index\.ts$/.test(node.arguments[0].text.replaceAll('\\', '/'))) importsIndex = true;
|
|
103
|
+
ts.forEachChild(node, visitBin);
|
|
104
|
+
};
|
|
105
|
+
visitBin(binSource);
|
|
106
|
+
const indexClosure = importsIndex ? staticClosure(repo, join(repo, 'src/index.ts')) : new Set<string>();
|
|
107
|
+
if (importsIndex && indexClosure.size > INDEX_MODULE_LIMIT) errors.push(`bin --tui next index static module count ${indexClosure.size} exceeds ${INDEX_MODULE_LIMIT}`);
|
|
108
|
+
else if (importsIndex && indexClosure.size < INDEX_MODULE_LIMIT) notes.push(`tighten index module cap ${INDEX_MODULE_LIMIT} -> ${indexClosure.size} after entry extraction`);
|
|
109
|
+
else if (!importsIndex) notes.push('bin has no dynamic import of src/index.ts; index fallback budget no longer applies');
|
|
110
|
+
return { errors, notes, entryModules: entryClosure.size, indexModules: indexClosure.size, oversized };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (import.meta.main) {
|
|
114
|
+
try {
|
|
115
|
+
const result = audit(resolve(dirname(new URL(import.meta.url).pathname), '../..'));
|
|
116
|
+
console.log(`NEXT_TUI_ENTRY_BUDGET entryModules=${result.entryModules} indexModules=${result.indexModules} oversized=${result.oversized.length}`);
|
|
117
|
+
for (const note of result.notes) console.log(`NOTE ${note}`);
|
|
118
|
+
for (const error of result.errors) console.error(`FAIL ${error}`);
|
|
119
|
+
process.exitCode = result.errors.length ? 1 : 0;
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error(`UNMEASURED ${error instanceof Error ? error.message : String(error)}`);
|
|
122
|
+
process.exitCode = 2;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Train-side sentinel for the
|
|
2
|
+
# Train-side sentinel for the HARD regressions and release-critical invariants. Run on the
|
|
3
3
|
# merged side tree before the changed-file gate; never interpret a missing test
|
|
4
4
|
# or an incomplete run as a pass.
|
|
5
5
|
set -u
|
|
6
6
|
|
|
7
7
|
files=(
|
|
8
8
|
scripts/ratchets/test-interference-patterns.test.ts
|
|
9
|
+
scripts/ratchets/next-tui-entry-budget.test.ts
|
|
9
10
|
src/domains/finance-cli.test.ts
|
|
10
11
|
src/instance/state-dir-provenance-ratchet.test.ts
|
|
11
12
|
src/self-implement/graph-yaml.test.ts
|
|
@@ -13,6 +14,11 @@ files=(
|
|
|
13
14
|
test/identity-env.test.ts
|
|
14
15
|
test/no-absolute-path-imports.test.ts
|
|
15
16
|
test/scenarios/integration.test.ts
|
|
17
|
+
test/rules-contract.test.ts
|
|
18
|
+
test/hook-order-sweep.test.ts
|
|
19
|
+
src/cli/g6a-commands.test.ts
|
|
20
|
+
test/spawn-sync-max-buffer.test.ts
|
|
21
|
+
test/telegram-coding-model-terra.test.ts
|
|
16
22
|
)
|
|
17
23
|
|
|
18
24
|
if [[ ${1:-} == --list ]]; then
|
|
@@ -6,7 +6,18 @@ import { join, resolve } from 'node:path';
|
|
|
6
6
|
import { debug } from '../../src/debug/log.js';
|
|
7
7
|
import { isReleaseVersion } from './release-version.js';
|
|
8
8
|
|
|
9
|
-
export interface CutBranchOptions {
|
|
9
|
+
export interface CutBranchOptions {
|
|
10
|
+
version: string;
|
|
11
|
+
/** Optional only on the --append path (RELEASE-APPEND-BASE-AUTO); required without --append. */
|
|
12
|
+
base?: string;
|
|
13
|
+
pick: string[];
|
|
14
|
+
append?: boolean;
|
|
15
|
+
dryRun?: boolean;
|
|
16
|
+
repoRoot?: string;
|
|
17
|
+
log?: (line: string) => void;
|
|
18
|
+
/** Run ledger's version-release record ({ commit, branch, base? }) — consulted when --append omits --base. */
|
|
19
|
+
ledger?: () => { commit?: unknown; base?: unknown; branch?: unknown } | undefined;
|
|
20
|
+
}
|
|
10
21
|
|
|
11
22
|
// git-spawn-allow: release branch operations happen only in an isolated temporary worktree; main is never checked out or changed.
|
|
12
23
|
function git(repo: string, args: string[]): string {
|
|
@@ -21,24 +32,35 @@ function ancestor(repo: string, sha: string, ref: string): boolean {
|
|
|
21
32
|
return result.status === 0;
|
|
22
33
|
}
|
|
23
34
|
|
|
35
|
+
/** RELEASE-APPEND-BASE-AUTO: the first parent of a release-branch tip — the commit main was cut from when the branch carries only release-side commits. */
|
|
36
|
+
function firstParent(repo: string, sha: string): string | undefined {
|
|
37
|
+
const parts = git(repo, ['rev-list', '--parents', '-n', '1', sha]).split(/\s+/);
|
|
38
|
+
const parent = parts[1];
|
|
39
|
+
return parent !== undefined && /^[0-9a-f]{40}$/i.test(parent) ? parent : undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** RELEASE-APPEND-BASE-AUTO: the main cut recorded by the run ledger's version-release node — its base field when present, else the first parent of its commit. Unresolvable records degrade to undefined so the caller keeps its refusal. */
|
|
43
|
+
function ledgerCut(repo: string, recorded: { commit?: unknown; base?: unknown; branch?: unknown } | undefined): string | undefined {
|
|
44
|
+
if (!recorded) return undefined;
|
|
45
|
+
try {
|
|
46
|
+
if (typeof recorded.base === 'string' && /^[0-9a-f]{7,40}$/i.test(recorded.base)) return git(repo, ['rev-parse', '--verify', `${recorded.base}^{commit}`]);
|
|
47
|
+
if (typeof recorded.commit === 'string' && /^[0-9a-f]{7,40}$/i.test(recorded.commit)) return firstParent(repo, git(repo, ['rev-parse', '--verify', `${recorded.commit}^{commit}`]));
|
|
48
|
+
} catch { return undefined; }
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
24
52
|
export function cutReleaseBranch(opts: CutBranchOptions): { branch: string; commit: string | null; dryRun: boolean } {
|
|
25
53
|
const repo = resolve(opts.repoRoot ?? process.cwd());
|
|
26
54
|
const branch = `release/${opts.version}`;
|
|
27
55
|
const log = opts.log ?? console.log;
|
|
28
|
-
const report = (event: 'created' | 'refused' | 'conflict' | 'appended', reason?: string, commit?: string, extra?: Record<string, string | string[]>) =>
|
|
56
|
+
const report = (event: 'created' | 'refused' | 'conflict' | 'appended' | 'base-resolved' | 'base-corrected', reason?: string, commit?: string, extra?: Record<string, string | string[]>) =>
|
|
29
57
|
debug.log('release-loop.cut-branch', event, { version: opts.version, branch, ...(commit ? { commit } : {}), ...(reason ? { reason } : {}), ...extra });
|
|
30
58
|
try {
|
|
31
59
|
if (!isReleaseVersion(opts.version)) throw new Error(`invalid release version: ${opts.version}`);
|
|
32
60
|
if (!opts.pick.length) throw new Error('at least one --pick commit is required');
|
|
33
|
-
|
|
61
|
+
if (opts.base === undefined && !opts.append) throw new Error('--base is required without --append');
|
|
62
|
+
for (const sha of [opts.base, ...opts.pick]) if (sha !== undefined && !/^[0-9a-f]{7,40}$/i.test(sha)) throw new Error(`invalid commit SHA: ${sha}`);
|
|
34
63
|
git(repo, ['fetch', 'origin', 'main']);
|
|
35
|
-
const base = git(repo, ['rev-parse', '--verify', `${opts.base}^{commit}`]);
|
|
36
|
-
if (!ancestor(repo, base, 'origin/main')) throw new Error(`base ${base} is not an ancestor of origin/main`);
|
|
37
|
-
const picks = opts.pick.map((sha) => git(repo, ['rev-parse', '--verify', `${sha}^{commit}`]));
|
|
38
|
-
for (const sha of picks) if (!ancestor(repo, sha, 'origin/main')) throw new Error(`pick ${sha} is not an ancestor of origin/main`);
|
|
39
|
-
for (const sha of picks) if (ancestor(repo, sha, base)) throw new Error(`pick ${sha} is already in base ${base}`);
|
|
40
|
-
if (new Set(picks).size !== picks.length) throw new Error('duplicate --pick commit');
|
|
41
|
-
for (const sha of picks) if (git(repo, ['rev-list', '--parents', '-n', '1', sha]).split(' ').length !== 2) throw new Error(`pick ${sha} must have exactly one parent`);
|
|
42
64
|
const remoteLine = git(repo, ['ls-remote', '--heads', 'origin', `refs/heads/${branch}`]);
|
|
43
65
|
if (remoteLine && !opts.append) throw new Error(`${branch} already exists on origin — use --append to fast-forward more picks onto it`);
|
|
44
66
|
if (!remoteLine && opts.append) throw new Error(`${branch} does not exist on origin — omit --append to create it`);
|
|
@@ -50,13 +72,40 @@ export function cutReleaseBranch(opts: CutBranchOptions): { branch: string; comm
|
|
|
50
72
|
git(repo, ['fetch', 'origin', `refs/heads/${branch}:refs/remotes/origin/${branch}`]);
|
|
51
73
|
remoteTip = git(repo, ['rev-parse', '--verify', `refs/remotes/origin/${branch}^{commit}`]);
|
|
52
74
|
if (advertised !== remoteTip) throw new Error(`${branch} remote tip moved — fast-forward refused (no force push)`);
|
|
53
|
-
for (const sha of picks) if (ancestor(repo, sha, remoteTip)) throw new Error(`pick ${sha} is already in ${branch}`);
|
|
54
75
|
}
|
|
76
|
+
// RELEASE-APPEND-BASE-AUTO (OP 0.2.38): a cut commit lives only on the release branch, so the main cut is resolved
|
|
77
|
+
// before the ancestor refusal — from the run ledger's version-release record, else the release tip's first parent.
|
|
78
|
+
let base: string;
|
|
79
|
+
if (opts.base !== undefined) {
|
|
80
|
+
base = git(repo, ['rev-parse', '--verify', `${opts.base}^{commit}`]);
|
|
81
|
+
} else {
|
|
82
|
+
const fromLedger = ledgerCut(repo, opts.ledger?.());
|
|
83
|
+
const ledgerCandidate = fromLedger !== undefined && ancestor(repo, fromLedger, 'origin/main') ? fromLedger : undefined;
|
|
84
|
+
const candidate = ledgerCandidate ?? (remoteTip !== undefined ? firstParent(repo, remoteTip) : undefined);
|
|
85
|
+
if (candidate === undefined || !ancestor(repo, candidate, 'origin/main'))
|
|
86
|
+
throw new Error(`base ${candidate ?? remoteTip ?? branch} is not an ancestor of origin/main`);
|
|
87
|
+
base = candidate;
|
|
88
|
+
report('base-resolved', undefined, base, { source: ledgerCandidate !== undefined ? 'ledger' : 'first-parent' });
|
|
89
|
+
}
|
|
90
|
+
if (!ancestor(repo, base, 'origin/main')) {
|
|
91
|
+
if (!opts.append) throw new Error(`base ${base} is not an ancestor of origin/main`);
|
|
92
|
+
const parent = firstParent(repo, base);
|
|
93
|
+
if (parent === undefined || !ancestor(repo, parent, 'origin/main')) throw new Error(`base ${base} is not an ancestor of origin/main`);
|
|
94
|
+
log(`base ${base} 는 origin/main 에 없다 — 그 부모 ${parent} 를 쓰라 (auto-corrected)`);
|
|
95
|
+
report('base-corrected', `그 부모 ${parent} 를 쓰라 — ${base} 는 origin/main 에 없다`, base, { parent });
|
|
96
|
+
base = parent;
|
|
97
|
+
}
|
|
98
|
+
const picks = opts.pick.map((sha) => git(repo, ['rev-parse', '--verify', `${sha}^{commit}`]));
|
|
99
|
+
for (const sha of picks) if (!ancestor(repo, sha, 'origin/main')) throw new Error(`pick ${sha} is not an ancestor of origin/main`);
|
|
100
|
+
for (const sha of picks) if (ancestor(repo, sha, base)) throw new Error(`pick ${sha} is already in base ${base}`);
|
|
101
|
+
if (new Set(picks).size !== picks.length) throw new Error('duplicate --pick commit');
|
|
102
|
+
for (const sha of picks) if (git(repo, ['rev-list', '--parents', '-n', '1', sha]).split(' ').length !== 2) throw new Error(`pick ${sha} must have exactly one parent`);
|
|
103
|
+
if (opts.append) for (const sha of picks) if (ancestor(repo, sha, remoteTip!)) throw new Error(`pick ${sha} is already in ${branch}`);
|
|
55
104
|
const versionAt = remoteTip ?? base;
|
|
56
105
|
const pkg = JSON.parse(git(repo, ['show', `${versionAt}:package.json`])) as { version?: unknown };
|
|
57
106
|
if (pkg.version !== opts.version) throw new Error(`${opts.append ? 'release branch' : 'base'} package.json version ${pkg.version} is not ${opts.version}`);
|
|
58
107
|
const start = remoteTip ?? base;
|
|
59
|
-
log(`${branch}: ${start} + ${picks.join(' + ')}${opts.append ? ' (append)' : ''}${opts.dryRun ? ' (dry-run)' : ''}`);
|
|
108
|
+
log(`${branch}: ${start} + ${picks.join(' + ')}${opts.append ? ' (append)' : ''}${opts.dryRun ? ' (dry-run)' : ''}${base !== start ? ` · base ${base}` : ''}`);
|
|
60
109
|
if (opts.dryRun) return { branch, commit: null, dryRun: true };
|
|
61
110
|
const temp = mkdtempSync(join(tmpdir(), 'release-cut-branch-'));
|
|
62
111
|
const tree = join(temp, 'tree');
|
|
@@ -46,9 +46,27 @@ export function runExportCheck(run: CommandRunner = runCommand, repoRoot = proce
|
|
|
46
46
|
step = 'build';
|
|
47
47
|
const publicDir = join(out, 'export');
|
|
48
48
|
symlinkSync(join(modulesRoot, 'node_modules'), join(publicDir, 'node_modules'), 'dir');
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
let pwaModules = join(root, 'apps', 'pwa', 'node_modules');
|
|
50
|
+
let pwaReady = existsSync(pwaModules);
|
|
51
|
+
if (!pwaReady) {
|
|
52
|
+
const installed = run('bun', ['install', '--cwd', join(root, 'apps', 'pwa'), '--frozen-lockfile'], root);
|
|
53
|
+
if (installed.status !== 0) {
|
|
54
|
+
// This path was absent before install. Remove partial output so a later retry cannot mistake it for a complete install.
|
|
55
|
+
let cleanupFailed = false;
|
|
56
|
+
try { rmSync(pwaModules, { recursive: true, force: true }); }
|
|
57
|
+
catch (error) {
|
|
58
|
+
cleanupFailed = true;
|
|
59
|
+
result = failed('build', `PWA dependency install partial-output cleanup: ${error instanceof Error ? error.message : String(error)}`, installed);
|
|
60
|
+
}
|
|
61
|
+
if (!cleanupFailed) result = failed('build', 'PWA dependency install', installed);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
pwaReady = existsSync(pwaModules);
|
|
65
|
+
if (!pwaReady) result = failed('build', 'PWA dependency install did not create apps/pwa/node_modules', installed);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (pwaReady) {
|
|
69
|
+
pwaModules = realpathSync(pwaModules);
|
|
52
70
|
if (existsSync(join(publicDir, 'apps', 'pwa'))) symlinkSync(pwaModules, join(publicDir, 'apps', 'pwa', 'node_modules'), 'dir');
|
|
53
71
|
const built = run('bun', ['bin/elanous.mjs', 'nexus', 'build'], publicDir);
|
|
54
72
|
result = built.status === 0 && existsSync(join(publicDir, 'apps', 'pwa', 'out', 'index.html'))
|