elanous 0.2.41 → 0.2.43
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/{GiOLWmt4MqDZePubBjA4Q → Om5xS9jpjSXJCeTNGYEi4}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/{2fe2c302.41b517f88d6fe502.js → 0966f8a1.745fcd44f64a87ea.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{385e4574.e9886ab32759eda3.js → 0ad6802e.ae7afb63fdcb4491.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1200.6a37c202f9f17e9a.js +226 -0
- package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1313-19f737e0222c4444.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6874.d5cf7eb8edb2cabe.js → 1406.a1dc2ab6f8449374.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5744.b9415e18ad623100.js → 1961.a81b12872c3e93a9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1970cf59.2d4d8ce5d6c81853.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2073-ba274e00e4f9efb4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5471.1e611302ed3a7c53.js → 2144.25b292396712196d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{3230-49298c3b73ef2268.js → 2268-53861f339e0b65a2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9834.63ab2bbc3153172e.js → 2312.0c8b61e22d3136d7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1800.f7ff51dc4978a958.js → 2573.387a707f6f9d720c.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9048.212083de42d25be3.js → 3072.01338851ca21a6f7.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +90 -0
- package/apps/pwa/out/_next/static/chunks/3095.dc44586a5f83b86d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2263.e09b6edea33bad2d.js → 3113.d7472bbc27d580c7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3402.44b565b314f2263c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{addc2b32.8c4ff8f0aefe987d.js → 3557ac4a.c8931684475018ad.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/360.ae9f9f4c33c395e8.js +79 -0
- package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +286 -0
- package/apps/pwa/out/_next/static/chunks/{a0a01613.6d1cca322238d7fe.js → 363bfab3.9623b9f89363541f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3694.e0099884345f0198.js +64 -0
- package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3903.3ef4656c67572764.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3935.16701e33f8982dc9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3955.6922286237f2ac2b.js +24 -0
- package/apps/pwa/out/_next/static/chunks/3969.272ee7f9fd6c62e5.js +34 -0
- package/apps/pwa/out/_next/static/chunks/4199.ce86b281fd0a60b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{530.d26346e18089640a.js → 4445.7990c76b3751a918.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4894.fec2ca9e99caefa2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +94 -0
- package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +36 -0
- package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +93 -0
- package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1219.7e17964e0e7cd8e5.js → 5564.9e72532188f57586.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5628.6ddb2d5ffba4ff4c.js +309 -0
- package/apps/pwa/out/_next/static/chunks/5730.43d7ccc09988e646.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1178.1aa9cad0e7695427.js → 5789.2da35c258292e1e5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4133.2056bb4d78f621af.js → 5824.da9527b15a3221e5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5866.366966af47fdde5d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4527.a69f2894d1bc9f4a.js → 5930.8b4df3b46c32b05a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +27 -0
- package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +104 -0
- package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +287 -0
- package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9507.7026657a2f47eb64.js → 6540.c7bef57ad8f90a87.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5574.f35accf4f132b29d.js → 6944.309f4e3ea54d1537.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7483.427a2fe2049e388d.js +148 -0
- package/apps/pwa/out/_next/static/chunks/7502-be74718178e13e56.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7900.096f455c7c1efc53.js +77 -0
- package/apps/pwa/out/_next/static/chunks/7910-6f139bcafd238b9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5947-135e26537d80a6b9.js → 8062-7cd0bcc7f01455ba.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +74 -0
- package/apps/pwa/out/_next/static/chunks/8205.282ca4bb62d54a0a.js +62 -0
- package/apps/pwa/out/_next/static/chunks/8313-dfa1021bb58a46d6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/837-81336ebaca8198a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8588.d1c6a2903727ce87.js +149 -0
- package/apps/pwa/out/_next/static/chunks/8637.90f92d5c8db4732c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2743.5d3f76948be32b34.js → 868.6e953be05bcf6dca.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5964-7e21164a8f2cf0ce.js → 8861-cc1fa1c7b920fa8e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8967-7dfebf710c9dec9d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5159.115f1c2ca471386c.js → 8986.8e2e4efbfa655c59.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +1 -0
- package/apps/pwa/out/_next/static/chunks/923.2034d10ae91e9c20.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +1 -0
- package/apps/pwa/out/_next/static/chunks/943.39ae5e82f4f1893f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +32 -0
- package/apps/pwa/out/_next/static/chunks/9770.5f75bc6088b16109.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +8 -0
- package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b2271e54.c1de3347976e90b0.js → aa57532f.510551854ff239b1.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-9ee28f7df07428ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-40f9e19149024298.js → page-79a8b5fee4c20871.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-a142dfb0331a05f5.js → page-ca2d09128c585ca4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-0a815f34367b6db6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{53aeb4ee-51c92f8d683f5220.js → c7945435-b44d4dbe90ba0dcb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2fdf2931.b431eee4fb468bc3.js → cb0f8df8.09a4a6be97e3fc5f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{c0c1a699.0ba79f97005965d4.js → d96660fb.cbc21a2a88539dbb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/ea514caa.05a24f78d9dffe5f.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{83184dcd-0ee6247ff41eb3f2.js → fb7d20d5-6892502b6ee39ca6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +1 -0
- package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
- package/apps/pwa/out/_next/static/css/d1f8bb401740a549.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +24 -25
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +23 -23
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +24 -25
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +24 -25
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/catalog/external-commands.yaml +5 -3
- package/catalog/meta/catalogVersion.yaml +2 -1
- package/catalog/signing/catalog-signing-public.pem +3 -0
- package/docs/goal-context/04-mock-scenarios.md +13 -0
- package/graphs/catalog/catalog.yaml +1 -1
- package/graphs/heal/heal-loop.yaml +1 -0
- package/graphs/intake/intake-daily.yaml +16 -0
- package/graphs/intake/news-sources.yaml +1 -0
- package/graphs/intake/recipes.yaml +7 -0
- package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
- package/graphs/overlays/stop-heal-ladder.yaml +113 -0
- package/graphs/profiles/local.yaml +5 -0
- package/graphs/profiles/pod.yaml +4 -0
- package/graphs/units/verbs/recipes.yaml +11 -11
- package/graphs/work/research-report.yaml +10 -2
- package/package.json +6 -2
- package/plugins/demo-absorption-briefing/plugin.json +18 -0
- package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
- package/plugins/demo-browser-hand/plugin.json +13 -0
- package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
- package/plugins/demo-linear-secretary/plugin.json +15 -0
- package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
- package/plugins/demo-plugin-wizard/plugin.json +11 -0
- package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
- package/plugins/demo-research/plugin.json +16 -0
- package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
- package/plugins/demo-video-briefing/plugin.json +15 -0
- package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
- package/scripts/build-signed-catalog.ts +48 -0
- package/scripts/ci-typecheck-main-delta.sh +88 -0
- package/scripts/codex-fallback-live-probe.ts +1 -1
- package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
- package/scripts/demo/demo1104-stage.config.ts +21 -0
- package/scripts/demo/demo1104-stage.ts +316 -0
- package/scripts/goal-method-audit.ts +17 -1
- package/scripts/graph-units/land-enqueue.ts +90 -0
- package/scripts/heal/run-role.ts +99 -5
- package/scripts/hooks/codex-notify.sh +32 -0
- package/scripts/install.sh +10 -38
- package/scripts/land-global-checks.ts +6 -1
- package/scripts/landing-heal/land-plan.ts +57 -0
- package/scripts/lib/decompose-ab.ts +1 -0
- package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
- package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
- package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
- package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
- package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
- package/scripts/lib/tui-regress-checks.ts +33 -13
- package/scripts/release-loop/auto-approve-node.ts +1 -1
- package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
- package/scripts/release-loop/gate-baseline-receipt.ts +47 -9
- package/scripts/release-loop/gate-image-pin.ts +81 -0
- package/scripts/release-loop/gate-method.ts +139 -0
- package/scripts/release-loop/gate-node-sim.ts +207 -0
- package/scripts/release-loop/gate-node.ts +463 -64
- package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
- package/scripts/release-loop/gate-radius-live.ts +97 -13
- package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
- package/scripts/release-loop/gate-traffic-mode.ts +151 -3
- package/scripts/release-loop/gate-train-receipts.ts +122 -0
- package/scripts/release-loop/node-verdict.ts +38 -25
- package/scripts/release-loop/preflight.ts +362 -8
- package/scripts/release-loop/resume-release.ts +83 -8
- package/scripts/release-loop/unattended-release.ts +20 -9
- package/scripts/rhythm/daily.ts +36 -4
- package/scripts/rhythm/linear-progress-sync.ts +298 -0
- package/scripts/ux-sim.ts +18 -1
- package/scripts/video-pipeline.ts +9 -1
- package/scripts/warm-pool-provider-config.ts +286 -0
- package/skills/omni-crawl/SKILL.md +5 -2
- package/skills/omni-crawl/scripts/main.ts +84 -23
- package/src/acp/agent-manager.ts +1 -0
- package/src/acp/codex-app-server-agent.ts +33 -0
- package/src/acp/codex-app-server-client.ts +153 -16
- package/src/acp/core-turn-bridge.ts +27 -9
- package/src/acp/event-router.ts +20 -1
- package/src/acp/server.ts +6 -0
- package/src/agent/registry.ts +2 -0
- package/src/agent/task-notification.ts +25 -5
- package/src/agent/types.ts +6 -0
- package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
- package/src/agent-mission/claude-headless.ts +4 -1
- package/src/agent-mission/codex-exec.ts +105 -0
- package/src/agent-mission/driver.ts +192 -11
- package/src/agent-mission/grok-auth-status.ts +47 -0
- package/src/agent-mission/hand-hooks.ts +101 -0
- package/src/agent-mission/mission-cli.ts +63 -4
- package/src/agent-mission/mission-hand-reply.ts +118 -0
- package/src/agent-mission/mission-line.ts +180 -0
- package/src/agent-mission/mission-out.ts +833 -0
- package/src/agent-mission/tool-install.ts +200 -3
- package/src/agent-substrate/context-strategy.ts +4 -4
- package/src/agent-substrate/self-review-cli.ts +178 -13
- package/src/agents/general-purpose.md +1 -1
- package/src/auto-research/research-turn.ts +211 -53
- package/src/autopilot/pr-manager.ts +69 -10
- package/src/autopilot/pty-control-loop.ts +2 -0
- package/src/boot/daemon-tools/self-implement.ts +3 -1
- package/src/boot/daemon-tools/web-search.ts +1 -2
- package/src/briefing/brief-items.ts +55 -11
- package/src/capture/tui-self-report.ts +22 -6
- package/src/chat/index.ts +1 -1
- package/src/cli/agent-cli.ts +2 -1
- package/src/cli/catalog-cli.ts +31 -0
- package/src/cli/connector-cli.ts +16 -0
- package/src/cli/doctor-fix.ts +2 -2
- package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
- package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
- package/src/cli/intake-source-cli.ts +44 -8
- package/src/cli/msg-cli.ts +32 -3
- package/src/cli/pr-cli.ts +21 -1
- package/src/cli/pr-land-heavy-remote.ts +75 -5
- package/src/cli/pr-land-overlap-evidence.ts +113 -2
- package/src/cli/pr-land-pod-shadow-job.ts +202 -4
- package/src/cli/pr-land-pod-shadow.ts +9 -2
- package/src/cli/release-checklist-read-cli.ts +57 -19
- package/src/cli/release-cli.ts +23 -3
- package/src/cli/research-cli.ts +13 -5
- package/src/cli/setup-cli.ts +166 -6
- package/src/cli/setup-keys.ts +187 -0
- package/src/cli/task-plugin-wizard-host.ts +114 -0
- package/src/cli/tasks-cli.ts +61 -9
- package/src/cli/tui-test-cli.ts +186 -0
- package/src/compact/auto.ts +8 -1
- package/src/config.ts +4 -2
- package/src/connectors/linear-daily-progress.ts +228 -0
- package/src/connectors/linear-projector.ts +34 -12
- package/src/connectors/linear.ts +151 -7
- package/src/control-plane/ledger.ts +52 -2
- package/src/control-plane/server.ts +16 -2
- package/src/core-turn/deep-turn-bloom.ts +67 -0
- package/src/core-turn/research-policy.ts +37 -0
- package/src/core-turn/run-core-turn.ts +606 -95
- package/src/core-turn/run-goal-loop.ts +18 -0
- package/src/core-turn/types.ts +4 -0
- package/src/dashboard/chat/acp-chat.ts +10 -0
- package/src/dashboard/classic-sidetab-mission-job.ts +161 -0
- package/src/dashboard/classic-sidetab-mission-pair.ts +81 -0
- package/src/dashboard/classic-sidetab-mission-trio.ts +219 -0
- package/src/dashboard/classic-sidetab-mission.ts +347 -0
- package/src/dashboard/index.ts +517 -18
- package/src/dashboard/input/agent-wake.ts +23 -1
- package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +17 -0
- package/src/dashboard/mission-cli-consumer.ts +165 -0
- package/src/dashboard/plugin-wizard-runtime.ts +50 -0
- package/src/dashboard/plugin-wizard-tool.ts +55 -0
- package/src/dashboard/seat-boot-preamble.ts +171 -1
- package/src/dashboard/side-basic-runtime.ts +54 -1
- package/src/dashboard/sidetab-runtime.ts +90 -1
- package/src/dashboard/skill-catalog-preamble.ts +101 -0
- package/src/dashboard/skill-detection-runtime.ts +55 -15
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
- package/src/dashboard/terminal-popup-runtime.ts +6 -3
- package/src/dashboard/turn-preamble.ts +53 -15
- package/src/dashboard/turn-prompt-runtime.ts +4 -2
- package/src/decisions/linear-progress-summary.ts +78 -0
- package/src/decisions/linear-progress-sync.ts +152 -0
- package/src/domains/outbound-alert.ts +49 -11
- package/src/domains/telegram-kind-route.ts +16 -9
- package/src/graph-runner/arg-allowance.ts +13 -0
- package/src/graph-runner/graph-cli.ts +23 -7
- package/src/graph-runner/graph-run-api.ts +3 -1
- package/src/graph-runner/graph-tick.ts +10 -2
- package/src/graph-runner/runner.ts +86 -18
- package/src/graph-wizard/mission-compose.ts +407 -12
- package/src/grok/agent-search.ts +14 -4
- package/src/grok/credential.ts +28 -11
- package/src/harness/dispatch-backpressure.ts +54 -1
- package/src/harness/dispatch-shadow-compare.ts +74 -0
- package/src/harness/harness-cli-command.ts +11 -1
- package/src/harness/harness-pod-dispatch.ts +81 -15
- package/src/harness/harness-stop.ts +155 -11
- package/src/harness/skill-exec.ts +21 -9
- package/src/harness/skill-select.ts +1 -1
- package/src/hooks/error-report-cloud.ts +101 -0
- package/src/hooks/receiver.ts +29 -2
- package/src/index.ts +159 -13
- package/src/instance/spawn-elanous.ts +6 -4
- package/src/intake-plane/actions.ts +354 -0
- package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
- package/src/intake-plane/intake-sources.ts +78 -8
- package/src/intake-plane/items.ts +14 -4
- package/src/intake-plane/linear-mission-sync.ts +80 -0
- package/src/intake-plane/linear-secretary-runtime.ts +178 -0
- package/src/intake-plane/linear-wish.ts +227 -1
- package/src/life/life-cli.ts +168 -0
- package/src/life/life-kinds.ts +160 -0
- package/src/live-supply/budget-consumer.ts +78 -0
- package/src/live-supply/read.ts +3 -0
- package/src/live-supply/snapshot.ts +45 -0
- package/src/llm/provider-credentials.ts +8 -2
- package/src/llm.ts +168 -9
- package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
- package/src/loops/orchestrator/tick.ts +13 -0
- package/src/maturity/feature-maturity.ts +4 -4
- package/src/msg/msg-sse-server.ts +3 -3
- package/src/msg/msg-store.ts +177 -19
- package/src/native-tool-catalog.ts +38 -4
- package/src/nexus/api/harness-traversal.ts +11 -0
- package/src/nexus/api/http-server.ts +37 -1
- package/src/nexus/api/mcp-public-allowlist.ts +2 -0
- package/src/nexus/index.ts +7 -2
- package/src/nexus/outbound/format.ts +9 -0
- package/src/nexus/outbound/router.ts +98 -13
- package/src/nexus/setup-status.ts +9 -0
- package/src/nexus/state/state.ts +3 -0
- package/src/oauth/codex-account-store.ts +20 -7
- package/src/oauth/codex-owner-mirror.ts +44 -0
- package/src/oauth/codex.ts +17 -2
- package/src/oauth/fallback-chain.ts +47 -17
- package/src/onboarding/first-run-doctor.ts +8 -1
- package/src/onboarding/first-run.ts +85 -26
- package/src/onboarding/key-setup.ts +103 -0
- package/src/onboarding/menu-answer.ts +13 -0
- package/src/onboarding/secret-prompt.ts +37 -0
- package/src/plugins/install/plugin-install.ts +59 -0
- package/src/pr-tool/census.ts +133 -2
- package/src/pty-shell/pty-control-ipc.ts +4 -1
- package/src/pty-shell/tui-run-state.ts +188 -2
- package/src/registry/catalog-server.ts +232 -0
- package/src/registry/loader.ts +45 -1
- package/src/registry/types.ts +1 -2
- package/src/release-loop/checklist-target-path-hint.ts +13 -0
- package/src/release-loop/checklist.ts +9 -1
- package/src/repl/index.ts +43 -2
- package/src/research/axis-fanout.ts +136 -16
- package/src/research/bloom-exemplars.ts +3 -1
- package/src/research/gap-followup.ts +13 -1
- package/src/research/plugin-discovery.ts +36 -14
- package/src/research-bridge/invoke.ts +22 -5
- package/src/research-bridge/types.ts +2 -0
- package/src/self-dev/ask-launch-flow.ts +72 -1
- package/src/self-dev/decompose.ts +119 -5
- package/src/self-dev/dev-cli.ts +4 -1
- package/src/self-dev/dev-pipeline.ts +5 -0
- package/src/self-dev/draft-residue.ts +64 -5
- package/src/self-dev/graph-front-nodes.ts +2 -1
- package/src/self-dev/graph-journey-route.ts +76 -21
- package/src/self-dev/launch-preflight-text.ts +5 -6
- package/src/self-dev/launch-preflight.ts +58 -0
- package/src/self-dev/orchestrate.ts +13 -3
- package/src/self-dev/review-provider-fallback.ts +9 -2
- package/src/self-dev/run-supervisor.ts +42 -4
- package/src/self-dev/run-types.ts +4 -0
- package/src/self-dev/shard-aggregate.ts +4 -0
- package/src/self-dev/shard-run.ts +36 -15
- package/src/self-implement/abandoned-classification.ts +12 -3
- package/src/self-implement/budget-gate.ts +7 -0
- package/src/self-implement/child-llm-preference.ts +10 -1
- package/src/self-implement/doctor-visit.ts +118 -8
- package/src/self-implement/elanous-tui-spawn.ts +3 -0
- package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
- package/src/self-implement/gate-artifacts.ts +2 -1
- package/src/self-implement/goal-author-cli.ts +4 -2
- package/src/self-implement/goal-author.ts +684 -7
- package/src/self-implement/graph-overlay-yaml.ts +37 -4
- package/src/self-implement/graph-overlay.ts +3 -1
- package/src/self-implement/graph-profile-yaml.ts +107 -0
- package/src/self-implement/graph-yaml.ts +26 -3
- package/src/self-implement/headless-elanous-driver.ts +31 -2
- package/src/self-implement/heal-intake.ts +112 -4
- package/src/self-implement/heal-triage.ts +20 -0
- package/src/self-implement/host-regate.ts +27 -4
- package/src/self-implement/merge-train.ts +5 -0
- package/src/self-implement/off-diff-evidence.ts +249 -5
- package/src/self-implement/orchestrator.ts +365 -25
- package/src/self-implement/regate-detail.ts +38 -1
- package/src/self-implement/rework-child-provider.ts +25 -0
- package/src/self-implement/run-chart.ts +122 -0
- package/src/self-implement/run-ledger.ts +162 -11
- package/src/self-implement/run-stop.ts +188 -4
- package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
- package/src/self-implement/stop-autoheal.ts +13 -0
- package/src/self-implement/tdd-evidence-tags.ts +9 -0
- package/src/self-implement/train-gate-receipt.ts +166 -0
- package/src/self-implement/train-gate-remote.ts +62 -18
- package/src/session/chat.ts +40 -4
- package/src/session/session-fanout.ts +2 -0
- package/src/session/streaming/acp-stream-sink.ts +2 -1
- package/src/session/streaming/chunk-producer.ts +6 -0
- package/src/session/streaming/stream-compositor.ts +3 -2
- package/src/session-runtime/index.ts +135 -5
- package/src/session-runtime/retry-policy.ts +1 -1
- package/src/session-runtime/tier-flip.ts +3 -3
- package/src/setup/llm-env-detect.ts +3 -0
- package/src/setup/service-key-catalog.ts +46 -0
- package/src/setup/service-keys.ts +241 -0
- package/src/sidetab-core/model.ts +19 -5
- package/src/sidetab-core/visible-agent-mission.ts +262 -0
- package/src/skills/name-match.ts +20 -0
- package/src/skills/tools/agent.ts +53 -6
- package/src/skills/tools/omni-search.ts +173 -13
- package/src/task-agent/parent-host.ts +10 -0
- package/src/task-agent/pod-distributor-entry.ts +3 -0
- package/src/task-agent/repair-outcomes.ts +65 -0
- package/src/task-agent/task-hand.ts +47 -7
- package/src/task-orchestrator/dispatcher.ts +14 -1
- package/src/task-orchestrator/linear-capture-events.ts +55 -0
- package/src/task-orchestrator/store.ts +16 -5
- package/src/task-orchestrator/surfaces/pod-artifact-return.ts +4 -0
- package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +92 -1
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
- package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
- package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
- package/src/task-orchestrator/surfaces/pod-source-receive.ts +178 -16
- package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
- package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
- package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +237 -41
- package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +337 -51
- package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
- package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
- package/src/task-orchestrator/types.ts +14 -0
- package/src/telegram.ts +14 -16
- package/src/terminal/coding-agent.ts +14 -5
- package/src/terminal/session-registry.ts +1 -1
- package/src/tokens.ts +35 -2
- package/src/tool-hints/gate.ts +1 -0
- package/src/tool-runtime/agent-runtime.ts +2 -0
- package/src/tool-runtime/browser-hand-runtime.ts +381 -0
- package/src/tool-runtime/browser-runtime.ts +2 -1
- package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
- package/src/tool-runtime/elanous-linear-secretary-runtime.ts +57 -0
- package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
- package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
- package/src/tool-runtime/index.ts +6 -0
- package/src/tool-runtime/skill-exec-runtime.ts +33 -13
- package/src/tool-runtime/types.ts +4 -0
- package/src/tui/entry.ts +38 -5
- package/src/tui/sidetab/attach.ts +177 -1
- package/src/tui/sidetab/herdr-portal.ts +225 -0
- package/src/tui-client/local-chat-turn.ts +26 -13
- package/src/tui.ts +22 -0
- package/src/user-config.ts +34 -9
- package/src/user-intent/types.ts +4 -3
- package/src/ux-sim/browser-hand.ts +165 -0
- package/src/ux-sim/draft-inventory-builder.ts +198 -0
- package/src/ux-sim/fake-browser-page.ts +81 -0
- package/src/ux-sim/fake-kubectl.ts +37 -3
- package/src/ux-sim/fake-linear-device.ts +31 -0
- package/src/ux-sim/fault-pool-cap.ts +11 -6
- package/src/ux-sim/graph-engine-sim.ts +47 -0
- package/src/ux-sim/linear-secretary.ts +216 -0
- package/src/ux-sim/mock-scenario-catalog.json +93 -0
- package/src/ux-sim/mock-scenario-catalog.ts +274 -0
- package/src/ux-sim/onboarding-first-run-device.ts +31 -21
- package/src/ux-sim/scenario.ts +185 -48
- package/src/ux-sim/service-key-setup.ts +50 -0
- package/src/ux-sim/term-slash-device.ts +74 -0
- package/src/ux-sim/turn-throw-sim.ts +31 -0
- package/src/version/packed-revision.json +1 -1
- package/src/voice/voice-tts-singleton.ts +18 -3
- package/src/web-search/exa.ts +77 -0
- package/src/web-search/grok.ts +5 -9
- package/src/web-search/index.ts +30 -9
- package/src/web-search/provider.ts +4 -1
- package/src/web-search/x-intent.ts +5 -0
- package/apps/pwa/out/_next/static/chunks/1115.434ae2ecb0ad986d.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +0 -36
- package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +0 -287
- package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1661.0dd330f3d89f73f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +0 -90
- package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1765.679b29625c8e88d4.js +0 -77
- package/apps/pwa/out/_next/static/chunks/1971-7efb628c471dc5a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2073.689dcb2680113d76.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +0 -1
- package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2527-5c636a43c7cc5dde.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +0 -32
- package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +0 -79
- package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +0 -74
- package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +0 -148
- package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +0 -226
- package/apps/pwa/out/_next/static/chunks/4667.97e31aa38c95c475.js +0 -309
- package/apps/pwa/out/_next/static/chunks/4702.4a4adc1f16d7c93b.js +0 -64
- package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +0 -94
- package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +0 -8
- package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +0 -24
- package/apps/pwa/out/_next/static/chunks/5892.2526d962339662d8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5937.c2df9e3447e1f667.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +0 -286
- package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +0 -27
- package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6552.a3840aa7da35ad68.js +0 -62
- package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +0 -122
- package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7191.fdc955f7d96064a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8050-9b364bdef8f71927.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +0 -104
- package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9541.eb8e2f8480c7feca.js +0 -93
- package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +0 -34
- package/apps/pwa/out/_next/static/chunks/9869.81a1e24ca682d5a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-14949db884bfa672.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +0 -1
- package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
- package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
- /package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → Om5xS9jpjSXJCeTNGYEi4}/_ssgManifest.js +0 -0
package/src/repl/index.ts
CHANGED
|
@@ -41,6 +41,8 @@ import {
|
|
|
41
41
|
type UserConfig,
|
|
42
42
|
} from '../user-config.js';
|
|
43
43
|
import { setAmbientSessionId, debug } from '../debug/log.js';
|
|
44
|
+
import { buildInstalledSkillCatalogMessage, type InstalledSkillSummary } from '../dashboard/skill-catalog-preamble.js';
|
|
45
|
+
import { resolveModelContextWindow } from '../models/context-window.js';
|
|
44
46
|
import { decideSigintAction } from './sigint.js';
|
|
45
47
|
import { decideSessionStart, observeSessionStart } from '../session/session-start.js';
|
|
46
48
|
import { buildReplayTurnsFromSession } from './replay.js';
|
|
@@ -275,13 +277,39 @@ export function buildReplSystemPrompt(ctx: {
|
|
|
275
277
|
sessionId?: string | undefined;
|
|
276
278
|
/** 시험·임베디드 호출부용 시임 — 기본은 실제 홈·msg 원장·process.env. */
|
|
277
279
|
seatBootDeps?: SeatBootDeps | undefined;
|
|
280
|
+
/** Installed skill summaries are injectable for deterministic prompt tests. */
|
|
281
|
+
skillCatalog?: readonly InstalledSkillSummary[] | undefined;
|
|
282
|
+
skillCatalogContextWindow?: number | null | undefined;
|
|
278
283
|
}): string | undefined {
|
|
279
284
|
const base = ctx.enabledToolNames === undefined
|
|
280
285
|
? undefined
|
|
281
286
|
: buildAgentSystemPrompt(ctx.cfg, ctx.enabledToolNames);
|
|
287
|
+
const skillToolsEnabled = ctx.enabledToolNames?.includes('skill_exec') === true
|
|
288
|
+
&& ctx.enabledToolNames.includes('elanous_skills_list');
|
|
289
|
+
let skillCatalogText = '';
|
|
290
|
+
if (skillToolsEnabled) {
|
|
291
|
+
try {
|
|
292
|
+
const catalog = ctx.skillCatalog ?? (() => {
|
|
293
|
+
const skills = require('../skills/index.js') as typeof import('../skills/index.js');
|
|
294
|
+
return skills.applySkillFilter(skills.getSkillIndex(), ctx.cfg.skills)
|
|
295
|
+
.map(({ name, description }) => ({ name, description }));
|
|
296
|
+
})();
|
|
297
|
+
const built = buildInstalledSkillCatalogMessage(
|
|
298
|
+
catalog,
|
|
299
|
+
ctx.skillCatalogContextWindow ?? resolveModelContextWindow(ctx.cfg.llm.model),
|
|
300
|
+
);
|
|
301
|
+
skillCatalogText = built.message?.content ?? '';
|
|
302
|
+
debug.log('repl.skill-catalog', 'built', {
|
|
303
|
+
skillCount: built.skillCount, estimatedTokens: built.estimatedTokens,
|
|
304
|
+
budgetTokens: built.budgetTokens, mode: built.mode,
|
|
305
|
+
});
|
|
306
|
+
} catch (error) {
|
|
307
|
+
debug.log('repl.skill-catalog', 'failed', { reason: error instanceof Error ? error.message : String(error) }, { level: 'warn' });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
282
310
|
const card = buildSeatBootCardText(ctx);
|
|
283
|
-
|
|
284
|
-
return
|
|
311
|
+
const parts = [skillCatalogText, base ?? '', card].filter(part => part.length > 0);
|
|
312
|
+
return parts.length > 0 ? parts.join('\n\n') : undefined;
|
|
285
313
|
}
|
|
286
314
|
|
|
287
315
|
/** 자리 부트 카드 문면(system 메시지 0~1개를 이어 붙인 것). 자리가 아니면 ''. */
|
|
@@ -344,6 +372,7 @@ async function runOneTurn(
|
|
|
344
372
|
nextTuiDelivery?: { pending: PendingTaskNotification[] },
|
|
345
373
|
onJsonDelta?: (delta: string) => void,
|
|
346
374
|
onJsonStatus?: (line: string) => void,
|
|
375
|
+
onJsonReplace?: (fullText: string) => void,
|
|
347
376
|
): Promise<{ reply: string; provider: string; model: string | null; durationMs: number; logPath: string | null }> {
|
|
348
377
|
const startedAt = Date.now();
|
|
349
378
|
const replyChunks: string[] = [];
|
|
@@ -374,6 +403,7 @@ async function runOneTurn(
|
|
|
374
403
|
userConfig: cfg,
|
|
375
404
|
sessionId,
|
|
376
405
|
userText,
|
|
406
|
+
utteranceSurface: 'tui',
|
|
377
407
|
systemPrompt,
|
|
378
408
|
userImages: userImages.length > 0 ? userImages : undefined,
|
|
379
409
|
...(process.env.ELANOUS_TEST_FAKE_LLM === '1' && Number.isFinite(Number(process.env.ELANOUS_TEST_FAKE_LLM_IDLE_TIMEOUT_MS))
|
|
@@ -387,6 +417,14 @@ async function runOneTurn(
|
|
|
387
417
|
}
|
|
388
418
|
else process.stdout.write(d);
|
|
389
419
|
},
|
|
420
|
+
onReplaceText: (fullText) => {
|
|
421
|
+
if (jsonOutput) {
|
|
422
|
+
replyChunks.splice(0, replyChunks.length, fullText);
|
|
423
|
+
onJsonReplace?.(fullText);
|
|
424
|
+
} else {
|
|
425
|
+
process.stdout.write(`\n\n [근거 반영된 답변]\n ${fullText}\n`);
|
|
426
|
+
}
|
|
427
|
+
},
|
|
390
428
|
onStatusLine: (line) => { onJsonStatus?.(line); },
|
|
391
429
|
tools: replToolSpecs,
|
|
392
430
|
dispatchTool: tools?.dispatch,
|
|
@@ -795,6 +833,9 @@ export async function runRepl(opts: ReplOpts): Promise<number> {
|
|
|
795
833
|
process.env.ELANOUS_NEXT_TUI_STREAM === '1' && typeof turn.id === 'string'
|
|
796
834
|
? (text) => { process.stdout.write(`${JSON.stringify({ event: 'status', turnId: turn.id, text })}\n`); }
|
|
797
835
|
: undefined,
|
|
836
|
+
process.env.ELANOUS_NEXT_TUI_STREAM === '1' && typeof turn.id === 'string'
|
|
837
|
+
? (text) => { process.stdout.write(`${JSON.stringify({ event: 'replace', turnId: turn.id, text })}\n`); }
|
|
838
|
+
: undefined,
|
|
798
839
|
);
|
|
799
840
|
} catch (error) {
|
|
800
841
|
if (!backgroundBridge) throw error;
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
// Research-only native fanout. The caller supplies Bloom's question ladder;
|
|
2
2
|
// each axis gets its own direct tool call and evidence stays attributed to it.
|
|
3
3
|
import type { BloomResearchQuestion, ResearchEvidenceEnvelope } from '../auto-research/question-ladder-contract.js';
|
|
4
|
-
import
|
|
4
|
+
import { getAvailableResearchWebSearchProviders } from '../web-search/index.js';
|
|
5
|
+
import type { WebSearchHit, WebSearchProvider } from '../web-search/provider.js';
|
|
6
|
+
import { debug } from '../debug/log.js';
|
|
7
|
+
|
|
8
|
+
const RESEARCH_SEARCH_ENGINES = ['exa', 'firecrawl'] as const;
|
|
9
|
+
const RESEARCH_WEB_FALLBACK_IDS = ['exa', 'firecrawl'] as const;
|
|
10
|
+
const RESEARCH_EXA_TIMEOUT_MS = 4_500;
|
|
11
|
+
// Leave scheduler/logging headroom under the user-visible 15s aggregate cap.
|
|
12
|
+
export const RESEARCH_SEARCH_BUDGET_MS = 14_500;
|
|
13
|
+
const ENGINE_BREAKER_FAILURE_LIMIT = 2;
|
|
5
14
|
|
|
6
15
|
export interface AxisToolCallPlan {
|
|
7
16
|
questionId: string;
|
|
@@ -25,10 +34,124 @@ export interface AxisSearchResult {
|
|
|
25
34
|
hits: AxisSearchHit[];
|
|
26
35
|
errors: string[];
|
|
27
36
|
}
|
|
28
|
-
export
|
|
37
|
+
export interface AxisSearchContext {
|
|
38
|
+
questionPrompt?: string;
|
|
39
|
+
requestedWindow?: string;
|
|
40
|
+
}
|
|
41
|
+
export type AxisSearch = (query: string, signal?: AbortSignal, context?: AxisSearchContext) => Promise<AxisSearchHit[] | AxisSearchResult>;
|
|
29
42
|
|
|
30
43
|
export interface AxisFanoutDeps {
|
|
31
44
|
search?: AxisSearch;
|
|
45
|
+
signal?: AbortSignal;
|
|
46
|
+
admitToolCall?: (toolName: 'OmniSearch') => boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface ProviderHealth {
|
|
50
|
+
failures: number;
|
|
51
|
+
open: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Build one bounded searcher per research prepass. Research uses only the
|
|
55
|
+
* sequential Exa → Firecrawl fallback; Grok is reserved for explicit X intent.
|
|
56
|
+
* Per-engine serialization lets a timeout open that engine's
|
|
57
|
+
* breaker before queued Bloom axes start. */
|
|
58
|
+
export function createResearchAxisSearcher(
|
|
59
|
+
availableProviders: readonly WebSearchProvider[] = getAvailableResearchWebSearchProviders(),
|
|
60
|
+
now: () => number = Date.now,
|
|
61
|
+
): AxisSearch {
|
|
62
|
+
const webFallback = RESEARCH_WEB_FALLBACK_IDS.flatMap(id => availableProviders.filter(provider => provider.id === id));
|
|
63
|
+
const allowed = [...webFallback];
|
|
64
|
+
const health = new Map(allowed.map(provider => [provider.id, { failures: 0, open: false }]));
|
|
65
|
+
const deadline = now() + RESEARCH_SEARCH_BUDGET_MS;
|
|
66
|
+
const tails = new Map<string, Promise<void>>();
|
|
67
|
+
|
|
68
|
+
debug.log('research.search', 'provider-preflight', {
|
|
69
|
+
allowed: RESEARCH_SEARCH_ENGINES,
|
|
70
|
+
available: allowed.map(provider => provider.id),
|
|
71
|
+
excluded: availableProviders.filter(provider => !(RESEARCH_SEARCH_ENGINES as readonly string[]).includes(provider.id))
|
|
72
|
+
.map(provider => provider.id),
|
|
73
|
+
budgetMs: RESEARCH_SEARCH_BUDGET_MS,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const enqueue = <T>(providerId: string, run: () => Promise<T>): Promise<T> => {
|
|
77
|
+
const previous = tails.get(providerId) ?? Promise.resolve();
|
|
78
|
+
const current = previous.then(run, run);
|
|
79
|
+
tails.set(providerId, current.then(() => undefined, () => undefined));
|
|
80
|
+
return current;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return async (query, signal) => {
|
|
84
|
+
const hits: AxisSearchHit[] = [];
|
|
85
|
+
const errors: string[] = [];
|
|
86
|
+
const execute = async (provider: WebSearchProvider): Promise<boolean> => enqueue(provider.id, async () => {
|
|
87
|
+
const state = health.get(provider.id)!;
|
|
88
|
+
if (state.open) return false;
|
|
89
|
+
const remainingMs = deadline - now();
|
|
90
|
+
if (remainingMs <= 0) {
|
|
91
|
+
state.open = true;
|
|
92
|
+
errors.push(`${provider.id}: research search budget exhausted`);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
const timeoutMs = provider.id === 'exa'
|
|
96
|
+
? Math.min(RESEARCH_EXA_TIMEOUT_MS, remainingMs)
|
|
97
|
+
: remainingMs;
|
|
98
|
+
const startedAt = now();
|
|
99
|
+
try {
|
|
100
|
+
const controller = new AbortController();
|
|
101
|
+
const abortFromCaller = (): void => controller.abort(signal?.reason);
|
|
102
|
+
if (signal?.aborted) abortFromCaller();
|
|
103
|
+
else signal?.addEventListener('abort', abortFromCaller, { once: true });
|
|
104
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
105
|
+
let result;
|
|
106
|
+
try {
|
|
107
|
+
result = await Promise.race([
|
|
108
|
+
provider.search({ query, limit: 5 }, controller.signal),
|
|
109
|
+
new Promise<never>((_, reject) => {
|
|
110
|
+
timer = setTimeout(() => {
|
|
111
|
+
controller.abort();
|
|
112
|
+
reject(new DOMException(`${provider.id} research search timed out after ${timeoutMs}ms`, 'TimeoutError'));
|
|
113
|
+
}, timeoutMs);
|
|
114
|
+
}),
|
|
115
|
+
]);
|
|
116
|
+
} finally {
|
|
117
|
+
if (timer !== undefined) clearTimeout(timer);
|
|
118
|
+
signal?.removeEventListener('abort', abortFromCaller);
|
|
119
|
+
}
|
|
120
|
+
if (result.hits.length === 0) {
|
|
121
|
+
state.failures += 1;
|
|
122
|
+
if (state.failures >= ENGINE_BREAKER_FAILURE_LIMIT) state.open = true;
|
|
123
|
+
} else {
|
|
124
|
+
state.failures = 0;
|
|
125
|
+
hits.push(...result.hits.map(hit => ({ ...hit, engine: provider.id })));
|
|
126
|
+
}
|
|
127
|
+
debug.log('research.search', 'provider-complete', {
|
|
128
|
+
provider: provider.id, queryLength: query.length, hits: result.hits.length,
|
|
129
|
+
durationMs: now() - startedAt, breakerOpen: state.open,
|
|
130
|
+
});
|
|
131
|
+
return result.hits.length > 0;
|
|
132
|
+
} catch (error) {
|
|
133
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
134
|
+
const timeout = error instanceof Error && /timeout|timed out|abort/i.test(`${error.name} ${error.message}`);
|
|
135
|
+
const quota = /quota|credit|rate.?limit|\b429\b|exhaust/i.test(message);
|
|
136
|
+
state.failures += 1;
|
|
137
|
+
if (timeout || quota || state.failures >= ENGINE_BREAKER_FAILURE_LIMIT) state.open = true;
|
|
138
|
+
errors.push(`${provider.id}: ${message}`);
|
|
139
|
+
debug.log('research.search', 'provider-failed', {
|
|
140
|
+
provider: provider.id, queryLength: query.length, durationMs: now() - startedAt,
|
|
141
|
+
timeout, quota, failures: state.failures, breakerOpen: state.open,
|
|
142
|
+
}, { level: 'warn' });
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
const runWebFallback = async (): Promise<void> => {
|
|
147
|
+
for (const provider of webFallback) {
|
|
148
|
+
if (!health.get(provider.id)?.open && await execute(provider)) return;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
await runWebFallback();
|
|
152
|
+
if (hits.length === 0 && errors.length === 0) errors.push('no healthy Exa/Firecrawl research provider');
|
|
153
|
+
return { hits, errors };
|
|
154
|
+
};
|
|
32
155
|
}
|
|
33
156
|
|
|
34
157
|
/** Keep every query attached to the Bloom question that produced it. */
|
|
@@ -39,18 +162,6 @@ export function planAxisToolCalls(questions: readonly BloomResearchQuestion[]):
|
|
|
39
162
|
.map(query => ({ questionId: question.id, tool: 'OmniSearch' as const, query })));
|
|
40
163
|
}
|
|
41
164
|
|
|
42
|
-
async function directOmniSearch(query: string): Promise<AxisSearchResult> {
|
|
43
|
-
const { dispatchOmniSearch } = await import('../skills/tools/omni-search.js');
|
|
44
|
-
const hits: AxisSearchHit[] = [];
|
|
45
|
-
const result = await dispatchOmniSearch({ query }, { onSource: hit => { hits.push(hit); } });
|
|
46
|
-
if (Object.keys(result.metadata.perEngine).length === 0) {
|
|
47
|
-
throw new Error('no available web-search providers');
|
|
48
|
-
}
|
|
49
|
-
const errors = Object.entries(result.metadata.perEngine)
|
|
50
|
-
.flatMap(([engine, info]) => info.error ? [`${engine}: ${info.error}`] : []);
|
|
51
|
-
return { hits, errors };
|
|
52
|
-
}
|
|
53
|
-
|
|
54
165
|
function evidenceFromHit(question: BloomResearchQuestion, hit: AxisSearchHit): ResearchEvidenceEnvelope {
|
|
55
166
|
const published = hit.publishedAt;
|
|
56
167
|
const date = published !== undefined && Number.isFinite(published) && published > 0
|
|
@@ -89,8 +200,17 @@ export async function fanOutAxisEvidence(
|
|
|
89
200
|
if (new Set(questions.map(question => question.id)).size !== questions.length) {
|
|
90
201
|
throw new Error('research axis question IDs must be unique');
|
|
91
202
|
}
|
|
92
|
-
const search = deps.search ??
|
|
93
|
-
const settled = await Promise.allSettled(plan.map(call =>
|
|
203
|
+
const search = deps.search ?? createResearchAxisSearcher();
|
|
204
|
+
const settled = await Promise.allSettled(plan.map(call => {
|
|
205
|
+
if (deps.admitToolCall && !deps.admitToolCall('OmniSearch')) {
|
|
206
|
+
return Promise.resolve({ hits: [], errors: ['research tool budget reached'] } satisfies AxisSearchResult);
|
|
207
|
+
}
|
|
208
|
+
const question = questions.find(candidate => candidate.id === call.questionId)!;
|
|
209
|
+
return search(call.query, deps.signal, {
|
|
210
|
+
questionPrompt: question.prompt,
|
|
211
|
+
requestedWindow: question.requestedWindow,
|
|
212
|
+
});
|
|
213
|
+
}));
|
|
94
214
|
const axes: AxisEvidenceGroup[] = questions.map(question => ({ questionId: question.id, evidence: [] }));
|
|
95
215
|
const groups = new Map(axes.map(axis => [axis.questionId, axis]));
|
|
96
216
|
const byQuestion = new Map(questions.map(question => [question.id, question]));
|
|
@@ -34,10 +34,12 @@ const BLOOM_BY_LEVEL = Object.fromEntries(COGNITIVE_BY_LEVEL.map((cognitive, ind
|
|
|
34
34
|
return [index + 1, cell];
|
|
35
35
|
})) as Record<BloomExemplarLevel, Bloom2D>;
|
|
36
36
|
|
|
37
|
-
// Public source tree intentionally contains
|
|
37
|
+
// Public source tree intentionally contains a small set of original exemplars.
|
|
38
38
|
const PUBLIC_EXEMPLARS: readonly BloomExemplar[] = [
|
|
39
39
|
{ domain: 'finance', level: 4, bloom: BLOOM_BY_LEVEL[4], question: '채권 금리 변화가 만기 구조와 발행자의 차환 위험에 어떤 경로로 연결되는가?' },
|
|
40
40
|
{ domain: 'finance', level: 5, bloom: BLOOM_BY_LEVEL[5], question: '현재 금리 전망을 반박할 수 있는 시장 지표와 그 신뢰도는 무엇인가?' },
|
|
41
|
+
{ domain: 'technology', level: 4, bloom: BLOOM_BY_LEVEL[4], question: 'AI 데이터센터의 추론 처리량 증가가 GPU 전력밀도와 냉각 부하, 랙당 계통용량 요구에 어떤 경로로 이어지는가?' },
|
|
42
|
+
{ domain: 'technology', level: 5, bloom: BLOOM_BY_LEVEL[5], question: 'AI 데이터센터 전력수요 전망을 반박할 수 있는 GPU 이용률·전력사용효율·계통접속 자료는 무엇이며 각 지표의 한계는 무엇인가?' },
|
|
41
43
|
];
|
|
42
44
|
|
|
43
45
|
const DOMAIN_TERMS: Record<BloomExemplarDomain, readonly string[]> = {
|
|
@@ -18,6 +18,7 @@ export interface ResearchGapFollowupInput {
|
|
|
18
18
|
request: string;
|
|
19
19
|
questions: readonly BloomResearchQuestion[];
|
|
20
20
|
evidence: readonly ResearchEvidenceEnvelope[];
|
|
21
|
+
signal?: AbortSignal;
|
|
21
22
|
/** Optional remaining time supplied by the owning turn; omitted uses the fixed 2-minute cap. */
|
|
22
23
|
remainingBudgetMs?: number;
|
|
23
24
|
roundsUsed?: number;
|
|
@@ -128,6 +129,7 @@ export async function runGapFollowup(
|
|
|
128
129
|
deps: ResearchGapFollowupDeps = {},
|
|
129
130
|
): Promise<ResearchGapFollowupResult> {
|
|
130
131
|
const plan = planGapFollowup(input);
|
|
132
|
+
if (input.signal?.aborted) return { ...plan, followupEvidence: [], discoveryCards: [] };
|
|
131
133
|
const startedAt = (deps.now ?? Date.now)();
|
|
132
134
|
const deadline = startedAt + plan.timeBudgetMs;
|
|
133
135
|
const discover = async (failedQuestions: ReadonlySet<string>): Promise<{ cards: string[]; evidence: ResearchEvidenceEnvelope[] }> => {
|
|
@@ -139,6 +141,9 @@ export async function runGapFollowup(
|
|
|
139
141
|
const remainingMs = deadline - (deps.now ?? Date.now)();
|
|
140
142
|
if (remainingMs <= 0) break;
|
|
141
143
|
const controller = new AbortController();
|
|
144
|
+
const abortFromParent = () => controller.abort(input.signal?.reason);
|
|
145
|
+
input.signal?.addEventListener('abort', abortFromParent, { once: true });
|
|
146
|
+
if (input.signal?.aborted) abortFromParent();
|
|
142
147
|
const timer = setTimeout(() => controller.abort(new Error('plugin discovery time budget exhausted')),
|
|
143
148
|
Math.min(10_000, remainingMs));
|
|
144
149
|
try {
|
|
@@ -158,7 +163,10 @@ export async function runGapFollowup(
|
|
|
158
163
|
questionId: gap.questionId, reason: error instanceof Error ? error.message.slice(0, 160) : String(error).slice(0, 160),
|
|
159
164
|
}, { level: 'warn' });
|
|
160
165
|
}
|
|
161
|
-
finally {
|
|
166
|
+
finally {
|
|
167
|
+
clearTimeout(timer);
|
|
168
|
+
input.signal?.removeEventListener('abort', abortFromParent);
|
|
169
|
+
}
|
|
162
170
|
}
|
|
163
171
|
return { cards, evidence };
|
|
164
172
|
};
|
|
@@ -168,6 +176,9 @@ export async function runGapFollowup(
|
|
|
168
176
|
}
|
|
169
177
|
|
|
170
178
|
const controller = new AbortController();
|
|
179
|
+
const abortFromParent = () => controller.abort(input.signal?.reason);
|
|
180
|
+
input.signal?.addEventListener('abort', abortFromParent, { once: true });
|
|
181
|
+
if (input.signal?.aborted) abortFromParent();
|
|
171
182
|
const timer = setTimeout(() => controller.abort(new Error('research gap follow-up time budget exhausted')),
|
|
172
183
|
Math.max(1, deadline - (deps.now ?? Date.now)()));
|
|
173
184
|
try {
|
|
@@ -200,6 +211,7 @@ export async function runGapFollowup(
|
|
|
200
211
|
return { ...plan, followupEvidence: [...outcomes, ...discovered.evidence], discoveryCards: discovered.cards };
|
|
201
212
|
} finally {
|
|
202
213
|
clearTimeout(timer);
|
|
214
|
+
input.signal?.removeEventListener('abort', abortFromParent);
|
|
203
215
|
}
|
|
204
216
|
}
|
|
205
217
|
|
|
@@ -136,15 +136,30 @@ function card(gap: string, candidates: readonly PluginDiscoveryCandidate[], inst
|
|
|
136
136
|
|
|
137
137
|
/** One bounded, fail-soft discovery attempt for a research capability gap. */
|
|
138
138
|
export async function discoverResearchPlugin(gapText: string, deps: PluginDiscoveryDeps = {}): Promise<PluginDiscoveryResult> {
|
|
139
|
+
const discoveryStartedAt = performance.now();
|
|
140
|
+
const log = deps.log ?? ((event: string, data: Record<string, unknown>) => debug.log('research.plugin-discovery', event, data));
|
|
141
|
+
const observe = (event: string, data: Record<string, unknown>): void => {
|
|
142
|
+
try { log(event, data); } catch { /* timing must not change discovery behavior */ }
|
|
143
|
+
};
|
|
144
|
+
observe('started', {});
|
|
145
|
+
const finish = (result: PluginDiscoveryResult): PluginDiscoveryResult => {
|
|
146
|
+
observe('completed', {
|
|
147
|
+
elapsedMs: Math.round((performance.now() - discoveryStartedAt) * 10) / 10,
|
|
148
|
+
outcome: result.outcome,
|
|
149
|
+
candidateCount: result.candidates.length,
|
|
150
|
+
installed: result.installed !== undefined,
|
|
151
|
+
});
|
|
152
|
+
return result;
|
|
153
|
+
};
|
|
139
154
|
const gap = safeGap(gapText);
|
|
140
|
-
if (!gap) return { candidates: [], card: 'Plugin discovery skipped: unsafe or empty gap.', outcome: 'invalid-gap' };
|
|
155
|
+
if (!gap) return finish({ candidates: [], card: 'Plugin discovery skipped: unsafe or empty gap.', outcome: 'invalid-gap' });
|
|
141
156
|
const aborted = (): PluginDiscoveryResult => ({ candidates: [], card: 'Plugin discovery skipped: time budget exhausted.', outcome: 'create-suggestion' });
|
|
142
|
-
if (deps.signal?.aborted) return aborted();
|
|
143
|
-
const log = deps.log ?? ((event: string, data: Record<string, unknown>) => debug.log('research.plugin-discovery', event, data));
|
|
157
|
+
if (deps.signal?.aborted) return finish(aborted());
|
|
144
158
|
const threshold = Number.isSafeInteger(deps.githubStarThreshold) && (deps.githubStarThreshold as number) > 0
|
|
145
159
|
? deps.githubStarThreshold as number : configuredStarThreshold();
|
|
146
160
|
const candidates: PluginDiscoveryCandidate[] = [];
|
|
147
161
|
|
|
162
|
+
const marketStartedAt = performance.now();
|
|
148
163
|
try {
|
|
149
164
|
const market = await (deps.market ?? (() => ensureMarketIndex('elanous')))();
|
|
150
165
|
// A signed index is the only built-in source with a verifiable install spec.
|
|
@@ -159,15 +174,19 @@ export async function discoverResearchPlugin(gapText: string, deps: PluginDiscov
|
|
|
159
174
|
installSpec: `${entry.name}@elanous` });
|
|
160
175
|
}
|
|
161
176
|
}
|
|
162
|
-
} catch {
|
|
163
|
-
|
|
177
|
+
} catch { observe('market-unavailable', { gap: gap.slice(0, 80) }); }
|
|
178
|
+
finally {
|
|
179
|
+
observe('stage-complete', { stage: 'signed-market', elapsedMs: Math.round((performance.now() - marketStartedAt) * 10) / 10 });
|
|
180
|
+
}
|
|
181
|
+
if (deps.signal?.aborted) return finish(aborted());
|
|
164
182
|
|
|
183
|
+
const searchStartedAt = performance.now();
|
|
165
184
|
try {
|
|
166
185
|
const found = await (deps.search ?? ((query: string, signal?: AbortSignal) => discoverCapability(query,
|
|
167
186
|
{ layer: 'skill', limit: MAX_CANDIDATES, community: false, signal })))(gap, deps.signal);
|
|
168
|
-
if (deps.signal?.aborted) return aborted();
|
|
187
|
+
if (deps.signal?.aborted) return finish(aborted());
|
|
169
188
|
for (const hit of found.slice(0, MAX_CANDIDATES)) {
|
|
170
|
-
if (deps.signal?.aborted) return aborted();
|
|
189
|
+
if (deps.signal?.aborted) return finish(aborted());
|
|
171
190
|
let url: URL;
|
|
172
191
|
try { url = new URL(hit.url); } catch { continue; }
|
|
173
192
|
if (url.protocol !== 'https:' || url.username || url.password) continue;
|
|
@@ -186,8 +205,11 @@ export async function discoverResearchPlugin(gapText: string, deps: PluginDiscov
|
|
|
186
205
|
? { installSpec: `https://github.com/${repo!.owner}/${repo!.repo}.git#${github.sha}` } : {}),
|
|
187
206
|
});
|
|
188
207
|
}
|
|
189
|
-
} catch {
|
|
190
|
-
|
|
208
|
+
} catch { observe('search-unavailable', { gap: gap.slice(0, 80) }); }
|
|
209
|
+
finally {
|
|
210
|
+
observe('stage-complete', { stage: 'capability-search', elapsedMs: Math.round((performance.now() - searchStartedAt) * 10) / 10 });
|
|
211
|
+
}
|
|
212
|
+
if (deps.signal?.aborted) return finish(aborted());
|
|
191
213
|
|
|
192
214
|
const deduped = candidates.filter((item, index) => candidates.findIndex(other => other.url === item.url && other.name === item.name) === index)
|
|
193
215
|
.slice(0, MAX_CANDIDATES);
|
|
@@ -197,20 +219,20 @@ export async function discoverResearchPlugin(gapText: string, deps: PluginDiscov
|
|
|
197
219
|
if (installable.length === 1) {
|
|
198
220
|
const candidate = installable[0]!;
|
|
199
221
|
try {
|
|
200
|
-
if (deps.signal?.aborted) return aborted();
|
|
222
|
+
if (deps.signal?.aborted) return finish(aborted());
|
|
201
223
|
const item = await (deps.install ?? defaultInstall)(candidate.installSpec!);
|
|
202
224
|
const undo = `eln plugin remove ${item.name}`;
|
|
203
225
|
installed = { name: item.name, path: item.path,
|
|
204
226
|
notice: `Reason: missing research capability ${gap}; source: ${candidate.source}; permissions: ${candidate.permissions.join(', ') || 'none declared'}.`, undo };
|
|
205
|
-
|
|
227
|
+
observe('installed', { name: item.name, source: candidate.source, undo });
|
|
206
228
|
} catch (error) {
|
|
207
|
-
|
|
229
|
+
observe('install-refused', { name: candidate.name, reason: error instanceof Error ? error.message.slice(0, 120) : 'unknown' });
|
|
208
230
|
}
|
|
209
231
|
}
|
|
210
232
|
const outcome: PluginDiscoveryResult['outcome'] = installed ? 'installed' : deduped.length ? 'proposed' : 'create-suggestion';
|
|
211
233
|
const result = { candidates: deduped, installed, card: card(gap, deduped, installed), outcome };
|
|
212
|
-
|
|
213
|
-
return result;
|
|
234
|
+
observe(outcome, { gap: gap.slice(0, 80), count: deduped.length, installed: installed?.name });
|
|
235
|
+
return finish(result);
|
|
214
236
|
}
|
|
215
237
|
|
|
216
238
|
/** Re-query through exactly one installed, declared read-only skill with no local-file or shell tools. */
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// isolation without standing up the LLM stack.
|
|
15
15
|
|
|
16
16
|
import type { ExternalResearchResult, InvokeResearchOpts } from './types.js';
|
|
17
|
-
import type { SkillManifest } from '../skills/runner.js';
|
|
17
|
+
import type { ExecuteSkillOpts, SkillManifest } from '../skills/runner.js';
|
|
18
18
|
import type { BloomResearchQuestion } from '../auto-research/question-ladder-contract.js';
|
|
19
19
|
import type { AxisFanoutDeps, AxisFanoutResult } from '../research/axis-fanout.js';
|
|
20
20
|
import { recordResult } from './store.js';
|
|
@@ -76,8 +76,23 @@ export type ResearchInvoker = (
|
|
|
76
76
|
args: string,
|
|
77
77
|
onProgress?: (delta: string) => void,
|
|
78
78
|
signal?: AbortSignal,
|
|
79
|
+
skillRootDir?: string,
|
|
79
80
|
) => Promise<ResearchInvocationOutcome>;
|
|
80
81
|
|
|
82
|
+
export type ResearchSkillExecutorForTest = (
|
|
83
|
+
manifest: SkillManifest,
|
|
84
|
+
args: string,
|
|
85
|
+
onProgress?: (delta: string) => void,
|
|
86
|
+
opts?: ExecuteSkillOpts,
|
|
87
|
+
) => Promise<{ finalResponse: string }>;
|
|
88
|
+
|
|
89
|
+
let researchSkillExecutorForTest: ResearchSkillExecutorForTest | null = null;
|
|
90
|
+
|
|
91
|
+
/** Replace only skill execution in tests; manifest parsing still uses the real selected skill root. */
|
|
92
|
+
export function setResearchSkillExecutorForTest(executor: ResearchSkillExecutorForTest | null): void {
|
|
93
|
+
researchSkillExecutorForTest = executor;
|
|
94
|
+
}
|
|
95
|
+
|
|
81
96
|
let invoker: ResearchInvoker | null = null;
|
|
82
97
|
|
|
83
98
|
/** Register the production / test invoker. Pass null to revert to
|
|
@@ -103,19 +118,21 @@ async function defaultInvoker(
|
|
|
103
118
|
args: string,
|
|
104
119
|
onProgress?: (delta: string) => void,
|
|
105
120
|
signal?: AbortSignal,
|
|
121
|
+
skillRootDir?: string,
|
|
106
122
|
): Promise<ResearchInvocationOutcome> {
|
|
107
123
|
const { parseSkillMd, executeSkill } = await import('../skills/runner.js');
|
|
108
|
-
const manifest = parseSkillMd(skillName);
|
|
124
|
+
const manifest = parseSkillMd(skillName, skillRootDir);
|
|
109
125
|
if (!manifest) {
|
|
110
126
|
return {
|
|
111
127
|
output: '',
|
|
112
128
|
ok: false,
|
|
113
|
-
error: `skill "${skillName}" not found under ~/.claude/skills/`,
|
|
129
|
+
error: `skill "${skillName}" not found under ${skillRootDir ?? '~/.claude/skills'}/`,
|
|
114
130
|
};
|
|
115
131
|
}
|
|
116
132
|
try {
|
|
117
133
|
// ★ research 격리 — 파일-쓰기 도구 deny 주입(main 트리 오염 차단). Bash·검색도구는 유지.
|
|
118
|
-
const
|
|
134
|
+
const run = researchSkillExecutorForTest ?? executeSkill;
|
|
135
|
+
const result = await run(withResearchIsolation(manifest), args, (delta) => {
|
|
119
136
|
if (onProgress) onProgress(delta);
|
|
120
137
|
}, { signal });
|
|
121
138
|
return researchOutcomeFromSkillRun(result);
|
|
@@ -138,7 +155,7 @@ export async function invokeResearch(
|
|
|
138
155
|
): Promise<ExternalResearchResult> {
|
|
139
156
|
const skillName = opts.skill || DEFAULT_SKILL;
|
|
140
157
|
const startedAt = new Date();
|
|
141
|
-
const outcome = await (invoker ?? defaultInvoker)(skillName, topic, opts.onProgress, opts.signal);
|
|
158
|
+
const outcome = await (invoker ?? defaultInvoker)(skillName, topic, opts.onProgress, opts.signal, opts.skillRootDir);
|
|
142
159
|
const finishedAt = new Date();
|
|
143
160
|
const result: ExternalResearchResult = {
|
|
144
161
|
topic,
|
|
@@ -28,6 +28,8 @@ export interface ExternalResearchResult {
|
|
|
28
28
|
export interface InvokeResearchOpts {
|
|
29
29
|
/** Skill name override; default 'omni-crawl'. */
|
|
30
30
|
skill?: string;
|
|
31
|
+
/** Root directory containing the selected catalog entry. */
|
|
32
|
+
skillRootDir?: string;
|
|
31
33
|
/** Stream progress chunks back to the caller (e.g. dashboard chat
|
|
32
34
|
* pane) so the user sees activity for long-running invocations. */
|
|
33
35
|
onProgress?: (delta: string) => void;
|
|
@@ -29,8 +29,10 @@ import {
|
|
|
29
29
|
renderConcurrentAuthoringNotice,
|
|
30
30
|
renderLaunchPreflight,
|
|
31
31
|
renderRepeatedBlockNotice,
|
|
32
|
+
renderSiblingContextLines,
|
|
32
33
|
siblingTestPath,
|
|
33
34
|
type AskPreflightDeps,
|
|
35
|
+
type SiblingContextCard,
|
|
34
36
|
type LaunchPreflightResult,
|
|
35
37
|
type PriorBlockSample,
|
|
36
38
|
type RecentAuthoringSample,
|
|
@@ -245,6 +247,8 @@ export interface AskLaunchFlowInput {
|
|
|
245
247
|
readonly goalType?: import('../self-implement/goal-author.js').GoalType;
|
|
246
248
|
/** 런 식별자가 이미 있으면 앞단 관측을 그 키로 잇는다. 없으면 관측은 runId 없이 남는다. */
|
|
247
249
|
readonly runId?: string;
|
|
250
|
+
/** CARD-TARGET-PATHS가 제공한 같은-경로 카드 관측. 발사 판정에는 쓰지 않는다. */
|
|
251
|
+
readonly cardsTouchingPaths?: readonly SiblingContextCard[];
|
|
248
252
|
/** Explicit harness choice; false is distinct from omission. */
|
|
249
253
|
readonly selfResolveClarifications?: boolean;
|
|
250
254
|
}
|
|
@@ -258,6 +262,18 @@ export type AskLaunchFlowResult =
|
|
|
258
262
|
/** ⑴ 저작에서 접지 예산(AUTHOR-TIMEBOX)을 넘겨 NOT-GROUNDED 로 끝났다 — 발사하지 «않는다». */
|
|
259
263
|
| { readonly kind: 'stopped-by-timebox'; readonly goalFile: string };
|
|
260
264
|
|
|
265
|
+
/**
|
|
266
|
+
* A harness entry can be named inside a request whose operative instruction is
|
|
267
|
+
* explicitly read-only. Require both a read-only marker and a no-write marker;
|
|
268
|
+
* either alone is too broad (for example, implementing a read-only feature).
|
|
269
|
+
*/
|
|
270
|
+
function isExplicitReadOnlyNoWriteRequest(text: string): boolean {
|
|
271
|
+
const normalized = text.normalize('NFKC').toLowerCase();
|
|
272
|
+
const readOnly = /(?:read[\s-]*only|readonly|읽기\s*전용|읽기만|파일\s*존재\s*여부만|상태만\s*확인)/u.test(normalized);
|
|
273
|
+
const noWrite = /(?:수정하지\s*마|변경하지\s*마|변경\s*금지|파일을?\s*만들지\s*마|쓰지\s*마|편집하지\s*마|no\s+(?:file\s+)?changes?|do\s+not\s+(?:edit|modify|write|create)|don't\s+(?:edit|modify|write|create)|without\s+(?:editing|modifying|writing)|\bcommit\b.{0,24}(?:하지\s*마|금지)|\bpush\b.{0,24}(?:하지\s*마|금지)|\bpr\b.{0,24}(?:하지\s*마|금지))/u.test(normalized);
|
|
274
|
+
return readOnly && noWrite;
|
|
275
|
+
}
|
|
276
|
+
|
|
261
277
|
/** ⑴ AUTHOR-TIMEBOX NOT-GROUNDED — 결과 줄을 쓰고 흐름을 끊는 값. */
|
|
262
278
|
export type AskLaunchFlowTimeboxStop = Extract<AskLaunchFlowResult, { kind: 'stopped-by-timebox' }>;
|
|
263
279
|
|
|
@@ -858,9 +874,23 @@ export async function runAskLaunchFlow(
|
|
|
858
874
|
// ⛔ 이 목록은 «광고»다 — 실제 단계와 어긋나면 조회하는 사람이 없는 단계를 찾거나 있는 단계를 안 찾는다.
|
|
859
875
|
// ⛔ 분해 단계는 «두 이름 중 하나»로 난다 — 켜졌으면 `…-decomposition`, 꺼졌으면 `…-decomposition-skipped`.
|
|
860
876
|
// ⭐ 뒤엣것을 빼 두면 조회하는 사람이 「분해 관측이 0건이다」를 보고 «없어졌다»로 읽는다(실은 꺼진 것이다).
|
|
861
|
-
steps: ['ask-start', 'ask-pre-preflight', 'ask-authored', 'ask-launching-tree', 'ask-preflight', 'ask-launch-decomposition', 'ask-launch-decomposition-skipped', 'ask-launch'],
|
|
877
|
+
steps: ['ask-start', 'ask-readonly-no-launch', 'ask-pre-preflight', 'ask-authored', 'ask-launching-tree', 'ask-preflight', 'ask-launch-decomposition', 'ask-launch-decomposition-skipped', 'ask-launch'],
|
|
862
878
|
}, 'info');
|
|
863
879
|
|
|
880
|
+
if (isExplicitReadOnlyNoWriteRequest(input.askText)) {
|
|
881
|
+
deps.log('ask-readonly-no-launch', {
|
|
882
|
+
entrance: entrance.id,
|
|
883
|
+
surface: entrance.surface,
|
|
884
|
+
inputSource: input.inputSource,
|
|
885
|
+
runId: input.runId ?? process.env.ELANOUS_RUN_ID ?? null,
|
|
886
|
+
authoringSkipped: true,
|
|
887
|
+
launchSkipped: true,
|
|
888
|
+
completionModeSelected: false,
|
|
889
|
+
}, 'info');
|
|
890
|
+
deps.print('[ask] 읽기 전용·변경 금지 요청으로 판정해 구현·자동 병합을 시작하지 않았습니다. TUI 읽기 도구로 결과만 확인하세요.');
|
|
891
|
+
return { kind: 'stopped-before-authoring' };
|
|
892
|
+
}
|
|
893
|
+
|
|
864
894
|
const launchPreflight = await runPrePreflight(input, deps);
|
|
865
895
|
if (launchPreflight === false) return { kind: 'stopped-before-authoring' };
|
|
866
896
|
|
|
@@ -1036,6 +1066,47 @@ export async function runAskLaunchFlow(
|
|
|
1036
1066
|
const preflight = decision.result;
|
|
1037
1067
|
deps.print(renderLaunchPreflight(preflight, input.forceRequested && decision.shouldLaunch && preflight.blockers.length > 0, 'before-launch'));
|
|
1038
1068
|
observeLaunchPreflight(deps, 'before-launch', decision);
|
|
1069
|
+
let siblingCards = input.cardsTouchingPaths;
|
|
1070
|
+
let siblingCardsUnmeasured = false;
|
|
1071
|
+
if (siblingCards === undefined && preflight.paths.length > 0) {
|
|
1072
|
+
try {
|
|
1073
|
+
// CARD-TARGET-PATHS is a read-only signal: production entrances use the shared task-card store when
|
|
1074
|
+
// no caller supplied a precomputed snapshot. The launch decision never depends on these matches.
|
|
1075
|
+
const taskHand = await import('../task-agent/task-hand.js');
|
|
1076
|
+
const state = taskHand.readTaskAgentState<{ tasks?: Record<string, import('../task-agent/task-hand.js').TaskCard> }>(taskHand.taskAgentStatePath());
|
|
1077
|
+
siblingCards = taskHand.cardsTouchingPaths(Object.values(state.tasks ?? {}), preflight.paths)
|
|
1078
|
+
.map(({ card, runId, paths }) => ({ cardId: card.id, ...(runId ? { runId } : {}), overlapPaths: paths }));
|
|
1079
|
+
} catch (error) {
|
|
1080
|
+
siblingCardsUnmeasured = true;
|
|
1081
|
+
try { debug.log('self-dev.ask', 'sibling-context-cards-unmeasured', { reason: error instanceof Error ? error.message : String(error) }); }
|
|
1082
|
+
catch { /* supplemental card context remains fail-soft */ }
|
|
1083
|
+
siblingCards = [];
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
const siblingContextLines = renderSiblingContextLines(preflight, siblingCards);
|
|
1087
|
+
const recentLanded = preflight.warnings.filter((warning) => warning.kind === 'recent-change' && preflight.paths.includes(warning.name)).length;
|
|
1088
|
+
const siblingContextObservation = {
|
|
1089
|
+
liveRuns: preflight.warnings.filter((warning) => warning.kind === 'live-run').length,
|
|
1090
|
+
openPrs: preflight.warnings.filter((warning) => warning.kind === 'open-pr' || warning.kind === 'sibling-pr').length,
|
|
1091
|
+
recentLanded,
|
|
1092
|
+
unmeasured: siblingCardsUnmeasured || preflight.liveRuns.state === 'unknown' || preflight.openPrs.state === 'unknown' || preflight.recentChanges.state === 'unknown' || preflight.unreadableRuns > 0,
|
|
1093
|
+
};
|
|
1094
|
+
try { debug.log('self-dev.ask', 'sibling-context', siblingContextObservation); }
|
|
1095
|
+
catch { /* sibling context observation must not change launch */ }
|
|
1096
|
+
if (!sanitizeFailed && existsSync(goalFile)) {
|
|
1097
|
+
try {
|
|
1098
|
+
const document = deps.readFile(goalFile);
|
|
1099
|
+
const firstSection = document.search(/^## /mu);
|
|
1100
|
+
const header = siblingContextLines.join('\n');
|
|
1101
|
+
const beforeFirstSection = firstSection < 0 ? document : document.slice(0, firstSection).trimEnd();
|
|
1102
|
+
const contextualized = firstSection < 0
|
|
1103
|
+
? `${header}\n\n${document}`
|
|
1104
|
+
: `${beforeFirstSection ? `${beforeFirstSection}\n` : ''}${header}\n형제가 같은 파일을 고친다 — 국소 변경만 · 무관 포맷 금지 · 자기 의도를 시험으로 고정\n\n${document.slice(firstSection)}`;
|
|
1105
|
+
(deps.writeGoalDocument ?? deps.writeFile)(goalFile, contextualized);
|
|
1106
|
+
} catch (error) {
|
|
1107
|
+
deps.print(`[ask] 형제 맥락 기록 못 남김 (${error instanceof Error ? error.message : String(error)})`);
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1039
1110
|
// ⛔ 자식 격리 worktree를 만들기 전, 이 흐름을 호출한 작업 트리에서만 센다.
|
|
1040
1111
|
// 이 관측은 발사 판정의 입력이 아니다 — 의도적으로 옛 판에서 쏘는 경우도 있다.
|
|
1041
1112
|
const invokerBehindDefaultBranch = deps.measureInvokerBehindDefaultBranch?.()
|