elanous 0.2.43 → 0.2.44
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/{Om5xS9jpjSXJCeTNGYEi4 → HMXsxdy5MIIcHPMHv1wD4}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{3557ac4a.c8931684475018ad.js → 08334415.f0e80896acbef722.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1032-78ba4f6391258cab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1082-53f86a26e03d309d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1109-7d0e264f6f2edbc7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1124-7c26330402481143.js +1 -0
- package/apps/pwa/out/_next/static/chunks/118.2a89982fe4276880.js +23 -0
- package/apps/pwa/out/_next/static/chunks/1244.6c435dbf1bf21d8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1252.9e665904d3aa3b1a.js +32 -0
- package/apps/pwa/out/_next/static/chunks/1266.a46cc33cb6a72d75.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{3955.6922286237f2ac2b.js → 1306.967240ede9a0f757.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1344.3b95f3bd1b77a3fe.js +94 -0
- package/apps/pwa/out/_next/static/chunks/{5628.6ddb2d5ffba4ff4c.js → 1401.22dfe92640a2b1ac.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/1431-f7c78bd5be21e011.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1451-cdd35a8a0b31834b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2573.387a707f6f9d720c.js → 1694.18debfd77562e56d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1708-f03d587b7a7545c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1775-fa7152bdeff6c95f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/178-4da509cd7266672a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7910-6f139bcafd238b9f.js → 1850-522de4ee34957210.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1876-c6f6e0ddcc76c6a1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1976.097066b072432242.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1406.a1dc2ab6f8449374.js → 1978.eeb60a606dc5deac.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{3402.44b565b314f2263c.js → 2043.e233e3b5a3e790f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2150.71b94e3348107c83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2158.ebc6fc5a10280ab7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3694.e0099884345f0198.js → 2216.802962c04f40a26e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2294.7890edcfa046c97d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/235.c89aaae4bcd6233a.js +74 -0
- package/apps/pwa/out/_next/static/chunks/239.de075467b5523469.js +287 -0
- package/apps/pwa/out/_next/static/chunks/{1200.6a37c202f9f17e9a.js → 249.ba7051590d603c8f.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/2571.a6ac4e26c8618403.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2610.e149cd564a08913e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2705.9816f3c244f8b85f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2801.afeb8a4dae22f85f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3935.16701e33f8982dc9.js → 2954.bbefc95d6b20e0d8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{aa57532f.510551854ff239b1.js → 2e0f720a.a0697c08e3806a60.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3042.96ec235fe41c8d4e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3097-8e358f158acef46b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3205-93b1abe28b4fb16a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3273.b4434f0dcae7eb29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3311.9cbc43ea0c90d60c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5930.8b4df3b46c32b05a.js → 3349.b5f09ee474d9533e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5866.366966af47fdde5d.js → 3503.a47a9755fb4d97b0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3506-5f429b3b7e1392b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7900.096f455c7c1efc53.js → 3843.bad404d008893291.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3877-4b40e530b47e3bf9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/435-ce2958253cf7de61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8588.d1c6a2903727ce87.js → 4393.28fa5228d0eec217.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/4404.7281c847c6e10dfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8062-7cd0bcc7f01455ba.js → 4415-b9d6a90960920a4a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{8313-dfa1021bb58a46d6.js → 447-5b304de1fe098f43.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4484-8ebea83d431e6fae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6944.309f4e3ea54d1537.js → 4502.bdcc877abd437a05.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4599-f95790fc5c65b8df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3072.01338851ca21a6f7.js → 46.57c783fa4884714f.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/463-b9114e411f33728e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4659.a57d1f0c5d754cd2.js +36 -0
- package/apps/pwa/out/_next/static/chunks/4722-a847e7a28115035f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8986.8e2e4efbfa655c59.js → 4757.67c6d7473a038e78.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4874-c86f878ec4502ad3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4891.3f80ba517a3b2373.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8205.282ca4bb62d54a0a.js → 4998.810ca8833084caa9.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/4f98febc.ea5841d4d616bfb2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5789.2da35c258292e1e5.js → 5052.7dbb12a55d4f18f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5166-ca73b3e361085a6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5180-039f4a18b07ad387.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5232.5a2ce4daf7a9e11d.js +115 -0
- package/apps/pwa/out/_next/static/chunks/{9770.5f75bc6088b16109.js → 5439.3fec6dbce29ecb36.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1313-19f737e0222c4444.js → 5612-074d9a5e00dfac6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5675-01989d524a84c505.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5751.af641a1adf5ec697.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5758-c6cb98714d18ab0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/578eded8.b582637306e16964.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{3969.272ee7f9fd6c62e5.js → 5790.5eb06a653ebd8571.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5853-4033e5bd5afbe06b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5904.97d70bb7f46b2db7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6540.c7bef57ad8f90a87.js → 5989.7ecd362c5c44b747.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{0ad6802e.ae7afb63fdcb4491.js → 5a34fb2f.52f1b4e1baebb48a.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{0966f8a1.745fcd44f64a87ea.js → 5a5078f8.2099200e5ea95e16.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6036-c302c34ff0b3d410.js +1 -0
- package/apps/pwa/out/_next/static/chunks/606.ef81c313381f4264.js +1 -0
- package/apps/pwa/out/_next/static/chunks/616.1af54a928b1ba704.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6201.bc936f71f613a8e9.js +41 -0
- package/apps/pwa/out/_next/static/chunks/6204-fdc86e0e64c4f92d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2144.25b292396712196d.js → 6245.1182e007e9d230d9.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{363bfab3.9623b9f89363541f.js → 63699a35.17262e162bc514b2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6420.494801a80030160c.js +27 -0
- package/apps/pwa/out/_next/static/chunks/{d96660fb.cbc21a2a88539dbb.js → 6549dad0.2740b25e51bf8f05.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/{5564.9e72532188f57586.js → 6881.9e7955847640c7fe.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/6931.fcdfb94141e67b3d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6991-8e081c6ce38c0ba1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3903.3ef4656c67572764.js → 7010.1bbd17a7f2b3e376.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7029.d1466acf55fae2ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7152-a123aa8e129c131f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7455.196168fffac3b9c4.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7638.6ca4770dd1129138.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7649-f37d76260e5e2a5a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2312.0c8b61e22d3136d7.js → 7679.32c40cdd14f20b4a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7751.04bfbd16b4c6cd0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7864.b1ff31d4030b8994.js +148 -0
- package/apps/pwa/out/_next/static/chunks/7869-c47bd2c075c1fefa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4199.ce86b281fd0a60b7.js → 8442.2f09ca969d631615.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8445.2738dbd59a78c78c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8447.5510c439f9938c6d.js +286 -0
- package/apps/pwa/out/_next/static/chunks/8551.f762945c2cda2e95.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8635-57a9d8d9db70f4f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{fb7d20d5-6892502b6ee39ca6.js → 86961958-4b0689a5048f756b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8709.3c6019bb18f8554f.js +8 -0
- package/apps/pwa/out/_next/static/chunks/8759.c999528a0a907bf6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/87f498e5-0881de09f2e44707.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8843.c3197f904c952b81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{cb0f8df8.09a4a6be97e3fc5f.js → 892fd990.456232f326cc39c2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{837-81336ebaca8198a8.js → 8965-135a2c9eaa2464cb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8971-8d3b9c96f8a6c958.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9059.c8598d96f8e5e9cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9115.90447ae198b84eae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9147.d9b0a02e0babc9b4.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9204-83075f4b70c61cdc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9244-c32ef14b5dc72bdf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/930.2a9a30f964350c66.js +90 -0
- package/apps/pwa/out/_next/static/chunks/{8637.90f92d5c8db4732c.js → 9398.1f56e3f17795f43f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9527.3e5ad31c891c5fcb.js +79 -0
- package/apps/pwa/out/_next/static/chunks/9571-4ac933e774d1225c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-0c9dace2db62bee8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f5e65c3dc9d89f2a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-2a9c19b9a140b7b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-61533ad92141adfb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-112004ced6fd0329.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-f733318c237a49d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-51ea677d2d33bbc0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-428b41f2f9566e3c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-1b29396ea90a61e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-cf83ec613ac904bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-3f4c0ecbc284bb5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-b63c322f54f70cc6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-fe328c4ee9aac6b4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-bfb855c584f0fb98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-47b1710c110eabd7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-42895214458bc6d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-d03de0ebd8366e23.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-3ed6c47e4b1c61c2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-ae653e9bf261c738.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-23f3f0a0209c0ac4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-88c691273aae66f9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e187ac52a95538b3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-6e45828daed1295e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-edb5d7287bb46186.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-4a7eaacd93c3f6a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ca073d43d74cc84.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1e9fee67b1199436.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-df1283ea963c6816.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-19fcf8d8301ccd18.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-5ab699e0303bbb40.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7cde0d29756984c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-9d4c598e8ee22f7a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-cc1609a71f44ec62.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7659a9a1345bfaa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-0afef60ecc0c4af5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-a3553949f8f34f5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-9fc644de2d8edae3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-057a69702f3c67c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-c0f0e570f3f74c73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-1825071ae34e3b89.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-6244e3e135d8ccfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/{page-0a815f34367b6db6.js → page-da787e8a10b8a82e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-1316d32498e2be42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-4df94572e343de2e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-708969f7475e88c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c58add08c919a1dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-a24847f45e5d5bf9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-acfec65a3a60e22e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-3dfc598e6fbde245.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-c658a626118411b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-4c73685fd891445b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-6310f7e5de7dd01d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-51c326bf48610be1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-d0beadf754da59b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-acd243bfbf3f6732.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/overlays/README.md +6 -0
- package/graphs/release/release-loop.yaml +33 -17
- package/graphs/units/verbs/make-doc.yaml +1 -0
- package/package.json +1 -1
- package/scripts/bench-metering-plan.ts +229 -0
- package/scripts/demo/demo1104-parallel-host.ts +56 -0
- package/scripts/demo/demo1104-parallel.ts +72 -0
- package/scripts/public-leak-baseline.txt +0 -1
- package/scripts/release-loop/docs-node.ts +4 -2
- package/scripts/release-loop/gate-image-pin.ts +116 -2
- package/scripts/release-loop/gate-node.ts +217 -25
- package/scripts/release-loop/gate-progress-sim.ts +73 -0
- package/scripts/release-loop/notes-repair.ts +18 -1
- package/scripts/release-loop/preflight.ts +188 -8
- package/scripts/release-loop/render-warm-control-manifest.ts +22 -0
- package/scripts/release-loop/resume-release.ts +9 -7
- package/scripts/release-loop/resume.ts +13 -4
- package/scripts/release-loop/warm-control-forward.ts +178 -0
- package/scripts/retro-cycle.ts +30 -8
- package/scripts/rhythm/daily.ts +4 -1
- package/scripts/rhythm/linear-progress-sync.ts +28 -15
- package/scripts/ux-sim.ts +7 -1
- package/scripts/warm-pool-provider-config.ts +6 -1
- package/src/agent-mission/grok-auth-status.ts +78 -18
- package/src/agent-mission/mission-out.ts +2 -2
- package/src/agent-substrate/pr-reviewer.ts +147 -11
- package/src/agent-substrate/self-review-cli.ts +10 -2
- package/src/auto-research/research-fanout.ts +221 -0
- package/src/auto-research/research-turn.ts +282 -36
- package/src/autopilot/mission-codebase-gate.ts +7 -3
- package/src/cli/control-cli.ts +15 -6
- package/src/cli/log-event-names.ts +8 -0
- package/src/cli/setup-keys.ts +20 -8
- package/src/cli/tui-test-cli.ts +9 -5
- package/src/control-plane/ledger.ts +42 -4
- package/src/control-plane/member-tokens.ts +25 -2
- package/src/control-plane/ports.ts +8 -3
- package/src/control-plane/server.ts +26 -5
- package/src/core-turn/research-policy.ts +7 -1
- package/src/core-turn/run-core-turn.ts +186 -39
- package/src/core-turn/types.ts +2 -0
- package/src/dashboard/classic-sidetab-mission-job.ts +113 -24
- package/src/dashboard/classic-sidetab-mission-pair.ts +3 -2
- package/src/dashboard/classic-sidetab-mission-trio.ts +35 -12
- package/src/dashboard/classic-sidetab-mission.ts +2 -0
- package/src/dashboard/index.ts +9 -1
- package/src/dashboard/sidetab-runtime.ts +2 -0
- package/src/dashboard/visible-mission-diagnostics.ts +16 -0
- package/src/domains/retro-cycle-observation.ts +43 -0
- package/src/domains/retro-cycle.ts +13 -2
- package/src/domains/retro-proposals.ts +92 -0
- package/src/domains/retro-report.ts +6 -1
- package/src/graph-runner/graph-cli.ts +24 -1
- package/src/graph-runner/graph-grow-llm.ts +3 -1
- package/src/graph-runner/runner.ts +226 -30
- package/src/harness/harness-cli-command.ts +4 -2
- package/src/harness/harness-pod-dispatch.ts +3 -0
- package/src/index.ts +2 -2
- package/src/llm/child-first-llm-observation.ts +112 -0
- package/src/llm/provider-credentials.ts +60 -4
- package/src/llm/provider-failure-evidence.ts +44 -0
- package/src/llm.ts +170 -11
- package/src/mcp/client.ts +7 -0
- package/src/mcp/proxy-runtime.ts +6 -1
- package/src/mcp/server.ts +54 -0
- package/src/native-tool-catalog.ts +2 -2
- package/src/nexus/api/consult-requests.ts +18 -6
- package/src/nexus/api/discord-trigger-bot.ts +6 -6
- package/src/nexus/api/graphs-api.ts +4 -2
- package/src/nexus/api/grokbot-trigger-bot.ts +206 -0
- package/src/nexus/api/telegram-trigger-bot.ts +6 -6
- package/src/nexus/boot/register-mcp-clients.ts +114 -8
- package/src/nexus/index.ts +15 -0
- package/src/nexus/outbound/grokbot-adapter.ts +71 -0
- package/src/nexus/outbound/router.ts +33 -13
- package/src/oauth/codex-owner-mirror.ts +47 -10
- package/src/onboarding/first-run.ts +44 -6
- package/src/preview/terminal.ts +22 -7
- package/src/prompt-enhance/enhance.ts +10 -0
- package/src/pty-shell/pty-write-provenance.ts +21 -3
- package/src/pty-shell/registry.ts +9 -2
- package/src/release-loop/proposal-auto-place.ts +83 -0
- package/src/research/axis-fanout.ts +40 -5
- package/src/research/lenses/second-order.ts +312 -0
- package/src/self-dev/dev-cli.ts +3 -1
- package/src/self-dev/draft-sweep.ts +31 -10
- package/src/self-dev/draft-triage-rules.ts +60 -3
- package/src/self-dev/run-supervisor.ts +152 -2
- package/src/self-implement/goal-author.ts +208 -23
- package/src/self-implement/graph-overlay-yaml.ts +151 -0
- package/src/self-implement/graph-yaml.ts +68 -2
- package/src/self-implement/orchestrator.ts +62 -15
- package/src/self-implement/test-scenario-request.ts +37 -6
- package/src/session/chat.ts +2 -2
- package/src/session-runtime/index.ts +37 -5
- package/src/sidetab-core/model.ts +205 -10
- package/src/sidetab-core/visible-agent-mission-pair.ts +51 -0
- package/src/sidetab-core/visible-agent-mission.ts +105 -47
- package/src/skills/tools/omni-search.ts +4 -2
- package/src/task-agent/parent-host.ts +19 -1
- package/src/task-agent/recall-inject.ts +98 -0
- package/src/task-agent/task-hand.ts +26 -7
- package/src/task-orchestrator/surfaces/pod-artifact-return.ts +19 -1
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +15 -0
- package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +21 -9
- package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +460 -96
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +45 -3
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +38 -8
- package/src/tool-hints/gate.ts +45 -14
- package/src/tool-hints/signals.ts +1 -1
- package/src/tool-hints/types.ts +2 -0
- package/src/tool-runtime/browser-hand-runtime.ts +11 -1
- package/src/tool-runtime/browser-runtime.ts +31 -18
- package/src/tool-runtime/elanous-linear-secretary-runtime.ts +152 -36
- package/src/tool-runtime/types.ts +2 -0
- package/src/tui/entry.ts +27 -7
- package/src/tui/sidetab/attach.ts +112 -0
- package/src/tui/sidetab/list.ts +3 -2
- package/src/tui-client/next-dashboard-runtime.ts +52 -0
- package/src/ux-sim/draft-inventory-builder.ts +2 -1
- package/src/ux-sim/linear-secretary.ts +4 -12
- package/src/ux-sim/mock-scenario-catalog.json +32 -29
- package/src/ux-sim/mock-scenario-catalog.ts +55 -3
- package/src/ux-sim/release-sim-rig.ts +62 -18
- package/src/ux-sim/service-key-setup.ts +63 -0
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1961.a81b12872c3e93a9.js +0 -23
- package/apps/pwa/out/_next/static/chunks/1970cf59.2d4d8ce5d6c81853.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2073-ba274e00e4f9efb4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2268-53861f339e0b65a2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +0 -90
- package/apps/pwa/out/_next/static/chunks/3095.dc44586a5f83b86d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3113.d7472bbc27d580c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +0 -1
- package/apps/pwa/out/_next/static/chunks/360.ae9f9f4c33c395e8.js +0 -79
- package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +0 -286
- package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4445.7990c76b3751a918.js +0 -115
- package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4894.fec2ca9e99caefa2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +0 -94
- package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +0 -36
- package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +0 -93
- package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5730.43d7ccc09988e646.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5824.da9527b15a3221e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +0 -27
- package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +0 -104
- package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +0 -287
- package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7483.427a2fe2049e388d.js +0 -148
- package/apps/pwa/out/_next/static/chunks/7502-be74718178e13e56.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +0 -74
- package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/868.6e953be05bcf6dca.js +0 -41
- package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8861-cc1fa1c7b920fa8e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8967-7dfebf710c9dec9d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +0 -1
- package/apps/pwa/out/_next/static/chunks/923.2034d10ae91e9c20.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +0 -1
- package/apps/pwa/out/_next/static/chunks/943.39ae5e82f4f1893f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +0 -32
- package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +0 -8
- package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-9ee28f7df07428ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-79a8b5fee4c20871.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ca2d09128c585ca4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +0 -1
- package/apps/pwa/out/_next/static/chunks/c7945435-b44d4dbe90ba0dcb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ea514caa.05a24f78d9dffe5f.js +0 -122
- package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +0 -1
- /package/apps/pwa/out/_next/static/{Om5xS9jpjSXJCeTNGYEi4 → HMXsxdy5MIIcHPMHv1wD4}/_ssgManifest.js +0 -0
package/src/mcp/server.ts
CHANGED
|
@@ -29,6 +29,7 @@ import { buildCliAgentTools } from '../cli/agent-cli.js';
|
|
|
29
29
|
import { getUserConfig } from '../user-config.js';
|
|
30
30
|
import type { TokenScope } from '../auth/scope.js';
|
|
31
31
|
import { filterToolsForScope, isToolAllowedForScope } from '../nexus/api/mcp-public-allowlist.js';
|
|
32
|
+
import { normalizeRunId } from '../harness/harness-space.js';
|
|
32
33
|
|
|
33
34
|
// ─── JSON-RPC shapes ─────────────────────────────────────────────
|
|
34
35
|
|
|
@@ -102,6 +103,30 @@ export interface McpServerContext {
|
|
|
102
103
|
tokenScope?: TokenScope;
|
|
103
104
|
}
|
|
104
105
|
|
|
106
|
+
/** Accept only an already-safe run identifier from standard MCP params._meta. */
|
|
107
|
+
function mcpRunId(params: Record<string, unknown> | undefined): string | undefined {
|
|
108
|
+
const meta = params?._meta;
|
|
109
|
+
if (!meta || typeof meta !== 'object' || Array.isArray(meta)) return undefined;
|
|
110
|
+
const value = (meta as Record<string, unknown>).elanousRunId;
|
|
111
|
+
if (typeof value !== 'string' || !/^[A-Za-z0-9_-]{1,64}$/.test(value)) return undefined;
|
|
112
|
+
const normalized = normalizeRunId(value);
|
|
113
|
+
return normalized === value ? value : undefined;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function logAsideRunIdDrop(toolName: string, params: Record<string, unknown> | undefined): void {
|
|
117
|
+
const meta = params?._meta;
|
|
118
|
+
const raw = meta && typeof meta === 'object' && !Array.isArray(meta)
|
|
119
|
+
? (meta as Record<string, unknown>).elanousRunId
|
|
120
|
+
: undefined;
|
|
121
|
+
const reason = typeof raw !== 'string'
|
|
122
|
+
? 'missing-or-non-string'
|
|
123
|
+
: !/^[A-Za-z0-9_-]{1,64}$/.test(raw)
|
|
124
|
+
? 'invalid-format'
|
|
125
|
+
: normalizeRunId(raw) !== raw ? 'not-normalized' : 'validation-rejected';
|
|
126
|
+
try { debug.log('mcp-server.aside', 'elanous-tool-call-run-id-dropped', { toolName, reason }); }
|
|
127
|
+
catch { /* observation must not block the caller */ }
|
|
128
|
+
}
|
|
129
|
+
|
|
105
130
|
/** Emit a `system.mcp.proxy_call` user-intent event for a single
|
|
106
131
|
* tool dispatch. Best-effort — sink failures swallowed upstream by
|
|
107
132
|
* `userIntentLogger.emit`, and the outer try/catch keeps the
|
|
@@ -177,8 +202,20 @@ export async function handleMcpRequest(
|
|
|
177
202
|
const args = (req.params?.arguments as Record<string, unknown>) ?? {};
|
|
178
203
|
const surface = ctx.surface ?? 'mcp';
|
|
179
204
|
const rt = getToolRuntime(name);
|
|
205
|
+
const runId = ctx.clientName === 'aside' ? mcpRunId(req.params) : undefined;
|
|
206
|
+
if (ctx.clientName === 'aside' && !runId) logAsideRunIdDrop(name, req.params);
|
|
207
|
+
const asideReturn = runId !== undefined;
|
|
180
208
|
const isExposedOnSurface = listToolRuntimes(surface).some(runtime => runtime.id === rt?.id);
|
|
181
209
|
if (!rt || !isExposedOnSurface) {
|
|
210
|
+
if (asideReturn) {
|
|
211
|
+
try {
|
|
212
|
+
debug.log('mcp-server.aside', 'elanous-tool-call', { runId, toolName: name });
|
|
213
|
+
debug.log('mcp-server.aside', 'elanous-tool-result', {
|
|
214
|
+
runId, toolName: name, ok: false,
|
|
215
|
+
errorClass: rt ? 'tool_not_exposed' : 'unknown_tool',
|
|
216
|
+
});
|
|
217
|
+
} catch { /* observation must not block the caller */ }
|
|
218
|
+
}
|
|
182
219
|
emitProxyCallIntent(name, ctx.origin, false, 'unknown_tool');
|
|
183
220
|
return {
|
|
184
221
|
...base,
|
|
@@ -186,6 +223,10 @@ export async function handleMcpRequest(
|
|
|
186
223
|
};
|
|
187
224
|
}
|
|
188
225
|
try {
|
|
226
|
+
if (asideReturn) {
|
|
227
|
+
try { debug.log('mcp-server.aside', 'elanous-tool-call', { runId, toolName: name }); }
|
|
228
|
+
catch { /* observation must not block the caller */ }
|
|
229
|
+
}
|
|
189
230
|
const isMcpAgent = surface === 'mcp' && rt.id === 'agent';
|
|
190
231
|
const agentArgs = isMcpAgent
|
|
191
232
|
? { ...args, run_in_background: args.run_in_background ?? true }
|
|
@@ -198,6 +239,7 @@ export async function handleMcpRequest(
|
|
|
198
239
|
const out = await dispatchToolByName(name, agentArgs, {
|
|
199
240
|
surface,
|
|
200
241
|
...(ctx.clientName ? { mcpClient: ctx.clientName } : {}),
|
|
242
|
+
...(runId ? { runId } : {}),
|
|
201
243
|
...(agentTools ? {
|
|
202
244
|
agentHostTools: agentTools.specs,
|
|
203
245
|
agentCwd,
|
|
@@ -212,10 +254,22 @@ export async function handleMcpRequest(
|
|
|
212
254
|
background: agentArgs.run_in_background === true,
|
|
213
255
|
});
|
|
214
256
|
}
|
|
257
|
+
if (asideReturn) {
|
|
258
|
+
const resultRecord = out && typeof out === 'object' ? out as Record<string, unknown> : {};
|
|
259
|
+
const toolOk = resultRecord.ok === false || resultRecord.isError === true
|
|
260
|
+
? false
|
|
261
|
+
: resultRecord.ok === true ? true : null;
|
|
262
|
+
try { debug.log('mcp-server.aside', 'elanous-tool-result', { runId, toolName: name, ok: toolOk }); }
|
|
263
|
+
catch { /* observation must not block the caller */ }
|
|
264
|
+
}
|
|
215
265
|
emitProxyCallIntent(name, ctx.origin, true);
|
|
216
266
|
return { ...base, result: toMcpToolCallResult(out) };
|
|
217
267
|
} catch (err) {
|
|
218
268
|
const msg = err instanceof Error ? err.message : String(err);
|
|
269
|
+
if (asideReturn) {
|
|
270
|
+
try { debug.log('mcp-server.aside', 'elanous-tool-result', { runId, toolName: name, ok: false, errorClass: err instanceof Error ? err.name : 'unknown' }); }
|
|
271
|
+
catch { /* observation must not block the caller */ }
|
|
272
|
+
}
|
|
219
273
|
emitProxyCallIntent(name, ctx.origin, false, msg);
|
|
220
274
|
throw err;
|
|
221
275
|
}
|
|
@@ -734,8 +734,8 @@ export const nativeToolCatalog: NativeToolCatalogEntry[] = [
|
|
|
734
734
|
{
|
|
735
735
|
id: 'elanous_linear_secretary',
|
|
736
736
|
kind: 'other', aliases: ['ElanousLinearSecretary'], displayName: 'ElanousLinearSecretary',
|
|
737
|
-
description: '
|
|
738
|
-
promptSummary: '`elanous_linear_secretary` (
|
|
737
|
+
description: 'DEMO-only grounded Linear secretary. Create a dated evidence-backed parent with 3–5 subtasks, record a child progress/Done transition using actual intake records and approved browser evidence, or open one local pending approval per parent. Repeated approval calls return the existing card state; no external notifications are sent.',
|
|
738
|
+
promptSummary: '`elanous_linear_secretary` (DEMO create/progress/Done/evidence/approval; approval is local and sends nothing externally)',
|
|
739
739
|
host: ['tui', 'mcp'], safety: ['mutating', 'network'], supportsParallel: false, defaultEnabled: true,
|
|
740
740
|
intentScope: 'ops-fleet',
|
|
741
741
|
},
|
|
@@ -2,9 +2,10 @@ import { closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, re
|
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { debug } from '../../debug/log.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { getUserConfig, type UserConfig } from '../../user-config.js';
|
|
6
|
+
import { roleForKind } from '../../domains/telegram-kind-route.js';
|
|
7
7
|
import { effectiveInstanceRoot } from '../../instance/resolve.js';
|
|
8
|
+
import { routeOutbound, type RouterDeps } from '../outbound/router.js';
|
|
8
9
|
import { jsonResponse } from './json-response.js';
|
|
9
10
|
|
|
10
11
|
export const CONSULT_REQUESTS_PATH = '/v1/consult-requests';
|
|
@@ -27,6 +28,8 @@ export interface ConsultRequestsDeps {
|
|
|
27
28
|
* ⛔ Never `sendOutbound` here: it is a synchronous curl to this very daemon's `/v1/outbound`, so inside the
|
|
28
29
|
* daemon it blocks the event loop until it times out (~25 s · `unreachable`) and the alert is lost (CS1 · 10-01). */
|
|
29
30
|
send?: (text: string, kind: string) => unknown;
|
|
31
|
+
/** In-process ChannelAdapter delivery seams for mock verification. */
|
|
32
|
+
routeDeps?: RouterDeps;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
function file(root: string): string {
|
|
@@ -114,12 +117,21 @@ export async function handleConsultRequests(req: Request, deps: ConsultRequestsD
|
|
|
114
117
|
const alert = `📮 상담 문의 ${entry.receiptId} · ${entry.name}(${entry.kind === 'personal' ? '개인' : (entry.org ?? '회사')}) · 관심 ${entry.interest}\n앱에서 보기`;
|
|
115
118
|
// Fire and forget — the receipt is already on disk; the answer must not wait for the channel.
|
|
116
119
|
void Promise.resolve()
|
|
117
|
-
.then(() =>
|
|
120
|
+
.then(() => deps.send ? deps.send(alert, 'ops-alert') : notifyInProcess(alert, 'ops-alert', deps.routeDeps))
|
|
118
121
|
.catch((error: unknown) => { debug.log('consult.request', 'notify-failed', { receiptId: entry.receiptId, reason: error instanceof Error ? error.message : String(error) }); });
|
|
119
122
|
return jsonResponse({ receiptId: entry.receiptId, receivedAt: entry.receivedAt }, 202);
|
|
120
123
|
}
|
|
121
124
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
function telegramOnlyConfig(cfg: UserConfig, kind: string): UserConfig {
|
|
126
|
+
// Deliberately replace all outbound policy for this one notification: it must stay Telegram-only.
|
|
127
|
+
// The existing Telegram sender resolves credentials and chat targets from cfg.telegram.
|
|
128
|
+
return { ...cfg, raw: { ...cfg.raw, outbound: { channels: [{ type: 'telegram' }], routes: { [kind]: ['telegram'] } } } };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function notifyInProcess(text: string, kind: string, routeDeps: RouterDeps = {}): Promise<void> {
|
|
132
|
+
const cfg = getUserConfig();
|
|
133
|
+
const route = await routeOutbound(telegramOnlyConfig(cfg, kind), { text, markdown: false, kind, role: roleForKind(cfg, kind) }, routeDeps);
|
|
134
|
+
debug.log('consult.request', route.delivered ? 'notified' : 'notify-failed', {
|
|
135
|
+
delivered: route.delivered, channels: route.channels.map(channel => `telegram:${channel.ok ? 'ok' : 'fail'}`),
|
|
136
|
+
});
|
|
125
137
|
}
|
|
@@ -111,9 +111,9 @@ export function createDiscordTriggerLogger(
|
|
|
111
111
|
* DiscordEvent shape. The two were intentionally kept congruent
|
|
112
112
|
* (`src/discord.ts:160-172` comment) so the wire is a near-identity
|
|
113
113
|
* with `raw` carrying the full gateway payload for debugging. */
|
|
114
|
-
export function toDiscordEvent(tap: DcTriggerEvent): DiscordEvent {
|
|
115
|
-
const envelope = receiveChannelEvent('discord', tap);
|
|
116
|
-
if (!envelope
|
|
114
|
+
export async function toDiscordEvent(tap: DcTriggerEvent): Promise<DiscordEvent> {
|
|
115
|
+
const envelope = await receiveChannelEvent('discord', tap);
|
|
116
|
+
if (!envelope) throw new Error('discord connector cannot normalize accepted tap');
|
|
117
117
|
return {
|
|
118
118
|
kind: tap.kind,
|
|
119
119
|
channel: envelope.channel ?? tap.channel,
|
|
@@ -136,10 +136,10 @@ export function buildDiscordTriggerTap(
|
|
|
136
136
|
return (tap: DcTriggerEvent): void => {
|
|
137
137
|
// Fire-and-forget — workflow dispatch errors are surfaced via the
|
|
138
138
|
// workflow daemon's lifecycle bus, not the gateway loop. Any
|
|
139
|
-
//
|
|
140
|
-
//
|
|
139
|
+
// normalization and dispatch rejections land here so the gateway
|
|
140
|
+
// loop and other accepted taps keep flowing.
|
|
141
141
|
void Promise.resolve()
|
|
142
|
-
.then(() => dispatch(toDiscordEvent(tap)))
|
|
142
|
+
.then(async () => dispatch(await toDiscordEvent(tap)))
|
|
143
143
|
.catch((err: unknown) => {
|
|
144
144
|
const reason = err instanceof Error ? err.message : String(err);
|
|
145
145
|
log(`workflow dispatch failed: ${reason}`);
|
|
@@ -207,11 +207,13 @@ function detailOf(id: string, source: 'core' | 'mine', editable: boolean, dir: s
|
|
|
207
207
|
const group = (node as { group?: unknown }).group;
|
|
208
208
|
return { node_id: nodeId, kind, recipe, max_visits: maxVisits, ...(typeof group === 'string' && group.trim() ? { group: group.trim() } : {}) };
|
|
209
209
|
}),
|
|
210
|
-
edges: spec.edges.map(({ from, to, on, map }) => ({
|
|
210
|
+
edges: spec.edges.map(({ from, to, on, map, branches, join }) => ({
|
|
211
211
|
from,
|
|
212
212
|
...(to === undefined ? {} : { to }),
|
|
213
213
|
...(on === undefined ? {} : { on }),
|
|
214
214
|
...(map === undefined ? {} : { map }),
|
|
215
|
+
...(branches === undefined ? {} : { branches }),
|
|
216
|
+
...(join === undefined ? {} : { join }),
|
|
215
217
|
})),
|
|
216
218
|
});
|
|
217
219
|
}
|
|
@@ -287,7 +289,7 @@ export function handleGraphsGet(pathname: string, dir = defaultGraphsDir(), deps
|
|
|
287
289
|
terminal_nodes: flat.terminalNodes,
|
|
288
290
|
graph_hash: graphVersionHash(flat),
|
|
289
291
|
nodes: flat.nodes.map(({ nodeId, kind, recipe, maxVisits }) => ({ node_id: nodeId, kind, recipe, max_visits: maxVisits })),
|
|
290
|
-
edges: flat.edges.map(({ from, to, on, map, fallback }) => ({ from, ...(to === undefined ? {} : { to }), ...(on === undefined ? {} : { on }), ...(map === undefined ? {} : { map }), ...(fallback === undefined ? {} : { fallback }) })),
|
|
292
|
+
edges: flat.edges.map(({ from, to, on, map, fallback, branches, join }) => ({ from, ...(to === undefined ? {} : { to }), ...(on === undefined ? {} : { on }), ...(map === undefined ? {} : { map }), ...(fallback === undefined ? {} : { fallback }), ...(branches === undefined ? {} : { branches }), ...(join === undefined ? {} : { join }) })),
|
|
291
293
|
});
|
|
292
294
|
} catch (error) {
|
|
293
295
|
return jsonResponse({ error: 'unit-flatten-failed', id, message: error instanceof Error ? error.message : String(error) }, 422);
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { debug } from '../../debug/log.js';
|
|
3
|
+
import { receiveChannelEvent } from '../outbound/router.js';
|
|
4
|
+
import { registerGrokbotAdapter } from '../outbound/grokbot-adapter.js';
|
|
5
|
+
import { createSession, listSessions } from '../../session/index.js';
|
|
6
|
+
import type { UserConfig } from '../../user-config.js';
|
|
7
|
+
import type { runTurn } from '../../session/chat.js';
|
|
8
|
+
import type { ChannelEnvelope } from '../outbound/router.js';
|
|
9
|
+
|
|
10
|
+
const DEFAULT_AGENT = 'COO';
|
|
11
|
+
const DEFAULT_POLL_INTERVAL_MS = 15_000;
|
|
12
|
+
const MAX_MESSAGE_BYTES = 64 * 1024;
|
|
13
|
+
|
|
14
|
+
export interface GrokbotPendingMessage {
|
|
15
|
+
id: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface GrokbotMailbox {
|
|
19
|
+
listPending(): Promise<GrokbotPendingMessage[]>;
|
|
20
|
+
/** Atomically move a pending request into processing; null means another consumer claimed it. */
|
|
21
|
+
claim(id: string): Promise<string | null>;
|
|
22
|
+
acknowledge(id: string, text: string): Promise<void>;
|
|
23
|
+
complete(id: string, text: string): Promise<void>;
|
|
24
|
+
sendPrompt(agent: string, prompt: string): Promise<{ preview?: string }>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface NexusGrokbotTriggerBotOptions {
|
|
28
|
+
mailbox: GrokbotMailbox;
|
|
29
|
+
dispatch: (event: ChannelEnvelope) => Promise<string>;
|
|
30
|
+
pollIntervalMs?: number;
|
|
31
|
+
now?: () => string;
|
|
32
|
+
log?: (event: string, data: Record<string, unknown>) => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const GROKBOT_SESSION_CHAT_ID = -707151151;
|
|
36
|
+
const GROKBOT_SESSION_BOT_ID = 'grokbot-coo';
|
|
37
|
+
|
|
38
|
+
function grokbotMainSessionId(): string {
|
|
39
|
+
const existing = listSessions().find((session) => session.origin === 'grokbot' && session.personaId === 'grokbot-coo');
|
|
40
|
+
if (existing) return existing.id;
|
|
41
|
+
return createSession({
|
|
42
|
+
source: 'cli', sourceKind: 'telegram', origin: 'grokbot', personaId: 'grokbot-coo',
|
|
43
|
+
title: 'Grok Bot COO · 주 세션',
|
|
44
|
+
}).id;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Reuse one durable main-agent session for the bot's conversation across requests and restarts. */
|
|
48
|
+
export function createGrokbotMainSessionDispatcher(
|
|
49
|
+
userConfig: UserConfig,
|
|
50
|
+
runTurnImpl: typeof runTurn,
|
|
51
|
+
getSessionId: () => string = grokbotMainSessionId,
|
|
52
|
+
): (event: ChannelEnvelope) => Promise<string> {
|
|
53
|
+
const sessionId = getSessionId();
|
|
54
|
+
return async (event) => {
|
|
55
|
+
const result = await runTurnImpl({
|
|
56
|
+
userConfig,
|
|
57
|
+
sessionId,
|
|
58
|
+
userText: event.text,
|
|
59
|
+
utteranceSurface: 'telegram',
|
|
60
|
+
tgChat: { botId: GROKBOT_SESSION_BOT_ID, chatId: GROKBOT_SESSION_CHAT_ID },
|
|
61
|
+
});
|
|
62
|
+
return result.text;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface NexusGrokbotTriggerBotHandle {
|
|
67
|
+
pollOnce(): Promise<void>;
|
|
68
|
+
start(): void;
|
|
69
|
+
stop(): Promise<void>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function safeReason(error: unknown): string {
|
|
73
|
+
const text = error instanceof Error ? error.message : String(error);
|
|
74
|
+
return text.replace(/Bearer\s+\S+/gi, 'Bearer [redacted]').slice(0, 240);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function validId(id: string): boolean {
|
|
78
|
+
return /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/.test(id);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function runRemote(script: string, timeoutMs = 20_000): Promise<string> {
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
const child = spawn('ssh', ['-o', 'BatchMode=yes', 'box@grbot-coo', 'bash -s'], { stdio: ['pipe', 'pipe', 'ignore'] });
|
|
84
|
+
let stdout = '';
|
|
85
|
+
const timeout = setTimeout(() => child.kill('SIGTERM'), timeoutMs);
|
|
86
|
+
child.stdout.setEncoding('utf8');
|
|
87
|
+
child.stdout.on('data', (chunk: string) => { stdout += chunk; });
|
|
88
|
+
child.on('error', () => { clearTimeout(timeout); reject(new Error('grokbot transport unavailable')); });
|
|
89
|
+
child.on('close', (code) => {
|
|
90
|
+
clearTimeout(timeout);
|
|
91
|
+
if (code === 0) resolve(stdout.trimEnd());
|
|
92
|
+
else reject(new Error('grokbot transport failed'));
|
|
93
|
+
});
|
|
94
|
+
child.stdin.end(script);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function encoded(value: string): string {
|
|
99
|
+
const bytes = Buffer.from(value, 'utf8');
|
|
100
|
+
if (bytes.byteLength > MAX_MESSAGE_BYTES) throw new Error('grokbot message exceeds 64 KiB');
|
|
101
|
+
return bytes.toString('base64');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function remoteWrite(relativePath: string, value: string): string {
|
|
105
|
+
if (!/^[A-Za-z0-9_./-]+$/.test(relativePath)) throw new Error('invalid grokbot output path');
|
|
106
|
+
const body = encoded(value);
|
|
107
|
+
const target = `"$HOME/${relativePath}"`;
|
|
108
|
+
return `set -eu\nmkdir -p "$(dirname ${target})"\nprintf '%s' '${body}' | base64 -d > ${target}\n`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** SSH-only transport to the COO bot host. The gateway credential remains on that host. */
|
|
112
|
+
export function createSshGrokbotMailbox(): GrokbotMailbox {
|
|
113
|
+
return {
|
|
114
|
+
async listPending() {
|
|
115
|
+
const output = await runRemote(`set -eu\nfor f in "$HOME"/elanous-inbox/*.txt; do\n [ -f "$f" ] || continue\n b=\${f##*/}; printf '%s\\n' "\${b%.txt}"\ndone\n`);
|
|
116
|
+
return output.split('\n').filter(validId).map((id) => ({ id }));
|
|
117
|
+
},
|
|
118
|
+
async claim(id) {
|
|
119
|
+
if (!validId(id)) throw new Error('invalid grokbot request id');
|
|
120
|
+
const output = await runRemote(`set -eu\nroot="$HOME/elanous-inbox"\nmkdir -p "$root/processing"\nsrc="$root/${id}.txt"\ndst="$root/processing/${id}.txt"\n[ -f "$src" ] || exit 3\n[ ! -e "$dst" ] || exit 4\nmv "$src" "$dst"\nbase64 "$dst" | tr -d '\\n'\n`);
|
|
121
|
+
return Buffer.from(output, 'base64').toString('utf8');
|
|
122
|
+
},
|
|
123
|
+
async acknowledge(id, text) {
|
|
124
|
+
if (!validId(id)) throw new Error('invalid grokbot request id');
|
|
125
|
+
await runRemote(`${remoteWrite(`elanous-outbox/${id}.ack`, text)}printf '%s\\n' "$(date -Is)" >> "$HOME/elanous-inbox/processing/${id}.accepted"\n`);
|
|
126
|
+
},
|
|
127
|
+
async complete(id, text) {
|
|
128
|
+
if (!validId(id)) throw new Error('invalid grokbot request id');
|
|
129
|
+
await runRemote(`${remoteWrite(`elanous-outbox/${id}.md`, text)}mkdir -p "$HOME/elanous-inbox/done"\nif [ -f "$HOME/elanous-inbox/processing/${id}.txt" ]; then mv "$HOME/elanous-inbox/processing/${id}.txt" "$HOME/elanous-inbox/done/${id}.txt"; fi\n`);
|
|
130
|
+
},
|
|
131
|
+
async sendPrompt(agent, prompt) {
|
|
132
|
+
if (agent !== DEFAULT_AGENT) throw new Error('grokbot agent is not allowlisted');
|
|
133
|
+
const body = encoded(prompt);
|
|
134
|
+
const script = `set -eu\ntoken=$(jq -er '.token | strings | select(length > 0)' "$HOME/sand-data/gateway.json")\nagent=$(curl -fsS -m 15 -X POST http://127.0.0.1:1340/api/listAgents -H 'Content-Type: application/json' -H "Authorization: Bearer $token" -d '{}' | jq -er '.[] | select(.name == "COO") | .id' | head -n 1)\n[ -n "$agent" ]\nprintf '%s' '${body}' | base64 -d | jq -Rs --arg agentId "$agent" '{agentId:$agentId,prompt:.}' | curl -fsS -m 30 -X POST http://127.0.0.1:1340/api/sendPrompt -H 'Content-Type: application/json' -H "Authorization: Bearer $token" --data-binary @- | jq -c '{preview:(.lastMessagePreview // .preview // "")}'\n`;
|
|
135
|
+
const response = await runRemote(script, 45_000);
|
|
136
|
+
const parsed = JSON.parse(response) as { preview?: unknown };
|
|
137
|
+
return { ...(typeof parsed.preview === 'string' && parsed.preview ? { preview: parsed.preview } : {}) };
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function createNexusGrokbotTriggerBot(options: NexusGrokbotTriggerBotOptions): NexusGrokbotTriggerBotHandle {
|
|
143
|
+
const now = options.now ?? (() => new Date().toISOString());
|
|
144
|
+
const log = options.log ?? ((event, data) => debug.log('channel.grokbot', event, data));
|
|
145
|
+
const unregister = registerGrokbotAdapter({
|
|
146
|
+
sendPrompt: (agent, prompt) => options.mailbox.sendPrompt(agent, prompt),
|
|
147
|
+
now,
|
|
148
|
+
log,
|
|
149
|
+
});
|
|
150
|
+
let stopped = false;
|
|
151
|
+
let polling = false;
|
|
152
|
+
let timer: ReturnType<typeof setInterval> | undefined;
|
|
153
|
+
let currentPoll: Promise<void> | undefined;
|
|
154
|
+
|
|
155
|
+
const pollOnce = async (): Promise<void> => {
|
|
156
|
+
if (stopped || polling) return currentPoll;
|
|
157
|
+
polling = true;
|
|
158
|
+
currentPoll = (async () => {
|
|
159
|
+
try {
|
|
160
|
+
const messages = await options.mailbox.listPending();
|
|
161
|
+
for (const { id } of messages) {
|
|
162
|
+
if (stopped) break;
|
|
163
|
+
let text: string | null;
|
|
164
|
+
try { text = await options.mailbox.claim(id); }
|
|
165
|
+
catch (error) { log('failure', { id, failedAt: now(), reason: safeReason(error), stage: 'claim' }); continue; }
|
|
166
|
+
if (text === null) continue;
|
|
167
|
+
try {
|
|
168
|
+
const kind = /^(승인|보류|수정)(?:\s|[::]|$)/.test(text.trim()) ? 'decision' : 'request';
|
|
169
|
+
const envelope = await receiveChannelEvent('grokbot', { id, text, kind });
|
|
170
|
+
if (!envelope || envelope instanceof Promise) throw new Error('grokbot request normalization failed');
|
|
171
|
+
await options.mailbox.acknowledge(id, 'OP 접수 — 답을 준비 중입니다.');
|
|
172
|
+
const reply = await options.dispatch(envelope);
|
|
173
|
+
if (!reply.trim()) throw new Error('main session returned an empty reply');
|
|
174
|
+
await options.mailbox.complete(id, reply);
|
|
175
|
+
log('reply', { id, repliedAt: now(), replyChars: reply.length });
|
|
176
|
+
} catch (error) {
|
|
177
|
+
const reason = safeReason(error);
|
|
178
|
+
log('failure', { id, failedAt: now(), reason, stage: 'dispatch-or-reply' });
|
|
179
|
+
try { await options.mailbox.complete(id, '요청을 처리하지 못했습니다. 주 세션 연결과 eln logs의 channel.grokbot 기록을 확인해 주세요.'); }
|
|
180
|
+
catch (replyError) { log('failure', { id, failedAt: now(), reason: safeReason(replyError), stage: 'failure-reply' }); }
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
} catch (error) {
|
|
184
|
+
log('failure', { failedAt: now(), reason: safeReason(error), stage: 'poll' });
|
|
185
|
+
}
|
|
186
|
+
})().finally(() => { polling = false; });
|
|
187
|
+
return currentPoll;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
pollOnce,
|
|
192
|
+
start() {
|
|
193
|
+
if (stopped || timer) return;
|
|
194
|
+
void pollOnce();
|
|
195
|
+
timer = setInterval(() => { void pollOnce(); }, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);
|
|
196
|
+
timer.unref?.();
|
|
197
|
+
},
|
|
198
|
+
async stop() {
|
|
199
|
+
stopped = true;
|
|
200
|
+
if (timer) clearInterval(timer);
|
|
201
|
+
timer = undefined;
|
|
202
|
+
await currentPoll;
|
|
203
|
+
unregister();
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
}
|
|
@@ -123,9 +123,9 @@ export function createTelegramTriggerLogger(
|
|
|
123
123
|
* TelegramEvent shape. Congruent fields (`src/telegram.ts:166-180`
|
|
124
124
|
* comment) so the wire is a near-identity with `raw` carrying the
|
|
125
125
|
* full payload (messageId · isDm) for debugging. */
|
|
126
|
-
export function toTelegramEvent(tap: TgTriggerEvent): TelegramEvent {
|
|
127
|
-
const envelope = receiveChannelEvent('telegram', tap);
|
|
128
|
-
if (!envelope
|
|
126
|
+
export async function toTelegramEvent(tap: TgTriggerEvent): Promise<TelegramEvent> {
|
|
127
|
+
const envelope = await receiveChannelEvent('telegram', tap);
|
|
128
|
+
if (!envelope) throw new Error('telegram connector cannot normalize accepted tap');
|
|
129
129
|
return {
|
|
130
130
|
kind: tap.kind,
|
|
131
131
|
chat: envelope.channel ?? tap.chat,
|
|
@@ -149,10 +149,10 @@ export function buildTelegramTriggerTap(
|
|
|
149
149
|
return (tap: TgTriggerEvent): void => {
|
|
150
150
|
// Fire-and-forget — workflow dispatch errors surface via the
|
|
151
151
|
// workflow daemon's lifecycle bus, not the polling loop. Any
|
|
152
|
-
//
|
|
153
|
-
//
|
|
152
|
+
// normalization and dispatch rejections land here so the polling
|
|
153
|
+
// loop and other accepted taps keep flowing.
|
|
154
154
|
void Promise.resolve()
|
|
155
|
-
.then(() => dispatch(toTelegramEvent(tap)))
|
|
155
|
+
.then(async () => dispatch(await toTelegramEvent(tap)))
|
|
156
156
|
.catch((err: unknown) => {
|
|
157
157
|
const reason = err instanceof Error ? err.message : String(err);
|
|
158
158
|
log(`workflow dispatch failed: ${reason}`);
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
// daemon exit.
|
|
29
29
|
|
|
30
30
|
import type { McpServerSpec } from '../../user-config.js';
|
|
31
|
-
import { McpClient, McpConnectionError, type McpTool, type McpToolCallResult } from '../../mcp/client.js';
|
|
31
|
+
import { McpClient, McpConnectionError, type McpCallMeta, type McpTool, type McpToolCallResult } from '../../mcp/client.js';
|
|
32
32
|
import {
|
|
33
33
|
createMcpProxyRuntime,
|
|
34
34
|
createMcpToolAuthorizer,
|
|
@@ -41,7 +41,8 @@ import { listNodeKinds } from '../../graph-kinds/registry.js';
|
|
|
41
41
|
import { syncInstalledPluginNodes } from '../../graph-kinds/installed-plugin-nodes.js';
|
|
42
42
|
import { listInstalledPlugins } from '../../plugins/install/plugin-install.js';
|
|
43
43
|
import { pluginEnv, credentialStatus } from '../../plugins/install/plugin-credentials.js';
|
|
44
|
-
import {
|
|
44
|
+
import { getHarnessRunId } from '../../harness/harness-space.js';
|
|
45
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
|
|
45
46
|
import { join, resolve, sep } from 'node:path';
|
|
46
47
|
|
|
47
48
|
export interface McpClientsHandle {
|
|
@@ -143,6 +144,8 @@ export interface RegisterMcpClientsOpts {
|
|
|
143
144
|
toolIndexStore?: McpToolIndexStore;
|
|
144
145
|
/** `lazy` 자식의 SIGTERM→SIGKILL 유예(ms). 기본 2500 — 종료 3초 계약 안쪽. */
|
|
145
146
|
lazyShutdownGraceMs?: number;
|
|
147
|
+
/** BROWSER-ROUNDTRIP-ASIDE test seam; production defaults to the state-root JSONL ledger. */
|
|
148
|
+
asideLedger?: AsideRoundtripLedger;
|
|
146
149
|
}
|
|
147
150
|
|
|
148
151
|
/** 한 서버가 지난 부팅에서 알린 툴 목록. `mcp-tool-index.json` 의 값. */
|
|
@@ -156,6 +159,77 @@ export interface McpToolIndexStore {
|
|
|
156
159
|
|
|
157
160
|
export const MCP_TOOL_INDEX_FILENAME = 'mcp-tool-index.json';
|
|
158
161
|
|
|
162
|
+
export interface AsideRoundtripEntry {
|
|
163
|
+
runId: string;
|
|
164
|
+
phase: 'call' | 'result';
|
|
165
|
+
toolName: string;
|
|
166
|
+
/** null means the caller did not provide a reason; do not invent one. */
|
|
167
|
+
reason: string | null;
|
|
168
|
+
at: string;
|
|
169
|
+
ok?: boolean;
|
|
170
|
+
classification?: string;
|
|
171
|
+
outputLength?: number;
|
|
172
|
+
errorClass?: string;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export interface AsideRoundtripLedger {
|
|
176
|
+
append(entry: AsideRoundtripEntry): void;
|
|
177
|
+
list(runId: string): AsideRoundtripEntry[];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const ASIDE_RUN_LEDGER_FILENAME = 'aside-run-roundtrip.jsonl';
|
|
181
|
+
|
|
182
|
+
/** Persist only the run join and result receipt metadata, never prompt/result contents. */
|
|
183
|
+
export function defaultAsideRoundtripLedger(root: string = elanousStateRoot()): AsideRoundtripLedger {
|
|
184
|
+
const file = join(root, ASIDE_RUN_LEDGER_FILENAME);
|
|
185
|
+
return {
|
|
186
|
+
append(entry) {
|
|
187
|
+
try {
|
|
188
|
+
mkdirSync(root, { recursive: true });
|
|
189
|
+
appendFileSync(file, `${JSON.stringify(entry)}\n`, 'utf8');
|
|
190
|
+
} catch (error) {
|
|
191
|
+
try { debug.log('mcp-client.aside', 'ledger-append-failed', { errorClass: error instanceof Error ? error.name : 'unknown' }); }
|
|
192
|
+
catch { /* a ledger failure must not block the MCP call */ }
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
list(runId) {
|
|
196
|
+
try {
|
|
197
|
+
return readFileSync(file, 'utf8').split('\n').flatMap((line) => {
|
|
198
|
+
if (!line.trim()) return [];
|
|
199
|
+
try {
|
|
200
|
+
const row = JSON.parse(line) as AsideRoundtripEntry;
|
|
201
|
+
return row && row.runId === runId && (row.phase === 'call' || row.phase === 'result') ? [row] : [];
|
|
202
|
+
} catch { return []; }
|
|
203
|
+
});
|
|
204
|
+
} catch { return []; }
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function asideReason(args: Record<string, unknown>): string | null {
|
|
210
|
+
const raw = args.reason;
|
|
211
|
+
return typeof raw === 'string' && raw.trim().length > 0
|
|
212
|
+
? redactSecretText(raw.trim()).slice(0, 240)
|
|
213
|
+
: null;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function asidePrompt(args: Record<string, unknown>, runId: string, reason: string | null): Record<string, unknown> {
|
|
217
|
+
if (typeof args.prompt !== 'string') return args;
|
|
218
|
+
const joinLine = `elanous 런 ${runId} · 결과는 elanous 도구로 돌려라.`;
|
|
219
|
+
if (args.prompt.includes(joinLine)) return args;
|
|
220
|
+
const instructions = [
|
|
221
|
+
joinLine,
|
|
222
|
+
...(reason ? [`Delegation reason: ${reason}.`] : []),
|
|
223
|
+
'Use TaskGet to load this run’s task context, then return findings through Elanous MCP tools to the same runId. Keep browser credentials in the browser.',
|
|
224
|
+
].join(' ');
|
|
225
|
+
return { ...args, prompt: `${instructions}\n\n${args.prompt}` };
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function asideTextLength(result: McpToolCallResult): number {
|
|
229
|
+
return (result.content ?? []).reduce((length, block) =>
|
|
230
|
+
block.type === 'text' && typeof block.text === 'string' ? length + block.text.length : length, 0);
|
|
231
|
+
}
|
|
232
|
+
|
|
159
233
|
/** 지연 기동 자식의 정리 유예. `McpClient` 기본 5000ms 는 「SIGTERM 3초 안에
|
|
160
234
|
* 안 끝남」이던 classic 종료 계약을 넘긴다 — 2500ms 면 SIGKILL 까지 3초 안쪽. */
|
|
161
235
|
const DEFAULT_LAZY_SHUTDOWN_GRACE_MS = 2500;
|
|
@@ -209,11 +283,11 @@ class DeferredMcpClient implements DeferredInner {
|
|
|
209
283
|
return this.inner.listTools();
|
|
210
284
|
}
|
|
211
285
|
|
|
212
|
-
async callTool(name: string, args: Record<string, unknown
|
|
286
|
+
async callTool(name: string, args: Record<string, unknown>, meta?: McpCallMeta): Promise<McpToolCallResult> {
|
|
213
287
|
await this.ensureStarted();
|
|
214
288
|
// ⚠️ 기동 «뒤»의 inner.callTool 을 부른다 — 자격증명 마스킹 래퍼가
|
|
215
289
|
// createClient 직후 client.callTool 에 씌워지므로 그 래퍼를 탄다.
|
|
216
|
-
return this.inner.callTool(name, args);
|
|
290
|
+
return this.inner.callTool(name, args, meta);
|
|
217
291
|
}
|
|
218
292
|
|
|
219
293
|
async dispose(): Promise<void> {
|
|
@@ -259,6 +333,8 @@ export async function registerMcpClients(
|
|
|
259
333
|
// A boot owns its ledger: same configured ids in concurrent/restarted boots
|
|
260
334
|
// cannot inherit grants or revoke one another's authorization lifetime.
|
|
261
335
|
const authorizer = createMcpToolAuthorizer();
|
|
336
|
+
let asideLedger = opts.asideLedger;
|
|
337
|
+
const asideLedgerFor = (): AsideRoundtripLedger => (asideLedger ??= defaultAsideRoundtripLedger());
|
|
262
338
|
// FU3 (2026-05-13) — pipe McpClient lifecycle events into elanous's
|
|
263
339
|
// keytrace logger so `mcp.client.spawn / .ready / .exit / .parse-error
|
|
264
340
|
// / .stderr` all land in the daemon's debug log. Without this hook
|
|
@@ -420,14 +496,44 @@ export async function registerMcpClients(
|
|
|
420
496
|
let client: McpClient | undefined;
|
|
421
497
|
try {
|
|
422
498
|
client = createClient(spec) as McpClient;
|
|
423
|
-
if (!opts.createClient
|
|
499
|
+
if (spec.transport === 'stdio' && (!opts.createClient || spec.id === 'aside')) {
|
|
424
500
|
const originalCallTool = client.callTool.bind(client);
|
|
425
|
-
client.callTool = async (name: string, args: Record<string, unknown
|
|
426
|
-
|
|
501
|
+
client.callTool = async (name: string, args: Record<string, unknown>, meta?: McpCallMeta): Promise<McpToolCallResult> => {
|
|
502
|
+
// Aside test clients use this same invocation boundary but bypass production credential injection.
|
|
503
|
+
const values = opts.createClient ? [] : injectedValuesByServer.get(spec.id) ?? [];
|
|
504
|
+
const isAsideExec = spec.id === 'aside' && name === 'exec';
|
|
505
|
+
const runId = isAsideExec ? (meta?.elanousRunId ?? getHarnessRunId()).trim() : '';
|
|
506
|
+
const reason = isAsideExec ? asideReason(args) : null;
|
|
507
|
+
const ledger = isAsideExec && runId ? asideLedgerFor() : undefined;
|
|
508
|
+
const now = () => new Date().toISOString();
|
|
509
|
+
const appendReceipt = (entry: AsideRoundtripEntry) => {
|
|
510
|
+
if (!ledger || !runId) return;
|
|
511
|
+
try { ledger.append(entry); } catch { /* bookkeeping must not block an MCP call */ }
|
|
512
|
+
};
|
|
513
|
+
const callArgs = isAsideExec && runId ? asidePrompt(args, runId, reason) : args;
|
|
514
|
+
if (isAsideExec && runId) {
|
|
515
|
+
try { debug.log('mcp-client.aside', 'exec-request', { runId, reason, toolName: name }); }
|
|
516
|
+
catch { /* observability is best-effort */ }
|
|
517
|
+
appendReceipt({ runId, phase: 'call', toolName: name, reason, at: now() });
|
|
518
|
+
}
|
|
427
519
|
try {
|
|
428
|
-
const result = await originalCallTool(name,
|
|
520
|
+
const result = await originalCallTool(name, callArgs, meta);
|
|
521
|
+
if (isAsideExec && runId) {
|
|
522
|
+
const isError = result.isError === true;
|
|
523
|
+
const classification = isError ? 'mcp-server-error' : undefined;
|
|
524
|
+
const outputLength = asideTextLength(result);
|
|
525
|
+
appendReceipt({ runId, phase: 'result', toolName: name, reason, at: now(), ok: !isError, ...(classification ? { classification } : {}), outputLength });
|
|
526
|
+
try { debug.log('mcp-client.aside', 'exec-result', { runId, reason, toolName: name, ok: !isError, ...(classification ? { classification } : {}), isError, outputLength }); }
|
|
527
|
+
catch { /* observability is best-effort */ }
|
|
528
|
+
}
|
|
429
529
|
return maskInjectedValues(result, values) as McpToolCallResult;
|
|
430
530
|
} catch (err) {
|
|
531
|
+
if (isAsideExec && runId) {
|
|
532
|
+
const errorClass = err instanceof Error ? err.name : 'unknown';
|
|
533
|
+
appendReceipt({ runId, phase: 'result', toolName: name, reason, at: now(), ok: false, classification: 'mcp-transport-error', errorClass });
|
|
534
|
+
try { debug.log('mcp-client.aside', 'exec-error', { runId, reason, toolName: name, callToolRejected: true, errorClass }); }
|
|
535
|
+
catch { /* observability is best-effort */ }
|
|
536
|
+
}
|
|
431
537
|
if (err instanceof Error) err.message = redactValues(err.message, values);
|
|
432
538
|
else throw new Error(redactValues(String(err), values));
|
|
433
539
|
throw err;
|